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

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

#include <dof_map.h>

Inheritance diagram for libMesh::DofMap:
[legend]

Classes

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

Public Member Functions

 DofMap (const unsigned int sys_number, MeshBase &mesh)
 Constructor. More...
 
 ~DofMap ()
 Destructor. More...
 
void attach_matrix (SparseMatrix< Number > &matrix)
 Additional matrices may be handled with this DofMap. More...
 
bool is_attached (SparseMatrix< Number > &matrix)
 Matrices should not be attached more than once. More...
 
void distribute_dofs (MeshBase &)
 Distribute dofs on the current mesh. More...
 
void compute_sparsity (const MeshBase &)
 Computes the sparsity pattern for the matrices corresponding to proc_id and sends that data to Linear Algebra packages for preallocation of sparse matrices. More...
 
void clear_sparsity ()
 Clears the sparsity pattern. More...
 
void add_coupling_functor (GhostingFunctor &coupling_functor)
 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. 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 &ghosting_functor)
 Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors. More...
 
void remove_algebraic_ghosting_functor (GhostingFunctor &ghosting_functor)
 Removes a functor which was previously added to the set of algebraic ghosting functors. More...
 
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_begin () const
 Beginning of range of algebraic ghosting functors. More...
 
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_end () const
 End of range of algebraic ghosting functors. More...
 
DefaultCouplingdefault_algebraic_ghosting ()
 Default algebraic ghosting functor. More...
 
void attach_extra_sparsity_object (DofMap::AugmentSparsityPattern &asp)
 Attach an object to use to populate the sparsity pattern with extra entries. More...
 
void attach_extra_sparsity_function (void(*func)(SparsityPattern::Graph &sparsity, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *), void *context=libmesh_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=libmesh_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...
 
const std::vector< dof_id_type > & get_send_list () const
 
const std::vector< dof_id_type > & get_n_nz () const
 
const std::vector< dof_id_type > & get_n_oz () const
 
void add_variable_group (const VariableGroup &var_group)
 Add an unknown of order order and finite element type type to the system of equations. More...
 
const VariableGroupvariable_group (const unsigned int c) const
 
const Variablevariable (const unsigned int c) const
 
Order variable_order (const unsigned int c) const
 
Order variable_group_order (const unsigned int vg) const
 
const FETypevariable_type (const unsigned int c) const
 
const FETypevariable_group_type (const unsigned int vg) const
 
unsigned int n_variable_groups () const
 
unsigned int n_variables () const
 
bool has_blocked_representation () const
 
unsigned int block_size () const
 
dof_id_type n_dofs () const
 
dof_id_type n_SCALAR_dofs () const
 
dof_id_type n_local_dofs () const
 
dof_id_type n_dofs_on_processor (const processor_id_type proc) const
 
dof_id_type first_dof (const processor_id_type proc) const
 
dof_id_type first_dof () const
 
dof_id_type first_old_dof (const processor_id_type proc) const
 
dof_id_type first_old_dof () const
 
dof_id_type last_dof (const processor_id_type proc) const
 
dof_id_type last_dof () const
 
dof_id_type end_dof (const processor_id_type proc) const
 
dof_id_type end_dof () const
 
processor_id_type dof_owner (const dof_id_type dof) const
 
dof_id_type end_old_dof (const processor_id_type proc) const
 
dof_id_type end_old_dof () const
 
void dof_indices (const Elem *const elem, std::vector< dof_id_type > &di) const
 Fills the vector di with the global degree of freedom indices for the element. More...
 
void dof_indices (const Elem *const elem, std::vector< dof_id_type > &di, const unsigned int vn, int p_level=-12345) const
 Fills the vector di with the global degree of freedom indices for the element. More...
 
void dof_indices (const Node *const node, std::vector< dof_id_type > &di) const
 Fills the vector di with the global degree of freedom indices for the node. More...
 
void dof_indices (const Node *const node, std::vector< dof_id_type > &di, const unsigned int vn) const
 Fills the vector di with the global degree of freedom indices for the node. 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
 
template<typename DofObjectSubclass >
bool is_evaluable (const DofObjectSubclass &obj, unsigned int var_num=libMesh::invalid_uint) const
 
void set_implicit_neighbor_dofs (bool implicit_neighbor_dofs)
 Allow the implicit_neighbor_dofs flag to be set programmatically. More...
 
bool use_coupled_neighbor_dofs (const MeshBase &mesh) const
 Tells other library functions whether or not this problem includes coupling between dofs in neighboring cells, as can currently be specified on the command line or inferred from the use of all discontinuous variables. More...
 
void extract_local_vector (const NumericVector< Number > &Ug, const std::vector< dof_id_type > &dof_indices, DenseVectorBase< Number > &Ue) const
 Builds the local element vector Ue from the global vector Ug, accounting for any constrained degrees of freedom. More...
 
void local_variable_indices (std::vector< dof_id_type > &idx, const MeshBase &mesh, unsigned int var_num) const
 Fills an array of those dof indices which belong to the given variable number and live on the current processor. More...
 
dof_id_type n_constrained_dofs () const
 
dof_id_type n_local_constrained_dofs () const
 
dof_id_type n_constrained_nodes () const
 
void create_dof_constraints (const MeshBase &, Real time=0)
 Rebuilds the raw degree of freedom and DofObject constraints. More...
 
void allgather_recursive_constraints (MeshBase &)
 Gathers constraint equation dependencies from other processors. More...
 
void scatter_constraints (MeshBase &)
 Sends constraint equations to constraining processors. More...
 
void gather_constraints (MeshBase &mesh, std::set< dof_id_type > &unexpanded_dofs, bool look_for_constrainees)
 Helper function for querying about constraint equations on other processors. More...
 
void process_constraints (MeshBase &)
 Postprocesses any constrained degrees of freedom to be constrained only in terms of unconstrained dofs, then adds unconstrained dofs to the send_list and prepares that for use. More...
 
void add_constraint_row (const dof_id_type dof_number, const DofConstraintRow &constraint_row, const Number constraint_rhs, const bool forbid_constraint_overwrite)
 Adds a copy of the user-defined row to the constraint matrix, using an inhomogeneous right-hand-side for the constraint equation. More...
 
void add_adjoint_constraint_row (const unsigned int qoi_index, const dof_id_type dof_number, const DofConstraintRow &constraint_row, const Number constraint_rhs, const bool forbid_constraint_overwrite)
 Adds a copy of the user-defined row to the constraint matrix, using an inhomogeneous right-hand-side for the adjoint constraint equation. More...
 
void add_constraint_row (const dof_id_type dof_number, const DofConstraintRow &constraint_row, const bool forbid_constraint_overwrite=true)
 Adds a copy of the user-defined row to the constraint matrix, using a homogeneous right-hand-side for the constraint equation. More...
 
DofConstraints::const_iterator constraint_rows_begin () const
 
DofConstraints::const_iterator constraint_rows_end () const
 
void stash_dof_constraints ()
 
void unstash_dof_constraints ()
 
NodeConstraints::const_iterator node_constraint_rows_begin () const
 
NodeConstraints::const_iterator node_constraint_rows_end () const
 
bool is_constrained_dof (const dof_id_type dof) const
 
bool has_heterogenous_adjoint_constraints (const unsigned int qoi_num) const
 
Number has_heterogenous_adjoint_constraint (const unsigned int qoi_num, const dof_id_type dof) const
 
DofConstraintValueMapget_primal_constraint_values ()
 
bool is_constrained_node (const Node *node) const
 
void print_dof_constraints (std::ostream &os=libMesh::out, bool print_nonlocal=false) const
 Prints (from processor 0) all DoF and Node constraints. More...
 
std::string get_local_constraints (bool print_nonlocal=false) const
 Gets a string reporting all DoF and Node constraints local to this processor. More...
 
std::pair< Real, Realmax_constraint_error (const System &system, NumericVector< Number > *v=libmesh_nullptr) const
 Tests the constrained degrees of freedom on the numeric vector v, which represents a solution defined on the mesh, returning a pair whose first entry is the maximum absolute error on a constrained DoF and whose second entry is the maximum relative error. More...
 
void constrain_element_matrix (DenseMatrix< Number > &matrix, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
 Constrains the element matrix. More...
 
void constrain_element_matrix (DenseMatrix< Number > &matrix, std::vector< dof_id_type > &row_dofs, std::vector< dof_id_type > &col_dofs, bool asymmetric_constraint_rows=true) const
 Constrains the element matrix. More...
 
void constrain_element_vector (DenseVector< Number > &rhs, std::vector< dof_id_type > &dofs, bool asymmetric_constraint_rows=true) const
 Constrains the element vector. More...
 
void constrain_element_matrix_and_vector (DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
 Constrains the element matrix and vector. More...
 
void heterogenously_constrain_element_matrix_and_vector (DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
 Constrains the element matrix and vector. More...
 
void heterogenously_constrain_element_vector (const DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
 Constrains the element vector. More...
 
void constrain_element_dyad_matrix (DenseVector< Number > &v, DenseVector< Number > &w, std::vector< dof_id_type > &row_dofs, bool asymmetric_constraint_rows=true) const
 Constrains a dyadic element matrix B = v w'. More...
 
void constrain_nothing (std::vector< dof_id_type > &dofs) const
 Does not actually constrain anything, but modifies dofs in the same way as any of the constrain functions would do, i.e. More...
 
void enforce_constraints_exactly (const System &system, NumericVector< Number > *v=libmesh_nullptr, bool homogeneous=false) const
 Constrains the numeric vector v, which represents a solution defined on the mesh. More...
 
void enforce_adjoint_constraints_exactly (NumericVector< Number > &v, unsigned int q) const
 Heterogenously constrains the numeric vector v, which represents an adjoint solution defined on the mesh for quantity fo interest q. More...
 
void add_periodic_boundary (const PeriodicBoundaryBase &periodic_boundary)
 Adds a copy of the specified periodic boundary to the system. More...
 
void add_periodic_boundary (const PeriodicBoundaryBase &boundary, const PeriodicBoundaryBase &inverse_boundary)
 Add a periodic boundary pair. More...
 
bool is_periodic_boundary (const boundary_id_type boundaryid) const
 
PeriodicBoundariesget_periodic_boundaries ()
 
void add_dirichlet_boundary (const DirichletBoundary &dirichlet_boundary)
 Adds a copy of the specified Dirichlet boundary to the system. More...
 
void add_adjoint_dirichlet_boundary (const DirichletBoundary &dirichlet_boundary, unsigned int q)
 Adds a copy of the specified Dirichlet boundary to the system, corresponding to the adjoint problem defined by Quantity of Interest q. More...
 
void remove_dirichlet_boundary (const DirichletBoundary &dirichlet_boundary)
 Removes the specified Dirichlet boundary from the system. More...
 
void remove_adjoint_dirichlet_boundary (const DirichletBoundary &dirichlet_boundary, unsigned int q)
 Removes from the system the specified Dirichlet boundary for the adjoint equation defined by Quantity of interest index q. More...
 
const DirichletBoundariesget_dirichlet_boundaries () const
 
DirichletBoundariesget_dirichlet_boundaries ()
 
bool has_adjoint_dirichlet_boundaries (unsigned int q) const
 
const DirichletBoundariesget_adjoint_dirichlet_boundaries (unsigned int q) const
 
DirichletBoundariesget_adjoint_dirichlet_boundaries (unsigned int q)
 
void old_dof_indices (const Elem *const elem, std::vector< dof_id_type > &di, const unsigned int vn=libMesh::invalid_uint) const
 After a mesh is refined and repartitioned it is possible that the _send_list will need to be augmented. More...
 
dof_id_type n_old_dofs () const
 
void constrain_p_dofs (unsigned int var, const Elem *elem, unsigned int s, unsigned int p)
 Constrains degrees of freedom on side s of element elem which correspond to variable number var and to p refinement levels above p. More...
 
void reinit (MeshBase &mesh)
 Reinitialize the underlying data structures conformal to the current mesh. More...
 
void clear ()
 Free all memory associated with the object, but keep the mesh pointer. More...
 
void print_info (std::ostream &os=libMesh::out) const
 Prints summary info about the sparsity bandwidth and constraints. More...
 
std::string get_info () const
 Gets summary info about the sparsity bandwidth and constraints. More...
 
unsigned int sys_number () const
 
const Parallel::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=libMesh::out)
 Prints the reference information, by default to libMesh::out. More...
 
static unsigned int n_objects ()
 Prints the number of outstanding (created, but not yet destroyed) objects. More...
 
static void enable_print_counter_info ()
 Methods to enable/disable the reference counter output from print_info() More...
 
static void disable_print_counter_info ()
 

Public Attributes

CouplingMatrix_dof_coupling
 Degree of freedom coupling. More...
 

Protected Types

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

Protected Member Functions

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

Protected Attributes

const Parallel::Communicator_communicator
 

Static Protected Attributes

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

Private Types

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

Private Member Functions

void _dof_indices (const Elem &elem, int p_level, std::vector< dof_id_type > &di, const unsigned int v, const Node *const *nodes, unsigned int n_nodes#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. More...
 
UniquePtr< SparsityPattern::Buildbuild_sparsity (const MeshBase &mesh) const
 Builds a sparsity pattern. More...
 
void invalidate_dofs (MeshBase &mesh) const
 Invalidates all active DofObject dofs for this system. More...
 
DofObjectnode_ptr (MeshBase &mesh, dof_id_type i) const
 
DofObjectelem_ptr (MeshBase &mesh, dof_id_type i) const
 
template<typename iterator_type >
void set_nonlocal_dof_objects (iterator_type objects_begin, iterator_type objects_end, MeshBase &mesh, dofobject_accessor objects)
 Helper function for distributing dofs in parallel. More...
 
void distribute_local_dofs_var_major (dof_id_type &next_free_dof, MeshBase &mesh)
 Distributes the global degrees of freedom, for dofs on this processor. More...
 
void distribute_local_dofs_node_major (dof_id_type &next_free_dof, MeshBase &mesh)
 Distributes the global degrees of freedom for dofs on this processor. More...
 
void add_neighbors_to_send_list (MeshBase &mesh)
 Adds entries to the _send_list vector corresponding to DoFs on elements neighboring the current processor. More...
 
void build_constraint_matrix (DenseMatrix< Number > &C, std::vector< dof_id_type > &elem_dofs, const bool called_recursively=false) const
 Build the constraint matrix C associated with the element degree of freedom indices elem_dofs. More...
 
void build_constraint_matrix_and_vector (DenseMatrix< Number > &C, DenseVector< Number > &H, std::vector< dof_id_type > &elem_dofs, int qoi_index=-1, const bool called_recursively=false) const
 Build the constraint matrix C and the forcing vector H associated with the element degree of freedom indices elem_dofs. More...
 
void find_connected_dofs (std::vector< dof_id_type > &elem_dofs) const
 Finds all the DOFS associated with the element DOFs elem_dofs. More...
 
void find_connected_dof_objects (std::vector< const DofObject * > &objs) const
 Finds all the DofObjects associated with the set in objs. More...
 
void add_constraints_to_send_list ()
 Adds entries to the _send_list vector corresponding to DoFs which are dependencies for constraint equations on the current processor. More...
 
void check_dirichlet_bcid_consistency (const MeshBase &mesh, const DirichletBoundary &boundary) const
 Check that all the ids in dirichlet_bcids are actually present in the mesh. More...
 

Static Private Member Functions

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

Private Attributes

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

Friends

class SparsityPattern::Build
 

Detailed Description

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

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

Author
Benjamin S. Kirk
Date
2002-2007 Manages the degrees of freedom (DOFs) in a simulation.

Definition at line 167 of file dof_map.h.

Member Typedef Documentation

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.

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

Constructor & Destructor Documentation

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()),
131  _variables(),
133  _sys_number(number),
134  _mesh(mesh),
135  _matrices(),
136  _first_df(),
137  _end_df(),
139  _send_list(),
146  _default_coupling(new DefaultCoupling()),
147  _default_evaluating(new DefaultCoupling()),
151  _n_dfs(0),
152  _n_SCALAR_dofs(0)
153 #ifdef LIBMESH_ENABLE_AMR
154  , _n_old_dfs(0),
155  _first_old_df(),
156  _end_old_df(),
158 #endif
159 #ifdef LIBMESH_ENABLE_CONSTRAINTS
160  , _dof_constraints()
164 #endif
165 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
167 #endif
168 #ifdef LIBMESH_ENABLE_PERIODIC
169  , _periodic_boundaries(new PeriodicBoundaries)
170 #endif
171 #ifdef LIBMESH_ENABLE_DIRICHLET
172  , _dirichlet_boundaries(new DirichletBoundaries)
174 #endif
177 {
178  _matrices.clear();
179 
180  _default_coupling->set_mesh(&_mesh);
181  _default_evaluating->set_mesh(&_mesh);
182  _default_evaluating->set_n_levels(1);
183 
184 #ifdef LIBMESH_ENABLE_PERIODIC
185  _default_coupling->set_periodic_boundaries(_periodic_boundaries.get());
186  _default_evaluating->set_periodic_boundaries(_periodic_boundaries.get());
187 #endif
188 
191 }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable.
Definition: dof_map.h:1413
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:1641
const unsigned int _sys_number
The number of the system we manage DOFs for.
Definition: dof_map.h:1418
bool _implicit_neighbor_dofs
Definition: dof_map.h:1642
UniquePtr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:1492
void * _extra_sparsity_context
A pointer associated with the extra sparsity that can optionally be passed in.
Definition: dof_map.h:1469
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:1452
MeshBase & mesh
AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:1457
const class libmesh_nullptr_t libmesh_nullptr
std::vector< dof_id_type > _end_old_df
Last old DOF index (plus 1) on processor p.
Definition: dof_map.h:1577
void add_coupling_functor(GhostingFunctor &coupling_functor)
Adds a functor which can specify coupling requirements for creation of sparse matrices.
Definition: dof_map.C:1794
UniquePtr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:1500
std::vector< dof_id_type > _first_old_df
First old DOF index on processor p.
Definition: dof_map.h:1572
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:1446
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:1596
std::vector< dof_id_type > * _n_nz
The number of on-processor nonzeros in my portion of the global matrix.
Definition: dof_map.h:1543
AugmentSendList * _augment_send_list
Function object to call to add extra entries to the send list.
Definition: dof_map.h:1474
std::vector< dof_id_type > * _n_oz
The number of off-processor nonzeros in my portion of the global matrix; allocated similar to _n_nz...
Definition: dof_map.h:1549
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:1529
void add_algebraic_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors...
Definition: dof_map.C:1813
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:1583
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:1462
dof_id_type _n_SCALAR_dofs
The total number of SCALAR dofs associated to all SCALAR variables.
Definition: dof_map.h:1560
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1592
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1240
std::vector< DirichletBoundaries * > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:1632
void * _extra_send_list_context
A pointer associated with the extra send list that can optionally be passed in.
Definition: dof_map.h:1484
std::vector< SparseMatrix< Number > * > _matrices
Additional matrices handled by this object.
Definition: dof_map.h:1430
UniquePtr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:1626
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:1594
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:1408
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:1592
dof_id_type _n_old_dfs
Total number of degrees of freedom on old dof objects.
Definition: dof_map.h:1567
UniquePtr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:1612
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:1440
std::vector< dof_id_type > _first_df
First DOF index on processor p.
Definition: dof_map.h:1435
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:1479
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:1423
dof_id_type _n_dfs
Total number of degrees of freedom.
Definition: dof_map.h:1554
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:1603
libMesh::DofMap::~DofMap ( )

Destructor.

Definition at line 196 of file dof_map.C.

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

197 {
198  this->clear();
199 
200  // clear() resets all but the default DofMap-based functors. We
201  // need to remove those from the mesh too before we die.
204 
205 #ifdef LIBMESH_ENABLE_DIRICHLET
206  for (std::size_t q = 0; q != _adjoint_dirichlet_boundaries.size(); ++q)
208 #endif
209 }
UniquePtr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:1492
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:305
UniquePtr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:1500
void clear()
Free all memory associated with the object, but keep the mesh pointer.
Definition: dof_map.C:803
std::vector< DirichletBoundaries * > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:1632
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:1423

Member Function Documentation

void libMesh::DofMap::_dof_indices ( const Elem elem,
int  p_level,
std::vector< dof_id_type > &  di,
const unsigned int  v,
const Node *const *  nodes,
unsigned int n_nodes#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.

In DEBUG mode, the tot_size parameter will add up the total number of dof indices that should have been added to di.

Definition at line 2164 of file dof_map.C.

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

Referenced by dof_indices().

2175 {
2176  const Variable & var = this->variable(v);
2177 
2178  if (var.active_on_subdomain(elem.subdomain_id()))
2179  {
2180  const ElemType type = elem.type();
2181  const unsigned int sys_num = this->sys_number();
2182  const unsigned int dim = elem.dim();
2183 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2184  const bool is_inf = elem.infinite();
2185 #endif
2186 
2187  // Increase the polynomial order on p refined elements
2188  FEType fe_type = var.type();
2189  fe_type.order = static_cast<Order>(fe_type.order + p_level);
2190 
2191  const bool extra_hanging_dofs =
2193 
2194 #ifdef DEBUG
2195  // The number of dofs per element is non-static for subdivision FE
2196  if (fe_type.family == SUBDIVISION)
2197  tot_size += n_nodes;
2198  else
2199  tot_size += FEInterface::n_dofs(dim,fe_type,type);
2200 #endif
2201 
2202  const FEInterface::n_dofs_at_node_ptr ndan =
2204 
2205  // Get the node-based DOF numbers
2206  for (unsigned int n=0; n<n_nodes; n++)
2207  {
2208  const Node * node = nodes[n];
2209 
2210  // There is a potential problem with h refinement. Imagine a
2211  // quad9 that has a linear FE on it. Then, on the hanging side,
2212  // it can falsely identify a DOF at the mid-edge node. This is why
2213  // we go through FEInterface instead of node->n_comp() directly.
2214  const unsigned int nc =
2215 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
2216  is_inf ?
2217  FEInterface::n_dofs_at_node(dim, fe_type, type, n) :
2218 #endif
2219  ndan (type, fe_type.order, n);
2220 
2221  // If this is a non-vertex on a hanging node with extra
2222  // degrees of freedom, we use the non-vertex dofs (which
2223  // come in reverse order starting from the end, to
2224  // simplify p refinement)
2225  if (extra_hanging_dofs && !elem.is_vertex(n))
2226  {
2227  const int dof_offset = node->n_comp(sys_num,v) - nc;
2228 
2229  // We should never have fewer dofs than necessary on a
2230  // node unless we're getting indices on a parent element,
2231  // and we should never need the indices on such a node
2232  if (dof_offset < 0)
2233  {
2234  libmesh_assert(!elem.active());
2235  di.resize(di.size() + nc, DofObject::invalid_id);
2236  }
2237  else
2238  for (int i=node->n_comp(sys_num,v)-1; i>=dof_offset; i--)
2239  {
2240  libmesh_assert_not_equal_to (node->dof_number(sys_num,v,i),
2242  di.push_back(node->dof_number(sys_num,v,i));
2243  }
2244  }
2245  // If this is a vertex or an element without extra hanging
2246  // dofs, our dofs come in forward order coming from the
2247  // beginning
2248  else
2249  for (unsigned int i=0; i<nc; i++)
2250  {
2251  libmesh_assert_not_equal_to (node->dof_number(sys_num,v,i),
2253  di.push_back(node->dof_number(sys_num,v,i));
2254  }
2255  }
2256 
2257  // If there are any element-based DOF numbers, get them
2258  const unsigned int nc = FEInterface::n_dofs_per_elem(dim,
2259  fe_type,
2260  type);
2261  // We should never have fewer dofs than necessary on an
2262  // element unless we're getting indices on a parent element,
2263  // and we should never need those indices
2264  if (nc != 0)
2265  {
2266  if (elem.n_systems() > sys_num &&
2267  nc <= elem.n_comp(sys_num,v))
2268  {
2269  for (unsigned int i=0; i<nc; i++)
2270  {
2271  libmesh_assert_not_equal_to (elem.dof_number(sys_num,v,i),
2273 
2274  di.push_back(elem.dof_number(sys_num,v,i));
2275  }
2276  }
2277  else
2278  {
2279  libmesh_assert(!elem.active() || fe_type.family == LAGRANGE || fe_type.family == SUBDIVISION);
2280  di.resize(di.size() + nc, DofObject::invalid_id);
2281  }
2282  }
2283  }
2284 }
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:473
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:414
unsigned int dim
ElemType
Defines an enum for geometric element types.
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:1667
libmesh_assert(j)
const dof_id_type n_nodes
Definition: tecplot_io.C:67
static bool extra_hanging_dofs(const FEType &fe_t)
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:324
unsigned int sys_number() const
Definition: dof_map.h:1649
static n_dofs_at_node_ptr n_dofs_at_node_function(const unsigned int dim, const FEType &fe_t)
Definition: fe_interface.C:459
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
Definition: fe_interface.C:436
unsigned int(* n_dofs_at_node_ptr)(const ElemType, const Order, const unsigned int)
Definition: fe_interface.h:113
Order
defines an enum for polynomial orders.
Definition: enum_order.h:32
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 1365 of file dof_map_constraints.C.

1370 {
1371  // Optionally allow the user to overwrite constraints. Defaults to false.
1372  if (forbid_constraint_overwrite)
1373  {
1374  if (!this->is_constrained_dof(dof_number))
1375  libmesh_error_msg("ERROR: DOF " << dof_number << " has no corresponding primal constraint!");
1376 #ifndef NDEBUG
1377  // No way to do this without a non-normalized tolerance?
1378  /*
1379  // If the user passed in more than just the rhs, let's check the
1380  // coefficients for consistency
1381  if (!constraint_row.empty())
1382  {
1383  DofConstraintRow row = _dof_constraints[dof_number];
1384  for (DofConstraintRow::const_iterator pos=row.begin();
1385  pos != row.end(); ++pos)
1386  {
1387  libmesh_assert(constraint_row.find(pos->first)->second
1388  == pos->second);
1389  }
1390  }
1391 
1392  if (_adjoint_constraint_values[qoi_index].find(dof_number) !=
1393  _adjoint_constraint_values[qoi_index].end())
1394  libmesh_assert_equal_to
1395  (_adjoint_constraint_values[qoi_index][dof_number],
1396  constraint_rhs);
1397  */
1398 #endif
1399  }
1400 
1401  // Creates the map of rhs values if it doesn't already exist; then
1402  // adds the current value to that map
1403 
1404  // We don't get insert_or_assign until C++17 so we make do.
1405  std::pair<DofConstraintValueMap::iterator, bool> rhs_it =
1406  _adjoint_constraint_values[qoi_index].insert(std::make_pair(dof_number,
1407  constraint_rhs));
1408  if (!rhs_it.second)
1409  rhs_it.first->second = constraint_rhs;
1410 }
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:1596
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1734
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 4064 of file dof_map_constraints.C.

4066 {
4067  unsigned int old_size = cast_int<unsigned int>
4069  for (unsigned int i = old_size; i <= qoi_index; ++i)
4071 
4072  _adjoint_dirichlet_boundaries[qoi_index]->push_back
4073  (new DirichletBoundary(dirichlet_boundary));
4074 }
This class allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
We&#39;re using a class instead of a typedef to allow forward declarations and future flexibility...
std::vector< DirichletBoundaries * > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:1632
void libMesh::DofMap::add_algebraic_ghosting_functor ( GhostingFunctor ghosting_functor)

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.

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.

Definition at line 1813 of file dof_map.C.

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

Referenced by clear(), DofMap(), main(), and PointNeighborCouplingTest::testCoupling().

1814 {
1815  _algebraic_ghosting_functors.insert(&algebraic_ghosting_functor);
1816  _mesh.add_ghosting_functor(algebraic_ghosting_functor);
1817 }
std::set< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:1510
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:1423
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
Definition: mesh_base.h:786
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 1342 of file dof_map_constraints.C.

1346 {
1347  // Optionally allow the user to overwrite constraints. Defaults to false.
1348  if (forbid_constraint_overwrite)
1349  if (this->is_constrained_dof(dof_number))
1350  libmesh_error_msg("ERROR: DOF " << dof_number << " was already constrained!");
1351 
1352  // We don't get insert_or_assign until C++17 so we make do.
1353  std::pair<DofConstraints::iterator, bool> it =
1354  _dof_constraints.insert(std::make_pair(dof_number, constraint_row));
1355  if (!it.second)
1356  it.first->second = constraint_row;
1357 
1358  std::pair<DofConstraintValueMap::iterator, bool> rhs_it =
1359  _primal_constraint_values.insert(std::make_pair(dof_number, constraint_rhs));
1360  if (!rhs_it.second)
1361  rhs_it.first->second = constraint_rhs;
1362 }
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1734
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1592
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:1594
void libMesh::DofMap::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.

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

Definition at line 816 of file dof_map.h.

819  { 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 ...
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 3943 of file dof_map_constraints.C.

References libMesh::n_processors().

3944 {
3945  // This function must be run on all processors at once
3946  parallel_object_only();
3947 
3948  // Return immediately if there's nothing to gather
3949  if (this->n_processors() == 1)
3950  return;
3951 
3952  // We might get to return immediately if none of the processors
3953  // found any constraints
3954  unsigned int has_constraints = !_dof_constraints.empty();
3955  this->comm().max(has_constraints);
3956  if (!has_constraints)
3957  return;
3958 
3959  for (DofConstraints::iterator i = _dof_constraints.begin();
3960  i != _dof_constraints.end(); ++i)
3961  {
3962  dof_id_type constrained_dof = i->first;
3963 
3964  // We only need the dependencies of our own constrained dofs
3965  if (constrained_dof < this->first_dof() ||
3966  constrained_dof >= this->end_dof())
3967  continue;
3968 
3969  DofConstraintRow & constraint_row = i->second;
3970  for (DofConstraintRow::const_iterator
3971  j=constraint_row.begin(); j != constraint_row.end();
3972  ++j)
3973  {
3974  dof_id_type constraint_dependency = j->first;
3975 
3976  // No point in adding one of our own dofs to the send_list
3977  if (constraint_dependency >= this->first_dof() &&
3978  constraint_dependency < this->end_dof())
3979  continue;
3980 
3981  _send_list.push_back(constraint_dependency);
3982  }
3983  }
3984 }
void max(T &r) const
Take a local variable and replace it with the maximum of it&#39;s values on all processors.
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:1452
processor_id_type n_processors() const
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1592
dof_id_type end_dof() const
Definition: dof_map.h:580
const Parallel::Communicator & comm() 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:88
dof_id_type first_dof() const
Definition: dof_map.h:538
uint8_t dof_id_type
Definition: id_types.h:64
void libMesh::DofMap::add_coupling_functor ( GhostingFunctor coupling_functor)

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.

Definition at line 1794 of file dof_map.C.

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

Referenced by clear(), DofMap(), and main().

1795 {
1796  _coupling_functors.insert(&coupling_functor);
1797  _mesh.add_ghosting_functor(coupling_functor);
1798 }
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:1523
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:1423
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
Definition: mesh_base.h:786
void libMesh::DofMap::add_dirichlet_boundary ( const DirichletBoundary dirichlet_boundary)

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

Definition at line 4058 of file dof_map_constraints.C.

Referenced by libMesh::DifferentiableSystem::add_dot_var_dirichlet_bcs(), assemble_and_solve(), HeatSystem::init_data(), main(), set_lid_driven_bcs(), set_system_parameters(), and BoundaryInfoTest::testShellFaceConstraints().

4059 {
4060  _dirichlet_boundaries->push_back(new DirichletBoundary(dirichlet_boundary));
4061 }
This class allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
UniquePtr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:1626
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 1479 of file dof_map.C.

References _send_list, libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), algebraic_ghosting_functors_begin(), algebraic_ghosting_functors_end(), libMesh::ConstCouplingRow::begin(), coupling_functors_begin(), coupling_functors_end(), dof_indices(), end, libMesh::ConstCouplingRow::end(), end_dof(), first_dof(), merge_ghost_functor_outputs(), n_variables(), libMesh::ParallelObject::processor_id(), and libMesh::DofObject::processor_id().

Referenced by distribute_dofs().

1480 {
1481  LOG_SCOPE("add_neighbors_to_send_list()", "DofMap");
1482 
1483  const unsigned int n_var = this->n_variables();
1484 
1485  MeshBase::const_element_iterator local_elem_it
1486  = mesh.active_local_elements_begin();
1487  const MeshBase::const_element_iterator local_elem_end
1488  = mesh.active_local_elements_end();
1489 
1490  GhostingFunctor::map_type elements_to_send;
1491 
1492  // Man, I wish we had guaranteed unique_ptr availability...
1493  std::set<CouplingMatrix *> temporary_coupling_matrices;
1494 
1495  // We need to add dofs to the send list if they've been directly
1496  // requested by an algebraic ghosting functor or they've been
1497  // indirectly requested by a coupling functor.
1498  this->merge_ghost_functor_outputs(elements_to_send,
1499  temporary_coupling_matrices,
1502  local_elem_it, local_elem_end, mesh.processor_id());
1503 
1504  this->merge_ghost_functor_outputs(elements_to_send,
1505  temporary_coupling_matrices,
1506  this->coupling_functors_begin(),
1507  this->coupling_functors_end(),
1508  local_elem_it, local_elem_end, mesh.processor_id());
1509 
1510  // Making a list of non-zero coupling matrix columns is an
1511  // O(N_var^2) operation. We cache it so we only have to do it once
1512  // per CouplingMatrix and not once per element.
1513  std::map<const CouplingMatrix *, std::vector<unsigned int>>
1514  column_variable_lists;
1515 
1516  GhostingFunctor::map_type::iterator etg_it = elements_to_send.begin();
1517  const GhostingFunctor::map_type::iterator etg_end = elements_to_send.end();
1518  for (; etg_it != etg_end; ++etg_it)
1519  {
1520  const Elem * const partner = etg_it->first;
1521 
1522  // We asked ghosting functors not to give us local elements
1523  libmesh_assert_not_equal_to
1524  (partner->processor_id(), this->processor_id());
1525 
1526  const CouplingMatrix * ghost_coupling = etg_it->second;
1527 
1528  // Loop over any present coupling matrix column variables if we
1529  // have a coupling matrix, or just add all variables to
1530  // send_list if not.
1531  if (ghost_coupling)
1532  {
1533  libmesh_assert_equal_to (ghost_coupling->size(), n_var);
1534 
1535  // Try to find a cached list of column variables.
1536  std::map<const CouplingMatrix *, std::vector<unsigned int>>::const_iterator
1537  column_variable_list = column_variable_lists.find(ghost_coupling);
1538 
1539  // If we didn't find it, then we need to create it.
1540  if (column_variable_list == column_variable_lists.end())
1541  {
1542  std::pair<std::map<const CouplingMatrix *, std::vector<unsigned int>>::iterator, bool>
1543  inserted_variable_list_pair = column_variable_lists.insert(std::make_pair(ghost_coupling,
1544  std::vector<unsigned int>()));
1545  column_variable_list = inserted_variable_list_pair.first;
1546 
1547  std::vector<unsigned int> & new_variable_list =
1548  inserted_variable_list_pair.first->second;
1549 
1550  std::vector<unsigned char> has_variable(n_var, false);
1551 
1552  for (unsigned int vi = 0; vi != n_var; ++vi)
1553  {
1554  ConstCouplingRow ccr(vi, *ghost_coupling);
1555 
1557  it = ccr.begin(),
1558  end = ccr.end();
1559  it != end; ++it)
1560  {
1561  const unsigned int vj = *it;
1562  has_variable[vj] = true;
1563  }
1564  }
1565  for (unsigned int vj = 0; vj != n_var; ++vj)
1566  {
1567  if (has_variable[vj])
1568  new_variable_list.push_back(vj);
1569  }
1570  }
1571 
1572  const std::vector<unsigned int> & variable_list =
1573  column_variable_list->second;
1574 
1575  for (std::size_t j=0; j != variable_list.size(); ++j)
1576  {
1577  const unsigned int vj=variable_list[j];
1578 
1579  std::vector<dof_id_type> di;
1580  this->dof_indices (partner, di, vj);
1581 
1582  // Insert the remote DOF indices into the send list
1583  for (std::size_t j=0; j != di.size(); ++j)
1584  if (di[j] < this->first_dof() ||
1585  di[j] >= this->end_dof())
1586  _send_list.push_back(di[j]);
1587  }
1588  }
1589  else
1590  {
1591  std::vector<dof_id_type> di;
1592  this->dof_indices (partner, di);
1593 
1594  // Insert the remote DOF indices into the send list
1595  for (std::size_t j=0; j != di.size(); ++j)
1596  if (di[j] < this->first_dof() ||
1597  di[j] >= this->end_dof())
1598  _send_list.push_back(di[j]);
1599  }
1600 
1601  }
1602 
1603  // We're now done with any merged coupling matrices we had to create.
1604  for (std::set<CouplingMatrix *>::iterator
1605  it = temporary_coupling_matrices.begin(),
1606  end = temporary_coupling_matrices.begin();
1607  it != end; ++it)
1608  delete *it;
1609 
1610  //-------------------------------------------------------------------------
1611  // Our coupling functors added dofs from neighboring elements to the
1612  // send list, but we may still need to add non-local dofs from local
1613  // elements.
1614  //-------------------------------------------------------------------------
1615 
1616  // Loop over the active local elements, adding all active elements
1617  // that neighbor an active local element to the send list.
1618  for ( ; local_elem_it != local_elem_end; ++local_elem_it)
1619  {
1620  const Elem * elem = *local_elem_it;
1621 
1622  std::vector<dof_id_type> di;
1623  this->dof_indices (elem, di);
1624 
1625  // Insert the remote DOF indices into the send list
1626  for (std::size_t j=0; j != di.size(); ++j)
1627  if (di[j] < this->first_dof() ||
1628  di[j] >= this->end_dof())
1629  _send_list.push_back(di[j]);
1630  }
1631 }
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_begin() const
Beginning of range of algebraic ghosting functors.
Definition: dof_map.h:311
std::set< GhostingFunctor * >::const_iterator coupling_functors_begin() const
Beginning of range of coupling functors.
Definition: dof_map.h:275
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:1452
MeshBase & mesh
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end...
std::unordered_map< const Elem *, const CouplingMatrix * > map_type
What elements do we care about and what variables do we care about on each element?
static void merge_ghost_functor_outputs(GhostingFunctor::map_type &elements_to_ghost, std::set< CouplingMatrix * > &temporary_coupling_matrices, const std::set< GhostingFunctor * >::iterator &gf_begin, const std::set< GhostingFunctor * >::iterator &gf_end, const MeshBase::const_element_iterator &elems_begin, const MeshBase::const_element_iterator &elems_end, processor_id_type p)
Definition: dof_map.C:1408
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_end() const
End of range of algebraic ghosting functors.
Definition: dof_map.h:317
dof_id_type end_dof() const
Definition: dof_map.h:580
unsigned int n_variables() const
Definition: dof_map.h:477
std::set< GhostingFunctor * >::const_iterator coupling_functors_end() const
End of range of coupling functors.
Definition: dof_map.h:281
ConstCouplingRowConstIterator const_iterator
dof_id_type first_dof() const
Definition: dof_map.h:538
processor_id_type processor_id() 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.
Definition: dof_map.C:1917
void libMesh::DofMap::add_periodic_boundary ( const PeriodicBoundaryBase periodic_boundary)

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

Definition at line 4192 of file dof_map_constraints.C.

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

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

4193 {
4194  // See if we already have a periodic boundary associated myboundary...
4195  PeriodicBoundaryBase * existing_boundary = _periodic_boundaries->boundary(periodic_boundary.myboundary);
4196 
4197  if (existing_boundary == libmesh_nullptr)
4198  {
4199  // ...if not, clone the input (and its inverse) and add them to the PeriodicBoundaries object
4200  PeriodicBoundaryBase * boundary = periodic_boundary.clone().release();
4201  PeriodicBoundaryBase * inverse_boundary = periodic_boundary.clone(PeriodicBoundaryBase::INVERSE).release();
4202 
4203  // _periodic_boundaries takes ownership of the pointers
4204  _periodic_boundaries->insert(std::make_pair(boundary->myboundary, boundary));
4205  _periodic_boundaries->insert(std::make_pair(inverse_boundary->myboundary, inverse_boundary));
4206  }
4207  else
4208  {
4209  // ...otherwise, merge this object's variable IDs with the existing boundary object's.
4210  existing_boundary->merge(periodic_boundary);
4211 
4212  // Do the same merging process for the inverse boundary. Note: the inverse better already exist!
4213  PeriodicBoundaryBase * inverse_boundary = _periodic_boundaries->boundary(periodic_boundary.pairedboundary);
4214  libmesh_assert(inverse_boundary);
4215  inverse_boundary->merge(periodic_boundary);
4216  }
4217 }
const class libmesh_nullptr_t libmesh_nullptr
libmesh_assert(j)
void merge(const PeriodicBoundaryBase &pb)
boundary_id_type myboundary
The boundary ID of this boundary and its counterpart.
virtual UniquePtr< 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...
UniquePtr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:1612
The base class for defining periodic boundaries.
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 4222 of file dof_map_constraints.C.

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

4224 {
4225  libmesh_assert_equal_to (boundary.myboundary, inverse_boundary.pairedboundary);
4226  libmesh_assert_equal_to (boundary.pairedboundary, inverse_boundary.myboundary);
4227 
4228  // Allocate copies on the heap. The _periodic_boundaries object will manage this memory.
4229  // Note: this also means that the copy constructor for the PeriodicBoundary (or user class
4230  // derived therefrom) must be implemented!
4231  // PeriodicBoundary * p_boundary = new PeriodicBoundary(boundary);
4232  // PeriodicBoundary * p_inverse_boundary = new PeriodicBoundary(inverse_boundary);
4233 
4234  // We can't use normal copy construction since this leads to slicing with derived classes.
4235  // Use clone() "virtual constructor" instead. But, this *requires* user to override the clone()
4236  // method. Note also that clone() allocates memory. In this case, the _periodic_boundaries object
4237  // takes responsibility for cleanup.
4238  PeriodicBoundaryBase * p_boundary = boundary.clone().release();
4239  PeriodicBoundaryBase * p_inverse_boundary = inverse_boundary.clone().release();
4240 
4241  // Add the periodic boundary and its inverse to the PeriodicBoundaries data structure. The
4242  // PeriodicBoundaries data structure takes ownership of the pointers.
4243  _periodic_boundaries->insert(std::make_pair(p_boundary->myboundary, p_boundary));
4244  _periodic_boundaries->insert(std::make_pair(p_inverse_boundary->myboundary, p_inverse_boundary));
4245 }
boundary_id_type myboundary
The boundary ID of this boundary and its counterpart.
virtual UniquePtr< 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...
UniquePtr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:1612
The base class for defining periodic boundaries.
void libMesh::DofMap::add_variable_group ( const 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 234 of file dof_map.C.

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

235 {
236  _variable_groups.push_back(var_group);
237 
238  VariableGroup & new_var_group = _variable_groups.back();
239 
240  for (unsigned int var=0; var<new_var_group.n_variables(); var++)
241  _variables.push_back (new_var_group(var));
242 }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable.
Definition: dof_map.h:1413
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:1408
std::set<GhostingFunctor *>::const_iterator libMesh::DofMap::algebraic_ghosting_functors_begin ( ) const

Beginning of range of algebraic ghosting functors.

Definition at line 311 of file dof_map.h.

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

312  { 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:1510
std::set<GhostingFunctor *>::const_iterator libMesh::DofMap::algebraic_ghosting_functors_end ( ) const

End of range of algebraic ghosting functors.

Definition at line 317 of file dof_map.h.

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

318  { 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:1510
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 2341 of file dof_map.C.

References semilocal_index().

Referenced by is_evaluable().

2342 {
2343  // We're all semilocal unless we find a counterexample
2344  for (std::size_t i=0; i != dof_indices_in.size(); ++i)
2345  {
2346  const dof_id_type di = dof_indices_in[i];
2347  if (!this->semilocal_index(di))
2348  return false;
2349  }
2350 
2351  return true;
2352 }
bool semilocal_index(dof_id_type dof_index) const
Definition: dof_map.C:2324
uint8_t dof_id_type
Definition: id_types.h:64
void libMesh::DofMap::allgather_recursive_constraints ( MeshBase mesh)

Gathers constraint equation dependencies from other processors.

Definition at line 2613 of file dof_map_constraints.C.

References libMesh::MeshBase::active_not_local_elements_begin(), libMesh::MeshBase::active_not_local_elements_end(), libMesh::DofObject::dof_number(), end, libMesh::DofObject::id(), libMesh::MeshBase::is_serial(), libMesh::libmesh_assert(), libMesh::libmesh_isnan(), libmesh_nullptr, mesh, libMesh::DofObject::n_comp(), n_nodes, libMesh::Elem::n_nodes(), libMesh::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::processor_id(), libMesh::DofObject::processor_id(), and libMesh::TypeVector< T >::size().

2614 {
2615  // This function must be run on all processors at once
2616  parallel_object_only();
2617 
2618  // Return immediately if there's nothing to gather
2619  if (this->n_processors() == 1)
2620  return;
2621 
2622  // We might get to return immediately if none of the processors
2623  // found any constraints
2624  unsigned int has_constraints = !_dof_constraints.empty()
2625 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2626  || !_node_constraints.empty()
2627 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
2628  ;
2629  this->comm().max(has_constraints);
2630  if (!has_constraints)
2631  return;
2632 
2633  // If we have heterogenous adjoint constraints we need to
2634  // communicate those too.
2635  const unsigned int max_qoi_num =
2636  _adjoint_constraint_values.empty() ?
2637  0 : _adjoint_constraint_values.rbegin()->first;
2638 
2639  // We might have calculated constraints for constrained dofs
2640  // which have support on other processors.
2641  // Push these out first.
2642  {
2643  std::vector<std::set<dof_id_type>> pushed_ids(this->n_processors());
2644 
2645 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2646  std::vector<std::set<dof_id_type>> pushed_node_ids(this->n_processors());
2647 #endif
2648 
2649  const unsigned int sys_num = this->sys_number();
2650 
2652  foreign_elem_it = mesh.active_not_local_elements_begin(),
2653  foreign_elem_end = mesh.active_not_local_elements_end();
2654 
2655  // Collect the constraints to push to each processor
2656  for (; foreign_elem_it != foreign_elem_end; ++foreign_elem_it)
2657  {
2658  const Elem * elem = *foreign_elem_it;
2659 
2660  const unsigned short n_nodes = elem->n_nodes();
2661 
2662  // Just checking dof_indices on the foreign element isn't
2663  // enough. Consider a central hanging node between a coarse
2664  // Q2/Q1 element and its finer neighbors on a higher-ranked
2665  // processor. The coarse element's processor will own the node,
2666  // and will thereby own the pressure dof on that node, despite
2667  // the fact that that pressure dof doesn't directly exist on the
2668  // coarse element!
2669  //
2670  // So, we loop through dofs manually.
2671 
2672  {
2673  const unsigned int n_vars = elem->n_vars(sys_num);
2674  for (unsigned int v=0; v != n_vars; ++v)
2675  {
2676  const unsigned int n_comp = elem->n_comp(sys_num,v);
2677  for (unsigned int c=0; c != n_comp; ++c)
2678  {
2679  const unsigned int id =
2680  elem->dof_number(sys_num,v,c);
2681  if (this->is_constrained_dof(id))
2682  pushed_ids[elem->processor_id()].insert(id);
2683  }
2684  }
2685  }
2686 
2687  for (unsigned short n = 0; n != n_nodes; ++n)
2688  {
2689  const Node & node = elem->node_ref(n);
2690  const unsigned int n_vars = node.n_vars(sys_num);
2691  for (unsigned int v=0; v != n_vars; ++v)
2692  {
2693  const unsigned int n_comp = node.n_comp(sys_num,v);
2694  for (unsigned int c=0; c != n_comp; ++c)
2695  {
2696  const unsigned int id =
2697  node.dof_number(sys_num,v,c);
2698  if (this->is_constrained_dof(id))
2699  pushed_ids[elem->processor_id()].insert(id);
2700  }
2701  }
2702  }
2703 
2704 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2705  for (unsigned short n = 0; n != n_nodes; ++n)
2706  if (this->is_constrained_node(elem->node_ptr(n)))
2707  pushed_node_ids[elem->processor_id()].insert(elem->node_id(n));
2708 #endif
2709  }
2710 
2711  // Now trade constraint rows
2712  for (processor_id_type p = 0; p != this->n_processors(); ++p)
2713  {
2714  // Push to processor procup while receiving from procdown
2715  processor_id_type procup =
2716  cast_int<processor_id_type>((this->processor_id() + p) %
2717  this->n_processors());
2718  processor_id_type procdown =
2719  cast_int<processor_id_type>((this->n_processors() +
2720  this->processor_id() - p) %
2721  this->n_processors());
2722 
2723  // Pack the dof constraint rows and rhs's to push to procup
2724  const std::size_t pushed_ids_size = pushed_ids[procup].size();
2725  std::vector<std::vector<dof_id_type>> pushed_keys(pushed_ids_size);
2726  std::vector<std::vector<Real>> pushed_vals(pushed_ids_size);
2727  std::vector<Number> pushed_rhss(pushed_ids_size);
2728 
2729  std::vector<std::vector<Number>>
2730  pushed_adj_rhss(max_qoi_num,
2731  std::vector<Number>(pushed_ids_size));
2732  std::set<dof_id_type>::const_iterator it = pushed_ids[procup].begin();
2733  for (std::size_t i = 0; it != pushed_ids[procup].end();
2734  ++i, ++it)
2735  {
2736  const dof_id_type pushed_id = *it;
2737  DofConstraintRow & row = _dof_constraints[pushed_id];
2738  std::size_t row_size = row.size();
2739  pushed_keys[i].reserve(row_size);
2740  pushed_vals[i].reserve(row_size);
2741  for (DofConstraintRow::iterator j = row.begin();
2742  j != row.end(); ++j)
2743  {
2744  pushed_keys[i].push_back(j->first);
2745  pushed_vals[i].push_back(j->second);
2746  }
2747 
2748  DofConstraintValueMap::const_iterator rhsit =
2749  _primal_constraint_values.find(pushed_id);
2750  pushed_rhss[i] =
2751  (rhsit == _primal_constraint_values.end()) ?
2752  0 : rhsit->second;
2753 
2754  for (unsigned int q = 0; q != max_qoi_num; ++q)
2755  {
2756  AdjointDofConstraintValues::const_iterator adjoint_map_it =
2758 
2759  if (adjoint_map_it == _adjoint_constraint_values.end())
2760  continue;
2761 
2762  const DofConstraintValueMap & constraint_map =
2763  adjoint_map_it->second;
2764 
2765  DofConstraintValueMap::const_iterator rhsit =
2766  constraint_map.find(pushed_id);
2767 
2768  pushed_adj_rhss[q][i] =
2769  (rhsit == constraint_map.end()) ?
2770  0 : rhsit->second;
2771  }
2772  }
2773 
2774 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2775  // Pack the node constraint rows to push to procup
2776  const std::size_t pushed_nodes_size = pushed_node_ids[procup].size();
2777  std::vector<std::vector<dof_id_type>> pushed_node_keys(pushed_nodes_size);
2778  std::vector<std::vector<Real>> pushed_node_vals(pushed_nodes_size);
2779  std::vector<Point> pushed_node_offsets(pushed_nodes_size);
2780  std::set<dof_id_type>::const_iterator node_it = pushed_node_ids[procup].begin();
2781  for (std::size_t i = 0; node_it != pushed_node_ids[procup].end();
2782  ++i, ++node_it)
2783  {
2784  const Node * node = mesh.node_ptr(*node_it);
2785  NodeConstraintRow & row = _node_constraints[node].first;
2786  std::size_t row_size = row.size();
2787  pushed_node_keys[i].reserve(row_size);
2788  pushed_node_vals[i].reserve(row_size);
2789  for (NodeConstraintRow::iterator j = row.begin();
2790  j != row.end(); ++j)
2791  {
2792  pushed_node_keys[i].push_back(j->first->id());
2793  pushed_node_vals[i].push_back(j->second);
2794  }
2795  pushed_node_offsets[i] = _node_constraints[node].second;
2796  }
2797 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
2798 
2799  // Trade pushed dof constraint rows
2800  std::vector<dof_id_type> pushed_ids_from_me
2801  (pushed_ids[procup].begin(), pushed_ids[procup].end());
2802  std::vector<dof_id_type> pushed_ids_to_me;
2803  std::vector<std::vector<dof_id_type>> pushed_keys_to_me;
2804  std::vector<std::vector<Real>> pushed_vals_to_me;
2805  std::vector<Number> pushed_rhss_to_me;
2806  std::vector<std::vector<Number>> pushed_adj_rhss_to_me;
2807  this->comm().send_receive(procup, pushed_ids_from_me,
2808  procdown, pushed_ids_to_me);
2809  this->comm().send_receive(procup, pushed_keys,
2810  procdown, pushed_keys_to_me);
2811  this->comm().send_receive(procup, pushed_vals,
2812  procdown, pushed_vals_to_me);
2813  this->comm().send_receive(procup, pushed_rhss,
2814  procdown, pushed_rhss_to_me);
2815  this->comm().send_receive(procup, pushed_adj_rhss,
2816  procdown, pushed_adj_rhss_to_me);
2817  libmesh_assert_equal_to (pushed_ids_to_me.size(), pushed_keys_to_me.size());
2818  libmesh_assert_equal_to (pushed_ids_to_me.size(), pushed_vals_to_me.size());
2819  libmesh_assert_equal_to (pushed_ids_to_me.size(), pushed_rhss_to_me.size());
2820 
2821 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2822  // Trade pushed node constraint rows
2823  std::vector<dof_id_type> pushed_node_ids_from_me
2824  (pushed_node_ids[procup].begin(), pushed_node_ids[procup].end());
2825  std::vector<dof_id_type> pushed_node_ids_to_me;
2826  std::vector<std::vector<dof_id_type>> pushed_node_keys_to_me;
2827  std::vector<std::vector<Real>> pushed_node_vals_to_me;
2828  std::vector<Point> pushed_node_offsets_to_me;
2829  this->comm().send_receive(procup, pushed_node_ids_from_me,
2830  procdown, pushed_node_ids_to_me);
2831  this->comm().send_receive(procup, pushed_node_keys,
2832  procdown, pushed_node_keys_to_me);
2833  this->comm().send_receive(procup, pushed_node_vals,
2834  procdown, pushed_node_vals_to_me);
2835  this->comm().send_receive(procup, pushed_node_offsets,
2836  procdown, pushed_node_offsets_to_me);
2837 
2838  // Note that we aren't doing a send_receive on the Nodes
2839  // themselves. At this point we should only be pushing out
2840  // "raw" constraints, and there should be no
2841  // constrained-by-constrained-by-etc. situations that could
2842  // involve non-semilocal nodes.
2843 
2844  libmesh_assert_equal_to (pushed_node_ids_to_me.size(), pushed_node_keys_to_me.size());
2845  libmesh_assert_equal_to (pushed_node_ids_to_me.size(), pushed_node_vals_to_me.size());
2846  libmesh_assert_equal_to (pushed_node_ids_to_me.size(), pushed_node_offsets_to_me.size());
2847 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
2848 
2849  // Add the dof constraints that I've been sent
2850  for (std::size_t i = 0; i != pushed_ids_to_me.size(); ++i)
2851  {
2852  libmesh_assert_equal_to (pushed_keys_to_me[i].size(), pushed_vals_to_me[i].size());
2853 
2854  dof_id_type constrained = pushed_ids_to_me[i];
2855 
2856  // If we don't already have a constraint for this dof,
2857  // add the one we were sent
2858  if (!this->is_constrained_dof(constrained))
2859  {
2860  DofConstraintRow & row = _dof_constraints[constrained];
2861  for (std::size_t j = 0; j != pushed_keys_to_me[i].size(); ++j)
2862  {
2863  row[pushed_keys_to_me[i][j]] = pushed_vals_to_me[i][j];
2864  }
2865  if (libmesh_isnan(pushed_rhss_to_me[i]))
2866  libmesh_assert(pushed_keys_to_me[i].empty());
2867  if (pushed_rhss_to_me[i] != Number(0))
2868  _primal_constraint_values[constrained] = pushed_rhss_to_me[i];
2869  else
2870  _primal_constraint_values.erase(constrained);
2871 
2872  for (unsigned int q = 0; q != max_qoi_num; ++q)
2873  {
2874  AdjointDofConstraintValues::iterator adjoint_map_it =
2876 
2877  if ((adjoint_map_it == _adjoint_constraint_values.end()) &&
2878  pushed_adj_rhss_to_me[q][constrained] == Number(0))
2879  continue;
2880 
2881  if (adjoint_map_it == _adjoint_constraint_values.end())
2882  adjoint_map_it = _adjoint_constraint_values.insert
2883  (std::make_pair(q,DofConstraintValueMap())).first;
2884 
2885  DofConstraintValueMap & constraint_map =
2886  adjoint_map_it->second;
2887 
2888  if (pushed_adj_rhss_to_me[q][i] != Number(0))
2889  constraint_map[constrained] =
2890  pushed_adj_rhss_to_me[q][i];
2891  else
2892  constraint_map.erase(constrained);
2893  }
2894  }
2895  }
2896 
2897 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2898  // Add the node constraints that I've been sent
2899  for (std::size_t i = 0; i != pushed_node_ids_to_me.size(); ++i)
2900  {
2901  libmesh_assert_equal_to (pushed_node_keys_to_me[i].size(), pushed_node_vals_to_me[i].size());
2902 
2903  dof_id_type constrained_id = pushed_node_ids_to_me[i];
2904 
2905  // If we don't already have a constraint for this node,
2906  // add the one we were sent
2907  const Node * constrained = mesh.node_ptr(constrained_id);
2908  if (!this->is_constrained_node(constrained))
2909  {
2910  NodeConstraintRow & row = _node_constraints[constrained].first;
2911  for (std::size_t j = 0; j != pushed_node_keys_to_me[i].size(); ++j)
2912  {
2913  const Node * key_node = mesh.node_ptr(pushed_node_keys_to_me[i][j]);
2914  libmesh_assert(key_node);
2915  row[key_node] = pushed_node_vals_to_me[i][j];
2916  }
2917  _node_constraints[constrained].second = pushed_node_offsets_to_me[i];
2918  }
2919  }
2920 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
2921  }
2922  }
2923 
2924  // Now start checking for any other constraints we need
2925  // to know about, requesting them recursively.
2926 
2927  // Create sets containing the DOFs and nodes we already depend on
2928  typedef std::set<dof_id_type> DoF_RCSet;
2929  DoF_RCSet unexpanded_dofs;
2930 
2931  for (DofConstraints::iterator i = _dof_constraints.begin();
2932  i != _dof_constraints.end(); ++i)
2933  {
2934  unexpanded_dofs.insert(i->first);
2935  }
2936 
2937  // Gather all the dof constraints we need
2938  this->gather_constraints(mesh, unexpanded_dofs, false);
2939 
2940  // Gather all the node constraints we need
2941 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
2942  typedef std::set<const Node *> Node_RCSet;
2943  Node_RCSet unexpanded_nodes;
2944 
2945  for (NodeConstraints::iterator i = _node_constraints.begin();
2946  i != _node_constraints.end(); ++i)
2947  {
2948  unexpanded_nodes.insert(i->first);
2949  }
2950 
2951  // We have to keep recursing while the unexpanded set is
2952  // nonempty on *any* processor
2953  bool unexpanded_set_nonempty = !unexpanded_nodes.empty();
2954  this->comm().max(unexpanded_set_nonempty);
2955 
2956  while (unexpanded_set_nonempty)
2957  {
2958  // Let's make sure we don't lose sync in this loop.
2959  parallel_object_only();
2960 
2961  // Request sets
2962  Node_RCSet node_request_set;
2963 
2964  // Request sets to send to each processor
2965  std::vector<std::vector<dof_id_type>>
2966  requested_node_ids(this->n_processors());
2967 
2968  // And the sizes of each
2969  std::vector<dof_id_type>
2970  node_ids_on_proc(this->n_processors(), 0);
2971 
2972  // Fill (and thereby sort and uniq!) the main request sets
2973  for (Node_RCSet::iterator i = unexpanded_nodes.begin();
2974  i != unexpanded_nodes.end(); ++i)
2975  {
2976  NodeConstraintRow & row = _node_constraints[*i].first;
2977  for (NodeConstraintRow::iterator j = row.begin();
2978  j != row.end(); ++j)
2979  {
2980  const Node * const node = j->first;
2981  libmesh_assert(node);
2982 
2983  // If it's non-local and we haven't already got a
2984  // constraint for it, we might need to ask for one
2985  if ((node->processor_id() != this->processor_id()) &&
2986  !_node_constraints.count(node))
2987  node_request_set.insert(node);
2988  }
2989  }
2990 
2991  // Clear the unexpanded constraint sets; we're about to expand
2992  // them
2993  unexpanded_nodes.clear();
2994 
2995  // Count requests by processor
2996  for (Node_RCSet::iterator i = node_request_set.begin();
2997  i != node_request_set.end(); ++i)
2998  {
2999  libmesh_assert(*i);
3000  libmesh_assert_less ((*i)->processor_id(), this->n_processors());
3001  node_ids_on_proc[(*i)->processor_id()]++;
3002  }
3003 
3004  for (processor_id_type p = 0; p != this->n_processors(); ++p)
3005  {
3006  requested_node_ids[p].reserve(node_ids_on_proc[p]);
3007  }
3008 
3009  // Prepare each processor's request set
3010  for (Node_RCSet::iterator i = node_request_set.begin();
3011  i != node_request_set.end(); ++i)
3012  {
3013  requested_node_ids[(*i)->processor_id()].push_back((*i)->id());
3014  }
3015 
3016  // Now request constraint rows from other processors
3017  for (processor_id_type p=1; p != this->n_processors(); ++p)
3018  {
3019  // Trade my requests with processor procup and procdown
3020  processor_id_type procup =
3021  cast_int<processor_id_type>((this->processor_id() + p) %
3022  this->n_processors());
3023  processor_id_type procdown =
3024  cast_int<processor_id_type>((this->n_processors() +
3025  this->processor_id() - p) %
3026  this->n_processors());
3027  std::vector<dof_id_type> node_request_to_fill;
3028 
3029  this->comm().send_receive(procup, requested_node_ids[procup],
3030  procdown, node_request_to_fill);
3031 
3032  // Fill those requests
3033  std::vector<std::vector<dof_id_type>>
3034  node_row_keys(node_request_to_fill.size());
3035  std::vector<std::vector<Real>>
3036  node_row_vals(node_request_to_fill.size());
3037  std::vector<Point>
3038  node_row_rhss(node_request_to_fill.size());
3039 
3040  // FIXME - this could be an unordered set, given a
3041  // hash<pointers> specialization
3042  std::set<const Node *> nodes_requested;
3043 
3044  for (std::size_t i=0; i != node_request_to_fill.size(); ++i)
3045  {
3046  dof_id_type constrained_id = node_request_to_fill[i];
3047  const Node * constrained_node = mesh.node_ptr(constrained_id);
3048  if (_node_constraints.count(constrained_node))
3049  {
3050  const NodeConstraintRow & row = _node_constraints[constrained_node].first;
3051  std::size_t row_size = row.size();
3052  node_row_keys[i].reserve(row_size);
3053  node_row_vals[i].reserve(row_size);
3054  for (NodeConstraintRow::const_iterator j = row.begin();
3055  j != row.end(); ++j)
3056  {
3057  const Node * node = j->first;
3058  node_row_keys[i].push_back(node->id());
3059  node_row_vals[i].push_back(j->second);
3060 
3061  // If we're not sure whether our send
3062  // destination already has this node, let's give
3063  // it a copy.
3064  if (node->processor_id() != procdown)
3065  nodes_requested.insert(node);
3066 
3067  // We can have 0 nodal constraint
3068  // coefficients, where no Lagrange constraint
3069  // exists but non-Lagrange basis constraints
3070  // might.
3071  // libmesh_assert(j->second);
3072  }
3073  node_row_rhss[i] = _node_constraints[constrained_node].second;
3074  }
3075  }
3076 
3077  // Trade back the results
3078  std::vector<std::vector<dof_id_type>> node_filled_keys;
3079  std::vector<std::vector<Real>> node_filled_vals;
3080  std::vector<Point> node_filled_rhss;
3081 
3082  this->comm().send_receive(procdown, node_row_keys,
3083  procup, node_filled_keys);
3084  this->comm().send_receive(procdown, node_row_vals,
3085  procup, node_filled_vals);
3086  this->comm().send_receive(procdown, node_row_rhss,
3087  procup, node_filled_rhss);
3088 
3089  // Constraining nodes might not even exist on our subset of
3090  // a distributed mesh, so let's make them exist.
3091  if (!mesh.is_serial())
3093  (procdown, &mesh, nodes_requested.begin(), nodes_requested.end(),
3095  (Node**)libmesh_nullptr);
3096 
3097  libmesh_assert_equal_to (node_filled_keys.size(), requested_node_ids[procup].size());
3098  libmesh_assert_equal_to (node_filled_vals.size(), requested_node_ids[procup].size());
3099  libmesh_assert_equal_to (node_filled_rhss.size(), requested_node_ids[procup].size());
3100 
3101  for (std::size_t i=0; i != requested_node_ids[procup].size(); ++i)
3102  {
3103  libmesh_assert_equal_to (node_filled_keys[i].size(), node_filled_vals[i].size());
3104  if (!node_filled_keys[i].empty())
3105  {
3106  dof_id_type constrained_id = requested_node_ids[procup][i];
3107  const Node * constrained_node = mesh.node_ptr(constrained_id);
3108  NodeConstraintRow & row = _node_constraints[constrained_node].first;
3109  for (std::size_t j = 0; j != node_filled_keys[i].size(); ++j)
3110  {
3111  const Node * key_node =
3112  mesh.node_ptr(node_filled_keys[i][j]);
3113  libmesh_assert(key_node);
3114  row[key_node] = node_filled_vals[i][j];
3115  }
3116  _node_constraints[constrained_node].second = node_filled_rhss[i];
3117 
3118  // And prepare to check for more recursive constraints
3119  unexpanded_nodes.insert(constrained_node);
3120  }
3121  }
3122  }
3123 
3124  // We have to keep recursing while the unexpanded set is
3125  // nonempty on *any* processor
3126  unexpanded_set_nonempty = !unexpanded_nodes.empty();
3127  this->comm().max(unexpanded_set_nonempty);
3128  }
3129 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
3130 }
The definition of the element_iterator struct.
Definition: mesh_base.h:1476
A Node is like a Point, but with more information.
Definition: node.h:52
virtual bool is_serial() const
Definition: mesh_base.h:140
unsigned int n_vars(const unsigned int s, const unsigned int vg) const
Definition: dof_object.h:745
void max(T &r) const
Take a local variable and replace it with the maximum of it&#39;s values on all processors.
void send_receive_packed_range(const unsigned int dest_processor_id, const Context1 *context1, RangeIter send_begin, const RangeIter send_end, const unsigned int source_processor_id, Context2 *context2, OutputIter out, const T *output_type, const MessageTag &send_tag=no_tag, const MessageTag &recv_tag=any_tag) const
Send a range-of-pointers to one processor while simultaneously receiving another range from a (potent...
processor_id_type n_processors() const
This is the base class from which all geometric element types are derived.
Definition: elem.h:89
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.
uint8_t processor_id_type
Definition: id_types.h:99
const class libmesh_nullptr_t libmesh_nullptr
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:810
virtual const Node * node_ptr(const dof_id_type i) const =0
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end...
const unsigned int n_vars
Definition: tecplot_io.C:68
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:1596
libmesh_assert(j)
virtual unsigned int n_nodes() const =0
void send_receive(const unsigned int dest_processor_id, const T1 &send, const unsigned int source_processor_id, T2 &recv, const MessageTag &send_tag=no_tag, const MessageTag &recv_tag=any_tag) const
Send data send to one processor while simultaneously receiving other data recv from a (potentially di...
const dof_id_type n_nodes
Definition: tecplot_io.C:67
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1734
bool is_constrained_node(const Node *node) const
Definition: dof_map.h:1717
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:1874
const Node & node_ref(const unsigned int i) const
Definition: elem.h:1896
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1592
unsigned int sys_number() const
Definition: dof_map.h:1649
A class for templated methods that expect output iterator arguments, which adds objects to the Mesh...
Storage for DofConstraint right hand sides for a particular problem.
Definition: dof_map.h:108
virtual element_iterator active_not_local_elements_end()=0
bool libmesh_isnan(float a)
const Parallel::Communicator & comm() const
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:1594
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:88
virtual element_iterator active_not_local_elements_begin()=0
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:136
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1831
unsigned int n_comp(const unsigned int s, const unsigned int var) const
Definition: dof_object.h:780
dof_id_type id() const
Definition: dof_object.h:632
uint8_t dof_id_type
Definition: id_types.h:64
processor_id_type processor_id() const
processor_id_type processor_id() const
Definition: dof_object.h:694
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:1603
void libMesh::DofMap::attach_extra_send_list_function ( void(*)(std::vector< dof_id_type > &, void *)  func,
void *  context = libmesh_nullptr 
)

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

Definition at line 373 of file dof_map.h.

void * _extra_send_list_context
A pointer associated with the extra send list that can optionally be passed in.
Definition: dof_map.h:1484
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:1479
void libMesh::DofMap::attach_extra_send_list_object ( DofMap::AugmentSendList asl)

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

365  {
366  _augment_send_list = &asl;
367  }
AugmentSendList * _augment_send_list
Function object to call to add extra entries to the send list.
Definition: dof_map.h:1474
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 = libmesh_nullptr 
)

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

void * _extra_sparsity_context
A pointer associated with the extra sparsity that can optionally be passed in.
Definition: dof_map.h:1469
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:1462
void libMesh::DofMap::attach_extra_sparsity_object ( DofMap::AugmentSparsityPattern asp)

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

336  {
338  }
AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:1457
void libMesh::DofMap::attach_matrix ( SparseMatrix< Number > &  matrix)

Additional matrices may be handled with this DofMap.

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

Definition at line 246 of file dof_map.C.

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

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

247 {
248  parallel_object_only();
249 
250  // We shouldn't be trying to re-attach the same matrices repeatedly
251  libmesh_assert (std::find(_matrices.begin(), _matrices.end(),
252  &matrix) == _matrices.end());
253 
254  _matrices.push_back(&matrix);
255 
256  matrix.attach_dof_map (*this);
257 
258  // If we've already computed sparsity, then it's too late
259  // to wait for "compute_sparsity" to help with sparse matrix
260  // initialization, and we need to handle this matrix individually
261  bool computed_sparsity_already =
262  ((_n_nz && !_n_nz->empty()) ||
263  (_n_oz && !_n_oz->empty()));
264  this->comm().max(computed_sparsity_already);
265  if (computed_sparsity_already &&
267  {
268  // We'd better have already computed the full sparsity pattern
269  // if we need it here
271  libmesh_assert(_sp.get());
272 
273  matrix.update_sparsity_pattern (_sp->sparsity_pattern);
274  }
275 
276  if (matrix.need_full_sparsity_pattern())
278 }
void max(T &r) const
Take a local variable and replace it with the maximum of it&#39;s values on all processors.
libmesh_assert(j)
std::vector< dof_id_type > * _n_nz
The number of on-processor nonzeros in my portion of the global matrix.
Definition: dof_map.h:1543
std::vector< dof_id_type > * _n_oz
The number of off-processor nonzeros in my portion of the global matrix; allocated similar to _n_nz...
Definition: dof_map.h:1549
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:1529
UniquePtr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix, kept around if it might be needed by future additions of t...
Definition: dof_map.h:1535
virtual bool need_full_sparsity_pattern() const
std::vector< SparseMatrix< Number > * > _matrices
Additional matrices handled by this object.
Definition: dof_map.h:1430
void attach_dof_map(const DofMap &dof_map)
Get a pointer to the DofMap to use.
virtual void update_sparsity_pattern(const SparsityPattern::Graph &)
Updates the matrix sparsity pattern.
const Parallel::Communicator & comm() const
unsigned int libMesh::DofMap::block_size ( ) const
Returns
The block size, if the variables are amenable to block storage. Otherwise 1.

Definition at line 498 of file dof_map.h.

499  {
500 #ifdef LIBMESH_ENABLE_BLOCKED_STORAGE
501  return (this->has_blocked_representation() ? this->n_variables() : 1);
502 #else
503  return 1;
504 #endif
505  }
unsigned int n_variables() const
Definition: dof_map.h:477
bool has_blocked_representation() const
Definition: dof_map.h:485
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 2360 of file dof_map_constraints.C.

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

2363 {
2364  LOG_SCOPE_IF("build_constraint_matrix()", "DofMap", !called_recursively);
2365 
2366  // Create a set containing the DOFs we already depend on
2367  typedef std::set<dof_id_type> RCSet;
2368  RCSet dof_set;
2369 
2370  bool we_have_constraints = false;
2371 
2372  // Next insert any other dofs the current dofs might be constrained
2373  // in terms of. Note that in this case we may not be done: Those
2374  // may in turn depend on others. So, we need to repeat this process
2375  // in that case until the system depends only on unconstrained
2376  // degrees of freedom.
2377  for (std::size_t i=0; i<elem_dofs.size(); i++)
2378  if (this->is_constrained_dof(elem_dofs[i]))
2379  {
2380  we_have_constraints = true;
2381 
2382  // If the DOF is constrained
2383  DofConstraints::const_iterator
2384  pos = _dof_constraints.find(elem_dofs[i]);
2385 
2386  libmesh_assert (pos != _dof_constraints.end());
2387 
2388  const DofConstraintRow & constraint_row = pos->second;
2389 
2390  // Constraint rows in p refinement may be empty
2391  //libmesh_assert (!constraint_row.empty());
2392 
2393  for (DofConstraintRow::const_iterator
2394  it=constraint_row.begin(); it != constraint_row.end();
2395  ++it)
2396  dof_set.insert (it->first);
2397  }
2398 
2399  // May be safe to return at this point
2400  // (but remember to stop the perflog)
2401  if (!we_have_constraints)
2402  return;
2403 
2404  for (std::size_t i=0; i != elem_dofs.size(); ++i)
2405  dof_set.erase (elem_dofs[i]);
2406 
2407  // If we added any DOFS then we need to do this recursively.
2408  // It is possible that we just added a DOF that is also
2409  // constrained!
2410  //
2411  // Also, we need to handle the special case of an element having DOFs
2412  // constrained in terms of other, local DOFs
2413  if (!dof_set.empty() || // case 1: constrained in terms of other DOFs
2414  !called_recursively) // case 2: constrained in terms of our own DOFs
2415  {
2416  const unsigned int old_size =
2417  cast_int<unsigned int>(elem_dofs.size());
2418 
2419  // Add new dependency dofs to the end of the current dof set
2420  elem_dofs.insert(elem_dofs.end(),
2421  dof_set.begin(), dof_set.end());
2422 
2423  // Now we can build the constraint matrix.
2424  // Note that resize also zeros for a DenseMatrix<Number>.
2425  C.resize (old_size,
2426  cast_int<unsigned int>(elem_dofs.size()));
2427 
2428  // Create the C constraint matrix.
2429  for (unsigned int i=0; i != old_size; i++)
2430  if (this->is_constrained_dof(elem_dofs[i]))
2431  {
2432  // If the DOF is constrained
2433  DofConstraints::const_iterator
2434  pos = _dof_constraints.find(elem_dofs[i]);
2435 
2436  libmesh_assert (pos != _dof_constraints.end());
2437 
2438  const DofConstraintRow & constraint_row = pos->second;
2439 
2440  // p refinement creates empty constraint rows
2441  // libmesh_assert (!constraint_row.empty());
2442 
2443  for (DofConstraintRow::const_iterator
2444  it=constraint_row.begin(); it != constraint_row.end();
2445  ++it)
2446  for (std::size_t j=0; j != elem_dofs.size(); j++)
2447  if (elem_dofs[j] == it->first)
2448  C(i,j) = it->second;
2449  }
2450  else
2451  {
2452  C(i,i) = 1.;
2453  }
2454 
2455  // May need to do this recursively. It is possible
2456  // that we just replaced a constrained DOF with another
2457  // constrained DOF.
2458  DenseMatrix<Number> Cnew;
2459 
2460  this->build_constraint_matrix (Cnew, elem_dofs, true);
2461 
2462  if ((C.n() == Cnew.m()) &&
2463  (Cnew.n() == elem_dofs.size())) // If the constraint matrix
2464  C.right_multiply(Cnew); // is constrained...
2465 
2466  libmesh_assert_equal_to (C.n(), elem_dofs.size());
2467  }
2468 }
unsigned int n() const
libmesh_assert(j)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1734
virtual void right_multiply(const DenseMatrixBase< T > &M2) libmesh_override
Performs the operation: (*this) <- (*this) * M3.
Definition: dense_matrix.C:210
unsigned int m() const
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1592
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...
void resize(const unsigned int new_m, const unsigned int new_n)
Resize the matrix.
Definition: dense_matrix.h:776
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:88
void libMesh::DofMap::build_constraint_matrix_and_vector ( DenseMatrix< Number > &  C,
DenseVector< Number > &  H,
std::vector< dof_id_type > &  elem_dofs,
int  qoi_index = -1,
const bool  called_recursively = false 
) const
private

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

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

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

Definition at line 2472 of file dof_map_constraints.C.

References libMesh::libmesh_assert(), libmesh_nullptr, 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().

2477 {
2478  LOG_SCOPE_IF("build_constraint_matrix_and_vector()", "DofMap", !called_recursively);
2479 
2480  // Create a set containing the DOFs we already depend on
2481  typedef std::set<dof_id_type> RCSet;
2482  RCSet dof_set;
2483 
2484  bool we_have_constraints = false;
2485 
2486  // Next insert any other dofs the current dofs might be constrained
2487  // in terms of. Note that in this case we may not be done: Those
2488  // may in turn depend on others. So, we need to repeat this process
2489  // in that case until the system depends only on unconstrained
2490  // degrees of freedom.
2491  for (std::size_t i=0; i<elem_dofs.size(); i++)
2492  if (this->is_constrained_dof(elem_dofs[i]))
2493  {
2494  we_have_constraints = true;
2495 
2496  // If the DOF is constrained
2497  DofConstraints::const_iterator
2498  pos = _dof_constraints.find(elem_dofs[i]);
2499 
2500  libmesh_assert (pos != _dof_constraints.end());
2501 
2502  const DofConstraintRow & constraint_row = pos->second;
2503 
2504  // Constraint rows in p refinement may be empty
2505  //libmesh_assert (!constraint_row.empty());
2506 
2507  for (DofConstraintRow::const_iterator
2508  it=constraint_row.begin(); it != constraint_row.end();
2509  ++it)
2510  dof_set.insert (it->first);
2511  }
2512 
2513  // May be safe to return at this point
2514  // (but remember to stop the perflog)
2515  if (!we_have_constraints)
2516  return;
2517 
2518  for (std::size_t i=0; i != elem_dofs.size(); ++i)
2519  dof_set.erase (elem_dofs[i]);
2520 
2521  // If we added any DOFS then we need to do this recursively.
2522  // It is possible that we just added a DOF that is also
2523  // constrained!
2524  //
2525  // Also, we need to handle the special case of an element having DOFs
2526  // constrained in terms of other, local DOFs
2527  if (!dof_set.empty() || // case 1: constrained in terms of other DOFs
2528  !called_recursively) // case 2: constrained in terms of our own DOFs
2529  {
2530  const DofConstraintValueMap * rhs_values = libmesh_nullptr;
2531  if (qoi_index < 0)
2532  rhs_values = &_primal_constraint_values;
2533  else
2534  {
2535  const AdjointDofConstraintValues::const_iterator
2536  it = _adjoint_constraint_values.find(qoi_index);
2537  if (it != _adjoint_constraint_values.end())
2538  rhs_values = &it->second;
2539  }
2540 
2541  const unsigned int old_size =
2542  cast_int<unsigned int>(elem_dofs.size());
2543 
2544  // Add new dependency dofs to the end of the current dof set
2545  elem_dofs.insert(elem_dofs.end(),
2546  dof_set.begin(), dof_set.end());
2547 
2548  // Now we can build the constraint matrix and vector.
2549  // Note that resize also zeros for a DenseMatrix and DenseVector
2550  C.resize (old_size,
2551  cast_int<unsigned int>(elem_dofs.size()));
2552  H.resize (old_size);
2553 
2554  // Create the C constraint matrix.
2555  for (unsigned int i=0; i != old_size; i++)
2556  if (this->is_constrained_dof(elem_dofs[i]))
2557  {
2558  // If the DOF is constrained
2559  DofConstraints::const_iterator
2560  pos = _dof_constraints.find(elem_dofs[i]);
2561 
2562  libmesh_assert (pos != _dof_constraints.end());
2563 
2564  const DofConstraintRow & constraint_row = pos->second;
2565 
2566  // p refinement creates empty constraint rows
2567  // libmesh_assert (!constraint_row.empty());
2568 
2569  for (DofConstraintRow::const_iterator
2570  it=constraint_row.begin(); it != constraint_row.end();
2571  ++it)
2572  for (std::size_t j=0; j != elem_dofs.size(); j++)
2573  if (elem_dofs[j] == it->first)
2574  C(i,j) = it->second;
2575 
2576  if (rhs_values)
2577  {
2578  DofConstraintValueMap::const_iterator rhsit =
2579  rhs_values->find(elem_dofs[i]);
2580  if (rhsit != rhs_values->end())
2581  H(i) = rhsit->second;
2582  }
2583  }
2584  else
2585  {
2586  C(i,i) = 1.;
2587  }
2588 
2589  // May need to do this recursively. It is possible
2590  // that we just replaced a constrained DOF with another
2591  // constrained DOF.
2592  DenseMatrix<Number> Cnew;
2593  DenseVector<Number> Hnew;
2594 
2595  this->build_constraint_matrix_and_vector (Cnew, Hnew, elem_dofs,
2596  qoi_index, true);
2597 
2598  if ((C.n() == Cnew.m()) && // If the constraint matrix
2599  (Cnew.n() == elem_dofs.size())) // is constrained...
2600  {
2601  // If x = Cy + h and y = Dz + g
2602  // Then x = (CD)z + (Cg + h)
2603  C.vector_mult_add(H, 1, Hnew);
2604 
2605  C.right_multiply(Cnew);
2606  }
2607 
2608  libmesh_assert_equal_to (C.n(), elem_dofs.size());
2609  }
2610 }
unsigned int n() const
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:350
const class libmesh_nullptr_t libmesh_nullptr
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:1596
libmesh_assert(j)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1734
virtual void right_multiply(const DenseMatrixBase< T > &M2) libmesh_override
Performs the operation: (*this) <- (*this) * M3.
Definition: dense_matrix.C:210
unsigned int m() const
void vector_mult_add(DenseVector< T > &dest, const T factor, const DenseVector< T > &arg) const
Performs the scaled matrix-vector multiplication, dest += factor * (*this) * arg. ...
Definition: dense_matrix.C:508
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1592
Storage for DofConstraint right hand sides for a particular problem.
Definition: dof_map.h:108
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:1594
void resize(const unsigned int new_m, const unsigned int new_n)
Resize the matrix.
Definition: dense_matrix.h:776
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:88
UniquePtr< SparsityPattern::Build > libMesh::DofMap::build_sparsity ( const MeshBase mesh) const
private

Builds a sparsity pattern.

Definition at line 55 of file dof_map.C.

References _augment_sparsity_pattern, _coupling_functors, _dof_coupling, _extra_sparsity_context, _extra_sparsity_function, libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), libMesh::DofMap::AugmentSparsityPattern::augment_sparsity_pattern(), libMesh::MeshBase::is_prepared(), libMesh::libmesh_assert(), n_dofs_on_processor(), need_full_sparsity_pattern, libMesh::out, libMesh::Threads::parallel_reduce(), libMesh::ParallelObject::processor_id(), and use_coupled_neighbor_dofs().

Referenced by compute_sparsity().

56 {
57  libmesh_assert (mesh.is_prepared());
58 
59  LOG_SCOPE("build_sparsity()", "DofMap");
60 
61  // Compute the sparsity structure of the global matrix. This can be
62  // fed into a PetscMatrix to allocate exactly the number of nonzeros
63  // necessary to store the matrix. This algorithm should be linear
64  // in the (# of elements)*(# nodes per element)
65 
66  // We can be more efficient in the threaded sparsity pattern assembly
67  // if we don't need the exact pattern. For some sparse matrix formats
68  // a good upper bound will suffice.
69 
70  // See if we need to include sparsity pattern entries for coupling
71  // between neighbor dofs
72  bool implicit_neighbor_dofs = this->use_coupled_neighbor_dofs(mesh);
73 
74  // We can compute the sparsity pattern in parallel on multiple
75  // threads. The goal is for each thread to compute the full sparsity
76  // pattern for a subset of elements. These sparsity patterns can
77  // be efficiently merged in the SparsityPattern::Build::join()
78  // method, especially if there is not too much overlap between them.
79  // Even better, if the full sparsity pattern is not needed then
80  // the number of nonzeros per row can be estimated from the
81  // sparsity patterns created on each thread.
82  UniquePtr<SparsityPattern::Build> sp
83  (new SparsityPattern::Build (mesh,
84  *this,
85  this->_dof_coupling,
86  this->_coupling_functors,
87  implicit_neighbor_dofs,
89 
90  Threads::parallel_reduce (ConstElemRange (mesh.active_local_elements_begin(),
91  mesh.active_local_elements_end()), *sp);
92 
93  sp->parallel_sync();
94 
95 #ifndef NDEBUG
96  // Avoid declaring these variables unless asserts are enabled.
97  const processor_id_type proc_id = mesh.processor_id();
98  const dof_id_type n_dofs_on_proc = this->n_dofs_on_processor(proc_id);
99 #endif
100  libmesh_assert_equal_to (sp->sparsity_pattern.size(), n_dofs_on_proc);
101 
102  // Check to see if we have any extra stuff to add to the sparsity_pattern
104  {
106  {
107  libmesh_here();
108  libMesh::out << "WARNING: You have specified both an extra sparsity function and object.\n"
109  << " Are you sure this is what you meant to do??"
110  << std::endl;
111  }
112 
114  (sp->sparsity_pattern, sp->n_nz,
115  sp->n_oz, _extra_sparsity_context);
116  }
117 
120  (sp->sparsity_pattern, sp->n_nz, sp->n_oz);
121 
122  return UniquePtr<SparsityPattern::Build>(sp.release());
123 }
void * _extra_sparsity_context
A pointer associated with the extra sparsity that can optionally be passed in.
Definition: dof_map.h:1469
MeshBase & mesh
uint8_t processor_id_type
Definition: id_types.h:99
AugmentSparsityPattern * _augment_sparsity_pattern
Function object to call to add extra entries to the sparsity pattern.
Definition: dof_map.h:1457
StoredRange< MeshBase::const_element_iterator, const Elem * > ConstElemRange
Definition: elem_range.h:34
dof_id_type n_dofs_on_processor(const processor_id_type proc) const
Definition: dof_map.h:526
libmesh_assert(j)
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:1529
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:1462
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1240
virtual void augment_sparsity_pattern(SparsityPattern::Graph &sparsity, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz)=0
User-defined function to augment the sparsity pattern.
OStreamProxy out
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:1523
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:1678
uint8_t dof_id_type
Definition: id_types.h:64
void libMesh::DofMap::check_dirichlet_bcid_consistency ( const MeshBase mesh,
const DirichletBoundary boundary 
) const
private

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

If not, this will throw an error.

Definition at line 4160 of file dof_map_constraints.C.

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

4162 {
4163  const std::set<boundary_id_type>& mesh_bcids = mesh.get_boundary_info().get_boundary_ids();
4164  const std::set<boundary_id_type>& dbc_bcids = boundary.b;
4165 
4166  // DirichletBoundary id sets should be consistent across all ranks
4167  libmesh_assert(mesh.comm().verify(dbc_bcids.size()));
4168 
4169  for (std::set<boundary_id_type>::const_iterator bid = dbc_bcids.begin();
4170  bid != dbc_bcids.end(); ++bid)
4171  {
4172  // DirichletBoundary id sets should be consistent across all ranks
4173  libmesh_assert(mesh.comm().verify(*bid));
4174 
4175  bool found_bcid = (mesh_bcids.find(*bid) != mesh_bcids.end());
4176 
4177  // On a distributed mesh, boundary id sets may *not* be
4178  // consistent across all ranks, since not all ranks see all
4179  // boundaries
4180  mesh.comm().max(found_bcid);
4181 
4182  if (!found_bcid)
4183  libmesh_error_msg("Could not find Dirichlet boundary id " << *bid << " in mesh!");
4184  }
4185 }
bool verify(const T &r) const
Verify that a local variable has the same value on all processors.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:117
void max(T &r) const
Take a local variable and replace it with the maximum of it&#39;s values on all processors.
const std::set< boundary_id_type > & get_boundary_ids() const
libmesh_assert(j)
const Parallel::Communicator & comm() const
std::set< boundary_id_type > b
void libMesh::DofMap::clear ( )

Free all memory associated with the object, but keep the mesh pointer.

Definition at line 803 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, _send_list, _stashed_dof_constraints, _variable_groups, _variables, add_algebraic_ghosting_functor(), add_coupling_functor(), algebraic_ghosting_functors_begin(), algebraic_ghosting_functors_end(), clear_sparsity(), coupling_functors_begin(), coupling_functors_end(), libMesh::libmesh_assert(), need_full_sparsity_pattern, libMesh::MeshBase::remove_ghosting_functor(), and use_coupled_neighbor_dofs().

Referenced by ~DofMap().

804 {
805  // we don't want to clear
806  // the coupling matrix!
807  // It should not change...
808  //_dof_coupling->clear();
809  //
810  // But it would be inconsistent to leave our coupling settings
811  // through a clear()...
812  _dof_coupling = NULL;
813 
814  // Reset ghosting functor statuses
815  {
816  std::set<GhostingFunctor *>::iterator gf_it = this->coupling_functors_begin();
817  const std::set<GhostingFunctor *>::iterator gf_end = this->coupling_functors_end();
818  for (; gf_it != gf_end; ++gf_it)
819  {
820  GhostingFunctor * gf = *gf_it;
821  libmesh_assert(gf);
823  }
824  this->_coupling_functors.clear();
825 
826  // Go back to default coupling
827 
828  _default_coupling->set_dof_coupling(this->_dof_coupling);
829  _default_coupling->set_n_levels(this->use_coupled_neighbor_dofs(this->_mesh));
830 
832  }
833 
834 
835  {
836  std::set<GhostingFunctor *>::iterator gf_it = this->algebraic_ghosting_functors_begin();
837  const std::set<GhostingFunctor *>::iterator gf_end = this->algebraic_ghosting_functors_end();
838  for (; gf_it != gf_end; ++gf_it)
839  {
840  GhostingFunctor * gf = *gf_it;
841  libmesh_assert(gf);
843  }
844  this->_algebraic_ghosting_functors.clear();
845 
846  // Go back to default send_list generation
847 
848  // _default_evaluating->set_dof_coupling(this->_dof_coupling);
849  _default_evaluating->set_n_levels(1);
851  }
852 
853  _variables.clear();
854  _variable_groups.clear();
855  _first_df.clear();
856  _end_df.clear();
857  _first_scalar_df.clear();
858  _send_list.clear();
859  this->clear_sparsity();
861 
862 #ifdef LIBMESH_ENABLE_AMR
863 
864  _dof_constraints.clear();
865  _stashed_dof_constraints.clear();
868  _n_old_dfs = 0;
869  _first_old_df.clear();
870  _end_old_df.clear();
871  _first_old_scalar_df.clear();
872 
873 #endif
874 
875  _matrices.clear();
876 
877  _n_dfs = 0;
878 }
std::vector< VariableGroup > _variable_groups
The finite element type for each variable.
Definition: dof_map.h:1413
UniquePtr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:1492
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_begin() const
Beginning of range of algebraic ghosting functors.
Definition: dof_map.h:311
std::set< GhostingFunctor * >::const_iterator coupling_functors_begin() const
Beginning of range of coupling functors.
Definition: dof_map.h:275
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:1452
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Removes a functor which was previously added to the set of ghosting functors.
Definition: mesh_base.C:305
std::set< GhostingFunctor * > _algebraic_ghosting_functors
The list of all GhostingFunctor objects to be used when distributing ghosted vectors.
Definition: dof_map.h:1510
std::vector< dof_id_type > _end_old_df
Last old DOF index (plus 1) on processor p.
Definition: dof_map.h:1577
void add_coupling_functor(GhostingFunctor &coupling_functor)
Adds a functor which can specify coupling requirements for creation of sparse matrices.
Definition: dof_map.C:1794
UniquePtr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:1500
std::vector< dof_id_type > _first_old_df
First old DOF index on processor p.
Definition: dof_map.h:1572
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:1446
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:1596
libmesh_assert(j)
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:1529
void add_algebraic_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors...
Definition: dof_map.C:1813
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:1583
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1592
CouplingMatrix * _dof_coupling
Degree of freedom coupling.
Definition: dof_map.h:1240
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_end() const
End of range of algebraic ghosting functors.
Definition: dof_map.h:317
std::vector< SparseMatrix< Number > * > _matrices
Additional matrices handled by this object.
Definition: dof_map.h:1430
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:1594
std::vector< Variable > _variables
The finite element type for each variable.
Definition: dof_map.h:1408
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:1592
dof_id_type _n_old_dfs
Total number of degrees of freedom on old dof objects.
Definition: dof_map.h:1567
void clear_sparsity()
Clears the sparsity pattern.
Definition: dof_map.C:1772
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:1523
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:1440
std::vector< dof_id_type > _first_df
First DOF index on processor p.
Definition: dof_map.h:1435
MeshBase & _mesh
The mesh that system uses.
Definition: dof_map.h:1423
std::set< GhostingFunctor * >::const_iterator coupling_functors_end() const
End of range of coupling functors.
Definition: dof_map.h:281
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:1678
dof_id_type _n_dfs
Total number of degrees of freedom.
Definition: dof_map.h:1554
void libMesh::DofMap::clear_sparsity ( )

Clears the sparsity pattern.

Definition at line 1772 of file dof_map.C.

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

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

1773 {
1775  {
1776  libmesh_assert(_sp.get());
1777  libmesh_assert(!_n_nz || _n_nz == &_sp->n_nz);
1778  libmesh_assert(!_n_oz || _n_oz == &_sp->n_oz);
1779  _sp.reset();
1780  }
1781  else
1782  {
1783  libmesh_assert(!_sp.get());
1784  delete _n_nz;
1785  delete _n_oz;
1786  }
1789 }
const class libmesh_nullptr_t libmesh_nullptr
libmesh_assert(j)
std::vector< dof_id_type > * _n_nz
The number of on-processor nonzeros in my portion of the global matrix.
Definition: dof_map.h:1543
std::vector< dof_id_type > * _n_oz
The number of off-processor nonzeros in my portion of the global matrix; allocated similar to _n_nz...
Definition: dof_map.h:1549
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:1529
UniquePtr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix, kept around if it might be needed by future additions of t...
Definition: dof_map.h:1535
const Parallel::Communicator& libMesh::ParallelObject::comm ( ) const
inherited
Returns
A reference to the Parallel::Communicator object used by this mesh.

Definition at line 87 of file parallel_object.h.

References libMesh::ParallelObject::_communicator.

Referenced by libMesh::__libmesh_petsc_diff_solver_monitor(), libMesh::__libmesh_petsc_diff_solver_residual(), libMesh::__libmesh_petsc_preconditioner_apply(), libMesh::__libmesh_petsc_snes_jacobian(), libMesh::__libmesh_petsc_snes_postcheck(), libMesh::__libmesh_petsc_snes_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::ParmetisPartitioner::_do_repartition(), libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::BoundaryInfo::_find_id_maps(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_get_diagonal(), libMesh::SlepcEigenSolver< T >::_petsc_shell_matrix_get_diagonal(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult(), libMesh::SlepcEigenSolver< T >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult_add(), libMesh::EquationSystems::_read_impl(), libMesh::MeshRefinement::_refine_elements(), libMesh::MeshRefinement::_smooth_flags(), add_cube_convex_hull_to_mesh(), libMesh::TransientRBConstruction::add_IC_to_RB_space(), libMesh::ImplicitSystem::add_matrix(), libMesh::RBConstruction::add_scaled_matrix_and_vector(), libMesh::System::add_vector(), libMesh::EigenSparseLinearSolver< T >::adjoint_solve(), libMesh::UnstructuredMesh::all_second_order(), libMesh::MeshTools::Modification::all_tri(), libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::TransientRBConstruction::allocate_data_structures(), libMesh::RBConstruction::allocate_data_structures(), libMesh::TransientRBConstruction::assemble_affine_expansion(), libMesh::FEMSystem::assemble_qoi(), libMesh::MeshCommunication::assign_global_indices(), libMesh::ParmetisPartitioner::assign_partitioning(), attach_matrix(), libMesh::Parallel::BinSorter< KeyType, IdxType >::binsort(), libMesh::Parallel::Sort< KeyType, IdxType >::binsort(), libMesh::MeshCommunication::broadcast(), libMesh::SparseMatrix< T >::build(), libMesh::MeshTools::Generation::build_extrusion(), libMesh::Parallel::Histogram< KeyType, IdxType >::build_histogram(), libMesh::PetscNonlinearSolver< T >::build_mat_null_space(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::MeshBase::cache_elem_dims(), libMesh::System::calculate_norm(), check_dirichlet_bcid_consistency(), libMesh::Parallel::Sort< KeyType, IdxType >::communicate_bins(), 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::RBSCMConstruction::compute_SCM_bounds_on_training_set(), libMesh::Problem_Interface::computeF(), libMesh::Problem_Interface::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::MeshTools::create_bounding_box(), libMesh::MeshTools::create_nodal_bounding_box(), libMesh::MeshRefinement::create_parent_error_vector(), libMesh::MeshTools::create_processor_bounding_box(), libMesh::MeshTools::create_subdomain_bounding_box(), libMesh::MeshCommunication::delete_remote_elements(), distribute_dofs(), DMlibMeshFunction(), DMlibMeshJacobian(), DMlibMeshSetSystem_libMesh(), DMVariableBounds_libMesh(), libMesh::MeshRefinement::eliminate_unrefined_patches(), libMesh::RBEIMConstruction::enrich_RB_space(), libMesh::TransientRBConstruction::enrich_RB_space(), libMesh::RBConstruction::enrich_RB_space(), AssembleOptimization::equality_constraints(), libMesh::WeightedPatchRecoveryErrorEstimator::estimate_error(), libMesh::JumpErrorEstimator::estimate_error(), libMesh::PatchRecoveryErrorEstimator::estimate_error(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::RBEIMConstruction::evaluate_mesh_function(), libMesh::MeshRefinement::flag_elements_by_elem_fraction(), libMesh::MeshRefinement::flag_elements_by_error_fraction(), libMesh::MeshRefinement::flag_elements_by_nelem_target(), libMesh::MeshCommunication::gather(), libMesh::MeshCommunication::gather_neighboring_elements(), libMesh::MeshfreeInterpolation::gather_remote_data(), libMesh::CondensedEigenSystem::get_eigenpair(), get_info(), libMesh::ImplicitSystem::get_linear_solver(), libMesh::EquationSystems::get_solution(), AssembleOptimization::inequality_constraints(), AssembleOptimization::inequality_constraints_jacobian(), libMesh::LocationMap< T >::init(), libMesh::TopologyMap::init(), libMesh::PetscDiffSolver::init(), libMesh::TimeSolver::init(), libMesh::TaoOptimizationSolver< T >::init(), libMesh::PetscNonlinearSolver< T >::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::EigenSystem::init_data(), libMesh::EigenSystem::init_matrices(), libMesh::ParmetisPartitioner::initialize(), libMesh::OptimizationSystem::initialize_equality_constraints_storage(), libMesh::OptimizationSystem::initialize_inequality_constraints_storage(), libMesh::RBEIMConstruction::initialize_rb_construction(), integrate_function(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_topology_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_flags(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_p_levels(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::MeshTools::libmesh_assert_valid_unique_ids(), libMesh::MeshRefinement::limit_level_mismatch_at_edge(), libMesh::MeshRefinement::limit_level_mismatch_at_node(), libMesh::MeshRefinement::limit_overrefined_boundary(), libMesh::MeshRefinement::limit_underrefined_boundary(), main(), libMesh::MeshRefinement::make_coarsening_compatible(), libMesh::MeshCommunication::make_elems_parallel_consistent(), libMesh::MeshRefinement::make_flags_parallel_consistent(), libMesh::MeshCommunication::make_new_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_new_nodes_parallel_consistent(), libMesh::MeshCommunication::make_node_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_unique_ids_parallel_consistent(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), libMesh::MeshCommunication::make_p_levels_parallel_consistent(), libMesh::MeshRefinement::make_refinement_compatible(), libMesh::TransientRBConstruction::mass_matrix_scaled_matvec(), libMesh::FEMSystem::mesh_position_set(), libMesh::MeshSerializer::MeshSerializer(), LinearElasticityWithContact::move_mesh(), libMesh::DistributedMesh::n_active_elem(), libMesh::MeshTools::n_active_levels(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::CondensedEigenSystem::n_global_non_condensed_dofs(), libMesh::MeshTools::n_levels(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::MeshTools::n_p_levels(), libMesh::BoundaryInfo::n_shellface_conds(), new_function_base(), libMesh::DistributedMesh::parallel_max_elem_id(), libMesh::DistributedMesh::parallel_max_node_id(), libMesh::ReplicatedMesh::parallel_max_unique_id(), libMesh::DistributedMesh::parallel_max_unique_id(), libMesh::DistributedMesh::parallel_n_elem(), libMesh::DistributedMesh::parallel_n_nodes(), libMesh::SparsityPattern::Build::parallel_sync(), libMesh::MeshTools::paranoid_n_levels(), libMesh::Partitioner::partition(), libMesh::MetisPartitioner::partition_range(), 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::SparseMatrix< T >::print(), FEMParameters::read(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::XdrIO::read(), libMesh::CheckpointIO::read_header(), libMesh::XdrIO::read_header(), libMesh::RBEvaluation::read_in_vectors_from_multiple_files(), libMesh::TransientRBConstruction::read_riesz_representors_from_files(), libMesh::RBConstruction::read_riesz_representors_from_files(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::MeshBase::recalculate_n_partitions(), libMesh::MeshCommunication::redistribute(), libMesh::MeshRefinement::refine_and_coarsen_elements(), libMesh::DistributedMesh::renumber_dof_objects(), LinearElasticityWithContact::residual_and_jacobian(), libMesh::MeshCommunication::send_coarse_ghosts(), libMesh::TransientRBConstruction::set_error_temporal_data(), libMesh::RBEIMConstruction::set_explicit_sys_subvector(), libMesh::Partitioner::set_node_processor_ids(), set_nonlocal_dof_objects(), libMesh::Partitioner::set_parent_processor_ids(), libMesh::LaplaceMeshSmoother::smooth(), libMesh::Parallel::Sort< KeyType, IdxType >::sort(), libMesh::MeshBase::subdomain_ids(), libMesh::BoundaryInfo::sync(), libMesh::Parallel::sync_element_data_by_parent_id(), libMesh::Parallel::sync_node_data_by_element_id(), libMesh::MeshRefinement::test_level_one(), MeshfunctionDFEM::test_mesh_function_dfem(), MeshfunctionDFEM::test_mesh_function_dfem_grad(), libMesh::MeshRefinement::test_unflagged(), PointLocatorTest::testLocator(), BoundaryInfoTest::testMesh(), SystemsTest::testProjectCubeWithMeshFunction(), libMesh::MeshTools::total_weight(), libMesh::MeshFunctionSolutionTransfer::transfer(), libMesh::MeshfreeSolutionTransfer::transfer(), libMesh::TransientRBConstruction::truth_assembly(), libMesh::RBConstruction::truth_assembly(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::TransientRBConstruction::update_RB_initial_condition_all_N(), libMesh::RBEIMConstruction::update_RB_system_matrices(), libMesh::TransientRBConstruction::update_RB_system_matrices(), libMesh::RBConstruction::update_RB_system_matrices(), libMesh::TransientRBConstruction::update_residual_terms(), libMesh::RBConstruction::update_residual_terms(), libMesh::NameBasedIO::write(), libMesh::XdrIO::write(), libMesh::RBEvaluation::write_out_vectors(), libMesh::TransientRBConstruction::write_riesz_representors_to_files(), libMesh::RBConstruction::write_riesz_representors_to_files(), libMesh::XdrIO::write_serialized_bcs_helper(), 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().

88  { return _communicator; }
const Parallel::Communicator & _communicator
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 1735 of file dof_map.C.

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

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

1736 {
1737  _sp = this->build_sparsity(mesh);
1738 
1739  // It is possible that some \p SparseMatrix implementations want to
1740  // see it. Let them see it before we throw it away.
1741  std::vector<SparseMatrix<Number> *>::const_iterator
1742  pos = _matrices.begin(),
1743  end = _matrices.end();
1744 
1745  // If we need the full sparsity pattern, then we share a view of its
1746  // arrays, and we pass it in to the matrices.
1748  {
1749  _n_nz = &_sp->n_nz;
1750  _n_oz = &_sp->n_oz;
1751 
1752  for (; pos != end; ++pos)
1753  (*pos)->update_sparsity_pattern (_sp->sparsity_pattern);
1754  }
1755  // If we don't need the full sparsity pattern anymore, steal the
1756  // arrays we do need and free the rest of the memory
1757  else
1758  {
1759  if (!_n_nz)
1760  _n_nz = new std::vector<dof_id_type>();
1761  _n_nz->swap(_sp->n_nz);
1762  if (!_n_oz)
1763  _n_oz = new std::vector<dof_id_type>();
1764  _n_oz->swap(_sp->n_oz);
1765 
1766  _sp.reset();
1767  }
1768 }
MeshBase & mesh
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end...
std::vector< dof_id_type > * _n_nz
The number of on-processor nonzeros in my portion of the global matrix.
Definition: dof_map.h:1543
std::vector< dof_id_type > * _n_oz
The number of off-processor nonzeros in my portion of the global matrix; allocated similar to _n_nz...
Definition: dof_map.h:1549
bool need_full_sparsity_pattern
Default false; set to true if any attached matrix requires a full sparsity pattern.
Definition: dof_map.h:1529
UniquePtr< SparsityPattern::Build > _sp
The sparsity pattern of the global matrix, kept around if it might be needed by future additions of t...
Definition: dof_map.h:1535
UniquePtr< SparsityPattern::Build > build_sparsity(const MeshBase &mesh) const
Builds a sparsity pattern.
Definition: dof_map.C:55
std::vector< SparseMatrix< Number > * > _matrices
Additional matrices handled by this object.
Definition: dof_map.h:1430
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

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

Referenced by assemble(), and heterogenously_constrain_element_vector().

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

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

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

1795  {}
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

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

1800  {}
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

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

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

1809  {}
void libMesh::DofMap::constrain_element_vector ( DenseVector< Number > &  rhs,
std::vector< dof_id_type > &  dofs,
bool  asymmetric_constraint_rows = true 
) const
void libMesh::DofMap::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.

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

Definition at line 2065 of file dof_map_constraints.C.

References libMesh::NumericVector< T >::build(), libMesh::NumericVector< T >::close(), libMesh::NumericVector< T >::closed(), enforce_adjoint_constraints_exactly(), enforce_constraints_exactly(), exact_value(), libMesh::NumericVector< T >::get(), libMesh::System::get_dof_map(), libMesh::GHOSTED, libMesh::libmesh_assert(), libmesh_nullptr, libMesh::NumericVector< T >::localize(), libMesh::PARALLEL, libMesh::SERIAL, libMesh::NumericVector< T >::set(), libMesh::NumericVector< T >::size(), libMesh::System::solution, and libMesh::NumericVector< T >::type().

2066 {
2067  // check for easy return
2068  if (this->_dof_constraints.empty())
2069  return;
2070 
2071  // All the work is done by \p build_constraint_matrix. We just need
2072  // a dummy matrix.
2074  this->build_constraint_matrix (R, dofs);
2075 }
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1592
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...
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 3993 of file dof_map_constraints.C.

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

Referenced by libMesh::FEGenericBase< OutputType >::compute_periodic_constraints(), and libMesh::FEGenericBase< OutputType >::compute_proj_constraints().

3997 {
3998  // We're constraining dofs on elem which correspond to p refinement
3999  // levels above p - this only makes sense if elem's p refinement
4000  // level is above p.
4001  libmesh_assert_greater (elem->p_level(), p);
4002  libmesh_assert_less (s, elem->n_sides());
4003 
4004  const unsigned int sys_num = this->sys_number();
4005  const unsigned int dim = elem->dim();
4006  ElemType type = elem->type();
4007  FEType low_p_fe_type = this->variable_type(var);
4008  FEType high_p_fe_type = this->variable_type(var);
4009  low_p_fe_type.order = static_cast<Order>(low_p_fe_type.order + p);
4010  high_p_fe_type.order = static_cast<Order>(high_p_fe_type.order +
4011  elem->p_level());
4012 
4013  const unsigned int n_nodes = elem->n_nodes();
4014  for (unsigned int n = 0; n != n_nodes; ++n)
4015  if (elem->is_node_on_side(n, s))
4016  {
4017  const Node & node = elem->node_ref(n);
4018  const unsigned int low_nc =
4019  FEInterface::n_dofs_at_node (dim, low_p_fe_type, type, n);
4020  const unsigned int high_nc =
4021  FEInterface::n_dofs_at_node (dim, high_p_fe_type, type, n);
4022 
4023  // since we may be running this method concurrently
4024  // on multiple threads we need to acquire a lock
4025  // before modifying the _dof_constraints object.
4026  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
4027 
4028  if (elem->is_vertex(n))
4029  {
4030  // Add "this is zero" constraint rows for high p vertex
4031  // dofs
4032  for (unsigned int i = low_nc; i != high_nc; ++i)
4033  {
4034  _dof_constraints[node.dof_number(sys_num,var,i)].clear();
4035  _primal_constraint_values.erase(node.dof_number(sys_num,var,i));
4036  }
4037  }
4038  else
4039  {
4040  const unsigned int total_dofs = node.n_comp(sys_num, var);
4041  libmesh_assert_greater_equal (total_dofs, high_nc);
4042  // Add "this is zero" constraint rows for high p
4043  // non-vertex dofs, which are numbered in reverse
4044  for (unsigned int j = low_nc; j != high_nc; ++j)
4045  {
4046  const unsigned int i = total_dofs - j - 1;
4047  _dof_constraints[node.dof_number(sys_num,var,i)].clear();
4048  _primal_constraint_values.erase(node.dof_number(sys_num,var,i));
4049  }
4050  }
4051  }
4052 }
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:178
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
A Node is like a Point, but with more information.
Definition: node.h:52
virtual ElemType type() const =0
unsigned int p_level() const
Definition: elem.h:2422
const FEType & variable_type(const unsigned int c) const
Definition: dof_map.h:1697
unsigned int dim
ElemType
Defines an enum for geometric element types.
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:810
OrderWrapper order
The approximation order of the element.
Definition: fe_type.h:197
virtual unsigned int n_nodes() const =0
const dof_id_type n_nodes
Definition: tecplot_io.C:67
spin_mutex spin_mtx
A convenient spin mutex object which can be used for obtaining locks.
Definition: threads.C:29
const Node & node_ref(const unsigned int i) const
Definition: elem.h:1896
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1592
virtual unsigned int n_sides() const =0
unsigned int sys_number() const
Definition: dof_map.h:1649
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 bool is_vertex(const unsigned int i) const =0
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:1594
virtual unsigned int dim() const =0
Order
defines an enum for polynomial orders.
Definition: enum_order.h:32
unsigned int n_comp(const unsigned int s, const unsigned int var) const
Definition: dof_object.h:780
DofConstraints::const_iterator libMesh::DofMap::constraint_rows_begin ( ) const
Returns
An iterator pointing to the first DoF constraint row.

Definition at line 824 of file dof_map.h.

825  { return _dof_constraints.begin(); }
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1592
DofConstraints::const_iterator libMesh::DofMap::constraint_rows_end ( ) const
Returns
An iterator pointing just past the last DoF constraint row.

Definition at line 830 of file dof_map.h.

831  { return _dof_constraints.end(); }
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1592
std::set<GhostingFunctor *>::const_iterator libMesh::DofMap::coupling_functors_begin ( ) const

Beginning of range of coupling functors.

Definition at line 275 of file dof_map.h.

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

276  { 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:1523
std::set<GhostingFunctor *>::const_iterator libMesh::DofMap::coupling_functors_end ( ) const

End of range of coupling functors.

Definition at line 281 of file dof_map.h.

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

282  { 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:1523
void libMesh::DofMap::create_dof_constraints ( const MeshBase mesh,
Real  time = 0 
)

Rebuilds the raw degree of freedom and DofObject constraints.

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

Definition at line 1185 of file dof_map_constraints.C.

References libMesh::StoredRange< iterator_type, object_type >::empty(), libMesh::MeshBase::is_prepared(), libMesh::MeshBase::is_serial(), libMesh::libmesh_assert(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshBase::local_elements_begin(), libMesh::MeshBase::local_elements_end(), libMesh::MeshBase::mesh_dimension(), libMesh::MeshBase::n_elem(), libMesh::Threads::parallel_for(), libMesh::StoredRange< iterator_type, object_type >::reset(), libMesh::MeshBase::sub_point_locator(), and libMesh::Parallel::verify().

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

1186 {
1187  parallel_object_only();
1188 
1189  LOG_SCOPE("create_dof_constraints()", "DofMap");
1190 
1191  libmesh_assert (mesh.is_prepared());
1192 
1193  // The user might have set boundary conditions after the mesh was
1194  // prepared; we should double-check that those boundary conditions
1195  // are still consistent.
1196 #ifdef DEBUG
1198 #endif
1199 
1200  // We might get constraint equations from AMR hanging nodes in 2D/3D
1201  // or from boundary conditions in any dimension
1202  const bool possible_local_constraints = false
1203  || !mesh.n_elem()
1204 #ifdef LIBMESH_ENABLE_AMR
1205  || mesh.mesh_dimension() > 1
1206 #endif
1207 #ifdef LIBMESH_ENABLE_PERIODIC
1208  || !_periodic_boundaries->empty()
1209 #endif
1210 #ifdef LIBMESH_ENABLE_DIRICHLET
1211  || !_dirichlet_boundaries->empty()
1212 #endif
1213  ;
1214 
1215  // Even if we don't have constraints, another processor might.
1216  bool possible_global_constraints = possible_local_constraints;
1217 #if defined(LIBMESH_ENABLE_PERIODIC) || defined(LIBMESH_ENABLE_DIRICHLET) || defined(LIBMESH_ENABLE_AMR)
1218  libmesh_assert(this->comm().verify(mesh.is_serial()));
1219 
1220  this->comm().max(possible_global_constraints);
1221 #endif
1222 
1223  if (!possible_global_constraints)
1224  {
1225  // Clear out any old constraints; maybe the user just deleted
1226  // their last remaining dirichlet/periodic/user constraint?
1227 #ifdef LIBMESH_ENABLE_CONSTRAINTS
1228  _dof_constraints.clear();
1229  _stashed_dof_constraints.clear();
1230  _primal_constraint_values.clear();
1232 #endif
1233 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
1234  _node_constraints.clear();
1235 #endif
1236 
1237  return;
1238  }
1239 
1240  // Here we build the hanging node constraints. This is done
1241  // by enforcing the condition u_a = u_b along hanging sides.
1242  // u_a = u_b is collocated at the nodes of side a, which gives
1243  // one row of the constraint matrix.
1244 
1245  // Processors only compute their local constraints
1246  ConstElemRange range (mesh.local_elements_begin(),
1247  mesh.local_elements_end());
1248 
1249  // Global computation fails if we're using a FEMFunctionBase BC on a
1250  // ReplicatedMesh in parallel
1251  // ConstElemRange range (mesh.elements_begin(),
1252  // mesh.elements_end());
1253 
1254  // compute_periodic_constraints requires a point_locator() from our
1255  // Mesh, but point_locator() construction is parallel and threaded.
1256  // Rather than nest threads within threads we'll make sure it's
1257  // preconstructed.
1258 #ifdef LIBMESH_ENABLE_PERIODIC
1259  bool need_point_locator = !_periodic_boundaries->empty() && !range.empty();
1260 
1261  this->comm().max(need_point_locator);
1262 
1263  if (need_point_locator)
1264  mesh.sub_point_locator();
1265 #endif
1266 
1267 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
1268  // recalculate node constraints from scratch
1269  _node_constraints.clear();
1270 
1271  Threads::parallel_for (range,
1272  ComputeNodeConstraints (_node_constraints,
1273  *this,
1274 #ifdef LIBMESH_ENABLE_PERIODIC
1276 #endif
1277  mesh));
1278 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
1279 
1280 
1281  // recalculate dof constraints from scratch
1282  _dof_constraints.clear();
1283  _stashed_dof_constraints.clear();
1284  _primal_constraint_values.clear();
1286 
1287  // Look at all the variables in the system. Reset the element
1288  // range at each iteration -- there is no need to reconstruct it.
1289  for (unsigned int variable_number=0; variable_number<this->n_variables();
1290  ++variable_number, range.reset())
1291  Threads::parallel_for (range,
1292  ComputeConstraints (_dof_constraints,
1293  *this,
1294 #ifdef LIBMESH_ENABLE_PERIODIC
1296 #endif
1297  mesh,
1298  variable_number));
1299 
1300 #ifdef LIBMESH_ENABLE_DIRICHLET
1301  for (DirichletBoundaries::iterator
1302  i = _dirichlet_boundaries->begin();
1303  i != _dirichlet_boundaries->end(); ++i, range.reset())
1304  {
1305  // Sanity check that the boundary ids associated with the DirichletBoundary
1306  // objects are actually present in the mesh
1307  this->check_dirichlet_bcid_consistency(mesh,**i);
1308 
1310  (range,
1311  ConstrainDirichlet(*this, mesh, time, **i,
1312  AddPrimalConstraint(*this))
1313  );
1314  }
1315 
1316  for (std::size_t qoi_index = 0;
1317  qoi_index != _adjoint_dirichlet_boundaries.size();
1318  ++qoi_index)
1319  {
1320  for (DirichletBoundaries::iterator
1321  i = _adjoint_dirichlet_boundaries[qoi_index]->begin();
1322  i != _adjoint_dirichlet_boundaries[qoi_index]->end();
1323  ++i, range.reset())
1324  {
1325  // Sanity check that the boundary ids associated with the DirichletBoundary
1326  // objects are actually present in the mesh
1327  this->check_dirichlet_bcid_consistency(mesh,**i);
1328 
1330  (range,
1331  ConstrainDirichlet(*this, mesh, time, **i,
1332  AddAdjointConstraint(*this, qoi_index))
1333  );
1334  }
1335  }
1336 
1337 #endif // LIBMESH_ENABLE_DIRICHLET
1338 }
virtual bool is_serial() const
Definition: mesh_base.h:140
void max(T &r) const
Take a local variable and replace it with the maximum of it&#39;s values on all processors.
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
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.
virtual element_iterator local_elements_begin()=0
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:52
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:1596
libmesh_assert(j)
virtual element_iterator local_elements_end()=0
void libmesh_assert_valid_boundary_ids(const MeshBase &mesh)
A function for verifying that boundary condition ids match across processors.
Definition: mesh_tools.C:1194
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1592
std::vector< DirichletBoundaries * > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:1632
bool is_prepared() const
Definition: mesh_base.h:133
unsigned int n_variables() const
Definition: dof_map.h:477
UniquePtr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:1626
bool verify(const T &r, const Communicator &comm=Communicator_World)
const Parallel::Communicator & comm() const
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:1594
unsigned int mesh_dimension() const
Definition: mesh_base.C:148
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:1592
UniquePtr< PeriodicBoundaries > _periodic_boundaries
Data structure containing periodic boundaries.
Definition: dof_map.h:1612
virtual dof_id_type n_elem() const =0
UniquePtr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:534
NodeConstraints _node_constraints
Data structure containing DofObject constraints.
Definition: dof_map.h:1603
DefaultCoupling& libMesh::DofMap::default_algebraic_ghosting ( )

Default algebraic ghosting functor.

Definition at line 323 of file dof_map.h.

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

323 { return *_default_evaluating; }
UniquePtr< DefaultCoupling > _default_evaluating
The default algebraic GhostingFunctor, used to implement standard libMesh send_list construction...
Definition: dof_map.h:1500
DefaultCoupling& libMesh::DofMap::default_coupling ( )

Default coupling functor.

Definition at line 287 of file dof_map.h.

Referenced by PointNeighborCouplingTest::testCoupling().

287 { return *_default_coupling; }
UniquePtr< DefaultCoupling > _default_coupling
The default coupling GhostingFunctor, used to implement standard libMesh sparsity pattern constructio...
Definition: dof_map.h:1492
void libMesh::ReferenceCounter::disable_print_counter_info ( )
staticinherited

Definition at line 107 of file reference_counter.C.

References libMesh::ReferenceCounter::_enable_print_counter.

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

108 {
109  _enable_print_counter = false;
110  return;
111 }
static bool _enable_print_counter
Flag to control whether reference count information is printed when print_info is called...
void libMesh::DofMap::distribute_dofs ( MeshBase mesh)

Distribute dofs on the current mesh.

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

Definition at line 882 of file dof_map.C.

References _end_df, _end_old_df, _first_df, _first_old_df, _first_old_scalar_df, _first_scalar_df, _n_dfs, _n_old_dfs, _send_list, add_neighbors_to_send_list(), algebraic_ghosting_functors_begin(), algebraic_ghosting_functors_end(), libMesh::Parallel::Communicator::allgather(), libMesh::ParallelObject::comm(), coupling_functors_begin(), coupling_functors_end(), distribute_local_dofs_node_major(), distribute_local_dofs_var_major(), libMesh::DofObject::dof_number(), libMesh::GhostingFunctor::dofmap_reinit(), elem_ptr(), libMesh::MeshBase::element_ptr_range(), libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), end_dof(), libMesh::FEType::family, first_dof(), libMesh::OrderWrapper::get_order(), libMesh::DofObject::invalid_id, invalidate_dofs(), libMesh::MeshBase::is_prepared(), libMesh::libmesh_assert(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), mesh, libMesh::DofObject::n_comp(), n_dofs(), libMesh::ParallelObject::n_processors(), n_SCALAR_dofs(), n_variables(), libMesh::DofObject::n_vars(), node_ptr(), libMesh::MeshBase::node_ptr_range(), libMesh::MeshBase::nodes_begin(), libMesh::MeshBase::nodes_end(), 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(), and libMesh::EquationSystems::reinit().

883 {
884  // This function must be run on all processors at once
885  parallel_object_only();
886 
887  // Log how long it takes to distribute the degrees of freedom
888  LOG_SCOPE("distribute_dofs()", "DofMap");
889 
890  libmesh_assert (mesh.is_prepared());
891 
892  const processor_id_type proc_id = this->processor_id();
893  const processor_id_type n_proc = this->n_processors();
894 
895  // libmesh_assert_greater (this->n_variables(), 0);
896  libmesh_assert_less (proc_id, n_proc);
897 
898  // re-init in case the mesh has changed
899  this->reinit(mesh);
900 
901  // By default distribute variables in a
902  // var-major fashion, but allow run-time
903  // specification
904  bool node_major_dofs = libMesh::on_command_line ("--node_major_dofs");
905 
906  // The DOF counter, will be incremented as we encounter
907  // new degrees of freedom
908  dof_id_type next_free_dof = 0;
909 
910  // Clear the send list before we rebuild it
911  _send_list.clear();
912 
913  // Set temporary DOF indices on this processor
914  if (node_major_dofs)
915  this->distribute_local_dofs_node_major (next_free_dof, mesh);
916  else
917  this->distribute_local_dofs_var_major (next_free_dof, mesh);
918 
919  // Get DOF counts on all processors
920  std::vector<dof_id_type> dofs_on_proc(n_proc, 0);
921  this->comm().allgather(next_free_dof, dofs_on_proc);
922 
923  // Resize and fill the _first_df and _end_df arrays
924 #ifdef LIBMESH_ENABLE_AMR
927 #endif
928 
929  _first_df.resize(n_proc);
930  _end_df.resize (n_proc);
931 
932  // Get DOF offsets
933  _first_df[0] = 0;
934  for (processor_id_type i=1; i < n_proc; ++i)
935  _first_df[i] = _end_df[i-1] = _first_df[i-1] + dofs_on_proc[i-1];
936  _end_df[n_proc-1] = _first_df[n_proc-1] + dofs_on_proc[n_proc-1];
937 
938  // Clear all the current DOF indices
939  // (distribute_dofs expects them cleared!)
940  this->invalidate_dofs(mesh);
941 
942  next_free_dof = _first_df[proc_id];
943 
944  // Set permanent DOF indices on this processor
945  if (node_major_dofs)
946  this->distribute_local_dofs_node_major (next_free_dof, mesh);
947  else
948  this->distribute_local_dofs_var_major (next_free_dof, mesh);
949 
950  libmesh_assert_equal_to (next_free_dof, _end_df[proc_id]);
951 
952  //------------------------------------------------------------
953  // At this point, all n_comp and dof_number values on local
954  // DofObjects should be correct, but a DistributedMesh might have
955  // incorrect values on non-local DofObjects. Let's request the
956  // correct values from each other processor.
957 
958  if (this->n_processors() > 1)
959  {
960  this->set_nonlocal_dof_objects(mesh.nodes_begin(),
961  mesh.nodes_end(),
963 
964  this->set_nonlocal_dof_objects(mesh.elements_begin(),
965  mesh.elements_end(),
967  }
968 
969 #ifdef DEBUG
970  {
971  const unsigned int
972  sys_num = this->sys_number();
973 
974  // Processors should all agree on DoF ids for the newly numbered
975  // system.
977 
978  // DoF processor ids should match DofObject processor ids
979  for (auto & node : mesh.node_ptr_range())
980  {
981  DofObject const * const dofobj = node;
982  const processor_id_type obj_proc_id = dofobj->processor_id();
983 
984  for (unsigned int v=0; v != dofobj->n_vars(sys_num); ++v)
985  for (unsigned int c=0; c != dofobj->n_comp(sys_num,v); ++c)
986  {
987  const dof_id_type dofid = dofobj->dof_number(sys_num,v,c);
988  libmesh_assert_greater_equal (dofid, this->first_dof(obj_proc_id));
989  libmesh_assert_less (dofid, this->end_dof(obj_proc_id));
990  }
991  }
992 
993  for (auto & elem : mesh.element_ptr_range())
994  {
995  DofObject const * const dofobj = elem;
996  const processor_id_type obj_proc_id = dofobj->processor_id();
997 
998  for (unsigned int v=0; v != dofobj->n_vars(sys_num); ++v)
999  for (unsigned int c=0; c != dofobj->n_comp(sys_num,v); ++c)
1000  {
1001  const dof_id_type dofid = dofobj->dof_number(sys_num,v,c);
1002  libmesh_assert_greater_equal (dofid, this->first_dof(obj_proc_id));
1003  libmesh_assert_less (dofid, this->end_dof(obj_proc_id));
1004  }
1005  }
1006  }
1007 #endif
1008 
1009  // Set the total number of degrees of freedom, then start finding
1010  // SCALAR degrees of freedom
1011 #ifdef LIBMESH_ENABLE_AMR
1012  _n_old_dfs = _n_dfs;
1014 #endif
1015  _n_dfs = _end_df[n_proc-1];
1016  _first_scalar_df.clear();
1018  dof_id_type current_SCALAR_dof_index = n_dofs() - n_SCALAR_dofs();
1019 
1020  // Calculate and cache the initial DoF indices for SCALAR variables.
1021  // This is an O(N_vars) calculation so we want to do it once per
1022  // renumbering rather than once per SCALAR_dof_indices() call
1023 
1024  for (unsigned int v=0; v<this->n_variables(); v++)
1025  if (this->variable(v).type().family == SCALAR)
1026  {
1027  _first_scalar_df[v] = current_SCALAR_dof_index;
1028  current_SCALAR_dof_index += this->variable(v).type().order.get_order();
1029  }
1030 
1031  // Allow our GhostingFunctor objects to reinit if necessary
1032  {
1033  std::set<GhostingFunctor *>::iterator gf_it = this->algebraic_ghosting_functors_begin();
1034  const std::set<GhostingFunctor *>::iterator gf_end = this->algebraic_ghosting_functors_end();
1035  for (; gf_it != gf_end; ++gf_it)
1036  {
1037  GhostingFunctor * gf = *gf_it;
1038  libmesh_assert(gf);
1039  gf->dofmap_reinit();
1040  }
1041  }
1042 
1043  {
1044  std::set<GhostingFunctor *>::iterator gf_it = this->coupling_functors_begin();
1045  const std::set<GhostingFunctor *>::iterator gf_end = this->coupling_functors_end();
1046  for (; gf_it != gf_end; ++gf_it)
1047  {
1048  GhostingFunctor * gf = *gf_it;
1049  libmesh_assert(gf);
1050  gf->dofmap_reinit();
1051  }
1052  }
1053 
1054  // Note that in the add_neighbors_to_send_list nodes on processor
1055  // boundaries that are shared by multiple elements are added for
1056  // each element.
1058 
1059  // Here we used to clean up that data structure; now System and
1060  // EquationSystems call that for us, after we've added constraint
1061  // dependencies to the send_list too.
1062  // this->sort_send_list ();
1063 }
DofObject * elem_ptr(MeshBase &mesh, dof_id_type i) const
Definition: dof_map.C:297
FEFamily family
The type of finite element.
Definition: fe_type.h:203
int get_order() const
Explicitly request the order as an int.
Definition: fe_type.h:77
void distribute_local_dofs_node_major(dof_id_type &next_free_dof, MeshBase &mesh)
Distributes the global degrees of freedom for dofs on this processor.
Definition: dof_map.C:1145
const FEType & type() const
Definition: variable.h:119
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_begin() const
Beginning of range of algebraic ghosting functors.
Definition: dof_map.h:311
std::set< GhostingFunctor * >::const_iterator coupling_functors_begin() const
Beginning of range of coupling functors.
Definition: dof_map.h:275
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:1452
processor_id_type n_processors() const
DofObject * node_ptr(MeshBase &mesh, dof_id_type i) const
Definition: dof_map.C:290
MeshBase & mesh
uint8_t processor_id_type
Definition: id_types.h:99
std::vector< dof_id_type > _end_old_df
Last old DOF index (plus 1) on processor p.
Definition: dof_map.h:1577
OrderWrapper order
The approximation order of the element.
Definition: fe_type.h:197
void invalidate_dofs(MeshBase &mesh) const
Invalidates all active DofObject dofs for this system.
Definition: dof_map.C:788
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:1667
dof_id_type n_dofs() const
Definition: dof_map.h:510
std::vector< dof_id_type > _first_old_df
First old DOF index on processor p.
Definition: dof_map.h:1572
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:1446
libmesh_assert(j)
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:1369
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:1479
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:1583
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:305
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:324
void reinit(MeshBase &mesh)
Reinitialize the underlying data structures conformal to the current mesh.
Definition: dof_map.C:455
unsigned int sys_number() const
Definition: dof_map.h:1649
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_end() const
End of range of algebraic ghosting functors.
Definition: dof_map.h:317
dof_id_type end_dof() const
Definition: dof_map.h:580
unsigned int n_variables() const
Definition: dof_map.h:477
bool on_command_line(const std::string &arg)
Definition: libmesh.C:921
const Parallel::Communicator & comm() const
dof_id_type _n_old_dfs
Total number of degrees of freedom on old dof objects.
Definition: dof_map.h:1567
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:1440
dof_id_type n_SCALAR_dofs() const
Definition: dof_map.h:515
std::vector< dof_id_type > _first_df
First DOF index on processor p.
Definition: dof_map.h:1435
std::set< GhostingFunctor * >::const_iterator coupling_functors_end() const
End of range of coupling functors.
Definition: dof_map.h:281
void distribute_local_dofs_var_major(dof_id_type &next_free_dof, MeshBase &mesh)
Distributes the global degrees of freedom, for dofs on this processor.
Definition: dof_map.C:1281
dof_id_type first_dof() const
Definition: dof_map.h:538
uint8_t dof_id_type
Definition: id_types.h:64
processor_id_type processor_id() const
dof_id_type _n_dfs
Total number of degrees of freedom.
Definition: dof_map.h:1554
void allgather(const T &send, std::vector< T > &recv) const
Take a vector of length this->size(), and fill in recv[processor_id] = the value of send on that proc...
void libMesh::DofMap::distribute_local_dofs_node_major ( dof_id_type next_free_dof,
MeshBase mesh 
)
private

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

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

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

Definition at line 1145 of file dof_map.C.

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

Referenced by distribute_dofs().

1147 {
1148  const unsigned int sys_num = this->sys_number();
1149  const unsigned int n_var_groups = this->n_variable_groups();
1150 
1151  //-------------------------------------------------------------------------
1152  // First count and assign temporary numbers to local dofs
1153  for (auto & elem : mesh.active_local_element_ptr_range())
1154  {
1155  // Only number dofs connected to active
1156  // elements on this processor.
1157  const unsigned int n_nodes = elem->n_nodes();
1158 
1159  // First number the nodal DOFS
1160  for (unsigned int n=0; n<n_nodes; n++)
1161  {
1162  Node & node = elem->node_ref(n);
1163 
1164  for (unsigned vg=0; vg<n_var_groups; vg++)
1165  {
1166  const VariableGroup & vg_description(this->variable_group(vg));
1167 
1168  if ((vg_description.type().family != SCALAR) &&
1169  (vg_description.active_on_subdomain(elem->subdomain_id())))
1170  {
1171  // assign dof numbers (all at once) if this is
1172  // our node and if they aren't already there
1173  if ((node.n_comp_group(sys_num,vg) > 0) &&
1174  (node.processor_id() == this->processor_id()) &&
1175  (node.vg_dof_base(sys_num,vg) ==
1177  {
1178  node.set_vg_dof_base(sys_num, vg,
1179  next_free_dof);
1180  next_free_dof += (vg_description.n_variables()*
1181  node.n_comp_group(sys_num,vg));
1182  //node.debug_buffer();
1183  }
1184  }
1185  }
1186  }
1187 
1188  // Now number the element DOFS
1189  for (unsigned vg=0; vg<n_var_groups; vg++)
1190  {
1191  const VariableGroup & vg_description(this->variable_group(vg));
1192 
1193  if ((vg_description.type().family != SCALAR) &&
1194  (vg_description.active_on_subdomain(elem->subdomain_id())))
1195  if (elem->n_comp_group(sys_num,vg) > 0)
1196  {
1197  libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1199 
1200  elem->set_vg_dof_base(sys_num,
1201  vg,
1202  next_free_dof);
1203 
1204  next_free_dof += (vg_description.n_variables()*
1205  elem->n_comp(sys_num,vg));
1206  }
1207  }
1208  } // done looping over elements
1209 
1210 
1211  // we may have missed assigning DOFs to nodes that we own
1212  // but to which we have no connected elements matching our
1213  // variable restriction criterion. this will happen, for example,
1214  // if variable V is restricted to subdomain S. We may not own
1215  // any elements which live in S, but we may own nodes which are
1216  // *connected* to elements which do. in this scenario these nodes
1217  // will presently have unnumbered DOFs. we need to take care of
1218  // them here since we own them and no other processor will touch them.
1219  for (auto & node : mesh.local_node_ptr_range())
1220  for (unsigned vg=0; vg<n_var_groups; vg++)
1221  {
1222  const VariableGroup & vg_description(this->variable_group(vg));
1223 
1224  if (node->n_comp_group(sys_num,vg))
1225  if (node->vg_dof_base(sys_num,vg) == DofObject::invalid_id)
1226  {
1227  node->set_vg_dof_base (sys_num,
1228  vg,
1229  next_free_dof);
1230 
1231  next_free_dof += (vg_description.n_variables()*
1232  node->n_comp(sys_num,vg));
1233  }
1234  }
1235 
1236  // Finally, count up the SCALAR dofs
1237  this->_n_SCALAR_dofs = 0;
1238  for (unsigned vg=0; vg<n_var_groups; vg++)
1239  {
1240  const VariableGroup & vg_description(this->variable_group(vg));
1241 
1242  if (vg_description.type().family == SCALAR)
1243  {
1244  this->_n_SCALAR_dofs += (vg_description.n_variables()*
1245  vg_description.type().order.get_order());
1246  continue;
1247  }
1248  }
1249 
1250  // Only increment next_free_dof if we're on the processor
1251  // that holds this SCALAR variable
1252  if (this->processor_id() == (this->n_processors()-1))
1253  next_free_dof += _n_SCALAR_dofs;
1254 
1255 #ifdef DEBUG
1256  {
1257  // libMesh::out << "next_free_dof=" << next_free_dof << std::endl
1258  // << "_n_SCALAR_dofs=" << _n_SCALAR_dofs << std::endl;
1259 
1260  // Make sure we didn't miss any nodes
1261  MeshTools::libmesh_assert_valid_procids<Node>(mesh);
1262 
1263  for (auto & node : mesh.local_node_ptr_range())
1264  {
1265  unsigned int n_var_g = node->n_var_groups(this->sys_number());
1266  for (unsigned int vg=0; vg != n_var_g; ++vg)
1267  {
1268  unsigned int n_comp_g =
1269  node->n_comp_group(this->sys_number(), vg);
1270  dof_id_type my_first_dof = n_comp_g ?
1271  node->vg_dof_base(this->sys_number(), vg) : 0;
1272  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
1273  }
1274  }
1275  }
1276 #endif // DEBUG
1277 }
processor_id_type n_processors() const
MeshBase & mesh
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:1657
const dof_id_type n_nodes
Definition: tecplot_io.C:67
dof_id_type _n_SCALAR_dofs
The total number of SCALAR dofs associated to all SCALAR variables.
Definition: dof_map.h:1560
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:324
unsigned int n_variable_groups() const
Definition: dof_map.h:469
unsigned int sys_number() const
Definition: dof_map.h:1649
uint8_t dof_id_type
Definition: id_types.h:64
processor_id_type processor_id() const
void libMesh::DofMap::distribute_local_dofs_var_major ( dof_id_type next_free_dof,
MeshBase mesh 
)
private

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

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

Definition at line 1281 of file dof_map.C.

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

Referenced by distribute_dofs().

1283 {
1284  const unsigned int sys_num = this->sys_number();
1285  const unsigned int n_var_groups = this->n_variable_groups();
1286 
1287  //-------------------------------------------------------------------------
1288  // First count and assign temporary numbers to local dofs
1289  for (unsigned vg=0; vg<n_var_groups; vg++)
1290  {
1291  const VariableGroup & vg_description(this->variable_group(vg));
1292 
1293  const unsigned int n_vars_in_group = vg_description.n_variables();
1294 
1295  // Skip the SCALAR dofs
1296  if (vg_description.type().family == SCALAR)
1297  continue;
1298 
1299  for (auto & elem : mesh.active_local_element_ptr_range())
1300  {
1301  // Only number dofs connected to active elements on this
1302  // processor and only variables which are active on on this
1303  // element's subdomain.
1304  if (!vg_description.active_on_subdomain(elem->subdomain_id()))
1305  continue;
1306 
1307  const unsigned int n_nodes = elem->n_nodes();
1308 
1309  // First number the nodal DOFS
1310  for (unsigned int n=0; n<n_nodes; n++)
1311  {
1312  Node & node = elem->node_ref(n);
1313 
1314  // assign dof numbers (all at once) if this is
1315  // our node and if they aren't already there
1316  if ((node.n_comp_group(sys_num,vg) > 0) &&
1317  (node.processor_id() == this->processor_id()) &&
1318  (node.vg_dof_base(sys_num,vg) ==
1320  {
1321  node.set_vg_dof_base(sys_num, vg, next_free_dof);
1322 
1323  next_free_dof += (n_vars_in_group*
1324  node.n_comp_group(sys_num,vg));
1325  }
1326  }
1327 
1328  // Now number the element DOFS
1329  if (elem->n_comp_group(sys_num,vg) > 0)
1330  {
1331  libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1333 
1334  elem->set_vg_dof_base(sys_num,
1335  vg,
1336  next_free_dof);
1337 
1338  next_free_dof += (n_vars_in_group*
1339  elem->n_comp_group(sys_num,vg));
1340  }
1341  } // end loop on elements
1342 
1343  // we may have missed assigning DOFs to nodes that we own
1344  // but to which we have no connected elements matching our
1345  // variable restriction criterion. this will happen, for example,
1346  // if variable V is restricted to subdomain S. We may not own
1347  // any elements which live in S, but we may own nodes which are
1348  // *connected* to elements which do. in this scenario these nodes
1349  // will presently have unnumbered DOFs. we need to take care of
1350  // them here since we own them and no other processor will touch them.
1351  for (auto & node : mesh.local_node_ptr_range())
1352  if (node->n_comp_group(sys_num,vg))
1353  if (node->vg_dof_base(sys_num,vg) == DofObject::invalid_id)
1354  {
1355  node->set_vg_dof_base (sys_num,
1356  vg,
1357  next_free_dof);
1358 
1359  next_free_dof += (n_vars_in_group*
1360  node->n_comp_group(sys_num,vg));
1361  }
1362  } // end loop on variable groups
1363 
1364  // Finally, count up the SCALAR dofs
1365  this->_n_SCALAR_dofs = 0;
1366  for (unsigned vg=0; vg<n_var_groups; vg++)
1367  {
1368  const VariableGroup & vg_description(this->variable_group(vg));
1369 
1370  if (vg_description.type().family == SCALAR)
1371  {
1372  this->_n_SCALAR_dofs += (vg_description.n_variables()*
1373  vg_description.type().order.get_order());
1374  continue;
1375  }
1376  }
1377 
1378  // Only increment next_free_dof if we're on the processor
1379  // that holds this SCALAR variable
1380  if (this->processor_id() == (this->n_processors()-1))
1381  next_free_dof += _n_SCALAR_dofs;
1382 
1383 #ifdef DEBUG
1384  {
1385  // Make sure we didn't miss any nodes
1386  MeshTools::libmesh_assert_valid_procids<Node>(mesh);
1387 
1388  for (auto & node : mesh.local_node_ptr_range())
1389  {
1390  unsigned int n_var_g = node->n_var_groups(this->sys_number());
1391  for (unsigned int vg=0; vg != n_var_g; ++vg)
1392  {
1393  unsigned int n_comp_g =
1394  node->n_comp_group(this->sys_number(), vg);
1395  dof_id_type my_first_dof = n_comp_g ?
1396  node->vg_dof_base(this->sys_number(), vg) : 0;
1397  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
1398  }
1399  }
1400  }
1401 #endif // DEBUG
1402 }
processor_id_type n_processors() const
MeshBase & mesh
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:1657
const dof_id_type n_nodes
Definition: tecplot_io.C:67
dof_id_type _n_SCALAR_dofs
The total number of SCALAR dofs associated to all SCALAR variables.
Definition: dof_map.h:1560
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:324
unsigned int n_variable_groups() const
Definition: dof_map.h:469
unsigned int sys_number() const
Definition: dof_map.h:1649
uint8_t dof_id_type
Definition: id_types.h:64
processor_id_type processor_id() const
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 1917 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::libmesh_assert(), n_nodes, libMesh::Elem::n_nodes(), n_variables(), n_vars, 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().

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

1919 {
1920  // We now allow elem==NULL to request just SCALAR dofs
1921  // libmesh_assert(elem);
1922 
1923  // If we are asking for current indices on an element, it ought to
1924  // be an active element (or a Side proxy, which also thinks it's
1925  // active)
1926  libmesh_assert(!elem || elem->active());
1927 
1928  LOG_SCOPE("dof_indices()", "DofMap");
1929 
1930  // Clear the DOF indices vector
1931  di.clear();
1932 
1933  const unsigned int n_vars = this->n_variables();
1934 
1935 #ifdef DEBUG
1936  // Check that sizes match in DEBUG mode
1937  std::size_t tot_size = 0;
1938 #endif
1939 
1940  if (elem && elem->type() == TRI3SUBDIVISION)
1941  {
1942  // Subdivision surface FE require the 1-ring around elem
1943  const Tri3Subdivision * sd_elem = static_cast<const Tri3Subdivision *>(elem);
1944 
1945  // Ghost subdivision elements have no real dofs
1946  if (!sd_elem->is_ghost())
1947  {
1948  // Determine the nodes contributing to element elem
1949  std::vector<const Node *> elem_nodes;
1950  MeshTools::Subdivision::find_one_ring(sd_elem, elem_nodes);
1951 
1952  // Get the dof numbers
1953  for (unsigned int v=0; v<n_vars; v++)
1954  {
1955  const Variable & var = this->variable(v);
1956  if (var.type().family == SCALAR &&
1957  var.active_on_subdomain(elem->subdomain_id()))
1958  {
1959 #ifdef DEBUG
1960  tot_size += this->variable(v).type().order;
1961 #endif
1962  std::vector<dof_id_type> di_new;
1963  this->SCALAR_dof_indices(di_new,v);
1964  di.insert( di.end(), di_new.begin(), di_new.end());
1965  }
1966  else
1967  _dof_indices(*elem, elem->p_level(), di, v,
1968  &elem_nodes[0], elem_nodes.size()
1969 #ifdef DEBUG
1970  , tot_size
1971 #endif
1972  );
1973  }
1974  }
1975 
1976  return;
1977  }
1978 
1979  // Get the dof numbers for each variable
1980  const unsigned int n_nodes = elem ? elem->n_nodes() : 0;
1981  for (unsigned int v=0; v<n_vars; v++)
1982  {
1983  const Variable & var = this->variable(v);
1984  if (var.type().family == SCALAR &&
1985  (!elem ||
1986  var.active_on_subdomain(elem->subdomain_id())))
1987  {
1988 #ifdef DEBUG
1989  tot_size += var.type().order;
1990 #endif
1991  std::vector<dof_id_type> di_new;
1992  this->SCALAR_dof_indices(di_new,v);
1993  di.insert( di.end(), di_new.begin(), di_new.end());
1994  }
1995  else if (elem)
1996  _dof_indices(*elem, elem->p_level(), di, v, elem->get_nodes(),
1997  n_nodes
1998 #ifdef DEBUG
1999  , tot_size
2000 #endif
2001  );
2002  }
2003 
2004 #ifdef DEBUG
2005  libmesh_assert_equal_to (tot_size, di.size());
2006 #endif
2007 }
const FEType & type() const
Definition: variable.h:119
OrderWrapper order
The approximation order of the element.
Definition: fe_type.h:197
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:1667
const unsigned int n_vars
Definition: tecplot_io.C:68
libmesh_assert(j)
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 v, const Node *const *nodes, unsigned int n_nodes#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:2164
unsigned int n_variables() const
Definition: dof_map.h:477
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:2288
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.
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 2010 of file dof_map.C.

References _dof_indices(), libMesh::Variable::active_on_subdomain(), libMesh::FEType::family, libMesh::MeshTools::Subdivision::find_one_ring(), libMesh::Elem::get_nodes(), libMesh::Elem::n_nodes(), 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().

2014 {
2015  // We now allow elem==NULL to request just SCALAR dofs
2016  // libmesh_assert(elem);
2017 
2018  LOG_SCOPE("dof_indices()", "DofMap");
2019 
2020  // Clear the DOF indices vector
2021  di.clear();
2022 
2023  // Use the default p refinement level?
2024  if (p_level == -12345)
2025  p_level = elem ? elem->p_level() : 0;
2026 
2027 #ifdef DEBUG
2028  // Check that sizes match in DEBUG mode
2029  std::size_t tot_size = 0;
2030 #endif
2031 
2032  if (elem && elem->type() == TRI3SUBDIVISION)
2033  {
2034  // Subdivision surface FE require the 1-ring around elem
2035  const Tri3Subdivision * sd_elem = static_cast<const Tri3Subdivision *>(elem);
2036 
2037  // Ghost subdivision elements have no real dofs
2038  if (!sd_elem->is_ghost())
2039  {
2040  // Determine the nodes contributing to element elem
2041  std::vector<const Node *> elem_nodes;
2042  MeshTools::Subdivision::find_one_ring(sd_elem, elem_nodes);
2043 
2044  _dof_indices(*elem, p_level, di, vn, &elem_nodes[0],
2045  elem_nodes.size()
2046 #ifdef DEBUG
2047  , tot_size
2048 #endif
2049  );
2050  }
2051 
2052  return;
2053  }
2054 
2055  const Variable & var = this->variable(vn);
2056 
2057  // Get the dof numbers
2058  if (var.type().family == SCALAR &&
2059  (!elem ||
2060  var.active_on_subdomain(elem->subdomain_id())))
2061  {
2062 #ifdef DEBUG
2063  tot_size += var.type().order;
2064 #endif
2065  std::vector<dof_id_type> di_new;
2066  this->SCALAR_dof_indices(di_new,vn);
2067  di.insert( di.end(), di_new.begin(), di_new.end());
2068  }
2069  else if (elem)
2070  _dof_indices(*elem, p_level, di, vn, elem->get_nodes(),
2071  elem->n_nodes()
2072 #ifdef DEBUG
2073  , tot_size
2074 #endif
2075  );
2076 
2077 #ifdef DEBUG
2078  libmesh_assert_equal_to (tot_size, di.size());
2079 #endif
2080 }
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:1667
void _dof_indices(const Elem &elem, int p_level, std::vector< dof_id_type > &di, const unsigned int v, const Node *const *nodes, unsigned int n_nodes#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:2164
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:2288
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.
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 2083 of file dof_map.C.

References libMesh::DofObject::dof_number(), libMesh::FEType::family, libMesh::DofObject::invalid_id, libMesh::DofObject::n_comp(), n_variables(), n_vars, libMesh::SCALAR, SCALAR_dof_indices(), sys_number(), libMesh::Variable::type(), and variable().

2085 {
2086  // We allow node==NULL to request just SCALAR dofs
2087  // libmesh_assert(elem);
2088 
2089  LOG_SCOPE("dof_indices(Node)", "DofMap");
2090 
2091  // Clear the DOF indices vector
2092  di.clear();
2093 
2094  const unsigned int n_vars = this->n_variables();
2095  const unsigned int sys_num = this->sys_number();
2096 
2097  // Get the dof numbers
2098  for (unsigned int v=0; v<n_vars; v++)
2099  {
2100  const Variable & var = this->variable(v);
2101  if (var.type().family == SCALAR)
2102  {
2103  std::vector<dof_id_type> di_new;
2104  this->SCALAR_dof_indices(di_new,v);
2105  di.insert( di.end(), di_new.begin(), di_new.end());
2106  }
2107  else
2108  {
2109  const int n_comp = node->n_comp(sys_num,v);
2110  for (int i=0; i != n_comp; ++i)
2111  {
2112  libmesh_assert_not_equal_to
2113  (node->dof_number(sys_num,v,i),
2115  di.push_back(node->dof_number(sys_num,v,i));
2116  }
2117  }
2118  }
2119 }
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:1667
const unsigned int n_vars
Definition: tecplot_io.C:68
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:324
unsigned int sys_number() const
Definition: dof_map.h:1649
unsigned int n_variables() const
Definition: dof_map.h:477
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:2288
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 2122 of file dof_map.C.

References dof_indices(), libMesh::DofObject::dof_number(), libMesh::FEType::family, libMesh::DofObject::invalid_id, libMesh::invalid_uint, libMesh::DofObject::n_comp(), libMesh::SCALAR, SCALAR_dof_indices(), sys_number(), libMesh::Variable::type(), and variable().

2125 {
2126  if (vn == libMesh::invalid_uint)
2127  {
2128  this->dof_indices(node, di);
2129  return;
2130  }
2131 
2132  // We allow node==NULL to request just SCALAR dofs
2133  // libmesh_assert(elem);
2134 
2135  LOG_SCOPE("dof_indices(Node)", "DofMap");
2136 
2137  // Clear the DOF indices vector
2138  di.clear();
2139 
2140  const unsigned int sys_num = this->sys_number();
2141 
2142  // Get the dof numbers
2143  const Variable & var = this->variable(vn);
2144  if (var.type().family == SCALAR)
2145  {
2146  std::vector<dof_id_type> di_new;
2147  this->SCALAR_dof_indices(di_new,vn);
2148  di.insert( di.end(), di_new.begin(), di_new.end());
2149  }
2150  else
2151  {
2152  const int n_comp = node->n_comp(sys_num,vn);
2153  for (int i=0; i != n_comp; ++i)
2154  {
2155  libmesh_assert_not_equal_to
2156  (node->dof_number(sys_num,vn,i),
2158  di.push_back(node->dof_number(sys_num,vn,i));
2159  }
2160  }
2161 }
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value.
Definition: libmesh.h:184
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:1667
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:324
unsigned int sys_number() const
Definition: dof_map.h:1649
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:2288
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:1917
processor_id_type libMesh::DofMap::dof_owner ( const dof_id_type  dof) const
Returns
The processor id that owns the dof index dof

Definition at line 586 of file dof_map.h.

References libMesh::libmesh_assert().

Referenced by DofMapTest::testDofOwner().

587  { std::vector<dof_id_type>::const_iterator ub =
588  std::upper_bound(_end_df.begin(), _end_df.end(), dof);
589  libmesh_assert (ub != _end_df.end());
590  return (ub - _end_df.begin());
591  }
libmesh_assert(j)
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:1440
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 297 of file dof_map.C.

References libMesh::MeshBase::elem_ptr().

Referenced by distribute_dofs().

298 {
299  return mesh.elem_ptr(i);
300 }
MeshBase & mesh
void libMesh::ReferenceCounter::enable_print_counter_info ( )
staticinherited

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

Definition at line 101 of file reference_counter.C.

References libMesh::ReferenceCounter::_enable_print_counter.

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

102 {
103  _enable_print_counter = true;
104  return;
105 }
static bool _enable_print_counter
Flag to control whether reference count information is printed when print_info is called...
dof_id_type libMesh::DofMap::end_dof ( const processor_id_type  proc) const
dof_id_type libMesh::DofMap::end_dof ( ) const

Definition at line 580 of file dof_map.h.

References libMesh::processor_id().

Referenced by add_neighbors_to_send_list(), distribute_dofs(), get_info(), local_variable_indices(), and semilocal_index().

581  { return this->end_dof(this->processor_id()); }
dof_id_type end_dof() const
Definition: dof_map.h:580
processor_id_type processor_id() const
dof_id_type libMesh::DofMap::end_old_dof ( const processor_id_type  proc) const
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 600 of file dof_map.h.

Referenced by libMesh::BuildProjectionList::operator()().

601  { 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:1577
dof_id_type libMesh::DofMap::end_old_dof ( ) const

Definition at line 603 of file dof_map.h.

References libMesh::MeshTools::Generation::Private::idx(), libMesh::invalid_uint, and libMesh::processor_id().

604  { return this->end_old_dof(this->processor_id()); }
dof_id_type end_old_dof() const
Definition: dof_map.h:603
processor_id_type processor_id() const
void libMesh::DofMap::enforce_adjoint_constraints_exactly ( NumericVector< Number > &  v,
unsigned int  q 
) const

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

For homogeneous constraints, use enforce_constraints_exactly instead

Definition at line 1820 of file dof_map.h.

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

1821  {}
void libMesh::DofMap::enforce_constraints_exactly ( const System system,
NumericVector< Number > *  v = libmesh_nullptr,
bool  homogeneous = false 
) const

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 == libmesh_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 1816 of file dof_map.h.

Referenced by libMesh::__libmesh_petsc_diff_solver_residual(), libMesh::__libmesh_petsc_snes_postcheck(), libMesh::Problem_Interface::computeF(), libMesh::Problem_Interface::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), constrain_nothing(), DMlibMeshFunction(), DMlibMeshJacobian(), libMesh::ImplicitSystem::sensitivity_solve(), libMesh::NewtonSolver::solve(), libMesh::PetscDiffSolver::solve(), libMesh::PetscNonlinearSolver< T >::solve(), libMesh::ImplicitSystem::weighted_sensitivity_adjoint_solve(), and libMesh::ImplicitSystem::weighted_sensitivity_solve().

1818  {}
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 1831 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().

1834 {
1835 #ifdef LIBMESH_ENABLE_AMR
1836 
1837  // Trivial mapping
1838  libmesh_assert_equal_to (dof_indices_in.size(), Ue.size());
1839  bool has_constrained_dofs = false;
1840 
1841  for (unsigned int il=0;
1842  il != cast_int<unsigned int>(dof_indices_in.size()); il++)
1843  {
1844  const dof_id_type ig = dof_indices_in[il];
1845 
1846  if (this->is_constrained_dof (ig)) has_constrained_dofs = true;
1847 
1848  libmesh_assert_less (ig, Ug.size());
1849 
1850  Ue.el(il) = Ug(ig);
1851  }
1852 
1853  // If the element has any constrained DOFs then we need
1854  // to account for them in the mapping. This will handle
1855  // the case that the input vector is not constrained.
1856  if (has_constrained_dofs)
1857  {
1858  // Copy the input DOF indices.
1859  std::vector<dof_id_type> constrained_dof_indices(dof_indices_in);
1860 
1861  DenseMatrix<Number> C;
1862  DenseVector<Number> H;
1863 
1864  this->build_constraint_matrix_and_vector (C, H, constrained_dof_indices);
1865 
1866  libmesh_assert_equal_to (dof_indices_in.size(), C.m());
1867  libmesh_assert_equal_to (constrained_dof_indices.size(), C.n());
1868 
1869  // zero-out Ue
1870  Ue.zero();
1871 
1872  // compute Ue = C Ug, with proper mapping.
1873  const unsigned int n_original_dofs =
1874  cast_int<unsigned int>(dof_indices_in.size());
1875  for (unsigned int i=0; i != n_original_dofs; i++)
1876  {
1877  Ue.el(i) = H(i);
1878 
1879  const unsigned int n_constrained =
1880  cast_int<unsigned int>(constrained_dof_indices.size());
1881  for (unsigned int j=0; j<n_constrained; j++)
1882  {
1883  const dof_id_type jg = constrained_dof_indices[j];
1884 
1885  // If Ug is a serial or ghosted vector, then this assert is
1886  // overzealous. If Ug is a parallel vector, then this assert
1887  // is redundant.
1888  // libmesh_assert ((jg >= Ug.first_local_index()) &&
1889  // (jg < Ug.last_local_index()));
1890 
1891  Ue.el(i) += C(i,j)*Ug(jg);
1892  }
1893  }
1894  }
1895 
1896 #else
1897 
1898  // Trivial mapping
1899 
1900  const unsigned int n_original_dofs =
1901  cast_int<unsigned int>(dof_indices_in.size());
1902 
1903  libmesh_assert_equal_to (n_original_dofs, Ue.size());
1904 
1905  for (unsigned int il=0; il<n_original_dofs; il++)
1906  {
1907  const dof_id_type ig = dof_indices_in[il];
1908 
1909  libmesh_assert ((ig >= Ug.first_local_index()) && (ig < Ug.last_local_index()));
1910 
1911  Ue.el(il) = Ug(ig);
1912  }
1913 
1914 #endif
1915 }
virtual numeric_index_type size() const =0
virtual numeric_index_type last_local_index() const =0
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 ...
libmesh_assert(j)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1734
virtual numeric_index_type first_local_index() const =0
uint8_t dof_id_type
Definition: id_types.h:64
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.

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

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

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

2562 {
2563  typedef std::set<dof_id_type> RCSet;
2564 
2565  // First insert the DOFS we already depend on into the set.
2566  RCSet dof_set (elem_dofs.begin(), elem_dofs.end());
2567 
2568  bool done = true;
2569 
2570  // Next insert any dofs those might be constrained in terms
2571  // of. Note that in this case we may not be done: Those may
2572  // in turn depend on others. So, we need to repeat this process
2573  // in that case until the system depends only on unconstrained
2574  // degrees of freedom.
2575  for (std::size_t i=0; i<elem_dofs.size(); i++)
2576  if (this->is_constrained_dof(elem_dofs[i]))
2577  {
2578  // If the DOF is constrained
2579  DofConstraints::const_iterator
2580  pos = _dof_constraints.find(elem_dofs[i]);
2581 
2582  libmesh_assert (pos != _dof_constraints.end());
2583 
2584  const DofConstraintRow & constraint_row = pos->second;
2585 
2586  // adaptive p refinement currently gives us lots of empty constraint
2587  // rows - we should optimize those DoFs away in the future. [RHS]
2588  //libmesh_assert (!constraint_row.empty());
2589 
2590  DofConstraintRow::const_iterator it = constraint_row.begin();
2591  DofConstraintRow::const_iterator it_end = constraint_row.end();
2592 
2593 
2594  // Add the DOFs this dof is constrained in terms of.
2595  // note that these dofs might also be constrained, so
2596  // we will need to call this function recursively.
2597  for ( ; it != it_end; ++it)
2598  if (!dof_set.count (it->first))
2599  {
2600  dof_set.insert (it->first);
2601  done = false;
2602  }
2603  }
2604 
2605 
2606  // If not done then we need to do more work
2607  // (obviously :-) )!
2608  if (!done)
2609  {
2610  // Fill the vector with the contents of the set
2611  elem_dofs.clear();
2612  elem_dofs.insert (elem_dofs.end(),
2613  dof_set.begin(), dof_set.end());
2614 
2615 
2616  // May need to do this recursively. It is possible
2617  // that we just replaced a constrained DOF with another
2618  // constrained DOF.
2619  this->find_connected_dofs (elem_dofs);
2620 
2621  } // end if (!done)
2622 }
libmesh_assert(j)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1734
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1592
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:88
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:2561
dof_id_type libMesh::DofMap::first_dof ( const processor_id_type  proc) const
dof_id_type libMesh::DofMap::first_dof ( ) const

Definition at line 538 of file dof_map.h.

References libMesh::processor_id().

Referenced by add_neighbors_to_send_list(), distribute_dofs(), get_info(), local_variable_indices(), and semilocal_index().

539  { return this->first_dof(this->processor_id()); }
dof_id_type first_dof() const
Definition: dof_map.h:538
processor_id_type processor_id() const
dof_id_type libMesh::DofMap::first_old_dof ( const processor_id_type  proc) const
Returns
The first old dof index that is local to partition proc.

Definition at line 545 of file dof_map.h.

Referenced by libMesh::BuildProjectionList::operator()().

546  { 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:1572
dof_id_type libMesh::DofMap::first_old_dof ( ) const

Definition at line 548 of file dof_map.h.

References libMesh::processor_id().

549  { return this->first_old_dof(this->processor_id()); }
dof_id_type first_old_dof() const
Definition: dof_map.h:548
processor_id_type processor_id() const
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 3688 of file dof_map_constraints.C.

References libMesh::libmesh_assert(), libMesh::libmesh_isnan(), libMesh::n_processors(), and libMesh::processor_id().

3691 {
3692  typedef std::set<dof_id_type> DoF_RCSet;
3693 
3694  // If we have heterogenous adjoint constraints we need to
3695  // communicate those too.
3696  const unsigned int max_qoi_num =
3697  _adjoint_constraint_values.empty() ?
3698  0 : _adjoint_constraint_values.rbegin()->first;
3699 
3700  // We have to keep recursing while the unexpanded set is
3701  // nonempty on *any* processor
3702  bool unexpanded_set_nonempty = !unexpanded_dofs.empty();
3703  this->comm().max(unexpanded_set_nonempty);
3704 
3705  while (unexpanded_set_nonempty)
3706  {
3707  // Let's make sure we don't lose sync in this loop.
3708  parallel_object_only();
3709 
3710  // Request sets
3711  DoF_RCSet dof_request_set;
3712 
3713  // Request sets to send to each processor
3714  std::vector<std::vector<dof_id_type>>
3715  requested_dof_ids(this->n_processors());
3716 
3717  // And the sizes of each
3718  std::vector<dof_id_type>
3719  dof_ids_on_proc(this->n_processors(), 0);
3720 
3721  // Fill (and thereby sort and uniq!) the main request sets
3722  for (DoF_RCSet::iterator i = unexpanded_dofs.begin();
3723  i != unexpanded_dofs.end(); ++i)
3724  {
3725  const dof_id_type unexpanded_dof = *i;
3726  DofConstraints::const_iterator
3727  pos = _dof_constraints.find(unexpanded_dof);
3728 
3729  // If we were asked for a DoF and we don't already have a
3730  // constraint for it, then we need to check for one.
3731  if (pos == _dof_constraints.end())
3732  {
3733  if (((unexpanded_dof < this->first_dof()) ||
3734  (unexpanded_dof >= this->end_dof())) &&
3735  !_dof_constraints.count(unexpanded_dof))
3736  dof_request_set.insert(unexpanded_dof);
3737  }
3738  // If we were asked for a DoF and we already have a
3739  // constraint for it, then we need to check if the
3740  // constraint is recursive.
3741  else
3742  {
3743  const DofConstraintRow & row = pos->second;
3744  for (DofConstraintRow::const_iterator j = row.begin();
3745  j != row.end(); ++j)
3746  {
3747  const dof_id_type constraining_dof = j->first;
3748 
3749  // If it's non-local and we haven't already got a
3750  // constraint for it, we might need to ask for one
3751  if (((constraining_dof < this->first_dof()) ||
3752  (constraining_dof >= this->end_dof())) &&
3753  !_dof_constraints.count(constraining_dof))
3754  dof_request_set.insert(constraining_dof);
3755  }
3756  }
3757  }
3758 
3759  // Clear the unexpanded constraint set; we're about to expand it
3760  unexpanded_dofs.clear();
3761 
3762  // Count requests by processor
3763  processor_id_type proc_id = 0;
3764  for (DoF_RCSet::iterator i = dof_request_set.begin();
3765  i != dof_request_set.end(); ++i)
3766  {
3767  while (*i >= _end_df[proc_id])
3768  proc_id++;
3769  dof_ids_on_proc[proc_id]++;
3770  }
3771 
3772  for (processor_id_type p = 0; p != this->n_processors(); ++p)
3773  {
3774  requested_dof_ids[p].reserve(dof_ids_on_proc[p]);
3775  }
3776 
3777  // Prepare each processor's request set
3778  proc_id = 0;
3779  for (DoF_RCSet::iterator i = dof_request_set.begin();
3780  i != dof_request_set.end(); ++i)
3781  {
3782  while (*i >= _end_df[proc_id])
3783  proc_id++;
3784  requested_dof_ids[proc_id].push_back(*i);
3785  }
3786 
3787  // Now request constraint rows from other processors
3788  for (processor_id_type p=1; p != this->n_processors(); ++p)
3789  {
3790  // Trade my requests with processor procup and procdown
3791  processor_id_type procup =
3792  cast_int<processor_id_type>((this->processor_id() + p) %
3793  this->n_processors());
3794  processor_id_type procdown =
3795  cast_int<processor_id_type>((this->n_processors() +
3796  this->processor_id() - p) %
3797  this->n_processors());
3798  std::vector<dof_id_type> dof_request_to_fill;
3799 
3800  this->comm().send_receive(procup, requested_dof_ids[procup],
3801  procdown, dof_request_to_fill);
3802 
3803  // Fill those requests
3804  std::vector<std::vector<dof_id_type>> dof_row_keys(dof_request_to_fill.size());
3805 
3806  std::vector<std::vector<Real>> dof_row_vals(dof_request_to_fill.size());
3807  std::vector<Number> dof_row_rhss(dof_request_to_fill.size());
3808  std::vector<std::vector<Number>>
3809  dof_adj_rhss(max_qoi_num,
3810  std::vector<Number>(dof_request_to_fill.size()));
3811  for (std::size_t i=0; i != dof_request_to_fill.size(); ++i)
3812  {
3813  dof_id_type constrained = dof_request_to_fill[i];
3814  if (_dof_constraints.count(constrained))
3815  {
3816  DofConstraintRow & row = _dof_constraints[constrained];
3817  std::size_t row_size = row.size();
3818  dof_row_keys[i].reserve(row_size);
3819  dof_row_vals[i].reserve(row_size);
3820  for (DofConstraintRow::iterator j = row.begin();
3821  j != row.end(); ++j)
3822  {
3823  dof_row_keys[i].push_back(j->first);
3824  dof_row_vals[i].push_back(j->second);
3825 
3826  // We should never have a 0 constraint
3827  // coefficient; that's implicit via sparse
3828  // constraint storage
3829  libmesh_assert(j->second);
3830  }
3831  DofConstraintValueMap::const_iterator rhsit =
3832  _primal_constraint_values.find(constrained);
3833  dof_row_rhss[i] = (rhsit == _primal_constraint_values.end()) ?
3834  0 : rhsit->second;
3835 
3836  for (unsigned int q = 0; q != max_qoi_num; ++q)
3837  {
3838  AdjointDofConstraintValues::const_iterator adjoint_map_it =
3840 
3841  if (adjoint_map_it == _adjoint_constraint_values.end())
3842  continue;
3843 
3844  const DofConstraintValueMap & constraint_map =
3845  adjoint_map_it->second;
3846 
3847  DofConstraintValueMap::const_iterator rhsit =
3848  constraint_map.find(constrained);
3849  dof_adj_rhss[q][i] = (rhsit == constraint_map.end()) ?
3850  0 : rhsit->second;
3851  }
3852  }
3853  else
3854  {
3855  // Get NaN from Real, where it should exist, not
3856  // from Number, which may be std::complex, in which
3857  // case quiet_NaN() silently returns zero, rather
3858  // than sanely returning NaN or throwing an
3859  // exception or sending Stroustrup hate mail.
3860  dof_row_rhss[i] =
3861  std::numeric_limits<Real>::quiet_NaN();
3862 
3863  // Make sure we don't get caught by "!isnan(NaN)"
3864  // bugs again.
3865  libmesh_assert(libmesh_isnan(dof_row_rhss[i]));
3866  }
3867  }
3868 
3869  // Trade back the results
3870  std::vector<std::vector<dof_id_type>> dof_filled_keys;
3871  std::vector<std::vector<Real>> dof_filled_vals;
3872  std::vector<Number> dof_filled_rhss;
3873  std::vector<std::vector<Number>> adj_filled_rhss;
3874  this->comm().send_receive(procdown, dof_row_keys,
3875  procup, dof_filled_keys);
3876  this->comm().send_receive(procdown, dof_row_vals,
3877  procup, dof_filled_vals);
3878  this->comm().send_receive(procdown, dof_row_rhss,
3879  procup, dof_filled_rhss);
3880  this->comm().send_receive(procdown, dof_adj_rhss,
3881  procup, adj_filled_rhss);
3882 
3883  libmesh_assert_equal_to (dof_filled_keys.size(), requested_dof_ids[procup].size());
3884  libmesh_assert_equal_to (dof_filled_vals.size(), requested_dof_ids[procup].size());
3885  libmesh_assert_equal_to (dof_filled_rhss.size(), requested_dof_ids[procup].size());
3886 #ifndef NDEBUG
3887  for (std::size_t q=0; q != adj_filled_rhss.size(); ++q)
3888  libmesh_assert_equal_to (adj_filled_rhss[q].size(), requested_dof_ids[procup].size());
3889 #endif
3890 
3891  // Add any new constraint rows we've found
3892  for (std::size_t i=0; i != requested_dof_ids[procup].size(); ++i)
3893  {
3894  libmesh_assert_equal_to (dof_filled_keys[i].size(), dof_filled_vals[i].size());
3895  if (!libmesh_isnan(dof_filled_rhss[i]))
3896  {
3897  dof_id_type constrained = requested_dof_ids[procup][i];
3898  DofConstraintRow & row = _dof_constraints[constrained];
3899  for (std::size_t j = 0; j != dof_filled_keys[i].size(); ++j)
3900  row[dof_filled_keys[i][j]] = dof_filled_vals[i][j];
3901  if (dof_filled_rhss[i] != Number(0))
3902  _primal_constraint_values[constrained] = dof_filled_rhss[i];
3903  else
3904  _primal_constraint_values.erase(constrained);
3905 
3906  for (unsigned int q = 0; q != max_qoi_num; ++q)
3907  {
3908  AdjointDofConstraintValues::iterator adjoint_map_it =
3910 
3911  if ((adjoint_map_it == _adjoint_constraint_values.end()) &&
3912  adj_filled_rhss[q][constrained] == Number(0))
3913  continue;
3914 
3915  if (adjoint_map_it == _adjoint_constraint_values.end())
3916  adjoint_map_it = _adjoint_constraint_values.insert
3917  (std::make_pair(q,DofConstraintValueMap())).first;
3918 
3919  DofConstraintValueMap & constraint_map =
3920  adjoint_map_it->second;
3921 
3922  if (adj_filled_rhss[q][i] != Number(0))
3923  constraint_map[constrained] =
3924  adj_filled_rhss[q][i];
3925  else
3926  constraint_map.erase(constrained);
3927  }
3928 
3929  // And prepare to check for more recursive constraints
3930  if (!dof_filled_keys[i].empty())
3931  unexpanded_dofs.insert(constrained);
3932  }
3933  }
3934  }
3935 
3936  // We have to keep recursing while the unexpanded set is
3937  // nonempty on *any* processor
3938  unexpanded_set_nonempty = !unexpanded_dofs.empty();
3939  this->comm().max(unexpanded_set_nonempty);
3940  }
3941 }
void max(T &r) const
Take a local variable and replace it with the maximum of it&#39;s values on all processors.
processor_id_type n_processors() const
uint8_t processor_id_type
Definition: id_types.h:99
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:1596
libmesh_assert(j)
void send_receive(const unsigned int dest_processor_id, const T1 &send, const unsigned int source_processor_id, T2 &recv, const MessageTag &send_tag=no_tag, const MessageTag &recv_tag=any_tag) const
Send data send to one processor while simultaneously receiving other data recv from a (potentially di...
DofConstraints _dof_constraints
Data structure containing DOF constraints.
Definition: dof_map.h:1592
Storage for DofConstraint right hand sides for a particular problem.
Definition: dof_map.h:108
dof_id_type end_dof() const
Definition: dof_map.h:580
bool libmesh_isnan(float a)
const Parallel::Communicator & comm() const
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:1594
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:88
std::vector< dof_id_type > _end_df
Last DOF index (plus 1) on processor p.
Definition: dof_map.h:1440
dof_id_type first_dof() const
Definition: dof_map.h:538
processor_id_type processor_id() const
uint8_t dof_id_type
Definition: id_types.h:64
const DirichletBoundaries * libMesh::DofMap::get_adjoint_dirichlet_boundaries ( unsigned int  q) const

Definition at line 4087 of file dof_map_constraints.C.

4088 {
4089  libmesh_assert_greater(_adjoint_dirichlet_boundaries.size(),q);
4091 }
std::vector< DirichletBoundaries * > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:1632
DirichletBoundaries * libMesh::DofMap::get_adjoint_dirichlet_boundaries ( unsigned int  q)

Definition at line 4095 of file dof_map_constraints.C.

4096 {
4097  unsigned int old_size = cast_int<unsigned int>
4099  for (unsigned int i = old_size; i <= q; ++i)
4101 
4103 }
We&#39;re using a class instead of a typedef to allow forward declarations and future flexibility...
std::vector< DirichletBoundaries * > _adjoint_dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:1632
const DirichletBoundaries* libMesh::DofMap::get_dirichlet_boundaries ( ) const

Definition at line 1145 of file dof_map.h.

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

1146  {
1147  return _dirichlet_boundaries.get();
1148  }
UniquePtr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:1626
DirichletBoundaries* libMesh::DofMap::get_dirichlet_boundaries ( )

Definition at line 1150 of file dof_map.h.

References libMesh::invalid_uint.

1151  {
1152  return _dirichlet_boundaries.get();
1153  }
UniquePtr< DirichletBoundaries > _dirichlet_boundaries
Data structure containing Dirichlet functions.
Definition: dof_map.h:1626
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 (Counts::iterator it = _counts.begin();
59  it != _counts.end(); ++it)
60  {
61  const std::string name(it->first);
62  const unsigned int creations = it->second.first;
63  const unsigned int destructions = it->second.second;
64 
65  oss << "| " << name << " reference count information:\n"
66  << "| Creations: " << creations << '\n'
67  << "| Destructions: " << destructions << '\n';
68  }
69 
70  oss << " ---------------------------------------------------------------------------- \n";
71 
72  return oss.str();
73 
74 #else
75 
76  return "";
77 
78 #endif
79 }
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:39
static Counts _counts
Actually holds the data.
std::string libMesh::DofMap::get_info ( ) const

Gets summary info about the sparsity bandwidth and constraints.

Definition at line 2635 of file dof_map.C.

References _dof_constraints, _matrices, _n_nz, _n_oz, _node_constraints, _primal_constraint_values, libMesh::ParallelObject::comm(), end, end_dof(), first_dof(), int, libMesh::libmesh_assert(), std::max(), libMesh::Parallel::Communicator::max(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::TypeVector< T >::size(), and libMesh::Parallel::Communicator::sum().

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

2636 {
2637  std::ostringstream os;
2638 
2639  // If we didn't calculate the exact sparsity pattern, the threaded
2640  // sparsity pattern assembly may have just given us an upper bound
2641  // on sparsity.
2642  const char * may_equal = " <= ";
2643 
2644  // If we calculated the exact sparsity pattern, then we can report
2645  // exact bandwidth figures:
2646  std::vector<SparseMatrix<Number> *>::const_iterator<