Processing math: 0%
libMesh
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
Classes | Public Member Functions | Static Public Member Functions | Public Attributes | Protected Types | Protected Member Functions | Protected Attributes | Static Protected Attributes | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | Friends | List of all members
libMesh::DofMap Class Reference

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

#include <dof_map.h>

Inheritance diagram for libMesh::DofMap:
[legend]

Classes

class  AugmentSendList
 Abstract base class to be used to add user-defined parallel degree of freedom couplings. More...
 
class  AugmentSparsityPattern
 Backwards compatibility for prior AugmentSparsityPattern users. More...
 

Public Member Functions

 DofMap (const unsigned int sys_number, MeshBase &mesh)
 Constructor. More...
 
 ~DofMap ()
 Destructor. More...
 
void attach_matrix (SparseMatrix< Number > &matrix)
 Additional matrices may be attached to this DofMap. More...
 
void update_sparsity_pattern (SparseMatrix< Number > &matrix) const
 Additional matrices may be be temporarily initialized by this DofMap. More...
 
bool is_attached (SparseMatrix< Number > &matrix)
 Matrices should not be attached more than once. More...
 
std::size_t distribute_dofs (MeshBase &)
 Distribute dofs on the current mesh. More...
 
void compute_sparsity (const MeshBase &)
 Computes the sparsity pattern for the matrices corresponding to proc_id and sends that data to Linear Algebra packages for preallocation of sparse matrices. More...
 
bool computed_sparsity_already () const
 Returns true iff a sparsity pattern has already been computed. More...
 
void set_constrained_sparsity_construction (bool use_constraints)
 Sets the current policy for constructing sparsity patterns: if use_constraints is true (for robustness), we explicitly account for sparsity entries created by constraint matrix pre- and post- application. More...
 
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...
 
std::set< GhostingFunctor * >::const_iterator coupling_functors_begin () const
 Beginning of range of coupling functors. More...
 
std::set< GhostingFunctor * >::const_iterator coupling_functors_end () const
 End of range of coupling functors. More...
 
DefaultCouplingdefault_coupling ()
 Default coupling functor. More...
 
void add_algebraic_ghosting_functor (GhostingFunctor &evaluable_functor, bool to_mesh=true)
 Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors. More...
 
void add_algebraic_ghosting_functor (std::shared_ptr< GhostingFunctor > evaluable_functor, bool to_mesh=true)
 Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors. More...
 
void remove_algebraic_ghosting_functor (GhostingFunctor &evaluable_functor)
 Removes a functor which was previously added to the set of algebraic ghosting functors, from both this DofMap and from the underlying mesh. More...
 
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_begin () const
 Beginning of range of algebraic ghosting functors. More...
 
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_end () const
 End of range of algebraic ghosting functors. More...
 
DefaultCouplingdefault_algebraic_ghosting ()
 Default algebraic ghosting functor. More...
 
void attach_extra_sparsity_object (SparsityPattern::AugmentSparsityPattern &asp)
 Attach an object to use to populate the sparsity pattern with extra entries. More...
 
void attach_extra_sparsity_function (void(*func)(SparsityPattern::Graph &sparsity, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *), void *context=nullptr)
 Attach a function pointer to use as a callback to populate the sparsity pattern with extra entries. More...
 
void attach_extra_send_list_object (DofMap::AugmentSendList &asl)
 Attach an object to populate the send_list with extra entries. More...
 
void attach_extra_send_list_function (void(*func)(std::vector< dof_id_type > &, void *), void *context=nullptr)
 Attach a function pointer to use as a callback to populate the send_list with extra entries. More...
 
void prepare_send_list ()
 Takes the _send_list vector (which may have duplicate entries) and sorts it. More...
 
void clear_send_list ()
 Clears the _send_list vector. More...
 
void reinit_send_list (MeshBase &mesh)
 Clears the _send_list vector and then rebuilds it. More...
 
const std::vector< dof_id_type > & get_send_list () const
 
const std::vector< dof_id_type > & get_n_nz () const
 
const std::vector< dof_id_type > & get_n_oz () const
 
const SparsityPattern::Buildget_sparsity_pattern () const
 
void add_variable_group (VariableGroup var_group)
 Add an unknown of order order and finite element type type to the system of equations. More...
 
void set_error_on_cyclic_constraint (bool error_on_cyclic_constraint)
 Specify whether or not we perform an extra (opt-mode enabled) check for constraint loops. More...
 
void set_error_on_constraint_loop (bool error_on_constraint_loop)
 
const VariableGroupvariable_group (const unsigned int c) const
 
const Variablevariable (const unsigned int c) const
 
Order variable_order (const unsigned int c) const
 
Order variable_group_order (const unsigned int vg) const
 
const FETypevariable_type (const unsigned int c) const
 
const FETypevariable_group_type (const unsigned int vg) const
 
unsigned int n_variable_groups () const
 
unsigned int n_variables () const
 
unsigned int var_group_from_var_number (unsigned int var_num) const
 
bool has_blocked_representation () const
 
unsigned int block_size () const
 
dof_id_type n_dofs () const
 
dof_id_type n_dofs (const unsigned int vn) const
 
dof_id_type n_SCALAR_dofs () const
 
dof_id_type n_local_dofs () const
 
dof_id_type n_local_dofs (const unsigned int vn) const
 
dof_id_type n_dofs_on_processor (const processor_id_type proc) const
 
std::vector< dof_id_typen_dofs_per_processor (const unsigned int vn) const
 
dof_id_type first_dof (const processor_id_type proc) const
 
dof_id_type first_dof () const
 
dof_id_type first_old_dof (const processor_id_type proc) const
 
dof_id_type first_old_dof () const
 
dof_id_type end_dof (const processor_id_type proc) const
 
dof_id_type end_dof () const
 
processor_id_type dof_owner (const dof_id_type dof) const
 
dof_id_type end_old_dof (const processor_id_type proc) const
 
dof_id_type end_old_dof () const
 
void dof_indices (const Elem *const elem, std::vector< dof_id_type > &di) const
 Fills the vector di with the global degree of freedom indices for the element. More...
 
void dof_indices (const Elem *const elem, std::vector< dof_id_type > &di, const unsigned int vn, int p_level=-12345) const
 Fills the vector di with the global degree of freedom indices for the element. More...
 
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
 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...
 
dof_id_type n_constrained_dofs () const
 
dof_id_type n_local_constrained_dofs () const
 
dof_id_type n_constrained_nodes () const
 
void create_dof_constraints (const MeshBase &, Real time=0)
 Rebuilds the raw degree of freedom and DofObject constraints, based on attached DirichletBoundary objects and on non-conforming interface in adapted meshes. More...
 
void allgather_recursive_constraints (MeshBase &)
 Gathers constraint equation dependencies from other processors. More...
 
void scatter_constraints (MeshBase &)
 Sends constraint equations to constraining processors. More...
 
void gather_constraints (MeshBase &mesh, std::set< dof_id_type > &unexpanded_dofs, bool look_for_constrainees)
 Helper function for querying about constraint equations on other processors. More...
 
void process_constraints (MeshBase &)
 Postprocesses any constrained degrees of freedom to be constrained only in terms of unconstrained dofs, then adds unconstrained dofs to the send_list and prepares that for use. More...
 
void check_for_cyclic_constraints ()
 Throw an error if we detect any constraint loops, i.e. More...
 
void check_for_constraint_loops ()
 
void add_constraint_row (const dof_id_type dof_number, const DofConstraintRow &constraint_row, const Number constraint_rhs, const bool forbid_constraint_overwrite)
 Adds a copy of the user-defined row to the constraint matrix, using an inhomogeneous right-hand-side for the constraint equation. More...
 
void add_adjoint_constraint_row (const unsigned int qoi_index, const dof_id_type dof_number, const DofConstraintRow &constraint_row, const Number constraint_rhs, const bool forbid_constraint_overwrite)
 Adds a copy of the user-defined row to the constraint matrix, using an inhomogeneous right-hand-side for the adjoint constraint equation. More...
 
void add_constraint_row (const dof_id_type dof_number, const DofConstraintRow &constraint_row, const bool forbid_constraint_overwrite=true)
 Adds a copy of the user-defined row to the constraint matrix, using a homogeneous right-hand-side for the constraint equation. More...
 
DofConstraints::const_iterator constraint_rows_begin () const
 
DofConstraints::const_iterator constraint_rows_end () const
 
const DofConstraintsget_dof_constraints () const
 Provide a const accessor to the DofConstraints map. More...
 
void stash_dof_constraints ()
 
void unstash_dof_constraints ()
 
void swap_dof_constraints ()
 Similar to the stash/unstash_dof_constraints() API, but swaps _dof_constraints and _stashed_dof_constraints without asserting that the source or destination is empty first. More...
 
NodeConstraints::const_iterator node_constraint_rows_begin () const
 
NodeConstraints::const_iterator node_constraint_rows_end () const
 
bool is_constrained_dof (const dof_id_type dof) const
 
bool has_heterogeneous_adjoint_constraints (const unsigned int qoi_num) const
 
bool has_heterogenous_adjoint_constraints (const unsigned int qoi_num) const
 Backwards compatibility with misspelling. More...
 
Number has_heterogeneous_adjoint_constraint (const unsigned int qoi_num, const dof_id_type dof) const
 
Number has_heterogenous_adjoint_constraint (const unsigned int qoi_num, const dof_id_type dof) const
 Backwards compatibility with misspelling. More...
 
DofConstraintValueMapget_primal_constraint_values ()
 
bool is_constrained_node (const Node *node) const
 
void print_dof_constraints (std::ostream &os=libMesh::out, bool print_nonlocal=false) const
 Prints (from processor 0) all DoF and Node constraints. More...
 
std::string get_local_constraints (bool print_nonlocal=false) const
 Gets a string reporting all DoF and Node constraints local to this processor. More...
 
std::pair< Real, Realmax_constraint_error (const System &system, NumericVector< Number > *v=nullptr) const
 Tests the constrained degrees of freedom on the numeric vector v, which represents a solution defined on the mesh, returning a pair whose first entry is the maximum absolute error on a constrained DoF and whose second entry is the maximum relative error. More...
 
void constrain_element_matrix (DenseMatrix< Number > &matrix, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
 Constrains the element matrix. More...
 
void constrain_element_matrix (DenseMatrix< Number > &matrix, std::vector< dof_id_type > &row_dofs, std::vector< dof_id_type > &col_dofs, bool asymmetric_constraint_rows=true) const
 Constrains the element matrix. More...
 
void constrain_element_vector (DenseVector< Number > &rhs, std::vector< dof_id_type > &dofs, bool asymmetric_constraint_rows=true) const
 Constrains the element vector. More...
 
void constrain_element_matrix_and_vector (DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
 Constrains the element matrix and vector. More...
 
void heterogeneously_constrain_element_matrix_and_vector (DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
 Constrains the element matrix and vector. More...
 
void heterogenously_constrain_element_matrix_and_vector (DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
 
void heterogeneously_constrain_element_vector (const DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
 Constrains the element vector. More...
 
void heterogenously_constrain_element_vector (const DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
 
void heterogeneously_constrain_element_jacobian_and_residual (DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, NumericVector< Number > &solution_local) const
 Constrains the element Jacobian and residual. More...
 
void heterogeneously_constrain_element_residual (DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, NumericVector< Number > &solution_local) const
 Constrains the element residual. More...
 
void constrain_element_residual (DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, NumericVector< Number > &solution_local) const
 Constrains the element residual. More...
 
void constrain_element_dyad_matrix (DenseVector< Number > &v, DenseVector< Number > &w, std::vector< dof_id_type > &row_dofs, bool asymmetric_constraint_rows=true) const
 Constrains a dyadic element matrix B = v w'. More...
 
void constrain_nothing (std::vector< dof_id_type > &dofs) const
 Does not actually constrain anything, but modifies dofs in the same way as any of the constrain functions would do, i.e. More...
 
void enforce_constraints_exactly (const System &system, NumericVector< Number > *v=nullptr, bool homogeneous=false) const
 Constrains the numeric vector v, which represents a solution defined on the mesh. More...
 
void enforce_adjoint_constraints_exactly (NumericVector< Number > &v, unsigned int q) const
 Heterogeneously constrains the numeric vector v, which represents an adjoint solution defined on the mesh for quantity fo interest q. More...
 
void enforce_constraints_on_residual (const NonlinearImplicitSystem &system, NumericVector< Number > *rhs, NumericVector< Number > const *solution, bool homogeneous=true) const
 
void enforce_constraints_on_jacobian (const NonlinearImplicitSystem &system, SparseMatrix< Number > *jac) const
 
void add_periodic_boundary (const PeriodicBoundaryBase &periodic_boundary)
 Adds a copy of the specified periodic boundary to the system. More...
 
void add_periodic_boundary (const PeriodicBoundaryBase &boundary, const PeriodicBoundaryBase &inverse_boundary)
 Add a periodic boundary pair. More...
 
bool is_periodic_boundary (const boundary_id_type boundaryid) const
 
PeriodicBoundariesget_periodic_boundaries ()
 
const PeriodicBoundariesget_periodic_boundaries () const
 
void add_dirichlet_boundary (const DirichletBoundary &dirichlet_boundary)
 Adds a copy of the specified Dirichlet boundary to the system. More...
 
void add_adjoint_dirichlet_boundary (const DirichletBoundary &dirichlet_boundary, unsigned int q)
 Adds a copy of the specified Dirichlet boundary to the system, corresponding to the adjoint problem defined by Quantity of Interest q. More...
 
void remove_dirichlet_boundary (const DirichletBoundary &dirichlet_boundary)
 Removes the specified Dirichlet boundary from the system. More...
 
void remove_adjoint_dirichlet_boundary (const DirichletBoundary &dirichlet_boundary, unsigned int q)
 Removes from the system the specified Dirichlet boundary for the adjoint equation defined by Quantity of interest index q. More...
 
const DirichletBoundariesget_dirichlet_boundaries () const
 
DirichletBoundariesget_dirichlet_boundaries ()
 
bool has_adjoint_dirichlet_boundaries (unsigned int q) const
 
const DirichletBoundariesget_adjoint_dirichlet_boundaries (unsigned int q) const
 
DirichletBoundariesget_adjoint_dirichlet_boundaries (unsigned int q)
 
void check_dirichlet_bcid_consistency (const MeshBase &mesh, const DirichletBoundary &boundary) const
 Check that all the ids in dirichlet_bcids are actually present in the mesh. More...
 
void old_dof_indices (const Elem *const elem, std::vector< dof_id_type > &di, const unsigned int vn=libMesh::invalid_uint) const
 After a mesh is refined and repartitioned it is possible that the _send_list will need to be augmented. More...
 
dof_id_type n_old_dofs () const
 
void constrain_p_dofs (unsigned int var, const Elem *elem, unsigned int s, unsigned int p)
 Constrains degrees of freedom on side s of element elem which correspond to variable number var and to p refinement levels above p. More...
 
void reinit (MeshBase &mesh, const std::map< const Node *, std::set< subdomain_id_type >> &constraining_subdomains)
 Reinitialize the underlying data structures conformal to the current mesh. More...
 
void clear ()
 Free all new memory associated with the object, but restore its original state, with the mesh pointer and any default ghosting. More...
 
void print_info (std::ostream &os=libMesh::out) const
 Prints summary info about the sparsity bandwidth and constraints. More...
 
std::string get_info () const
 Gets summary info about the sparsity bandwidth and constraints. More...
 
unsigned int sys_number () const
 
std::unique_ptr< SparsityPattern::Buildbuild_sparsity (const MeshBase &mesh, bool calculate_constrained=false) const
 Builds a sparsity pattern for matrices using the current degree-of-freedom numbering and coupling. More...
 
void should_p_refine (unsigned int g, bool p_refine)
 Describe whether the given variable group should be p-refined. More...
 
bool should_p_refine (unsigned int g) const
 Whether the given variable group should be p-refined. More...
 
bool should_p_refine_var (unsigned int var) const
 Whether the given variable should be p-refined. More...
 
void should_p_refine (FEFamily, bool)=delete
 
void should_p_refine (Order, bool)=delete
 
bool should_p_refine (FEFamily) const =delete
 
bool should_p_refine (Order) const =delete
 
void add_static_condensation (const StaticCondensation &sc)
 Add a static condensation class. More...
 
bool has_static_condensation () const
 Checks whether we have static condensation. More...
 
const StaticCondensationget_static_condensation () 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

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

Protected Attributes

const Parallel::Communicator_communicator
 

Static Protected Attributes

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

Private Types

typedef DofObject *(DofMap::* dofobject_accessor) (MeshBase &mesh, dof_id_type i) const
 A member function type like node_ptr() or elem_ptr(). More...
 
typedef std::set< std::unique_ptr< CouplingMatrix >, Utility::CompareUnderlyingCouplingMatricesSet
 

Private Member Functions

void _dof_indices (const Elem &elem, int p_level, std::vector< dof_id_type > &di, const unsigned int vg, const unsigned int vig, const Node *const *nodes, unsigned int n_nodes, 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 std::set< GhostingFunctor *>::iterator &gf_begin, const std::set< GhostingFunctor *>::iterator &gf_end, const MeshBase::const_element_iterator &elems_begin, const MeshBase::const_element_iterator &elems_end, processor_id_type p)
 

Private Attributes

bool _error_on_constraint_loop
 This flag indicates whether or not we do an opt-mode check for the presence of constraint loops, i.e. More...
 
bool _constrained_sparsity_construction
 This flag indicates whether or not we explicitly take constraint equations into account when computing a sparsity pattern. More...
 
std::vector< Variable_variables
 The finite element type for each variable. More...
 
std::vector< VariableGroup_variable_groups
 The finite element type for each variable group. More...
 
std::vector< unsigned int_variable_group_numbers
 The variable group number for each variable. More...
 
std::unordered_map< unsigned int, unsigned int_var_to_vg
 A map from variable number to variable group number. More...
 
const unsigned int _sys_number
 The number of the system we manage DOFs for. More...
 
MeshBase_mesh
 The mesh that system uses. More...
 
std::vector< SparseMatrix< Number > *> _matrices
 Additional matrices handled by this object. More...
 
std::vector< dof_id_type_first_df
 First DOF index on processor p. More...
 
std::vector< dof_id_type_end_df
 Last DOF index (plus 1) on processor p. More...
 
std::vector< dof_id_type_first_scalar_df
 First DOF index for SCALAR variable v, or garbage for non-SCALAR variable v. More...
 
std::vector< dof_id_type_send_list
 A list containing all the global DOF indices that affect the solution on my processor. More...
 
SparsityPattern::AugmentSparsityPattern_augment_sparsity_pattern
 Function object to call to add extra entries to the sparsity pattern. More...
 
void(* _extra_sparsity_function )(SparsityPattern::Graph &, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *)
 A function pointer to a function to call to add extra entries to the sparsity pattern. More...
 
void * _extra_sparsity_context
 A pointer associated with the extra sparsity that can optionally be passed in. More...
 
AugmentSendList_augment_send_list
 Function object to call to add extra entries to the send list. More...
 
void(* _extra_send_list_function )(std::vector< dof_id_type > &, void *)
 A function pointer to a function to call to add extra entries to the send list. More...
 
void * _extra_send_list_context
 A pointer associated with the extra send list that can optionally be passed in. More...
 
std::unique_ptr< DefaultCoupling_default_coupling
 The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern construction. More...
 
std::unique_ptr< DefaultCoupling_default_evaluating
 The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction. More...
 
std::set< GhostingFunctor * > _algebraic_ghosting_functors
 The list of all GhostingFunctor objects to be used when distributing ghosted vectors. More...
 
std::set< GhostingFunctor * > _coupling_functors
 The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsity patterns. More...
 
std::map< GhostingFunctor *, std::shared_ptr< GhostingFunctor > > _shared_functors
 Hang on to references to any GhostingFunctor objects we were passed in shared_ptr form. More...
 
bool need_full_sparsity_pattern
 Default false; set to true if any attached matrix requires a full sparsity pattern. More...
 
std::unique_ptr< SparsityPattern::Build_sp
 The sparsity pattern of the global matrix. More...
 
dof_id_type _n_dfs
 Total number of degrees of freedom. More...
 
dof_id_type _n_SCALAR_dofs
 The total number of SCALAR dofs associated to all SCALAR variables. More...
 
dof_id_type _n_old_dfs
 Total number of degrees of freedom on old dof objects. More...
 
std::vector< dof_id_type_first_old_df
 First old DOF index on processor p. More...
 
std::vector< dof_id_type_end_old_df
 Last old DOF index (plus 1) on processor p. More...
 
std::vector< dof_id_type_first_old_scalar_df
 First old DOF index for SCALAR variable v, or garbage for non-SCALAR variable v. More...
 
std::unordered_set< unsigned int_dont_p_refine
 A container of variable groups that we should not p-refine. More...
 
DofConstraints _dof_constraints
 Data structure containing DOF constraints. More...
 
DofConstraints _stashed_dof_constraints
 
DofConstraintValueMap _primal_constraint_values
 
AdjointDofConstraintValues _adjoint_constraint_values
 
NodeConstraints _node_constraints
 Data structure containing DofObject constraints. More...
 
std::unique_ptr< PeriodicBoundaries_periodic_boundaries
 Data structure containing periodic boundaries. More...
 
std::unique_ptr< DirichletBoundaries_dirichlet_boundaries
 Data structure containing Dirichlet functions. More...
 
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
 Data structure containing Dirichlet functions. More...
 
bool _implicit_neighbor_dofs_initialized
 Bools to indicate if we override the –implicit_neighbor_dofs commandline options. More...
 
bool _implicit_neighbor_dofs
 
bool _verify_dirichlet_bc_consistency
 Flag which determines whether we should do some additional checking of the consistency of the DirichletBoundary objects added by the user. More...
 
const StaticCondensation_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 178 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 1912 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 1829 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 127 of file dof_map.C.

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

128  :
129  ParallelObject (mesh.comm()),
130  _dof_coupling(nullptr),
133  _variables(),
136  _sys_number(number),
137  _mesh(mesh),
138  _matrices(),
139  _first_df(),
140  _end_df(),
142  _send_list(),
143  _augment_sparsity_pattern(nullptr),
144  _extra_sparsity_function(nullptr),
145  _extra_sparsity_context(nullptr),
146  _augment_send_list(nullptr),
147  _extra_send_list_function(nullptr),
148  _extra_send_list_context(nullptr),
149  _default_coupling(std::make_unique<DefaultCoupling>()),
150  _default_evaluating(std::make_unique<DefaultCoupling>()),
152  _n_dfs(0),
153  _n_SCALAR_dofs(0)
154 #ifdef LIBMESH_ENABLE_AMR
155  , _n_old_dfs(0),
156  _first_old_df(),
157  _end_old_df(),
159 #endif
160 #ifdef LIBMESH_ENABLE_CONSTRAINTS
161  , _dof_constraints()
165 #endif
166 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
168 #endif
169 #ifdef LIBMESH_ENABLE_PERIODIC
170  , _periodic_boundaries(std::make_unique<PeriodicBoundaries>())
171 #endif
172 #ifdef LIBMESH_ENABLE_DIRICHLET
173  , _dirichlet_boundaries(std::make_unique<DirichletBoundaries>())
175 #endif
179  _sc(nullptr)
180 {
181  _matrices.clear();
182 
183  _default_coupling->set_mesh(&_mesh);
184  _default_evaluating->set_mesh(&_mesh);
185  _default_evaluating->set_n_levels(1);
186 
187 #ifdef LIBMESH_ENABLE_PERIODIC
188  _default_coupling->set_periodic_boundaries(_periodic_boundaries.get());
189  _default_evaluating->set_periodic_boundaries(_periodic_boundaries.get());
190 #endif
191 
194 }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable group.
Definition: dof_map.h:2014
ParallelObject(const Parallel::Communicator &comm_in)
Constructor.
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
Definition: dof_map.h:2243
const unsigned int _sys_number
The number of the system we manage DOFs for.
Definition: dof_map.h:2029
bool _implicit_neighbor_dofs
Definition: dof_map.h:2244
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:1998
void * _extra_sparsity_context
A pointer associated with the extra sparsity that can optionally be passed in.
Definition: dof_map.h:2080
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:2063
MeshBase & mesh
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2228
std::vector< dof_id_type > _end_old_df
Last old DOF index (plus 1) on processor p.
Definition: dof_map.h:2181
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:2053
std::vector< dof_id_type > _first_old_df
First old DOF index on processor p.
Definition: dof_map.h:2176
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:2057
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2204
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
Definition: dof_map.h:2004
AugmentSendList * _augment_send_list
Function object to call to add extra entries to the send list.
Definition: dof_map.h:2085
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2146
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:2187
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:2073
dof_id_type _n_SCALAR_dofs
The total number of SCALAR dofs associated to all SCALAR variables.
Definition: dof_map.h:2164
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2200
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1683
void * _extra_send_list_context
A pointer associated with the extra send list that can optionally be passed in.
Definition: dof_map.h:2095
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2041
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2234
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2220
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:2256
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:2103
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2202
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:2009
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2200
SparsityPattern::AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:2068
dof_id_type _n_old_dfs
Total number of degrees of freedom on old dof objects.
Definition: dof_map.h:2171
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:2051
std::vector< dof_id_type > _first_df
First DOF index on processor p.
Definition: dof_map.h:2046
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:2090
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2034
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:2111
const StaticCondensation * _sc
Static condensation class.
Definition: dof_map.h:2259
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:2019
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:2078
dof_id_type _n_dfs
Total number of degrees of freedom.
Definition: dof_map.h:2158
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2211

◆ ~DofMap()

libMesh::DofMap::~DofMap ( )

Destructor.

Definition at line 199 of file dof_map.C.

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

200 {
201  this->clear();
202 
203  // clear() resets all but the default DofMap-based functors. We
204  // need to remove those from the mesh too before we die.
207 }
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:930
void clear()
Free all new memory associated with the object, but restore its original state, with the mesh pointer...
Definition: dof_map.C:898
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:2103
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2034
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:2111

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

References n_nodes.

Referenced by dof_indices().

2548 {
2549  _dof_indices(elem,
2550  p_level,
2551  di,
2552  vg,
2553  vig,
2554  nodes,
2555  n_nodes,
2556  v,
2557 #ifdef DEBUG
2558  tot_size,
2559 #endif
2560  [](const Elem &,
2561  unsigned int,
2562  unsigned int,
2563  std::vector<dof_id_type> & functor_di,
2564  const dof_id_type dof) { functor_di.push_back(dof); });
2565 }
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:2535
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 2543 of file dof_map.h.

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

2555 {
2556  const VariableGroup & var = this->variable_group(vg);
2557 
2558  if (var.active_on_subdomain(elem.subdomain_id()))
2559  {
2560  const ElemType type = elem.type();
2561  const unsigned int sys_num = this->sys_number();
2562 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2563  const bool is_inf = elem.infinite();
2564 #endif
2565 
2566  const bool extra_hanging_dofs =
2567  FEInterface::extra_hanging_dofs(var.type());
2568 
2569  FEType fe_type = var.type();
2570 
2571  const bool add_p_level =
2572 #ifdef LIBMESH_ENABLE_AMR
2573  !_dont_p_refine.count(vg);
2574 #else
2575  false;
2576 #endif
2577 
2578 #ifdef DEBUG
2579  // The number of dofs per element is non-static for subdivision FE
2580  if (var.type().family == SUBDIVISION)
2581  tot_size += n_nodes;
2582  else
2583  // FIXME: Is the passed-in p_level just elem.p_level()? If so,
2584  // this seems redundant.
2585  tot_size += FEInterface::n_dofs(fe_type, add_p_level*p_level, &elem);
2586 #endif
2587 
2588  // The total Order is not required when getting the function
2589  // pointer, it is only needed when the function is called (see
2590  // below).
2591  const FEInterface::n_dofs_at_node_ptr ndan =
2592  FEInterface::n_dofs_at_node_function(fe_type, &elem);
2593 
2594  // Get the node-based DOF numbers
2595  for (unsigned int n=0; n != n_nodes; n++)
2596  {
2597  const Node & node = *nodes[n];
2598 
2599  // Cache the intermediate lookups that are common to every
2600  // component
2601 #ifdef DEBUG
2602  const std::pair<unsigned int, unsigned int>
2603  vg_and_offset = node.var_to_vg_and_offset(sys_num,v);
2604  libmesh_assert_equal_to (vg, vg_and_offset.first);
2605  libmesh_assert_equal_to (vig, vg_and_offset.second);
2606 #endif
2607  const unsigned int n_comp = node.n_comp_group(sys_num,vg);
2608 
2609  // There is a potential problem with h refinement. Imagine a
2610  // quad9 that has a linear FE on it. Then, on the hanging side,
2611  // it can falsely identify a DOF at the mid-edge node. This is why
2612  // we go through FEInterface instead of node.n_comp() directly.
2613  const unsigned int nc =
2614 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2615  is_inf ?
2616  FEInterface::n_dofs_at_node(fe_type, add_p_level*p_level, &elem, n) :
2617 #endif
2618  ndan (type, fe_type.order + add_p_level*p_level, n);
2619 
2620  // If this is a non-vertex on a hanging node with extra
2621  // degrees of freedom, we use the non-vertex dofs (which
2622  // come in reverse order starting from the end, to
2623  // simplify p refinement)
2624  if (extra_hanging_dofs && !elem.is_vertex(n))
2625  {
2626  const int dof_offset = n_comp - nc;
2627 
2628  // We should never have fewer dofs than necessary on a
2629  // node unless we're getting indices on a parent element,
2630  // and we should never need the indices on such a node
2631  if (dof_offset < 0)
2632  {
2633  libmesh_assert(!elem.active());
2634  di.resize(di.size() + nc, DofObject::invalid_id);
2635  }
2636  else
2637  for (int i=int(n_comp)-1; i>=dof_offset; i--)
2638  {
2639  const dof_id_type d =
2640  node.dof_number(sys_num, vg, vig, i, n_comp);
2641  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2642  field_dofs_functor(elem, n, v, di, d);
2643  }
2644  }
2645  // If this is a vertex or an element without extra hanging
2646  // dofs, our dofs come in forward order coming from the
2647  // beginning
2648  else
2649  {
2650  // We have a good component index only if it's being
2651  // used on this FE type (nc) *and* it's available on
2652  // this DofObject (n_comp).
2653  const unsigned int good_nc = std::min(n_comp, nc);
2654  for (unsigned int i=0; i!=good_nc; ++i)
2655  {
2656  const dof_id_type d =
2657  node.dof_number(sys_num, vg, vig, i, n_comp);
2658  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2659  libmesh_assert_less (d, this->n_dofs());
2660  field_dofs_functor(elem, n, v, di, d);
2661  }
2662 
2663  // With fewer good component indices than we need, e.g.
2664  // due to subdomain expansion, the remaining expected
2665  // indices are marked invalid.
2666  if (n_comp < nc)
2667  for (unsigned int i=n_comp; i!=nc; ++i)
2668  di.push_back(DofObject::invalid_id);
2669  }
2670  }
2671 
2672  // If there are any element-based DOF numbers, get them
2673  const unsigned int nc = FEInterface::n_dofs_per_elem(fe_type, add_p_level*p_level, &elem);
2674 
2675  // We should never have fewer dofs than necessary on an
2676  // element unless we're getting indices on a parent element
2677  // (and we should never need those indices) or off-domain for a
2678  // subdomain-restricted variable (where invalid_id is the
2679  // correct thing to return)
2680  if (nc != 0)
2681  {
2682  const unsigned int n_comp = elem.n_comp_group(sys_num,vg);
2683  if (elem.n_systems() > sys_num && nc <= n_comp)
2684  {
2685  for (unsigned int i=0; i<nc; i++)
2686  {
2687  const dof_id_type d =
2688  elem.dof_number(sys_num, vg, vig, i, n_comp);
2689  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2690 
2691  field_dofs_functor(elem, invalid_uint, v, di, d);
2692  }
2693  }
2694  else
2695  {
2696  libmesh_assert(!elem.active() || fe_type.family == LAGRANGE || fe_type.family == SUBDIVISION);
2697  di.resize(di.size() + nc, DofObject::invalid_id);
2698  }
2699  }
2700  }
2701 }
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:530
ElemType
Defines an enum for geometric element types.
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:355
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:293
unsigned int sys_number() const
Definition: dof_map.h:2266
const dof_id_type n_nodes
Definition: tecplot_io.C:67
dof_id_type n_dofs() const
Definition: dof_map.h:673
static bool extra_hanging_dofs(const FEType &fe_t)
libmesh_assert(ctx)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2274
static n_dofs_at_node_ptr n_dofs_at_node_function(const unsigned int dim, const FEType &fe_t)
Definition: fe_interface.C:458
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
Definition: fe_interface.C:436
unsigned int(* n_dofs_at_node_ptr)(const ElemType, const Order, const unsigned int)
Definition: fe_interface.h:151
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
Definition: dof_map.h:2192
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 2451 of file dof_map.C.

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

Referenced by dof_indices(), and old_dof_indices().

2456 {
2457  // Half of this is a cut and paste of _dof_indices code below, but
2458  // duplication actually seems cleaner than creating a helper
2459  // function with a million arguments and hoping the compiler inlines
2460  // it properly into one of our most highly trafficked functions.
2461 
2462  LOG_SCOPE("_node_dof_indices()", "DofMap");
2463 
2464  const unsigned int sys_num = this->sys_number();
2465  const auto [vg, vig] =
2466  obj.var_to_vg_and_offset(sys_num,vn);
2467  const unsigned int n_comp = obj.n_comp_group(sys_num,vg);
2468 
2469  const VariableGroup & var = this->variable_group(vg);
2470  FEType fe_type = var.type();
2471  const bool extra_hanging_dofs =
2473 
2474  const bool add_p_level =
2475 #ifdef LIBMESH_ENABLE_AMR
2476  !_dont_p_refine.count(vg);
2477 #else
2478  false;
2479 #endif
2480 
2481  // There is a potential problem with h refinement. Imagine a
2482  // quad9 that has a linear FE on it. Then, on the hanging side,
2483  // it can falsely identify a DOF at the mid-edge node. This is why
2484  // we go through FEInterface instead of obj->n_comp() directly.
2485  const unsigned int nc =
2486  FEInterface::n_dofs_at_node(fe_type, &elem, n, add_p_level);
2487 
2488  // If this is a non-vertex on a hanging node with extra
2489  // degrees of freedom, we use the non-vertex dofs (which
2490  // come in reverse order starting from the end, to
2491  // simplify p refinement)
2492  if (extra_hanging_dofs && nc && !elem.is_vertex(n))
2493  {
2494  const int dof_offset = n_comp - nc;
2495 
2496  // We should never have fewer dofs than necessary on a
2497  // node unless we're getting indices on a parent element,
2498  // and we should never need the indices on such a node
2499  if (dof_offset < 0)
2500  {
2501  libmesh_assert(!elem.active());
2502  di.resize(di.size() + nc, DofObject::invalid_id);
2503  }
2504  else
2505  for (unsigned int i = dof_offset; i != n_comp; ++i)
2506  {
2507  const dof_id_type d =
2508  obj.dof_number(sys_num, vg, vig, i, n_comp);
2509  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2510  di.push_back(d);
2511  }
2512  }
2513  // If this is a vertex or an element without extra hanging
2514  // dofs, our dofs come in forward order coming from the
2515  // beginning. But we still might not have all those dofs, in cases
2516  // where a subdomain-restricted variable just had its subdomain
2517  // expanded.
2518  else
2519  {
2520  const unsigned int good_nc =
2521  std::min(static_cast<unsigned int>(n_comp), nc);
2522  for (unsigned int i=0; i != good_nc; ++i)
2523  {
2524  const dof_id_type d =
2525  obj.dof_number(sys_num, vg, vig, i, n_comp);
2526  libmesh_assert_not_equal_to (d, DofObject::invalid_id);
2527  di.push_back(d);
2528  }
2529  for (unsigned int i=good_nc; i != nc; ++i)
2530  di.push_back(DofObject::invalid_id);
2531  }
2532 }
unsigned int sys_number() const
Definition: dof_map.h:2266
static bool extra_hanging_dofs(const FEType &fe_t)
libmesh_assert(ctx)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
const VariableGroup & variable_group(const unsigned int c) const
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:436
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
Definition: dof_map.h:2192
uint8_t dof_id_type
Definition: id_types.h:67

◆ add_adjoint_constraint_row()

void libMesh::DofMap::add_adjoint_constraint_row ( const unsigned int  qoi_index,
const dof_id_type  dof_number,
const DofConstraintRow constraint_row,
const Number  constraint_rhs,
const bool  forbid_constraint_overwrite 
)

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

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

Definition at line 2211 of file dof_map_constraints.C.

References _adjoint_constraint_values, and is_constrained_dof().

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

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

References _adjoint_dirichlet_boundaries.

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

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

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

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

2080 {
2081  _algebraic_ghosting_functors.insert(&evaluable_functor);
2082  evaluable_functor.set_mesh(&_mesh);
2083  if (to_mesh)
2084  _mesh.add_ghosting_functor(evaluable_functor);
2085 }
std::set< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:2121
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2034
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
Definition: mesh_base.h:1262

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

References _shared_functors, and add_algebraic_ghosting_functor().

407  { _shared_functors[evaluable_functor.get()] = evaluable_functor;
408  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:2140
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:2078

◆ add_constraint_row() [1/2]

void libMesh::DofMap::add_constraint_row ( const dof_id_type  dof_number,
const DofConstraintRow constraint_row,
const Number  constraint_rhs,
const bool  forbid_constraint_overwrite 
)

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

Definition at line 2179 of file dof_map_constraints.C.

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

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

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

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

References add_constraint_row().

1096  { 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 5307 of file dof_map_constraints.C.

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

Referenced by process_constraints().

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

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

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

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

2055 {
2056  _coupling_functors.insert(&coupling_functor);
2057  coupling_functor.set_mesh(&_mesh);
2058  if (to_mesh)
2059  _mesh.add_ghosting_functor(coupling_functor);
2060 }
std::set< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
Definition: dof_map.h:2134
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2034
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
Definition: mesh_base.h:1262

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

References _shared_functors, and add_coupling_functor().

345  { _shared_functors[coupling_functor.get()] = coupling_functor;
346  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:2053
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:2140

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

2045 {
2046  this->add_coupling_functor(this->default_coupling());
2048 }
DefaultCoupling & default_coupling()
Default coupling functor.
Definition: dof_map.h:370
DefaultCoupling & default_algebraic_ghosting()
Default algebraic ghosting functor.
Definition: dof_map.h:432
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:2053
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:2078

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

References _dirichlet_boundaries.

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

5409 {
5410  _dirichlet_boundaries->push_back(std::make_unique<DirichletBoundary>(dirichlet_boundary));
5411 }
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2228

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

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

Referenced by distribute_dofs(), and reinit_send_list().

1737 {
1738  LOG_SCOPE("add_neighbors_to_send_list()", "DofMap");
1739 
1740  // Return immediately if there's no ghost data
1741  if (this->n_processors() == 1)
1742  return;
1743 
1744  const unsigned int n_var = this->n_variables();
1745 
1746  MeshBase::const_element_iterator local_elem_it
1747  = mesh.active_local_elements_begin();
1748  const MeshBase::const_element_iterator local_elem_end
1749  = mesh.active_local_elements_end();
1750 
1751  GhostingFunctor::map_type elements_to_send;
1752  DofMap::CouplingMatricesSet temporary_coupling_matrices;
1753 
1754  // We need to add dofs to the send list if they've been directly
1755  // requested by an algebraic ghosting functor or they've been
1756  // indirectly requested by a coupling functor.
1757  this->merge_ghost_functor_outputs(elements_to_send,
1758  temporary_coupling_matrices,
1761  local_elem_it, local_elem_end, mesh.processor_id());
1762 
1763  this->merge_ghost_functor_outputs(elements_to_send,
1764  temporary_coupling_matrices,
1765  this->coupling_functors_begin(),
1766  this->coupling_functors_end(),
1767  local_elem_it, local_elem_end, mesh.processor_id());
1768 
1769  // Making a list of non-zero coupling matrix columns is an
1770  // O(N_var^2) operation. We cache it so we only have to do it once
1771  // per CouplingMatrix and not once per element.
1772  std::map<const CouplingMatrix *, std::vector<unsigned int>>
1773  column_variable_lists;
1774 
1775  for (const auto & [partner, ghost_coupling] : elements_to_send)
1776  {
1777  // We asked ghosting functors not to give us local elements
1778  libmesh_assert_not_equal_to
1779  (partner->processor_id(), this->processor_id());
1780 
1781  // Loop over any present coupling matrix column variables if we
1782  // have a coupling matrix, or just add all variables to
1783  // send_list if not.
1784  if (ghost_coupling)
1785  {
1786  libmesh_assert_equal_to (ghost_coupling->size(), n_var);
1787 
1788  // Try to find a cached list of column variables.
1789  std::map<const CouplingMatrix *, std::vector<unsigned int>>::const_iterator
1790  column_variable_list = column_variable_lists.find(ghost_coupling);
1791 
1792  // If we didn't find it, then we need to create it.
1793  if (column_variable_list == column_variable_lists.end())
1794  {
1795  auto inserted_variable_list_pair =
1796  column_variable_lists.emplace(ghost_coupling, std::vector<unsigned int>());
1797  column_variable_list = inserted_variable_list_pair.first;
1798 
1799  std::vector<unsigned int> & new_variable_list =
1800  inserted_variable_list_pair.first->second;
1801 
1802  std::vector<unsigned char> has_variable(n_var, false);
1803 
1804  for (unsigned int vi = 0; vi != n_var; ++vi)
1805  {
1806  ConstCouplingRow ccr(vi, *ghost_coupling);
1807 
1808  for (const auto & vj : ccr)
1809  has_variable[vj] = true;
1810  }
1811  for (unsigned int vj = 0; vj != n_var; ++vj)
1812  {
1813  if (has_variable[vj])
1814  new_variable_list.push_back(vj);
1815  }
1816  }
1817 
1818  const std::vector<unsigned int> & variable_list =
1819  column_variable_list->second;
1820 
1821  for (const auto & vj : variable_list)
1822  {
1823  std::vector<dof_id_type> di;
1824  this->dof_indices (partner, di, vj);
1825 
1826  // Insert the remote DOF indices into the send list
1827  for (auto d : di)
1828  if (d != DofObject::invalid_id &&
1829  !this->local_index(d))
1830  {
1831  libmesh_assert_less(d, this->n_dofs());
1832  _send_list.push_back(d);
1833  }
1834  }
1835  }
1836  else
1837  {
1838  std::vector<dof_id_type> di;
1839  this->dof_indices (partner, di);
1840 
1841  // Insert the remote DOF indices into the send list
1842  for (const auto & dof : di)
1843  if (dof != DofObject::invalid_id &&
1844  !this->local_index(dof))
1845  {
1846  libmesh_assert_less(dof, this->n_dofs());
1847  _send_list.push_back(dof);
1848  }
1849  }
1850 
1851  }
1852 
1853  // We're now done with any merged coupling matrices we had to create.
1854  temporary_coupling_matrices.clear();
1855 
1856  //-------------------------------------------------------------------------
1857  // Our coupling functors added dofs from neighboring elements to the
1858  // send list, but we may still need to add non-local dofs from local
1859  // elements.
1860  //-------------------------------------------------------------------------
1861 
1862  // Loop over the active local elements, adding all active elements
1863  // that neighbor an active local element to the send list.
1864  for ( ; local_elem_it != local_elem_end; ++local_elem_it)
1865  {
1866  const Elem * elem = *local_elem_it;
1867 
1868  std::vector<dof_id_type> di;
1869  this->dof_indices (elem, di);
1870 
1871  // Insert the remote DOF indices into the send list
1872  for (const auto & dof : di)
1873  if (dof != DofObject::invalid_id &&
1874  !this->local_index(dof))
1875  {
1876  libmesh_assert_less(dof, this->n_dofs());
1877  _send_list.push_back(dof);
1878  }
1879  }
1880 }
std::set< GhostingFunctor * >::const_iterator coupling_functors_begin() const
Beginning of range of coupling functors.
Definition: dof_map.h:358
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
Definition: dof_map.C:2184
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:2063
MeshBase & mesh
unsigned int n_variables() const
Definition: dof_map.h:635
std::map< const Elem *, const CouplingMatrix *, CompareDofObjectsByPIDAndThenID > map_type
What elements do we care about and what variables do we care about on each element?
processor_id_type n_processors() const
dof_id_type n_dofs() const
Definition: dof_map.h:673
static void merge_ghost_functor_outputs(GhostingFunctor::map_type &elements_to_ghost, CouplingMatricesSet &temporary_coupling_matrices, const std::set< GhostingFunctor *>::iterator &gf_begin, const std::set< GhostingFunctor *>::iterator &gf_end, const MeshBase::const_element_iterator &elems_begin, const MeshBase::const_element_iterator &elems_end, processor_id_type p)
Definition: dof_map.C:1634
std::set< std::unique_ptr< CouplingMatrix >, Utility::CompareUnderlying > CouplingMatricesSet
Definition: dof_map.h:1912
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_end() const
End of range of algebraic ghosting functors.
Definition: dof_map.h:426
std::set< GhostingFunctor * >::const_iterator coupling_functors_end() const
End of range of coupling functors.
Definition: dof_map.h:364
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_begin() const
Beginning of range of algebraic ghosting functors.
Definition: dof_map.h:420
processor_id_type processor_id() const
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:916

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

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

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

5529 {
5530  // See if we already have a periodic boundary associated myboundary...
5531  PeriodicBoundaryBase * existing_boundary = _periodic_boundaries->boundary(periodic_boundary.myboundary);
5532 
5533  if (!existing_boundary)
5534  {
5535  // ...if not, clone the input (and its inverse) and add them to the PeriodicBoundaries object
5536  // Pass the pairedboundary of the original as the boundary id of the inverse clone.
5537  _periodic_boundaries->emplace(periodic_boundary.myboundary, periodic_boundary.clone());
5538  _periodic_boundaries->emplace(periodic_boundary.pairedboundary, periodic_boundary.clone(PeriodicBoundaryBase::INVERSE));
5539  }
5540  else
5541  {
5542  // ...otherwise, merge this object's variable IDs with the existing boundary object's.
5543  existing_boundary->merge(periodic_boundary);
5544 
5545  // Do the same merging process for the inverse boundary. Note: the inverse better already exist!
5546  PeriodicBoundaryBase * inverse_boundary = _periodic_boundaries->boundary(periodic_boundary.pairedboundary);
5547  libmesh_assert(inverse_boundary);
5548  inverse_boundary->merge(periodic_boundary);
5549  }
5550 }
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:2220
The base class for defining periodic boundaries.

◆ add_periodic_boundary() [2/2]

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

Add a periodic boundary pair.

Parameters
boundary- primary boundary
inverse_boundary- inverse boundary

Definition at line 5555 of file dof_map_constraints.C.

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

5557 {
5558  libmesh_assert_equal_to (boundary.myboundary, inverse_boundary.pairedboundary);
5559  libmesh_assert_equal_to (boundary.pairedboundary, inverse_boundary.myboundary);
5560 
5561  // Store clones of the passed-in objects. These will be cleaned up
5562  // automatically in the _periodic_boundaries destructor.
5563  _periodic_boundaries->emplace(boundary.myboundary, boundary.clone());
5564  _periodic_boundaries->emplace(inverse_boundary.myboundary, inverse_boundary.clone());
5565 }
boundary_id_type myboundary
The boundary ID of this boundary and its counterpart.
virtual std::unique_ptr< PeriodicBoundaryBase > clone(TransformationType t=FORWARD) const =0
If we want the DofMap to be able to make copies of references and store them in the underlying map...
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2220

◆ add_static_condensation()

void libMesh::DofMap::add_static_condensation ( const StaticCondensation sc)
inline

Add a static condensation class.

Definition at line 1732 of file dof_map.h.

References _sc.

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

1732 { _sc = &sc; }
const StaticCondensation * _sc
Static condensation class.
Definition: dof_map.h:2259

◆ add_variable_group()

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

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

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

Definition at line 245 of file dof_map.C.

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

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

◆ algebraic_ghosting_functors_begin()

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

Beginning of range of algebraic ghosting functors.

Definition at line 420 of file dof_map.h.

References _algebraic_ghosting_functors.

Referenced by add_neighbors_to_send_list().

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

◆ algebraic_ghosting_functors_end()

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

End of range of algebraic ghosting functors.

Definition at line 426 of file dof_map.h.

References _algebraic_ghosting_functors.

Referenced by add_neighbors_to_send_list().

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

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

References semilocal_index().

Referenced by is_evaluable().

2620 {
2621  // We're all semilocal unless we find a counterexample
2622  for (const auto & di : dof_indices_in)
2623  if (!this->semilocal_index(di))
2624  return false;
2625 
2626  return true;
2627 }
bool semilocal_index(dof_id_type dof_index) const
Definition: dof_map.C:2603

◆ allgather_recursive_constraints()

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

Gathers constraint equation dependencies from other processors.

Definition at line 3673 of file dof_map_constraints.C.

References _adjoint_constraint_values, _dof_constraints, _node_constraints, _primal_constraint_values, libMesh::as_range(), libMesh::ParallelObject::comm(), libMesh::DofObject::dof_number(), gather_constraints(), TIMPI::Communicator::get_unique_tag(), libMesh::DofObject::id(), libMesh::index_range(), libMesh::DofObject::invalid_id, is_constrained_dof(), is_constrained_node(), libMesh::MeshBase::is_serial(), libMesh::libmesh_assert(), libMesh::libmesh_isnan(), TIMPI::Communicator::max(), mesh, libMesh::DofObject::n_comp(), n_nodes, libMesh::Elem::n_nodes(), libMesh::ParallelObject::n_processors(), n_vars, libMesh::DofObject::n_vars(), libMesh::Elem::node_id(), libMesh::Elem::node_ptr(), libMesh::MeshBase::node_ptr(), libMesh::Elem::node_ref(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::Real, TIMPI::Communicator::receive_packed_range(), TIMPI::Communicator::send_packed_range(), and sys_number().

Referenced by process_constraints().

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

◆ assert_no_nodes_missed()

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

Definition at line 1612 of file dof_map.C.

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

1613 {
1614  MeshTools::libmesh_assert_valid_procids<Node>(mesh);
1615 
1616  for (auto & node : mesh.local_node_ptr_range())
1617  {
1618  unsigned int n_var_g = node->n_var_groups(this->sys_number());
1619  for (unsigned int vg=0; vg != n_var_g; ++vg)
1620  {
1621  unsigned int n_comp_g =
1622  node->n_comp_group(this->sys_number(), vg);
1623  dof_id_type my_first_dof = n_comp_g ?
1624  node->vg_dof_base(this->sys_number(), vg) : 0;
1625  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
1626  }
1627  }
1628 }
MeshBase & mesh
unsigned int sys_number() const
Definition: dof_map.h:2266
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
uint8_t dof_id_type
Definition: id_types.h:67

◆ attach_extra_send_list_function()

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

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

Definition at line 482 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:2095
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:2090

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

References _augment_send_list.

474  {
475  _augment_send_list = &asl;
476  }
AugmentSendList * _augment_send_list
Function object to call to add extra entries to the send list.
Definition: dof_map.h:2085

◆ 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 459 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:2080
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:2073

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

References _augment_sparsity_pattern.

445  {
447  }
SparsityPattern::AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:2068

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

272 {
273  parallel_object_only();
274 
275  // We shouldn't be trying to re-attach the same matrices repeatedly
276  libmesh_assert (std::find(_matrices.begin(), _matrices.end(),
277  &matrix) == _matrices.end());
278 
279  _matrices.push_back(&matrix);
280 
281  this->update_sparsity_pattern(matrix);
282 
283  if (matrix.need_full_sparsity_pattern())
285 }
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2146
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:300
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2041
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 665 of file dof_map.h.

References has_blocked_representation(), and n_variables().

666  {
667  return (this->has_blocked_representation() ? this->n_variables() : 1);
668  }
unsigned int n_variables() const
Definition: dof_map.h:635
bool has_blocked_representation() const
Definition: dof_map.h:648

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

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

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

◆ build_sparsity()

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

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

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

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

Definition at line 61 of file dof_map.C.

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

63 {
64  libmesh_assert (mesh.is_prepared());
65 
66  LOG_SCOPE("build_sparsity()", "DofMap");
67 
68  // Compute the sparsity structure of the global matrix. This can be
69  // fed into a PetscMatrixBase to allocate exactly the number of nonzeros
70  // necessary to store the matrix. This algorithm should be linear
71  // in the (# of elements)*(# nodes per element)
72 
73  // We can be more efficient in the threaded sparsity pattern assembly
74  // if we don't need the exact pattern. For some sparse matrix formats
75  // a good upper bound will suffice.
76 
77  // See if we need to include sparsity pattern entries for coupling
78  // between neighbor dofs
79  bool implicit_neighbor_dofs = this->use_coupled_neighbor_dofs(mesh);
80 
81  // We can compute the sparsity pattern in parallel on multiple
82  // threads. The goal is for each thread to compute the full sparsity
83  // pattern for a subset of elements. These sparsity patterns can
84  // be efficiently merged in the SparsityPattern::Build::join()
85  // method, especially if there is not too much overlap between them.
86  // Even better, if the full sparsity pattern is not needed then
87  // the number of nonzeros per row can be estimated from the
88  // sparsity patterns created on each thread.
89  auto sp = std::make_unique<SparsityPattern::Build>
90  (*this,
91  this->_dof_coupling,
92  this->_coupling_functors,
93  implicit_neighbor_dofs,
95  calculate_constrained);
96 
97  Threads::parallel_reduce (ConstElemRange (mesh.active_local_elements_begin(),
98  mesh.active_local_elements_end()), *sp);
99 
100  sp->parallel_sync();
101 
102  libmesh_assert_equal_to (sp->get_sparsity_pattern().size(), this->n_local_dofs());
103 
104  // Check to see if we have any extra stuff to add to the sparsity_pattern
106  {
108  {
109  libmesh_here();
110  libMesh::out << "WARNING: You have specified both an extra sparsity function and object.\n"
111  << " Are you sure this is what you meant to do??"
112  << std::endl;
113  }
114 
115  sp->apply_extra_sparsity_function(_extra_sparsity_function,
117  }
118 
120  sp->apply_extra_sparsity_object(*_augment_sparsity_pattern);
121 
122  return sp;
123 }
dof_id_type n_local_dofs() const
Definition: dof_map.h:694
void * _extra_sparsity_context
A pointer associated with the extra sparsity that can optionally be passed in.
Definition: dof_map.h:2080
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:1952
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:2146
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:2073
libmesh_assert(ctx)
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1683
OStreamProxy out
SparsityPattern::AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:2068
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:101
std::set< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
Definition: dof_map.h:2134

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

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

Referenced by distribute_dofs().

1306 {
1307  std::map<const Node *, std::set<subdomain_id_type>> constraining_subdomains;
1308  const auto & constraint_rows = _mesh.get_constraint_rows();
1309 
1310  // We can't just loop over constraint rows here because we need
1311  // element subdomain ids for the constrained nodes, but we don't
1312  // want an extra loop if there are no constraint rows.
1313  if (!constraint_rows.empty())
1314  for (auto & elem : _mesh.active_element_ptr_range())
1315  {
1316  const subdomain_id_type sbdid = elem->subdomain_id();
1317 
1318  for (const Node & node : elem->node_ref_range())
1319  {
1320  if (auto it = constraint_rows.find(&node);
1321  it != constraint_rows.end())
1322  {
1323  for (const auto & [pr, val] : it->second)
1324  {
1325  const Node * spline_node =
1326  pr.first->node_ptr(pr.second);
1327 
1328  constraining_subdomains[spline_node].insert(sbdid);
1329  }
1330  }
1331  }
1332  }
1333 
1334  return constraining_subdomains;
1335 }
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
Definition: mesh_base.h:1698
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:2034

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

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

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

Referenced by check_for_cyclic_constraints(), and process_constraints().

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

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

References check_for_constraint_loops().

4500 {
4501  // Eventually make this officially libmesh_deprecated();
4503 }

◆ clear()

void libMesh::DofMap::clear ( )

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

Definition at line 898 of file dof_map.C.

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

Referenced by libMesh::ReplicatedMesh::clear(), libMesh::DistributedMesh::clear(), and ~DofMap().

899 {
900  // we don't want to clear
901  // the coupling matrix!
902  // It should not change...
903  //_dof_coupling->clear();
904  //
905  // But it would be inconsistent to leave our coupling settings
906  // through a clear()...
907  _dof_coupling = nullptr;
908 
909  // Reset ghosting functor statuses
910  {
911  for (const auto & gf : _coupling_functors)
912  {
913  libmesh_assert(gf);
915  }
916  this->_coupling_functors.clear();
917 
918  // Go back to default coupling
919 
920  _default_coupling->set_dof_coupling(this->_dof_coupling);
921  _default_coupling->set_n_levels(this->use_coupled_neighbor_dofs(this->_mesh));
922 
924  }
925 
926 
927  {
928  for (const auto & gf : _algebraic_ghosting_functors)
929  {
930  libmesh_assert(gf);
932  }
933  this->_algebraic_ghosting_functors.clear();
934 
935  // Go back to default send_list generation
936 
937  // _default_evaluating->set_dof_coupling(this->_dof_coupling);
938  _default_evaluating->set_n_levels(1);
940  }
941 
942  this->_shared_functors.clear();
943 
944  _variables.clear();
945  _variable_groups.clear();
946  _var_to_vg.clear();
947  _variable_group_numbers.clear();
948  _first_df.clear();
949  _end_df.clear();
950  _first_scalar_df.clear();
951  this->clear_send_list();
952  this->clear_sparsity();
954 
955 #ifdef LIBMESH_ENABLE_AMR
956 
957  _dof_constraints.clear();
958  _stashed_dof_constraints.clear();
961  _n_old_dfs = 0;
962  _first_old_df.clear();
963  _end_old_df.clear();
964  _first_old_scalar_df.clear();
965 
966 #endif
967 
968  _matrices.clear();
969 
970  _n_dfs = 0;
971 }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable group.
Definition: dof_map.h:2014
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:930
void clear_send_list()
Clears the _send_list vector.
Definition: dof_map.h:499
std::set< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:2121
std::vector< dof_id_type > _end_old_df
Last old DOF index (plus 1) on processor p.
Definition: dof_map.h:2181
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:1952
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:2053
std::vector< dof_id_type > _first_old_df
First old DOF index on processor p.
Definition: dof_map.h:2176
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:2057
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2204
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2146
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
Definition: dof_map.h:2024
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:2187
libmesh_assert(ctx)
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2200
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1683
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2041
std::unique_ptr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:2103
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2202
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:2009
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2200
dof_id_type _n_old_dfs
Total number of degrees of freedom on old dof objects.
Definition: dof_map.h:2171
void clear_sparsity()
Clears the sparsity pattern.
Definition: dof_map.C:2029
std::set< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
Definition: dof_map.h:2134
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:2051
std::vector< dof_id_type > _first_df
First DOF index on processor p.
Definition: dof_map.h:2046
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2034
std::unique_ptr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:2111
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:2019
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:2140
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:2078
dof_id_type _n_dfs
Total number of degrees of freedom.
Definition: dof_map.h:2158

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

References _send_list.

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

500  {
501  _send_list.clear();
502  }
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:2063

◆ clear_sparsity()

void libMesh::DofMap::clear_sparsity ( )

Clears the sparsity pattern.

Definition at line 2029 of file dof_map.C.

References _sp.

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

2030 {
2031  _sp.reset();
2032 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2153

◆ 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(), libMesh::System::add_variable(), libMesh::System::add_variables(), libMesh::System::add_vector(), libMesh::MeshTools::Modification::all_tri(), libMesh::LaplaceMeshSmoother::allgather_graph(), allgather_recursive_constraints(), libMesh::TransientRBConstruction::allocate_data_structures(), libMesh::RBConstruction::allocate_data_structures(), libMesh::TransientRBConstruction::assemble_affine_expansion(), libMesh::AdvectionSystem::assemble_claw_rhs(), libMesh::FEMSystem::assemble_qoi(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::MeshCommunication::assign_global_indices(), libMesh::Partitioner::assign_partitioning(), libMesh::MeshTools::Generation::build_extrusion(), libMesh::Partitioner::build_graph(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::PetscDMWrapper::build_section(), libMesh::PetscDMWrapper::build_sf(), libMesh::MeshBase::cache_elem_data(), libMesh::System::calculate_norm(), check_dirichlet_bcid_consistency(), libMesh::RBConstruction::compute_Fq_representor_innerprods(), libMesh::RBConstruction::compute_max_error_bound(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::RBConstruction::compute_output_dual_innerprods(), libMesh::RBConstruction::compute_residual_dual_norm_slow(), libMesh::RBSCMConstruction::compute_SCM_bounds_on_training_set(), computed_sparsity_already(), libMesh::Problem_Interface::computeF(), libMesh::Problem_Interface::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), libMesh::ContinuationSystem::ContinuationSystem(), libMesh::MeshBase::copy_constraint_rows(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::ExodusII_IO::copy_nodal_solution(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::CondensedEigenSystem::copy_super_to_sub(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::MeshTools::create_bounding_box(), create_dof_constraints(), libMesh::MeshTools::create_nodal_bounding_box(), libMesh::MeshRefinement::create_parent_error_vector(), libMesh::MeshTools::create_processor_bounding_box(), libMesh::MeshTools::create_subdomain_bounding_box(), libMesh::PetscMatrix< T >::create_submatrix_nosort(), create_wrapped_function(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::RBEIMEvaluation::distribute_bfs(), distribute_dofs(), DMlibMeshFunction(), DMlibMeshJacobian(), DMlibMeshSetSystem_libMesh(), DMVariableBounds_libMesh(), libMesh::DTKSolutionTransfer::DTKSolutionTransfer(), libMesh::MeshRefinement::eliminate_unrefined_patches(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_interiors(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_nodes(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_sides(), libMesh::TransientRBConstruction::enrich_RB_space(), libMesh::EpetraVector< T >::EpetraVector(), AssembleOptimization::equality_constraints(), libMesh::PatchRecoveryErrorEstimator::estimate_error(), libMesh::WeightedPatchRecoveryErrorEstimator::estimate_error(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::MeshRefinement::flag_elements_by_elem_fraction(), libMesh::MeshRefinement::flag_elements_by_error_fraction(), libMesh::MeshRefinement::flag_elements_by_error_tolerance(), libMesh::MeshRefinement::flag_elements_by_mean_stddev(), libMesh::MeshRefinement::flag_elements_by_nelem_target(), libMesh::RBEIMEvaluation::gather_bfs(), gather_constraints(), libMesh::MeshfreeInterpolation::gather_remote_data(), libMesh::CondensedEigenSystem::get_eigenpair(), libMesh::RBEIMEvaluation::get_eim_basis_function_node_value(), libMesh::RBEIMEvaluation::get_eim_basis_function_side_value(), libMesh::RBEIMEvaluation::get_eim_basis_function_value(), libMesh::MeshBase::get_info(), libMesh::System::get_info(), get_info(), libMesh::RBEIMEvaluation::get_interior_basis_functions_as_vecs(), libMesh::ImplicitSystem::get_linear_solver(), libMesh::RBEIMConstruction::get_max_abs_value(), libMesh::RBEIMConstruction::get_node_max_abs_value(), libMesh::RBEIMEvaluation::get_parametrized_function_node_value(), libMesh::RBEIMEvaluation::get_parametrized_function_side_value(), libMesh::RBEIMEvaluation::get_parametrized_function_value(), libMesh::RBEIMConstruction::get_random_point(), AssembleOptimization::inequality_constraints(), AssembleOptimization::inequality_constraints_jacobian(), libMesh::LocationMap< T >::init(), libMesh::TimeSolver::init(), libMesh::StaticCondensation::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::AdvectionSystem::init_data(), libMesh::ClawSystem::init_data(), libMesh::PetscDMWrapper::init_petscdm(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::OptimizationSystem::initialize_equality_constraints_storage(), libMesh::OptimizationSystem::initialize_inequality_constraints_storage(), libMesh::RBEIMConstruction::initialize_parametrized_functions_in_training_set(), libMesh::RBEIMConstruction::inner_product(), integrate_function(), libMesh::MeshTools::libmesh_assert_consistent_distributed(), libMesh::MeshTools::libmesh_assert_consistent_distributed_nodes(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_equal_connectivity(), libMesh::MeshTools::libmesh_assert_equal_points(), libMesh::MeshTools::libmesh_assert_parallel_consistent_new_node_procids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_topology_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshTools::libmesh_assert_valid_constraint_rows(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_flags(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_p_levels(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::MeshTools::libmesh_assert_valid_unique_ids(), libMesh::libmesh_petsc_linesearch_shellfunc(), libMesh::libmesh_petsc_preconditioner_apply(), libMesh::libmesh_petsc_recalculate_monitor(), libMesh::libmesh_petsc_snes_fd_residual(), libMesh::libmesh_petsc_snes_jacobian(), libMesh::libmesh_petsc_snes_mffd_interface(), libMesh::libmesh_petsc_snes_mffd_residual(), libMesh::libmesh_petsc_snes_postcheck(), libMesh::libmesh_petsc_snes_precheck(), libMesh::libmesh_petsc_snes_residual(), libMesh::libmesh_petsc_snes_residual_helper(), libMesh::MeshRefinement::limit_level_mismatch_at_edge(), libMesh::MeshRefinement::limit_level_mismatch_at_node(), libMesh::MeshRefinement::limit_overrefined_boundary(), libMesh::MeshRefinement::limit_underrefined_boundary(), libMesh::LinearImplicitSystem::LinearImplicitSystem(), main(), libMesh::MeshRefinement::make_coarsening_compatible(), libMesh::MeshCommunication::make_elems_parallel_consistent(), libMesh::MeshRefinement::make_flags_parallel_consistent(), libMesh::MeshCommunication::make_new_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_new_nodes_parallel_consistent(), libMesh::MeshCommunication::make_node_bcids_parallel_consistent(), libMesh::MeshCommunication::make_node_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_unique_ids_parallel_consistent(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), libMesh::MeshCommunication::make_p_levels_parallel_consistent(), libMesh::MeshRefinement::make_refinement_compatible(), libMesh::TransientRBConstruction::mass_matrix_scaled_matvec(), libMesh::FEMSystem::mesh_position_set(), libMesh::TriangulatorInterface::MeshedHole::MeshedHole(), LinearElasticityWithContact::move_mesh(), libMesh::DistributedMesh::n_active_elem(), libMesh::MeshTools::n_active_levels(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::MeshTools::n_connected_components(), n_constrained_dofs(), libMesh::MeshBase::n_constraint_rows(), n_dofs(), n_dofs_per_processor(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::CondensedEigenSystem::n_global_non_condensed_dofs(), libMesh::MeshTools::n_levels(), MixedOrderTest::n_neighbor_links(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::SparsityPattern::Build::n_nonzeros(), libMesh::MeshTools::n_p_levels(), libMesh::BoundaryInfo::n_shellface_conds(), libMesh::RBEIMEvaluation::node_distribute_bfs(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::RBEIMConstruction::node_inner_product(), libMesh::MeshBase::operator==(), libMesh::DistributedMesh::parallel_max_elem_id(), libMesh::DistributedMesh::parallel_max_node_id(), libMesh::ReplicatedMesh::parallel_max_unique_id(), libMesh::DistributedMesh::parallel_max_unique_id(), libMesh::DistributedMesh::parallel_n_elem(), libMesh::DistributedMesh::parallel_n_nodes(), libMesh::SparsityPattern::Build::parallel_sync(), libMesh::BoundaryInfo::parallel_sync_node_ids(), libMesh::BoundaryInfo::parallel_sync_side_ids(), libMesh::MeshTools::paranoid_n_levels(), libMesh::Partitioner::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::petsc_auto_fieldsplit(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::MeshBase::prepare_for_use(), libMesh::MeshBase::print_constraint_rows(), print_dof_constraints(), process_mesh_constraint_rows(), libMesh::Partitioner::processor_pairs_to_interface_nodes(), libMesh::InterMeshProjection::project_system_vectors(), FEMParameters::read(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::EquationSystems::read(), libMesh::ExodusII_IO::read_header(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::System::read_header(), libMesh::RBEIMEvaluation::read_in_interior_basis_functions(), libMesh::RBEIMEvaluation::read_in_node_basis_functions(), libMesh::RBEIMEvaluation::read_in_side_basis_functions(), libMesh::RBEvaluation::read_in_vectors_from_multiple_files(), libMesh::System::read_legacy_data(), libMesh::TransientRBConstruction::read_riesz_representors_from_files(), libMesh::RBConstruction::read_riesz_representors_from_files(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::Nemesis_IO_Helper::read_var_names_impl(), libMesh::MeshBase::recalculate_n_partitions(), libMesh::MeshRefinement::refine_and_coarsen_elements(), libMesh::SimplexRefiner::refine_via_edges(), 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::ClawSystem::solve_conservation_law(), libMesh::split_mesh(), libMesh::RBEIMConstruction::store_eim_solutions_for_training_set(), libMesh::MeshBase::subdomain_ids(), libMesh::BoundaryInfo::sync(), ConstraintOperatorTest::test1DCoarseningNewNodes(), ConstraintOperatorTest::test1DCoarseningOperator(), libMesh::MeshRefinement::test_level_one(), MeshfunctionDFEM::test_mesh_function_dfem(), MeshfunctionDFEM::test_mesh_function_dfem_grad(), MeshFunctionTest::test_p_level(), libMesh::MeshRefinement::test_unflagged(), DofMapTest::testBadElemFECombo(), SystemsTest::testBlockRestrictedVarNDofs(), BoundaryInfoTest::testBoundaryOnChildrenErrors(), VolumeTest::testC0PolygonMethods(), ConstraintOperatorTest::testCoreform(), ConnectedComponentsTest::testEdge(), MeshInputTest::testExodusIGASidesets(), MeshTriangulationTest::testFoundCenters(), PointLocatorTest::testLocator(), BoundaryInfoTest::testMesh(), PointLocatorTest::testPlanar(), MeshTriangulationTest::testPoly2TriRefinementBase(), SystemsTest::testProjectCubeWithMeshFunction(), BoundaryInfoTest::testRenumber(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), MeshTriangulationTest::testTriangulatorInterp(), MeshTriangulationTest::testTriangulatorMeshedHoles(), MeshTriangulationTest::testTriangulatorRoundHole(), libMesh::MeshTools::total_weight(), libMesh::RBConstruction::train_reduced_basis_with_POD(), libMesh::MeshFunctionSolutionTransfer::transfer(), libMesh::MeshfreeSolutionTransfer::transfer(), libMesh::Poly2TriTriangulator::triangulate(), libMesh::TransientRBConstruction::truth_assembly(), libMesh::RBConstruction::truth_assembly(), libMesh::MeshRefinement::uniformly_coarsen(), 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_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 2008 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().

2009 {
2011 
2012  // It is possible that some \p SparseMatrix implementations want to
2013  // see the sparsity pattern before we throw it away. If so, we
2014  // share a view of its arrays, and we pass it in to the matrices.
2015  for (const auto & mat : _matrices)
2016  {
2017  mat->attach_sparsity_pattern (*_sp);
2019  mat->update_sparsity_pattern (_sp->get_sparsity_pattern());
2020  }
2021  // If we don't need the full sparsity pattern anymore, free the
2022  // parts of it we don't need.
2024  _sp->clear_full_sparsity();
2025 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2153
MeshBase & mesh
std::unique_ptr< SparsityPattern::Build > build_sparsity(const MeshBase &mesh, bool calculate_constrained=false) const
Builds a sparsity pattern for matrices using the current degree-of-freedom numbering and coupling...
Definition: dof_map.C:61
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
Definition: dof_map.h:2004
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2146
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2041

◆ computed_sparsity_already()

bool libMesh::DofMap::computed_sparsity_already ( ) const

Returns true iff a sparsity pattern has already been computed.

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

290 {
292  (!_sp->get_n_nz().empty() ||
293  !_sp->get_n_oz().empty());
294  this->comm().max(computed_sparsity_already);
296 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2153
const Parallel::Communicator & comm() const
bool computed_sparsity_already() const
Returns true iff a sparsity pattern has already been computed.
Definition: dof_map.C:289
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 2437 of file dof_map.h.

Referenced by assemble().

2440  {}

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

2413  {}

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

2418  {}

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

2427  {}

◆ constrain_element_residual()

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

Constrains the element residual.

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

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

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

Definition at line 2762 of file dof_map_constraints.C.

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

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

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

2422  {}

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

2442 {}

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

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

References _constrained_sparsity_construction.

2487 {
2488 #ifdef LIBMESH_ENABLE_CONSTRAINTS
2490 #else
2491  return true;
2492 #endif
2493 }
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
Definition: dof_map.h:2004

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

References _dof_constraints.

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

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

References _dof_constraints.

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

◆ coupling_functors_begin()

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

Beginning of range of coupling functors.

Definition at line 358 of file dof_map.h.

References _coupling_functors.

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

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

◆ coupling_functors_end()

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

End of range of coupling functors.

Definition at line 364 of file dof_map.h.

References _coupling_functors.

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

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

◆ create_dof_constraints()

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

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

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

Definition at line 1735 of file dof_map_constraints.C.

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

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

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

◆ default_algebraic_ghosting()

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

Default algebraic ghosting functor.

Definition at line 432 of file dof_map.h.

References _default_evaluating.

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

432 { 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:2111

◆ default_coupling()

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

Default coupling functor.

Definition at line 370 of file dof_map.h.

References _default_coupling.

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

370 { 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:2103

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

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

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

976 {
977  // This function must be run on all processors at once
978  parallel_object_only();
979 
980  // Log how long it takes to distribute the degrees of freedom
981  LOG_SCOPE("distribute_dofs()", "DofMap");
982 
983  libmesh_assert (mesh.is_prepared());
984 
985  const processor_id_type proc_id = this->processor_id();
986  const processor_id_type n_proc = this->n_processors();
987 
988  // libmesh_assert_greater (this->n_variables(), 0);
989  libmesh_assert_less (proc_id, n_proc);
990 
991  // Data structure to ensure we can correctly combine
992  // subdomain-restricted variables with constraining nodes from
993  // different subdomains
994  const std::map<const Node *, std::set<subdomain_id_type>>
995  constraining_subdomains =
997 
998  // re-init in case the mesh has changed
999  this->reinit(mesh,
1000  constraining_subdomains);
1001 
1002  // By default distribute variables in a
1003  // var-major fashion, but allow run-time
1004  // specification
1005  bool node_major_dofs = libMesh::on_command_line ("--node-major-dofs");
1006 
1007  // The DOF counter, will be incremented as we encounter
1008  // new degrees of freedom
1009  dof_id_type next_free_dof = 0;
1010 
1011  // Clear the send list before we rebuild it
1012  this->clear_send_list();
1013 
1014  // Set temporary DOF indices on this processor
1015  if (node_major_dofs)
1017  (next_free_dof, mesh, constraining_subdomains);
1018  else
1020  (next_free_dof, mesh, constraining_subdomains);
1021 
1022  // Get DOF counts on all processors
1023  std::vector<dof_id_type> dofs_on_proc(n_proc, 0);
1024  this->comm().allgather(next_free_dof, dofs_on_proc);
1025 
1026  // Resize and fill the _first_df and _end_df arrays
1027 #ifdef LIBMESH_ENABLE_AMR
1029  _end_old_df = _end_df;
1030 #endif
1031 
1032  _first_df.resize(n_proc);
1033  _end_df.resize (n_proc);
1034 
1035  // Get DOF offsets
1036  _first_df[0] = 0;
1037  for (processor_id_type i=1; i < n_proc; ++i)
1038  _first_df[i] = _end_df[i-1] = _first_df[i-1] + dofs_on_proc[i-1];
1039  _end_df[n_proc-1] = _first_df[n_proc-1] + dofs_on_proc[n_proc-1];
1040 
1041  // Clear all the current DOF indices
1042  // (distribute_dofs expects them cleared!)
1043  this->invalidate_dofs(mesh);
1044 
1045  next_free_dof = _first_df[proc_id];
1046 
1047  // Set permanent DOF indices on this processor
1048  if (node_major_dofs)
1050  (next_free_dof, mesh, constraining_subdomains);
1051  else
1053  (next_free_dof, mesh, constraining_subdomains);
1054 
1055  libmesh_assert_equal_to (next_free_dof, _end_df[proc_id]);
1056 
1057  //------------------------------------------------------------
1058  // At this point, all n_comp and dof_number values on local
1059  // DofObjects should be correct, but a DistributedMesh might have
1060  // incorrect values on non-local DofObjects. Let's request the
1061  // correct values from each other processor.
1062 
1063  if (this->n_processors() > 1)
1064  {
1065  this->set_nonlocal_dof_objects(mesh.nodes_begin(),
1066  mesh.nodes_end(),
1068 
1069  this->set_nonlocal_dof_objects(mesh.elements_begin(),
1070  mesh.elements_end(),
1072  }
1073 
1074 #ifdef DEBUG
1075  {
1076  const unsigned int
1077  sys_num = this->sys_number();
1078 
1079  // Processors should all agree on DoF ids for the newly numbered
1080  // system.
1082 
1083  // DoF processor ids should match DofObject processor ids
1084  for (auto & node : mesh.node_ptr_range())
1085  {
1086  DofObject const * const dofobj = node;
1087  const processor_id_type obj_proc_id = dofobj->processor_id();
1088 
1089  for (auto v : make_range(dofobj->n_vars(sys_num)))
1090  for (auto c : make_range(dofobj->n_comp(sys_num,v)))
1091  {
1092  const dof_id_type dofid = dofobj->dof_number(sys_num,v,c);
1093  libmesh_assert_greater_equal (dofid, this->first_dof(obj_proc_id));
1094  libmesh_assert_less (dofid, this->end_dof(obj_proc_id));
1095  }
1096  }
1097 
1098  for (auto & elem : mesh.element_ptr_range())
1099  {
1100  DofObject const * const dofobj = elem;
1101  const processor_id_type obj_proc_id = dofobj->processor_id();
1102 
1103  for (auto v : make_range(dofobj->n_vars(sys_num)))
1104  for (auto c : make_range(dofobj->n_comp(sys_num,v)))
1105  {
1106  const dof_id_type dofid = dofobj->dof_number(sys_num,v,c);
1107  libmesh_assert_greater_equal (dofid, this->first_dof(obj_proc_id));
1108  libmesh_assert_less (dofid, this->end_dof(obj_proc_id));
1109  }
1110  }
1111  }
1112 #endif
1113 
1114  // Set the total number of degrees of freedom, then start finding
1115  // SCALAR degrees of freedom
1116 #ifdef LIBMESH_ENABLE_AMR
1117  _n_old_dfs = _n_dfs;
1119 #endif
1120  _n_dfs = _end_df[n_proc-1];
1121  _first_scalar_df.clear();
1123  dof_id_type current_SCALAR_dof_index = n_dofs() - n_SCALAR_dofs();
1124 
1125  // Calculate and cache the initial DoF indices for SCALAR variables.
1126  // This is an O(N_vars) calculation so we want to do it once per
1127  // renumbering rather than once per SCALAR_dof_indices() call
1128 
1129  for (auto v : make_range(this->n_variables()))
1130  if (this->variable(v).type().family == SCALAR)
1131  {
1132  _first_scalar_df[v] = current_SCALAR_dof_index;
1133  current_SCALAR_dof_index += this->variable(v).type().order.get_order();
1134  }
1135 
1136  // Allow our GhostingFunctor objects to reinit if necessary
1137  for (const auto & gf : _algebraic_ghosting_functors)
1138  {
1139  libmesh_assert(gf);
1140  gf->dofmap_reinit();
1141  }
1142 
1143  for (const auto & gf : _coupling_functors)
1144  {
1145  libmesh_assert(gf);
1146  gf->dofmap_reinit();
1147  }
1148 
1149  // Note that in the add_neighbors_to_send_list nodes on processor
1150  // boundaries that are shared by multiple elements are added for
1151  // each element.
1153 
1154  // Here we used to clean up that data structure; now System and
1155  // EquationSystems call that for us, after we've added constraint
1156  // dependencies to the send_list too.
1157  // this->sort_send_list ();
1158 
1159  // Return total number of DOFs across all procs. We compute and
1160  // return this as a std::size_t so that we can detect situations in
1161  // which the total number of DOFs across all procs would exceed the
1162  // capability of the underlying NumericVector representation to
1163  // index into it correctly (std::size_t is the largest unsigned
1164  // type, so no NumericVector representation can exceed it).
1165  return std::accumulate(dofs_on_proc.begin(), dofs_on_proc.end(), static_cast<std::size_t>(0));
1166 }
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
dof_id_type n_SCALAR_dofs() const
Definition: dof_map.h:689
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:500
void clear_send_list()
Clears the _send_list vector.
Definition: dof_map.h:499
MeshBase & mesh
unsigned int n_variables() const
Definition: dof_map.h:635
const Parallel::Communicator & comm() const
std::set< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:2121
std::vector< dof_id_type > _end_old_df
Last old DOF index (plus 1) on processor p.
Definition: dof_map.h:2181
OrderWrapper order
The approximation order of the element.
Definition: fe_type.h:215
std::vector< dof_id_type > _first_old_df
First old DOF index on processor p.
Definition: dof_map.h:2176
unsigned int sys_number() const
Definition: dof_map.h:2266
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:2057
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:1872
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:1467
uint8_t processor_id_type
processor_id_type n_processors() const
dof_id_type n_dofs() const
Definition: dof_map.h:673
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:1736
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:2187
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:2284
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:349
libmesh_assert(ctx)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
dof_id_type end_dof() const
Definition: dof_map.h:759
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:341
void invalidate_dofs(MeshBase &mesh) const
Invalidates all active DofObject dofs for this system.
Definition: dof_map.C:883
dof_id_type first_dof() const
Definition: dof_map.h:735
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:140
dof_id_type _n_old_dfs
Total number of degrees of freedom on old dof objects.
Definition: dof_map.h:2171
std::set< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
Definition: dof_map.h:2134
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:2051
std::vector< dof_id_type > _first_df
First DOF index on processor p.
Definition: dof_map.h:2046
DofObject * node_ptr(MeshBase &mesh, dof_id_type i) const
Definition: dof_map.C:334
bool on_command_line(std::string arg)
Definition: libmesh.C:981
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:1305
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:1339
uint8_t dof_id_type
Definition: id_types.h:67
dof_id_type _n_dfs
Total number of degrees of freedom.
Definition: dof_map.h:2158
const FEType & type() const
Definition: variable.h:140

◆ distribute_local_dofs_node_major()

void libMesh::DofMap::distribute_local_dofs_node_major ( dof_id_type next_free_dof,
MeshBase mesh,
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 1339 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().

1343 {
1344  const unsigned int sys_num = this->sys_number();
1345  const unsigned int n_var_groups = this->n_variable_groups();
1346 
1347  // This is the common case and we want to optimize for it
1348  const bool constraining_subdomains_empty =
1349  constraining_subdomains.empty();
1350 
1351  // Our numbering here must be kept consistent with the numbering
1352  // scheme assumed by DofMap::local_variable_indices!
1353 
1354  //-------------------------------------------------------------------------
1355  // First count and assign temporary numbers to local dofs
1356  for (auto & elem : mesh.active_local_element_ptr_range())
1357  {
1358  // Only number dofs connected to active
1359  // elements on this processor.
1360  const unsigned int n_nodes = elem->n_nodes();
1361 
1362  const subdomain_id_type sbdid = elem->subdomain_id();
1363 
1364  // First number the nodal DOFS
1365  for (unsigned int n=0; n<n_nodes; n++)
1366  {
1367  Node & node = elem->node_ref(n);
1368 
1369  for (unsigned vg=0; vg<n_var_groups; vg++)
1370  {
1371  const VariableGroup & vg_description(this->variable_group(vg));
1372 
1373  if (vg_description.type().family == SCALAR)
1374  continue;
1375 
1376  bool active_on_node =
1377  vg_description.active_on_subdomain(sbdid);
1378 
1379  // Are we at least active indirectly here?
1380  if (!active_on_node && !constraining_subdomains_empty)
1381  if (auto it = constraining_subdomains.find(&node);
1382  it != constraining_subdomains.end())
1383  for (auto s : it->second)
1384  if (vg_description.active_on_subdomain(s))
1385  {
1386  active_on_node = true;
1387  break;
1388  }
1389 
1390  if (active_on_node)
1391  {
1392  // assign dof numbers (all at once) if this is
1393  // our node and if they aren't already there
1394  if ((node.n_comp_group(sys_num,vg) > 0) &&
1395  (node.processor_id() == this->processor_id()) &&
1396  (node.vg_dof_base(sys_num,vg) ==
1398  {
1399  node.set_vg_dof_base(sys_num, vg,
1400  next_free_dof);
1401  next_free_dof += (vg_description.n_variables()*
1402  node.n_comp_group(sys_num,vg));
1403  //node.debug_buffer();
1404  }
1405  }
1406  }
1407  }
1408 
1409  // Now number the element DOFS
1410  for (unsigned vg=0; vg<n_var_groups; vg++)
1411  {
1412  const VariableGroup & vg_description(this->variable_group(vg));
1413 
1414  if ((vg_description.type().family != SCALAR) &&
1415  (vg_description.active_on_subdomain(elem->subdomain_id())))
1416  if (elem->n_comp_group(sys_num,vg) > 0)
1417  {
1418  libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1420 
1421  elem->set_vg_dof_base(sys_num,
1422  vg,
1423  next_free_dof);
1424 
1425  next_free_dof += (vg_description.n_variables()*
1426  elem->n_comp_group(sys_num,vg));
1427  }
1428  }
1429  } // done looping over elements
1430 
1431 
1432  // we may have missed assigning DOFs to nodes that we own
1433  // but to which we have no connected elements matching our
1434  // variable restriction criterion. this will happen, for example,
1435  // if variable V is restricted to subdomain S. We may not own
1436  // any elements which live in S, but we may own nodes which are
1437  // *connected* to elements which do. in this scenario these nodes
1438  // will presently have unnumbered DOFs. we need to take care of
1439  // them here since we own them and no other processor will touch them.
1440  for (auto & node : mesh.local_node_ptr_range())
1441  for (unsigned vg=0; vg<n_var_groups; vg++)
1442  {
1443  const VariableGroup & vg_description(this->variable_group(vg));
1444 
1445  if (node->n_comp_group(sys_num,vg))
1446  if (node->vg_dof_base(sys_num,vg) == DofObject::invalid_id)
1447  {
1448  node->set_vg_dof_base (sys_num,
1449  vg,
1450  next_free_dof);
1451 
1452  next_free_dof += (vg_description.n_variables()*
1453  node->n_comp(sys_num,vg));
1454  }
1455  }
1456 
1457  this->distribute_scalar_dofs(next_free_dof);
1458 
1459 #ifdef DEBUG
1461 #endif // DEBUG
1462 }
unsigned int n_variable_groups() const
Definition: dof_map.h:627
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:2266
const dof_id_type n_nodes
Definition: tecplot_io.C:67
void assert_no_nodes_missed(MeshBase &mesh)
Definition: dof_map.C:1612
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2274
void distribute_scalar_dofs(dof_id_type &next_free_dof)
Definition: dof_map.C:1588
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 1467 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().

1471 {
1472  const unsigned int sys_num = this->sys_number();
1473  const unsigned int n_var_groups = this->n_variable_groups();
1474 
1475  // This is the common case and we want to optimize for it
1476  const bool constraining_subdomains_empty =
1477  constraining_subdomains.empty();
1478 
1479  // Our numbering here must be kept consistent with the numbering
1480  // scheme assumed by DofMap::local_variable_indices!
1481 
1482  //-------------------------------------------------------------------------
1483  // First count and assign temporary numbers to local dofs
1484  for (unsigned vg=0; vg<n_var_groups; vg++)
1485  {
1486  const VariableGroup & vg_description(this->variable_group(vg));
1487 
1488  const unsigned int n_vars_in_group = vg_description.n_variables();
1489 
1490  // Skip the SCALAR dofs
1491  if (vg_description.type().family == SCALAR)
1492  continue;
1493 
1494  for (auto & elem : mesh.active_local_element_ptr_range())
1495  {
1496  // Only number dofs connected to active elements on this
1497  // processor and only for variables which are active on on
1498  // this element's subdomain or which are active on the
1499  // subdomain of a node constrained by this node.
1500  const bool active_on_elem =
1501  vg_description.active_on_subdomain(elem->subdomain_id());
1502 
1503  // If there's no way we're active on this element then we're
1504  // done
1505  if (!active_on_elem && constraining_subdomains_empty)
1506  continue;
1507 
1508  const unsigned int n_nodes = elem->n_nodes();
1509 
1510  // First number the nodal DOFS
1511  for (unsigned int n=0; n<n_nodes; n++)
1512  {
1513  Node & node = elem->node_ref(n);
1514 
1515  bool active_on_node = active_on_elem;
1516  if (!active_on_node)
1517  if (auto it = constraining_subdomains.find(&node);
1518  it != constraining_subdomains.end())
1519  for (auto s : it->second)
1520  if (vg_description.active_on_subdomain(s))
1521  {
1522  active_on_node = true;
1523  break;
1524  }
1525 
1526  if (!active_on_node)
1527  continue;
1528 
1529  // assign dof numbers (all at once) if this is
1530  // our node and if they aren't already there
1531  if ((node.n_comp_group(sys_num,vg) > 0) &&
1532  (node.processor_id() == this->processor_id()) &&
1533  (node.vg_dof_base(sys_num,vg) ==
1535  {
1536  node.set_vg_dof_base(sys_num, vg, next_free_dof);
1537 
1538  next_free_dof += (n_vars_in_group*
1539  node.n_comp_group(sys_num,vg));
1540  }
1541  }
1542 
1543  // Now number the element DOFS
1544  if (elem->n_comp_group(sys_num,vg) > 0)
1545  {
1546  libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1548 
1549  elem->set_vg_dof_base(sys_num,
1550  vg,
1551  next_free_dof);
1552 
1553  next_free_dof += (n_vars_in_group*
1554  elem->n_comp_group(sys_num,vg));
1555  }
1556  } // end loop on elements
1557 
1558  // we may have missed assigning DOFs to nodes that we own
1559  // but to which we have no connected elements matching our
1560  // variable restriction criterion. this will happen, for example,
1561  // if variable V is restricted to subdomain S. We may not own
1562  // any elements which live in S, but we may own nodes which are
1563  // *connected* to elements which do. in this scenario these nodes
1564  // will presently have unnumbered DOFs. we need to take care of
1565  // them here since we own them and no other processor will touch them.
1566  for (auto & node : mesh.local_node_ptr_range())
1567  if (node->n_comp_group(sys_num,vg))
1568  if (node->vg_dof_base(sys_num,vg) == DofObject::invalid_id)
1569  {
1570  node->set_vg_dof_base (sys_num,
1571  vg,
1572  next_free_dof);
1573 
1574  next_free_dof += (n_vars_in_group*
1575  node->n_comp_group(sys_num,vg));
1576  }
1577  } // end loop on variable groups
1578 
1579  this->distribute_scalar_dofs(next_free_dof);
1580 
1581 #ifdef DEBUG
1583 #endif
1584 }
unsigned int n_variable_groups() const
Definition: dof_map.h:627
MeshBase & mesh
unsigned int sys_number() const
Definition: dof_map.h:2266
const dof_id_type n_nodes
Definition: tecplot_io.C:67
void assert_no_nodes_missed(MeshBase &mesh)
Definition: dof_map.C:1612
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2274
void distribute_scalar_dofs(dof_id_type &next_free_dof)
Definition: dof_map.C:1588
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 1588 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().

1589 {
1590  this->_n_SCALAR_dofs = 0;
1591  for (auto vg : make_range(this->n_variable_groups()))
1592  {
1593  const VariableGroup & vg_description(this->variable_group(vg));
1594 
1595  if (vg_description.type().family == SCALAR)
1596  {
1597  this->_n_SCALAR_dofs += (vg_description.n_variables()*
1598  vg_description.type().order.get_order());
1599  continue;
1600  }
1601  }
1602 
1603  // Only increment next_free_dof if we're on the processor
1604  // that holds this SCALAR variable
1605  if (this->processor_id() == (this->n_processors()-1))
1606  next_free_dof += _n_SCALAR_dofs;
1607 }
unsigned int n_variable_groups() const
Definition: dof_map.h:627
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:2164
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2274
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:140
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

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

Definition at line 2184 of file dof_map.C.

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

Referenced by libMesh::ExactSolution::_compute_error(), libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::MeshFunction::_gradient_on_elem(), add_neighbors_to_send_list(), libMesh::HPCoarsenTest::add_projection(), assemble(), LinearElasticity::assemble(), 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::StaticCondensation::init(), 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::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::HDGProblem::residual(), LargeDeformationElasticity::residual(), Biharmonic::JR::residual_and_jacobian(), LinearElasticityWithContact::residual_and_jacobian(), scatter_constraints(), libMesh::HPCoarsenTest::select_refinement(), libMesh::PetscDMWrapper::set_point_range_in_section(), FETestBase< order, family, elem_type, 1 >::setUp(), SolidSystem::side_time_derivative(), libMesh::SparsityPattern::Build::sorted_connected_dofs(), MixedDimensionMeshTest::testDofOrdering(), MixedDimensionRefinedMeshTest::testDofOrdering(), MixedDimensionNonUniformRefinement::testDofOrdering(), MixedDimensionNonUniformRefinementTriangle::testDofOrdering(), MixedDimensionNonUniformRefinement3D::testDofOrdering(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), InfFERadialTest::testRefinement(), BoundaryInfoTest::testShellFaceConstraints(), libMesh::BoundaryVolumeSolutionTransfer::transfer_boundary_volume(), NonManifoldGhostingFunctorTest::verify_send_list_entries_helper(), libMesh::Nemesis_IO_Helper::write_nodal_solution(), libMesh::EnsightIO::write_scalar_ascii(), and libMesh::EnsightIO::write_vector_ascii().

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

◆ 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

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

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

Definition at line 2300 of file dof_map.C.

References dof_indices(), and int.

2304 {
2305  dof_indices(
2306  elem,
2307  di,
2308  vn,
2309  [](const Elem &,
2310  std::vector<dof_id_type> & dof_indices,
2311  const std::vector<dof_id_type> & scalar_dof_indices) {
2312  dof_indices.insert(dof_indices.end(), scalar_dof_indices.begin(), scalar_dof_indices.end());
2313  },
2314  [](const Elem &,
2315  unsigned int,
2316  unsigned int,
2317  std::vector<dof_id_type> & dof_indices,
2318  const dof_id_type dof) { dof_indices.push_back(dof); },
2319  p_level);
2320 }
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
Definition: dof_map.C:2184
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 2706 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().

2712 {
2713  // We now allow elem==nullptr to request just SCALAR dofs
2714  // libmesh_assert(elem);
2715 
2716  LOG_SCOPE("dof_indices()", "DofMap");
2717 
2718  // Clear the DOF indices vector
2719  di.clear();
2720 
2721  // Use the default p refinement level?
2722  if (p_level == -12345)
2723  p_level = elem ? elem->p_level() : 0;
2724 
2725  const unsigned int vg = this->_variable_group_numbers[vn];
2726  const VariableGroup & var = this->variable_group(vg);
2727  const unsigned int vig = vn - var.number();
2728 
2729 #ifdef DEBUG
2730  // Check that sizes match in DEBUG mode
2731  std::size_t tot_size = 0;
2732 #endif
2733 
2734  if (elem && elem->type() == TRI3SUBDIVISION)
2735  {
2736  // Subdivision surface FE require the 1-ring around elem
2737  const Tri3Subdivision * sd_elem = static_cast<const Tri3Subdivision *>(elem);
2738 
2739  // Ghost subdivision elements have no real dofs
2740  if (!sd_elem->is_ghost())
2741  {
2742  // Determine the nodes contributing to element elem
2743  std::vector<const Node *> elem_nodes;
2744  MeshTools::Subdivision::find_one_ring(sd_elem, elem_nodes);
2745 
2746  _dof_indices(*elem, p_level, di, vg, vig, elem_nodes.data(),
2747  cast_int<unsigned int>(elem_nodes.size()), vn,
2748 #ifdef DEBUG
2749  tot_size,
2750 #endif
2751  field_dofs_functor);
2752  }
2753 
2754  return;
2755  }
2756 
2757  // Get the dof numbers
2758  if (var.type().family == SCALAR &&
2759  (!elem ||
2760  var.active_on_subdomain(elem->subdomain_id())))
2761  {
2762 #ifdef DEBUG
2763  tot_size += var.type().order;
2764 #endif
2765  std::vector<dof_id_type> di_new;
2766  this->SCALAR_dof_indices(di_new,vn);
2767  scalar_dofs_functor(*elem, di, di_new);
2768  }
2769  else if (elem)
2770  _dof_indices(*elem, p_level, di, vg, vig, elem->get_nodes(),
2771  elem->n_nodes(), vn,
2772 #ifdef DEBUG
2773  tot_size,
2774 #endif
2775  field_dofs_functor);
2776 
2777 #ifdef DEBUG
2778  libmesh_assert_equal_to (tot_size, di.size());
2779 #endif
2780 }
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:2567
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:2274
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:2535
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:2019

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

2324 {
2325  // We allow node==nullptr to request just SCALAR dofs
2326  // libmesh_assert(elem);
2327 
2328  // dof_indices() is a relatively light-weight function that is
2329  // called millions of times in normal codes. Therefore, it is not a
2330  // good candidate for logging, since the cost of the logging code
2331  // itself is roughly on par with the time required to call
2332  // dof_indices().
2333  // LOG_SCOPE("dof_indices(Node)", "DofMap");
2334 
2335  // Clear the DOF indices vector
2336  di.clear();
2337 
2338  const unsigned int n_var_groups = this->n_variable_groups();
2339  const unsigned int sys_num = this->sys_number();
2340 
2341  // Get the dof numbers
2342  for (unsigned int vg=0; vg<n_var_groups; vg++)
2343  {
2344  const VariableGroup & var = this->variable_group(vg);
2345  const unsigned int vars_in_group = var.n_variables();
2346 
2347  if (var.type().family == SCALAR)
2348  {
2349  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2350  {
2351  std::vector<dof_id_type> di_new;
2352  this->SCALAR_dof_indices(di_new,var.number(vig));
2353  di.insert( di.end(), di_new.begin(), di_new.end());
2354  }
2355  }
2356  else
2357  {
2358  const int n_comp = node->n_comp_group(sys_num,vg);
2359  for (unsigned int vig=0; vig != vars_in_group; ++vig)
2360  {
2361  for (int i=0; i != n_comp; ++i)
2362  {
2363  const dof_id_type d =
2364  node->dof_number(sys_num, vg, vig, i, n_comp);
2365  libmesh_assert_not_equal_to
2366  (d, DofObject::invalid_id);
2367  di.push_back(d);
2368  }
2369  }
2370  }
2371  }
2372 }
unsigned int n_variable_groups() const
Definition: dof_map.h:627
unsigned int sys_number() const
Definition: dof_map.h:2266
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:2567
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2274
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

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

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

2378 {
2379  if (vn == libMesh::invalid_uint)
2380  {
2381  this->dof_indices(node, di);
2382  return;
2383  }
2384 
2385  // We allow node==nullptr to request just SCALAR dofs
2386  // libmesh_assert(elem);
2387 
2388  // dof_indices() is a relatively light-weight function that is
2389  // called millions of times in normal codes. Therefore, it is not a
2390  // good candidate for logging, since the cost of the logging code
2391  // itself is roughly on par with the time required to call
2392  // dof_indices().
2393  // LOG_SCOPE("dof_indices(Node)", "DofMap");
2394 
2395  // Clear the DOF indices vector
2396  di.clear();
2397 
2398  const unsigned int sys_num = this->sys_number();
2399 
2400  // Get the dof numbers
2401  const unsigned int vg = this->_variable_group_numbers[vn];
2402  const VariableGroup & var = this->variable_group(vg);
2403 
2404  if (var.type().family == SCALAR)
2405  {
2406  std::vector<dof_id_type> di_new;
2407  this->SCALAR_dof_indices(di_new,vn);
2408  di.insert( di.end(), di_new.begin(), di_new.end());
2409  }
2410  else
2411  {
2412  const unsigned int vig = vn - var.number();
2413  const int n_comp = node->n_comp_group(sys_num,vg);
2414  for (int i=0; i != n_comp; ++i)
2415  {
2416  const dof_id_type d =
2417  node->dof_number(sys_num, vg, vig, i, n_comp);
2418  libmesh_assert_not_equal_to
2419  (d, DofObject::invalid_id);
2420  di.push_back(d);
2421  }
2422  }
2423 }
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:293
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
Definition: dof_map.C:2184
unsigned int sys_number() const
Definition: dof_map.h:2266
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:2567
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:2274
std::vector< unsigned int > _variable_group_numbers
The variable group number for each variable.
Definition: dof_map.h:2019
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 2426 of file dof_map.C.

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

2430 {
2431  this->_node_dof_indices(elem, n, elem.node_ref(n), di, vn);
2432 }
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:2451

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

References _end_df, and libMesh::libmesh_assert().

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

766  { std::vector<dof_id_type>::const_iterator ub =
767  std::upper_bound(_end_df.begin(), _end_df.end(), dof);
768  libmesh_assert (ub != _end_df.end());
769  return cast_int<processor_id_type>(ub - _end_df.begin());
770  }
libmesh_assert(ctx)
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:2051

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

References mesh.

Referenced by distribute_dofs().

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

◆ enable_print_counter_info()

void libMesh::ReferenceCounter::enable_print_counter_info ( )
staticinherited

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

Definition at line 94 of file reference_counter.C.

References libMesh::ReferenceCounter::_enable_print_counter.

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

◆ end_dof() [1/2]

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

◆ end_dof() [2/2]

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

Definition at line 759 of file dof_map.h.

References libMesh::ParallelObject::processor_id().

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

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

◆ end_old_dof() [1/2]

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

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

Definition at line 779 of file dof_map.h.

References _end_old_df.

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

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

◆ end_old_dof() [2/2]

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

Definition at line 782 of file dof_map.h.

References libMesh::ParallelObject::processor_id().

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

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

2449  {}

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

2446  {}

◆ enforce_constraints_on_jacobian()

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

Definition at line 2459 of file dof_map.h.

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

2460  {}

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

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

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

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

2876 {
2877  typedef std::set<dof_id_type> RCSet;
2878 
2879  // First insert the DOFS we already depend on into the set.
2880  RCSet dof_set (elem_dofs.begin(), elem_dofs.end());
2881 
2882  bool done = true;
2883 
2884  // Next insert any dofs those might be constrained in terms
2885  // of. Note that in this case we may not be done: Those may
2886  // in turn depend on others. So, we need to repeat this process
2887  // in that case until the system depends only on unconstrained
2888  // degrees of freedom.
2889  for (const auto & dof : elem_dofs)
2890  if (this->is_constrained_dof(dof))
2891  {
2892  // If the DOF is constrained
2893  DofConstraints::const_iterator
2894  pos = _dof_constraints.find(dof);
2895 
2896  libmesh_assert (pos != _dof_constraints.end());
2897 
2898  const DofConstraintRow & constraint_row = pos->second;
2899 
2900  // adaptive p refinement currently gives us lots of empty constraint
2901  // rows - we should optimize those DoFs away in the future. [RHS]
2902  //libmesh_assert (!constraint_row.empty());
2903 
2904  // Add the DOFs this dof is constrained in terms of.
2905  // note that these dofs might also be constrained, so
2906  // we will need to call this function recursively.
2907  for (const auto & pr : constraint_row)
2908  if (!dof_set.count (pr.first))
2909  {
2910  dof_set.insert (pr.first);
2911  done = false;
2912  }
2913  }
2914 
2915 
2916  // If not done then we need to do more work
2917  // (obviously :-) )!
2918  if (!done)
2919  {
2920  // Fill the vector with the contents of the set
2921  elem_dofs.clear();
2922  elem_dofs.insert (elem_dofs.end(),
2923  dof_set.begin(), dof_set.end());
2924 
2925 
2926  // May need to do this recursively. It is possible
2927  // that we just replaced a constrained DOF with another
2928  // constrained DOF.
2929  this->find_connected_dofs (elem_dofs);
2930 
2931  } // end if (!done)
2932 }
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:2875
libmesh_assert(ctx)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:2352
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2200
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:99

◆ first_dof() [1/2]

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

◆ first_dof() [2/2]

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

Definition at line 735 of file dof_map.h.

References libMesh::ParallelObject::processor_id().

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

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

◆ first_old_dof() [1/2]

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

Definition at line 742 of file dof_map.h.

References _first_old_df.

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

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

◆ first_old_dof() [2/2]

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

Definition at line 745 of file dof_map.h.

References libMesh::ParallelObject::processor_id().

746  { return this->first_old_dof(this->processor_id()); }
dof_id_type first_old_dof() const
Definition: dof_map.h:745
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 2480 of file dof_map.h.

References need_full_sparsity_pattern.

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

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

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

Referenced by allgather_recursive_constraints(), and scatter_constraints().

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

◆ get_adjoint_dirichlet_boundaries() [1/2]

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

Definition at line 5438 of file dof_map_constraints.C.

References _adjoint_dirichlet_boundaries.

5439 {
5440  libmesh_assert_greater(_adjoint_dirichlet_boundaries.size(),q);
5441  return _adjoint_dirichlet_boundaries[q].get();
5442 }
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2234

◆ get_adjoint_dirichlet_boundaries() [2/2]

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

Definition at line 5446 of file dof_map_constraints.C.

References _adjoint_dirichlet_boundaries.

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

◆ get_dirichlet_boundaries() [1/2]

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

Definition at line 1573 of file dof_map.h.

References _dirichlet_boundaries.

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

1574  {
1575  return _dirichlet_boundaries.get();
1576  }
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2228

◆ get_dirichlet_boundaries() [2/2]

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

Definition at line 1578 of file dof_map.h.

References _dirichlet_boundaries.

1579  {
1580  return _dirichlet_boundaries.get();
1581  }
std::unique_ptr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2228

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

References _dof_constraints.

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

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

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

◆ get_local_constraints()

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

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

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

Definition at line 2278 of file dof_map_constraints.C.

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

Referenced by print_dof_constraints().

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

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

References _sp, and libMesh::libmesh_assert().

535  {
537  return _sp->get_n_nz();
538  }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2153
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 547 of file dof_map.h.

References _sp, and libMesh::libmesh_assert().

548  {
550  return _sp->get_n_oz();
551  }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2153
libmesh_assert(ctx)

◆ get_periodic_boundaries() [1/2]

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

Definition at line 1520 of file dof_map.h.

References _periodic_boundaries.

Referenced by main().

1521  {
1522  return _periodic_boundaries.get();
1523  }
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2220

◆ get_periodic_boundaries() [2/2]

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

Definition at line 1525 of file dof_map.h.

References _periodic_boundaries.

1526  {
1527  return _periodic_boundaries.get();
1528  }
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2220

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

References _primal_constraint_values.

2398 {
2400 }
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:2202

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

References _sp.

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

563  {
564  return _sp.get();
565  }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2153

◆ get_static_condensation()

const StaticCondensation & 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 2783 of file dof_map.h.

References _sc, and libMesh::libmesh_assert().

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

2784 {
2786  return *_sc;
2787 }
libmesh_assert(ctx)
const StaticCondensation * _sc
Static condensation class.
Definition: dof_map.h:2259

◆ has_adjoint_dirichlet_boundaries()

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

Definition at line 5428 of file dof_map_constraints.C.

References _adjoint_dirichlet_boundaries.

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

5429 {
5430  if (_adjoint_dirichlet_boundaries.size() > q)
5431  return true;
5432 
5433  return false;
5434 }
std::vector< std::unique_ptr< DirichletBoundaries > > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:2234

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

References n_variable_groups(), and n_variables().

Referenced by block_size().

649  {
650  return ((this->n_variable_groups() == 1) && (this->n_variables() > 1));
651  }
unsigned int n_variable_groups() const
Definition: dof_map.h:627
unsigned int n_variables() const
Definition: dof_map.h:635

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

References _adjoint_constraint_values.

Referenced by has_heterogenous_adjoint_constraint().

2378 {
2379  AdjointDofConstraintValues::const_iterator it =
2380  _adjoint_constraint_values.find(qoi_num);
2381  if (it != _adjoint_constraint_values.end())
2382  {
2383  DofConstraintValueMap::const_iterator rhsit =
2384  it->second.find(dof);
2385  if (rhsit == it->second.end())
2386  return 0;
2387  else
2388  return rhsit->second;
2389  }
2390 
2391  return 0;
2392 }
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2204

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

References _adjoint_constraint_values.

Referenced by has_heterogenous_adjoint_constraints().

2363 {
2364  AdjointDofConstraintValues::const_iterator it =
2365  _adjoint_constraint_values.find(qoi_num);
2366  if (it == _adjoint_constraint_values.end())
2367  return false;
2368  if (it->second.empty())
2369  return false;
2370 
2371  return true;
2372 }
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:2204

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

References has_heterogeneous_adjoint_constraint().

1192  {
1193  return this->has_heterogeneous_adjoint_constraint (qoi_num, dof);
1194  }
Number has_heterogeneous_adjoint_constraint(const unsigned int qoi_num, const dof_id_type dof) const
Definition: dof_map.h:2376

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

References has_heterogeneous_adjoint_constraints().

1175  {
1176  return this->has_heterogeneous_adjoint_constraints (qoi_num);
1177  }
bool has_heterogeneous_adjoint_constraints(const unsigned int qoi_num) const
Definition: dof_map.h:2362

◆ has_static_condensation()

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

Checks whether we have static condensation.

Definition at line 1737 of file dof_map.h.

References _sc.

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

1737 { return _sc; }
const StaticCondensation * _sc
Static condensation class.
Definition: dof_map.h:2259

◆ heterogeneously_constrain_element_jacobian_and_residual()

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

Constrains the element Jacobian and residual.

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

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

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

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

Definition at line 2619 of file dof_map_constraints.C.

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

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

◆ heterogeneously_constrain_element_matrix_and_vector()

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

Constrains the element matrix and vector.

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

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

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

Definition at line 2430 of file dof_map.h.

Referenced by heterogenously_constrain_element_matrix_and_vector(), and process_mesh_constraint_rows().

2431  {}

◆ heterogeneously_constrain_element_residual()

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

Constrains the element residual.

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

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

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

Definition at line 2702 of file dof_map_constraints.C.

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

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

Referenced by heterogenously_constrain_element_vector().

2435  {}

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

References heterogeneously_constrain_element_matrix_and_vector().

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

1330  {
1332  (matrix, rhs, elem_dofs, asymmetric_constraint_rows, qoi_index);
1333  }
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:2430

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

References heterogeneously_constrain_element_vector().

1374  {
1376  (matrix, rhs, elem_dofs, asymmetric_constraint_rows, qoi_index);
1377  }
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:2434

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

References mesh, and sys_number().

Referenced by distribute_dofs().

884 {
885  const unsigned int sys_num = this->sys_number();
886 
887  // All the nodes
888  for (auto & node : mesh.node_ptr_range())
889  node->invalidate_dofs(sys_num);
890 
891  // All the active elements.
892  for (auto & elem : mesh.active_element_ptr_range())
893  elem->invalidate_dofs(sys_num);
894 }
MeshBase & mesh
unsigned int sys_number() const
Definition: dof_map.h:2266

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

References _matrices.

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

327 {
328  return (std::find(_matrices.begin(), _matrices.end(),
329  &matrix) != _matrices.end());
330 }
std::vector< SparseMatrix< Number > *> _matrices
Additional matrices handled by this object.
Definition: dof_map.h:2041

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

References _node_constraints.

Referenced by allgather_recursive_constraints(), and scatter_constraints().

2341 {
2342 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2343  if (_node_constraints.count(node))
2344  return true;
2345 #endif
2346 
2347  return false;
2348 }
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:2211

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

2634 {
2635  // Everything is evaluable on a local object
2636  if (obj.processor_id() == this->processor_id())
2637  return true;
2638 
2639  std::vector<dof_id_type> di;
2640 
2641  if (var_num == libMesh::invalid_uint)
2642  this->dof_indices(&obj, di);
2643  else
2644  this->dof_indices(&obj, di, var_num);
2645 
2646  return this->all_semilocal_indices(di);
2647 }
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:293
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
Definition: dof_map.C:2184
bool all_semilocal_indices(const std::vector< dof_id_type > &dof_indices) const
Definition: dof_map.C:2619
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 212 of file dof_map.C.

References _periodic_boundaries.

213 {
214  if (_periodic_boundaries->count(boundaryid) != 0)
215  return true;
216 
217  return false;
218 }
std::unique_ptr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:2220

◆ local_index()

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

◆ local_variable_indices()

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 > >
template 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 1171 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(), n_local_dofs(), libMesh::petsc_auto_fieldsplit(), and SystemsTest::testBlockRestrictedVarNDofs().

1174 {
1175  // Only used if T == dof_id_type to keep track of the greatest dof we've seen
1176  dof_id_type greatest = 0;
1177 
1178  if constexpr (std::is_same_v<T, dof_id_type>)
1179  idx = 0;
1180  else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1181  idx.clear();
1182 
1183  // Count dofs in the *exact* order that distribute_dofs numbered
1184  // them, so that we can assume ascending indices and use push_back
1185  // instead of find+insert.
1186 
1187  const unsigned int sys_num = this->sys_number();
1188 
1189  // If this isn't a SCALAR variable, we need to find all its field
1190  // dofs on the mesh
1191  if (this->variable_type(var_num).family != SCALAR)
1192  {
1193  const Variable & var(this->variable(var_num));
1194 
1195  for (auto & elem : mesh.active_local_element_ptr_range())
1196  {
1197  if (!var.active_on_subdomain(elem->subdomain_id()))
1198  continue;
1199 
1200  // Only count dofs connected to active
1201  // elements on this processor.
1202  const unsigned int n_nodes = elem->n_nodes();
1203 
1204  // First get any new nodal DOFS
1205  for (unsigned int n=0; n<n_nodes; n++)
1206  {
1207  const Node & node = elem->node_ref(n);
1208 
1209  if (node.processor_id() != this->processor_id())
1210  continue;
1211 
1212  const unsigned int n_comp = node.n_comp(sys_num, var_num);
1213  for(unsigned int i=0; i<n_comp; i++)
1214  {
1215  const dof_id_type index = node.dof_number(sys_num,var_num,i);
1216  libmesh_assert (this->local_index(index));
1217 
1218  if constexpr (std::is_same_v<T, dof_id_type>)
1219  {
1220  if (idx == 0 || index > greatest)
1221  { idx++; greatest = index; }
1222  }
1223  else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1224  {
1225  if (idx.empty() || index > idx.back())
1226  idx.push_back(index);
1227  }
1228  }
1229  }
1230 
1231  // Next get any new element DOFS
1232  const unsigned int n_comp = elem->n_comp(sys_num, var_num);
1233  for (unsigned int i=0; i<n_comp; i++)
1234  {
1235  const dof_id_type index = elem->dof_number(sys_num,var_num,i);
1236 
1237  if constexpr (std::is_same_v<T, dof_id_type>)
1238  {
1239  if (idx == 0 || index > greatest)
1240  { idx++; greatest = index; }
1241  }
1242  else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1243  {
1244  if (idx.empty() || index > idx.back())
1245  idx.push_back(index);
1246  }
1247  }
1248  } // done looping over elements
1249 
1250 
1251  // we may have missed assigning DOFs to nodes that we own
1252  // but to which we have no connected elements matching our
1253  // variable restriction criterion. this will happen, for example,
1254  // if variable V is restricted to subdomain S. We may not own
1255  // any elements which live in S, but we may own nodes which are
1256  // *connected* to elements which do. in this scenario these nodes
1257  // will presently have unnumbered DOFs. we need to take care of
1258  // them here since we own them and no other processor will touch them.
1259  for (const auto & node : mesh.local_node_ptr_range())
1260  {
1261  libmesh_assert(node);
1262 
1263  const unsigned int n_comp = node->n_comp(sys_num, var_num);
1264  for (unsigned int i=0; i<n_comp; i++)
1265  {
1266  const dof_id_type index = node->dof_number(sys_num,var_num,i);
1267 
1268  if constexpr (std::is_same_v<T, dof_id_type>)
1269  {
1270  if (idx == 0 || index > greatest)
1271  { idx++; greatest = index; }
1272  }
1273  else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1274  {
1275  if (idx.empty() || index > idx.back())
1276  idx.push_back(index);
1277  }
1278  }
1279  }
1280  }
1281  // Otherwise, count up the SCALAR dofs, if we're on the processor
1282  // that holds this SCALAR variable
1283  else if (this->processor_id() == (this->n_processors()-1))
1284  {
1285  std::vector<dof_id_type> di_scalar;
1286  this->SCALAR_dof_indices(di_scalar,var_num);
1287 
1288  if constexpr (std::is_same_v<T, dof_id_type>)
1289  idx += std::distance(di_scalar.begin(), di_scalar.end());
1290  else if constexpr (std::is_same_v<T, std::vector<dof_id_type>>)
1291  idx.insert(idx.end(), di_scalar.begin(), di_scalar.end());
1292  }
1293 }
const FEType & variable_type(const unsigned int c) const
Definition: dof_map.h:2314
MeshBase & mesh
Real distance(const Point &p)
unsigned int sys_number() const
Definition: dof_map.h:2266
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:2567
processor_id_type n_processors() const
const dof_id_type n_nodes
Definition: tecplot_io.C:67
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:2284
libmesh_assert(ctx)
void clear()
Free all new memory associated with the object, but restore its original state, with the mesh pointer...
Definition: dof_map.C:898
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:916

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

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

◆ merge_ghost_functor_outputs()

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

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

1641 {
1642  for (const auto & gf : as_range(gf_begin, gf_end))
1643  {
1644  GhostingFunctor::map_type more_elements_to_ghost;
1645 
1646  libmesh_assert(gf);
1647  (*gf)(elems_begin, elems_end, p, more_elements_to_ghost);
1648 
1649  // A GhostingFunctor should only return active elements, but
1650  // I forgot to *document* that, so let's go as easy as we
1651  // can on functors that return inactive elements.
1652 #if defined(LIBMESH_ENABLE_DEPRECATED) && defined(LIBMESH_ENABLE_AMR)
1653  std::vector<std::pair<const Elem*, const CouplingMatrix*>> children_to_couple;
1654  for (auto it = more_elements_to_ghost.begin();
1655  it != more_elements_to_ghost.end();)
1656  {
1657  const Elem * elem = it->first;
1658  if (!elem->active())
1659  {
1660  libmesh_deprecated();
1661  std::vector<const Elem*> children_to_ghost;
1662  elem->active_family_tree(children_to_ghost,
1663  /*reset=*/ false);
1664  for (const Elem * child : children_to_ghost)
1665  if (child->processor_id() != p)
1666  children_to_couple.emplace_back(child, it->second);
1667 
1668  it = more_elements_to_ghost.erase(it);
1669  }
1670  else
1671  ++it;
1672  }
1673  more_elements_to_ghost.insert(children_to_couple.begin(),
1674  children_to_couple.end());
1675 #endif
1676 
1677  for (const auto & [elem, elem_cm] : more_elements_to_ghost)
1678  {
1679  // At this point we should only have active elements, even
1680  // if we had to fix up gf output to get here.
1681  libmesh_assert(elem->active());
1682 
1683  if (const auto existing_it = elements_to_ghost.find(elem);
1684  existing_it == elements_to_ghost.end())
1685  elements_to_ghost.emplace(elem, elem_cm);
1686  else
1687  {
1688  if (existing_it->second)
1689  {
1690  if (elem_cm)
1691  {
1692  // If this isn't already a temporary
1693  // then we need to make one so we'll
1694  // have a non-const matrix to merge
1695  if (temporary_coupling_matrices.empty() ||
1696  !temporary_coupling_matrices.count(existing_it->second))
1697  {
1698  // Make copy. This just calls the
1699  // compiler-generated copy constructor
1700  // because the CouplingMatrix class does not
1701  // define a custom copy constructor.
1702  auto result_pr = temporary_coupling_matrices.insert(std::make_unique<CouplingMatrix>(*existing_it->second));
1703  existing_it->second = result_pr.first->get();
1704  }
1705 
1706  // Merge elem_cm into existing CouplingMatrix
1707  const_cast<CouplingMatrix &>(*existing_it->second) &= *elem_cm;
1708  }
1709  else // elem_cm == nullptr
1710  {
1711  // Any existing_it matrix merged with a full
1712  // matrix (symbolized as nullptr) gives another
1713  // full matrix (symbolizable as nullptr).
1714 
1715  // So if existing_it->second is a temporary then
1716  // we don't need it anymore; we might as well
1717  // remove it to keep the set of temporaries
1718  // small.
1719  if (const auto temp_it = temporary_coupling_matrices.find(existing_it->second);
1720  temp_it != temporary_coupling_matrices.end())
1721  temporary_coupling_matrices.erase(temp_it);
1722 
1723  existing_it->second = nullptr;
1724  }
1725  }
1726  // else we have a nullptr already, then we have a full
1727  // coupling matrix, already, and merging with anything
1728  // else won't change that, so we're done.
1729  }
1730  }
1731  }
1732 }
std::map< const Elem *, const CouplingMatrix *, CompareDofObjectsByPIDAndThenID > map_type
What elements do we care about and what variables do we care about on each element?
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
libmesh_assert(ctx)

◆ n_constrained_dofs()

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

Definition at line 1713 of file dof_map_constraints.C.

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

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

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

◆ n_constrained_nodes()

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

Definition at line 996 of file dof_map.h.

References _node_constraints.

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

◆ n_dofs() [1/2]

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

◆ n_dofs() [2/2]

dof_id_type libMesh::DofMap::n_dofs ( const unsigned int  vn) const
inline
Returns
The total number of degrees of freedom for a particular variable vn.

Definition at line 679 of file dof_map.h.

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

680  {
681  dof_id_type n = this->n_local_dofs(vn);
682  this->comm().sum(n);
683  return n;
684  }
dof_id_type n_local_dofs() const
Definition: dof_map.h:694
void sum(T &r) const
const Parallel::Communicator & comm() const
uint8_t dof_id_type
Definition: id_types.h:67

◆ n_dofs_on_processor()

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

Definition at line 712 of file dof_map.h.

References _end_df, and _first_df.

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

713  {
714  libmesh_assert_less (proc, _first_df.size());
715  return cast_int<dof_id_type>(_end_df[proc] - _first_df[proc]);
716  }
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:2051
std::vector< dof_id_type > _first_df
First DOF index on processor p.
Definition: dof_map.h:2046

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

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

Referenced by SystemsTest::test100KVariables().

723  {
724  std::vector<dof_id_type> n_local_dofs(this->n_processors(), 0);
725  this->comm().allgather(this->n_local_dofs(vn), n_local_dofs);
726  return n_local_dofs;
727  }
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
dof_id_type n_local_dofs() const
Definition: dof_map.h:694
const Parallel::Communicator & comm() const
processor_id_type n_processors() const

◆ n_local_constrained_dofs()

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

Definition at line 1723 of file dof_map_constraints.C.

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

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

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

◆ n_local_dofs() [1/2]

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

◆ n_local_dofs() [2/2]

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

References _mesh, and local_variable_indices().

703  {
704  dof_id_type n;
705  this->local_variable_indices(n, _mesh, vn);
706  return n;
707  }
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:1171
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2034
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::DofMap::n_old_dofs ( ) const
inline
Returns
The total number of degrees of freedom on old_dof_objects

Definition at line 1630 of file dof_map.h.

References _n_old_dfs.

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

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

◆ n_processors()

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

Definition at line 103 of file parallel_object.h.

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

Referenced by libMesh::Partitioner::_find_global_index_by_pid_map(), libMesh::BoundaryInfo::_find_id_maps(), add_constraints_to_send_list(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::DistributedMesh::add_elem(), add_neighbors_to_send_list(), libMesh::DistributedMesh::add_node(), libMesh::System::add_vector(), libMesh::LaplaceMeshSmoother::allgather_graph(), allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::Partitioner::assign_partitioning(), libMesh::AztecLinearSolver< T >::AztecLinearSolver(), libMesh::Partitioner::build_graph(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::DistributedMesh::clear(), libMesh::DistributedMesh::clear_elems(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::UnstructuredMesh::copy_nodes_and_elements(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::Nemesis_IO::copy_scalar_solution(), libMesh::UnstructuredMesh::create_pid_mesh(), libMesh::MeshTools::create_processor_bounding_box(), distribute_dofs(), distribute_scalar_dofs(), libMesh::DistributedMesh::DistributedMesh(), libMesh::EnsightIO::EnsightIO(), libMesh::RBEIMEvaluation::gather_bfs(), libMesh::MeshBase::get_info(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_petscdm(), libMesh::Nemesis_IO_Helper::initialize(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::DistributedMesh::insert_elem(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_new_node_procids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_topology_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), local_variable_indices(), libMesh::MeshRefinement::make_coarsening_compatible(), libMesh::MeshBase::n_active_elem_on_proc(), n_dofs_per_processor(), libMesh::MeshBase::n_elem_on_proc(), libMesh::MeshBase::n_nodes_on_proc(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::Partitioner::partition(), libMesh::MeshBase::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), prepare_send_list(), libMesh::MeshBase::print_constraint_rows(), print_dof_constraints(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::CheckpointIO::read_connectivity(), libMesh::XdrIO::read_header(), libMesh::CheckpointIO::read_nodes(), libMesh::System::read_parallel_data(), libMesh::System::read_SCALAR_dofs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::System::read_serialized_vector(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::Partitioner::repartition(), OverlappingFunctorTest::run_partitioner_test(), scatter_constraints(), libMesh::DistributedMesh::set_next_unique_id(), set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), WriteVecAndScalar::setupTests(), libMesh::RBEIMEvaluation::side_gather_bfs(), DistributedMeshTest::testRemoteElemError(), CheckpointIOTest::testSplitter(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::DistributedMesh::update_parallel_id_counts(), libMesh::GMVIO::write_binary(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::VTKIO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data(), libMesh::System::write_parallel_data(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), and libMesh::XdrIO::write_serialized_nodesets().

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

◆ n_SCALAR_dofs()

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

Definition at line 689 of file dof_map.h.

References _n_SCALAR_dofs.

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

689 { 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:2164

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

References _variable_groups.

Referenced by distribute_scalar_dofs(), dof_indices(), has_blocked_representation(), libMesh::StaticCondensation::init(), old_dof_indices(), and set_nonlocal_dof_objects().

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

◆ n_variables()

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

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

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

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

References _node_constraints.

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

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

References _node_constraints.

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

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

References mesh.

Referenced by distribute_dofs().

335 {
336  return mesh.node_ptr(i);
337 }
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 2438 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().

2442 {
2443  const DofObject & old_obj = elem.node_ref(n).get_old_dof_object_ref();
2444  this->_node_dof_indices(elem, n, old_obj, di, vn);
2445 }
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:2451

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

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

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

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

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

1885 {
1886  LOG_SCOPE("prepare_send_list()", "DofMap");
1887 
1888  // Return immediately if there's no ghost data
1889  if (this->n_processors() == 1)
1890  return;
1891 
1892  // Check to see if we have any extra stuff to add to the send_list
1894  {
1895  if (_augment_send_list)
1896  {
1897  libmesh_here();
1898  libMesh::out << "WARNING: You have specified both an extra send list function and object.\n"
1899  << " Are you sure this is what you meant to do??"
1900  << std::endl;
1901  }
1902 
1904  }
1905 
1906  if (_augment_send_list)
1908 
1909  // First sort the send list. After this
1910  // duplicated elements will be adjacent in the
1911  // vector
1912  std::sort(_send_list.begin(), _send_list.end());
1913 
1914  // Now use std::unique to remove duplicate entries
1915  std::vector<dof_id_type>::iterator new_end =
1916  std::unique (_send_list.begin(), _send_list.end());
1917 
1918  // Remove the end of the send_list. Use the "swap trick"
1919  // from Effective STL
1920  std::vector<dof_id_type> (_send_list.begin(), new_end).swap (_send_list);
1921 
1922  // Make sure the send list has nothing invalid in it.
1923  libmesh_assert(_send_list.empty() || _send_list.back() < this->n_dofs());
1924 }
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:2063
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:2085
processor_id_type n_processors() const
dof_id_type n_dofs() const
Definition: dof_map.h:673
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:2095
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:2090

◆ print_dof_constraints()

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

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

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

Definition at line 2252 of file dof_map_constraints.C.

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

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

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

◆ print_info() [1/2]

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

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

Definition at line 81 of file reference_counter.C.

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

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

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

◆ print_info() [2/2]

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

Prints summary info about the sparsity bandwidth and constraints.

Definition at line 2938 of file dof_map.C.

References get_info().

2939 {
2940  os << this->get_info();
2941 }
std::string get_info() const
Gets summary info about the sparsity bandwidth and constraints.
Definition: dof_map.C:2945

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

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

◆ process_mesh_constraint_rows()

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

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

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

Definition at line 1897 of file dof_map_constraints.C.

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

Referenced by create_dof_constraints().

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

◆ processor_id()

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

Definition at line 114 of file parallel_object.h.

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

Referenced by libMesh::BoundaryInfo::_find_id_maps(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::DistributedMesh::add_elem(), libMesh::BoundaryInfo::add_elements(), add_neighbors_to_send_list(), libMesh::DistributedMesh::add_node(), libMesh::MeshTools::Modification::all_tri(), allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::Partitioner::assign_partitioning(), libMesh::Nemesis_IO_Helper::build_element_and_node_maps(), libMesh::Partitioner::build_graph(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::MeshFunction::check_found_elem(), libMesh::DistributedMesh::clear(), libMesh::DistributedMesh::clear_elems(), libMesh::ExodusII_IO_Helper::close(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::compute_communication_map_parameters(), libMesh::Nemesis_IO_Helper::compute_internal_and_border_elems_and_internal_nodes(), libMesh::RBConstruction::compute_max_error_bound(), libMesh::Nemesis_IO_Helper::compute_node_communication_maps(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::ExodusII_IO::copy_nodal_solution(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::Nemesis_IO::copy_scalar_solution(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::ExodusII_IO_Helper::create(), libMesh::DistributedMesh::delete_elem(), libMesh::MeshCommunication::delete_remote_elements(), distribute_dofs(), distribute_scalar_dofs(), libMesh::DistributedMesh::DistributedMesh(), end_dof(), end_old_dof(), libMesh::EnsightIO::EnsightIO(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::find_dofs_to_send(), libMesh::UnstructuredMesh::find_neighbors(), first_dof(), first_old_dof(), libMesh::RBEIMEvaluation::gather_bfs(), libMesh::Nemesis_IO_Helper::get_cmap_params(), libMesh::Nemesis_IO_Helper::get_eb_info_global(), libMesh::Nemesis_IO_Helper::get_elem_cmap(), libMesh::Nemesis_IO_Helper::get_elem_map(), libMesh::MeshBase::get_info(), get_info(), libMesh::Nemesis_IO_Helper::get_init_global(), libMesh::Nemesis_IO_Helper::get_init_info(), libMesh::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::StaticCondensation::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(), n_local_dofs(), libMesh::MeshBase::n_local_elem(), libMesh::MeshBase::n_local_nodes(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::BoundaryInfo::n_shellface_conds(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::DistributedMesh::own_node(), libMesh::BoundaryInfo::parallel_sync_node_ids(), libMesh::BoundaryInfo::parallel_sync_side_ids(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), libMesh::MeshBase::print_constraint_rows(), print_dof_constraints(), process_mesh_constraint_rows(), libMesh::Nemesis_IO_Helper::put_cmap_params(), libMesh::Nemesis_IO_Helper::put_elem_cmap(), libMesh::Nemesis_IO_Helper::put_elem_map(), libMesh::Nemesis_IO_Helper::put_loadbal_param(), libMesh::Nemesis_IO_Helper::put_node_cmap(), libMesh::Nemesis_IO_Helper::put_node_map(), libMesh::NameBasedIO::read(), libMesh::Nemesis_IO::read(), libMesh::XdrIO::read(), libMesh::CheckpointIO::read(), libMesh::EquationSystems::read(), libMesh::ExodusII_IO_Helper::read_elem_num_map(), libMesh::ExodusII_IO_Helper::read_global_values(), libMesh::ExodusII_IO::read_header(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::System::read_header(), libMesh::System::read_legacy_data(), libMesh::DynaIO::read_mesh(), libMesh::ExodusII_IO_Helper::read_node_num_map(), libMesh::System::read_parallel_data(), libMesh::TransientRBConstruction::read_riesz_representors_from_files(), libMesh::RBConstruction::read_riesz_representors_from_files(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::System::read_serialized_data(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::System::read_serialized_vectors(), libMesh::Nemesis_IO_Helper::read_var_names_impl(), libMesh::SimplexRefiner::refine_via_edges(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::DistributedMesh::renumber_nodes_and_elements(), scatter_constraints(), libMesh::CheckpointIO::select_split_config(), libMesh::DistributedMesh::set_next_unique_id(), set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::RBEIMEvaluation::side_gather_bfs(), ExodusTest< elem_type >::test_read_gold(), ExodusTest< elem_type >::test_write(), MeshInputTest::testAbaqusRead(), MeshInputTest::testBadGmsh(), MeshInputTest::testCopyElementSolutionImpl(), MeshInputTest::testCopyElementVectorImpl(), MeshInputTest::testCopyNodalSolutionImpl(), DefaultCouplingTest::testCoupling(), PointNeighborCouplingTest::testCoupling(), MeshInputTest::testDynaFileMappings(), MeshInputTest::testDynaNoSplines(), MeshInputTest::testDynaReadElem(), MeshInputTest::testDynaReadPatch(), MeshInputTest::testExodusFileMappings(), MeshInputTest::testExodusIGASidesets(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), MeshInputTest::testGmshBCIDOverlap(), MeshInputTest::testGoodGmsh(), MeshInputTest::testGoodSTL(), MeshInputTest::testGoodSTLBinary(), MeshInputTest::testLowOrderEdgeBlocks(), SystemsTest::testProjectMatrix3D(), BoundaryInfoTest::testShellFaceConstraints(), MeshInputTest::testSingleElementImpl(), WriteVecAndScalar::testSolution(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), libMesh::MeshTools::total_weight(), libMesh::NetGenMeshInterface::triangulate(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::DistributedMesh::update_parallel_id_counts(), libMesh::DTKAdapter::update_variable_values(), libMesh::MeshTools::volume(), libMesh::STLIO::write(), libMesh::NameBasedIO::write(), libMesh::XdrIO::write(), libMesh::CheckpointIO::write(), libMesh::EquationSystems::write(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::ExodusII_IO::write_element_data(), libMesh::ExodusII_IO_Helper::write_element_values(), libMesh::ExodusII_IO_Helper::write_element_values_element_major(), libMesh::ExodusII_IO_Helper::write_elements(), libMesh::ExodusII_IO_Helper::write_elemset_data(), libMesh::ExodusII_IO_Helper::write_elemsets(), libMesh::ExodusII_IO::write_global_data(), libMesh::ExodusII_IO_Helper::write_global_values(), libMesh::System::write_header(), libMesh::ExodusII_IO::write_information_records(), libMesh::ExodusII_IO_Helper::write_information_records(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::UCDIO::write_nodal_data(), libMesh::VTKIO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data_common(), libMesh::ExodusII_IO::write_nodal_data_discontinuous(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::ExodusII_IO_Helper::write_nodeset_data(), libMesh::Nemesis_IO_Helper::write_nodesets(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::RBEIMEvaluation::write_out_interior_basis_functions(), libMesh::RBEIMEvaluation::write_out_node_basis_functions(), libMesh::RBEIMEvaluation::write_out_side_basis_functions(), write_output_solvedata(), libMesh::System::write_parallel_data(), libMesh::RBConstruction::write_riesz_representors_to_files(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bc_names(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::System::write_serialized_data(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::XdrIO::write_serialized_subdomain_names(), libMesh::System::write_serialized_vector(), libMesh::System::write_serialized_vectors(), libMesh::ExodusII_IO_Helper::write_sideset_data(), libMesh::Nemesis_IO_Helper::write_sidesets(), libMesh::ExodusII_IO_Helper::write_sidesets(), libMesh::ExodusII_IO::write_timestep(), libMesh::ExodusII_IO_Helper::write_timestep(), and libMesh::ExodusII_IO::write_timestep_discontinuous().

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

◆ reinit()

void libMesh::DofMap::reinit ( MeshBase mesh,
const std::map< const Node *, std::set< subdomain_id_type >> &  constraining_subdomains 
)

Reinitialize the underlying data structures conformal to the current mesh.

Definition at line 500 of file dof_map.C.

References libMesh::Variable::active_on_subdomain(), libMesh::Utility::enum_to_string(), libMesh::err, libMesh::FEInterface::extra_hanging_dofs(), libMesh::FEType::family, libMesh::OrderWrapper::get_order(), int, libMesh::MeshBase::is_prepared(), libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), libMesh::FEInterface::max_order(), mesh, libMesh::DofObject::n_comp_group(), libMesh::FEInterface::n_dofs_at_node(), libMesh::FEInterface::n_dofs_per_elem(), libMesh::VariableGroup::n_variables(), libMesh::FEType::order, libMesh::SCALAR, libMesh::DofObject::set_n_comp_group(), libMesh::DofObject::set_vg_dof_base(), libMesh::Variable::type(), and libMesh::DofObject::vg_dof_base().

Referenced by distribute_dofs().

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

1927 {
1928  this->clear_send_list();
1930 
1931 #ifdef LIBMESH_ENABLE_CONSTRAINTS
1932  // This is assuming that we only need to recommunicate
1933  // the constraints and no new ones have been added since
1934  // a previous call to reinit_constraints.
1935  this->process_constraints(mesh);
1936 #endif
1937  this->prepare_send_list();
1938 }
void clear_send_list()
Clears the _send_list vector.
Definition: dof_map.h:499
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:1736
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:1884

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

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

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

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

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

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

2091 {
2092  _algebraic_ghosting_functors.erase(&evaluable_functor);
2093  _mesh.remove_ghosting_functor(evaluable_functor);
2094 
2095  if (const auto it = _shared_functors.find(&evaluable_functor);
2096  it != _shared_functors.end())
2097  _shared_functors.erase(it);
2098 }
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:930
std::set< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:2121
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2034
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:2140

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

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

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

2066 {
2067  _coupling_functors.erase(&coupling_functor);
2068  _mesh.remove_ghosting_functor(coupling_functor);
2069 
2070  if (const auto it = _shared_functors.find(&coupling_functor);
2071  it != _shared_functors.end())
2072  _shared_functors.erase(it);
2073 }
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:930
std::set< GhostingFunctor * > _coupling_functors
The list of all GhostingFunctor objects to be used when coupling degrees of freedom in matrix sparsit...
Definition: dof_map.h:2134
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:2034
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:2140

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

2037 {
2040 }
DefaultCoupling & default_coupling()
Default coupling functor.
Definition: dof_map.h:370
DefaultCoupling & default_algebraic_ghosting()
Default algebraic ghosting functor.
Definition: dof_map.h:432
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:2065
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:2090

◆ remove_dirichlet_boundary()

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

Removes the specified Dirichlet boundary from the system.

Definition at line 5457 of file dof_map_constraints.C.

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

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

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

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

2575 {
2576  LOG_SCOPE("SCALAR_dof_indices()", "DofMap");
2577 
2578  libmesh_assert(this->variable(vn).type().family == SCALAR);
2579 
2580 #ifdef LIBMESH_ENABLE_AMR
2581  // If we're asking for old dofs then we'd better have some
2582  if (old_dofs)
2583  libmesh_assert_greater_equal(n_old_dofs(), n_SCALAR_dofs());
2584 
2585  dof_id_type my_idx = old_dofs ?
2586  this->_first_old_scalar_df[vn] : this->_first_scalar_df[vn];
2587 #else
2588  dof_id_type my_idx = this->_first_scalar_df[vn];
2589 #endif
2590 
2591  libmesh_assert_not_equal_to(my_idx, DofObject::invalid_id);
2592 
2593  // The number of SCALAR dofs comes from the variable order
2594  const int n_dofs_vn = this->variable(vn).type().order.get_order();
2595 
2596  di.resize(n_dofs_vn);
2597  for (int i = 0; i != n_dofs_vn; ++i)
2598  di[i] = my_idx++;
2599 }
dof_id_type n_SCALAR_dofs() const
Definition: dof_map.h:689
OrderWrapper order
The approximation order of the element.
Definition: fe_type.h:215
dof_id_type n_old_dofs() const
Definition: dof_map.h:1630
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:2057
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:2187
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:2284
libmesh_assert(ctx)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:482
int get_order() const
Explicitly request the order as an int.
Definition: fe_type.h:80
uint8_t dof_id_type
Definition: id_types.h:67
const FEType & type() const
Definition: variable.h:140

◆ scatter_constraints()

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

Sends constraint equations to constraining processors.

Definition at line 4603 of file dof_map_constraints.C.

References _dof_constraints, _end_df, _node_constraints, _primal_constraint_values, libMesh::as_range(), libMesh::ParallelObject::comm(), coupling_functors_begin(), coupling_functors_end(), dof_indices(), gather_constraints(), TIMPI::Communicator::get_unique_tag(), libMesh::DofObject::id(), libMesh::index_range(), is_constrained_dof(), is_constrained_node(), libMesh::MeshBase::is_serial(), TIMPI::Communicator::max(), merge_ghost_functor_outputs(), mesh, libMesh::ParallelObject::n_processors(), libMesh::MeshBase::node_ptr(), libMesh::ParallelObject::processor_id(), and libMesh::DofObject::processor_id().

Referenced by process_constraints().

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

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

References _send_list, and local_index().

Referenced by all_semilocal_indices().

2604 {
2605  // If it's not in the local indices
2606  if (!this->local_index(dof_index))
2607  {
2608  // and if it's not in the ghost indices, then we're not
2609  // semilocal
2610  if (!std::binary_search(_send_list.begin(), _send_list.end(), dof_index))
2611  return false;
2612  }
2613 
2614  return true;
2615 }
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:2063
bool local_index(dof_id_type dof_index) const
Definition: dof_map.h:916

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

References _constrained_sparsity_construction, and libMesh::libmesh_ignore().

2468 {
2469  // This got only partly finished...
2470  if (use_constraints)
2471  libmesh_not_implemented();
2472 
2473 #ifdef LIBMESH_ENABLE_CONSTRAINTS
2474  _constrained_sparsity_construction = use_constraints;
2475 #endif
2476  libmesh_ignore(use_constraints);
2477 }
bool _constrained_sparsity_construction
This flag indicates whether or not we explicitly take constraint equations into account when computin...
Definition: dof_map.h:2004
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 238 of file dof_map.C.

References _error_on_constraint_loop.

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

239 {
240  _error_on_constraint_loop = error_on_constraint_loop;
241 }
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:1998

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

References set_error_on_constraint_loop().

232 {
233  // This function will eventually be officially libmesh_deprecated();
234  // Call DofMap::set_error_on_constraint_loop() instead.
235  set_error_on_constraint_loop(error_on_cyclic_constraint);
236 }
void set_error_on_constraint_loop(bool error_on_constraint_loop)
Definition: dof_map.C:238

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

References _implicit_neighbor_dofs, and _implicit_neighbor_dofs_initialized.

1941 {
1943  _implicit_neighbor_dofs = implicit_neighbor_dofs;
1944 }
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
Definition: dof_map.h:2243
bool _implicit_neighbor_dofs
Definition: dof_map.h:2244

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

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

◆ set_verify_dirichlet_bc_consistency()

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

Set the _verify_dirichlet_bc_consistency flag.

Definition at line 1946 of file dof_map.C.

References _verify_dirichlet_bc_consistency.

1947 {
1949 }
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:2256

◆ should_p_refine() [1/6]

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

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

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

Definition at line 2496 of file dof_map.h.

References _dont_p_refine, and libMesh::libmesh_ignore().

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

2497 {
2498 #ifdef LIBMESH_ENABLE_AMR
2499  if (p_refine)
2500  {
2501  auto it = _dont_p_refine.find(g);
2502  if (it != _dont_p_refine.end())
2503  _dont_p_refine.erase(it);
2504  }
2505  else
2506  _dont_p_refine.insert(g);
2507 #else
2508  libmesh_ignore(g, p_refine);
2509 #endif
2510 }
void libmesh_ignore(const Args &...)
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
Definition: dof_map.h:2192

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

References _dont_p_refine, and libMesh::libmesh_ignore().

2514 {
2515 #ifdef LIBMESH_ENABLE_AMR
2516  return !_dont_p_refine.count(g);
2517 #else
2518  libmesh_ignore(g);
2519  return false;
2520 #endif
2521 }
void libmesh_ignore(const Args &...)
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
Definition: dof_map.h:2192

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

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

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

2532 {
2533 #ifdef LIBMESH_ENABLE_AMR
2534  const auto vg = this->var_group_from_var_number(var);
2535  return !_dont_p_refine.count(vg);
2536 #else
2537  libmesh_ignore(var);
2538  return false;
2539 #endif
2540 }
unsigned int var_group_from_var_number(unsigned int var_num) const
Definition: dof_map.h:2524
void libmesh_ignore(const Args &...)
std::unordered_set< unsigned int > _dont_p_refine
A container of variable groups that we should not p-refine.
Definition: dof_map.h:2192

◆ stash_dof_constraints()

void libMesh::DofMap::stash_dof_constraints ( )
inline

Definition at line 1116 of file dof_map.h.

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

1117  {
1120  }
libmesh_assert(ctx)
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2200
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2200

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

References _dof_constraints, and _stashed_dof_constraints.

1141  {
1143  }
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2200
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2200

◆ sys_number()

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

◆ unstash_dof_constraints()

void libMesh::DofMap::unstash_dof_constraints ( )
inline

Definition at line 1122 of file dof_map.h.

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

1123  {
1126  }
libmesh_assert(ctx)
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:2200
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:2200

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

301 {
302  matrix.attach_dof_map (*this);
303 
304  // If we've already computed sparsity, then it's too late
305  // to wait for "compute_sparsity" to help with sparse matrix
306  // initialization, and we need to handle this matrix individually
307  if (this->computed_sparsity_already())
308  {
309  libmesh_assert(_sp.get());
310 
311  if (matrix.need_full_sparsity_pattern())
312  {
313  // We'd better have already computed the full sparsity
314  // pattern if we need it here
316 
317  matrix.update_sparsity_pattern (_sp->get_sparsity_pattern());
318  }
319 
320  matrix.attach_sparsity_pattern(*_sp);
321  }
322 }
std::unique_ptr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix.
Definition: dof_map.h:2153
void attach_sparsity_pattern(const SparsityPattern::Build &sp)
Set a pointer to a sparsity pattern to use.
Definition: sparse_matrix.C:84
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:2146
libmesh_assert(ctx)
bool computed_sparsity_already() const
Returns true iff a sparsity pattern has already been computed.
Definition: dof_map.C:289
void attach_dof_map(const DofMap &dof_map)
Set a pointer to the DofMap to use.
Definition: sparse_matrix.C:74
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 1952 of file dof_map.C.

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

Referenced by build_sparsity(), and clear().

1953 {
1954  // If we were asked on the command line, then we need to
1955  // include sensitivities between neighbor degrees of freedom
1956  bool implicit_neighbor_dofs =
1957  libMesh::on_command_line ("--implicit-neighbor-dofs");
1958 
1959  // If the user specifies --implicit-neighbor-dofs 0, then
1960  // presumably he knows what he is doing and we won't try to
1961  // automatically turn it on even when all the variables are
1962  // discontinuous.
1963  if (implicit_neighbor_dofs)
1964  {
1965  // No flag provided defaults to 'true'
1966  int flag = 1;
1967  flag = libMesh::command_line_next ("--implicit-neighbor-dofs", flag);
1968 
1969  if (!flag)
1970  {
1971  // The user said --implicit-neighbor-dofs 0, so he knows
1972  // what he is doing and really doesn't want it.
1973  return false;
1974  }
1975  }
1976 
1977  // Possibly override the commandline option, if set_implicit_neighbor_dofs
1978  // has been called.
1980  {
1981  implicit_neighbor_dofs = _implicit_neighbor_dofs;
1982 
1983  // Again, if the user explicitly says implicit_neighbor_dofs = false,
1984  // then we return here.
1985  if (!implicit_neighbor_dofs)
1986  return false;
1987  }
1988 
1989  // Look at all the variables in this system. If every one is
1990  // discontinuous then the user must be doing DG/FVM, so be nice
1991  // and force implicit_neighbor_dofs=true.
1992  {
1993  bool all_discontinuous_dofs = true;
1994 
1995  for (auto var : make_range(this->n_variables()))
1997  all_discontinuous_dofs = false;
1998 
1999  if (all_discontinuous_dofs)
2000  implicit_neighbor_dofs = true;
2001  }
2002 
2003  return implicit_neighbor_dofs;
2004 }
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:1072
bool _implicit_neighbor_dofs_initialized
Bools to indicate if we override the –implicit_neighbor_dofs commandline options.
Definition: dof_map.h:2243
bool _implicit_neighbor_dofs
Definition: dof_map.h:2244
const FEType & variable_type(const unsigned int c) const
Definition: dof_map.h:2314
unsigned int n_variables() const
Definition: dof_map.h:635
static FEContinuity get_continuity(const FEType &fe_type)
Returns the input FEType&#39;s FEContinuity based on the underlying FEFamily and potentially the Order...
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:140
bool on_command_line(std::string arg)
Definition: libmesh.C:981

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

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

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

2525 {
2526  libmesh_assert(var_num < n_variables());
2527  return libmesh_map_find(_var_to_vg, var_num);
2528 }
unsigned int n_variables() const
Definition: dof_map.h:635
std::unordered_map< unsigned int, unsigned int > _var_to_vg
A map from variable number to variable group number.
Definition: dof_map.h:2024
libmesh_assert(ctx)

◆ variable()

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

Definition at line 2284 of file dof_map.h.

References _variables.

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

2285 {
2286  libmesh_assert_less (c, _variables.size());
2287 
2288  return _variables[c];
2289 }
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:2009

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

References _variable_groups.

Referenced by _dof_indices(), _node_dof_indices(), distribute_scalar_dofs(), dof_indices(), libMesh::System::get_info(), libMesh::StaticCondensation::init(), and old_dof_indices().

2275 {
2276  libmesh_assert_less (g, _variable_groups.size());
2277 
2278  return _variable_groups[g];
2279 }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable group.
Definition: dof_map.h:2014

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

References _variable_groups.

2305 {
2306  libmesh_assert_less (vg, _variable_groups.size());
2307 
2308  return _variable_groups[vg].type().order;
2309 }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable group.
Definition: dof_map.h:2014

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

References _variable_groups.

2325 {
2326  libmesh_assert_less (vg, _variable_groups.size());
2327 
2328  return _variable_groups[vg].type();
2329 }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable group.
Definition: dof_map.h:2014

◆ variable_order()

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

Definition at line 2294 of file dof_map.h.

References _variables.

2295 {
2296  libmesh_assert_less (c, _variables.size());
2297 
2298  return _variables[c].type().order;
2299 }
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:2009

◆ variable_type()

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

Definition at line 2314 of file dof_map.h.

References _variables.

Referenced by libMesh::ExactSolution::_compute_error(), libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::MeshFunction::_gradient_on_elem(), LinearElasticity::assemble(), AssembleOptimization::assemble_A_and_F(), assemble_elasticity(), assemble_mass(), assemble_matrices(), assemble_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::PatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::MeshFunction::operator()(), libMesh::System::point_gradient(), libMesh::System::point_hessian(), libMesh::System::point_value(), process_mesh_constraint_rows(), LargeDeformationElasticity::residual(), Biharmonic::JR::residual_and_jacobian(), LinearElasticityWithContact::residual_and_jacobian(), libMesh::HPCoarsenTest::select_refinement(), and use_coupled_neighbor_dofs().

2315 {
2316  libmesh_assert_less (c, _variables.size());
2317 
2318  return _variables[c].type();
2319 }
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:2009

Friends And Related Function Documentation

◆ SparsityPattern::Build

friend class SparsityPattern::Build
friend

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

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

◆ _algebraic_ghosting_functors

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

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

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

Definition at line 2121 of file dof_map.h.

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

◆ _augment_send_list

AugmentSendList* libMesh::DofMap::_augment_send_list
private

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

Definition at line 2085 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 2068 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 2004 of file dof_map.h.

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

◆ _counts

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

Actually holds the data.

Definition at line 124 of file reference_counter.h.

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

◆ _coupling_functors

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

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

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

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

Definition at line 2134 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 2103 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 2111 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 2228 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 1683 of file dof_map.h.

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

◆ _dont_p_refine

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

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

Definition at line 2192 of file dof_map.h.

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

◆ _enable_print_counter

bool libMesh::ReferenceCounter::_enable_print_counter = true
staticprotectedinherited

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

Definition at line 143 of file reference_counter.h.

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

◆ _end_df

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

Last DOF index (plus 1) on processor p.

Definition at line 2051 of file dof_map.h.

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

◆ _end_old_df

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

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

Definition at line 2181 of file dof_map.h.

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

◆ _error_on_constraint_loop

bool libMesh::DofMap::_error_on_constraint_loop
private

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

cases where the constraint graph is cyclic.

Definition at line 1998 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 2095 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 2090 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 2080 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 2073 of file dof_map.h.

Referenced by attach_extra_sparsity_function(), and build_sparsity().

◆ _first_df

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

First DOF index on processor p.

Definition at line 2046 of file dof_map.h.

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

◆ _first_old_df

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

First old DOF index on processor p.

Definition at line 2176 of file dof_map.h.

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

◆ _first_old_scalar_df

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

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

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

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

◆ _implicit_neighbor_dofs

bool libMesh::DofMap::_implicit_neighbor_dofs
private

Definition at line 2244 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 2243 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 2041 of file dof_map.h.

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

◆ _mesh

MeshBase& libMesh::DofMap::_mesh
private

◆ _mutex

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

Mutual exclusion object to enable thread-safe reference counting.

Definition at line 137 of file reference_counter.h.

◆ _n_dfs

dof_id_type libMesh::DofMap::_n_dfs
private

Total number of degrees of freedom.

Definition at line 2158 of file dof_map.h.

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

◆ _n_objects

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

The number of objects.

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

Definition at line 132 of file reference_counter.h.

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

◆ _n_old_dfs

dof_id_type libMesh::DofMap::_n_old_dfs
private

Total number of degrees of freedom on old dof objects.

Definition at line 2171 of file dof_map.h.

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

◆ _n_SCALAR_dofs

dof_id_type libMesh::DofMap::_n_SCALAR_dofs
private

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

Definition at line 2164 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 2220 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

const StaticCondensation* libMesh::DofMap::_sc
private

Static condensation class.

Definition at line 2259 of file dof_map.h.

Referenced by add_static_condensation(), get_static_condensation(), and has_static_condensation().

◆ _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 2063 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 2140 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 2153 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 2029 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 2024 of file dof_map.h.

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

◆ _variable_group_numbers

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

The variable group number for each variable.

Definition at line 2019 of file dof_map.h.

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

◆ _variable_groups

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

The finite element type for each variable group.

Definition at line 2014 of file dof_map.h.

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

◆ _variables

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

The finite element type for each variable.

Definition at line 2009 of file dof_map.h.

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

◆ _verify_dirichlet_bc_consistency

bool libMesh::DofMap::_verify_dirichlet_bc_consistency
private

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

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

Definition at line 2256 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 2146 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: