libMesh::DofMap Class Reference

Manages the degrees of freedom (DOFs) in a simulation. More...

#include <dof_map.h>

Inheritance diagram for libMesh::DofMap:

Classes

class  AugmentSendList
 
class  AugmentSparsityPattern
 

Public Member Functions

 DofMap (const unsigned int sys_number, MeshBase &mesh)
 
 ~DofMap ()
 
void attach_matrix (SparseMatrix< Number > &matrix)
 
bool is_attached (SparseMatrix< Number > &matrix)
 
void distribute_dofs (MeshBase &)
 
void compute_sparsity (const MeshBase &)
 
void clear_sparsity ()
 
void add_coupling_functor (GhostingFunctor &coupling_functor)
 
void remove_coupling_functor (GhostingFunctor &coupling_functor)
 
std::set< GhostingFunctor * >::const_iterator coupling_functors_begin () const
 
std::set< GhostingFunctor * >::const_iterator coupling_functors_end () const
 
DefaultCouplingdefault_coupling ()
 
void add_algebraic_ghosting_functor (GhostingFunctor &ghosting_functor)
 
void remove_algebraic_ghosting_functor (GhostingFunctor &ghosting_functor)
 
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_begin () const
 
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_end () const
 
DefaultCouplingdefault_algebraic_ghosting ()
 
void attach_extra_sparsity_object (DofMap::AugmentSparsityPattern &asp)
 
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)
 
void attach_extra_send_list_object (DofMap::AugmentSendList &asl)
 
void attach_extra_send_list_function (void(*func)(std::vector< dof_id_type > &, void *), void *context=libmesh_nullptr)
 
void prepare_send_list ()
 
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)
 
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
 
void dof_indices (const Elem *const elem, std::vector< dof_id_type > &di, const unsigned int vn, int p_level=-12345) const
 
void dof_indices (const Node *const node, std::vector< dof_id_type > &di) const
 
void dof_indices (const Node *const node, std::vector< dof_id_type > &di, const unsigned int vn) const
 
void SCALAR_dof_indices (std::vector< dof_id_type > &di, const unsigned int vn, const bool old_dofs=false) 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)
 
bool use_coupled_neighbor_dofs (const MeshBase &mesh) const
 
void extract_local_vector (const NumericVector< Number > &Ug, const std::vector< dof_id_type > &dof_indices, DenseVectorBase< Number > &Ue) const
 
void local_variable_indices (std::vector< dof_id_type > &idx, const MeshBase &mesh, unsigned int var_num) const
 
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)
 
void allgather_recursive_constraints (MeshBase &)
 
void scatter_constraints (MeshBase &)
 
void gather_constraints (MeshBase &mesh, std::set< dof_id_type > &unexpanded_dofs, bool look_for_constrainees)
 
void process_constraints (MeshBase &)
 
void add_constraint_row (const dof_id_type dof_number, const DofConstraintRow &constraint_row, const Number constraint_rhs, const bool forbid_constraint_overwrite)
 
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)
 
void add_constraint_row (const dof_id_type dof_number, const DofConstraintRow &constraint_row, const bool forbid_constraint_overwrite=true)
 
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
 
std::string get_local_constraints (bool print_nonlocal=false) const
 
std::pair< Real, Realmax_constraint_error (const System &system, NumericVector< Number > *v=libmesh_nullptr) const
 
void constrain_element_matrix (DenseMatrix< Number > &matrix, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
 
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
 
void constrain_element_vector (DenseVector< Number > &rhs, std::vector< dof_id_type > &dofs, bool asymmetric_constraint_rows=true) const
 
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
 
void heterogenously_constrain_element_matrix_and_vector (DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
 
void heterogenously_constrain_element_vector (const DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
 
void constrain_element_dyad_matrix (DenseVector< Number > &v, DenseVector< Number > &w, std::vector< dof_id_type > &row_dofs, bool asymmetric_constraint_rows=true) const
 
void constrain_nothing (std::vector< dof_id_type > &dofs) const
 
void enforce_constraints_exactly (const System &system, NumericVector< Number > *v=libmesh_nullptr, bool homogeneous=false) const
 
void enforce_adjoint_constraints_exactly (NumericVector< Number > &v, unsigned int q) const
 
void add_periodic_boundary (const PeriodicBoundaryBase &periodic_boundary)
 
void add_periodic_boundary (const PeriodicBoundaryBase &boundary, const PeriodicBoundaryBase &inverse_boundary)
 
bool is_periodic_boundary (const boundary_id_type boundaryid) const
 
PeriodicBoundariesget_periodic_boundaries ()
 
void add_dirichlet_boundary (const DirichletBoundary &dirichlet_boundary)
 
void add_adjoint_dirichlet_boundary (const DirichletBoundary &dirichlet_boundary, unsigned int q)
 
void remove_dirichlet_boundary (const DirichletBoundary &dirichlet_boundary)
 
void remove_adjoint_dirichlet_boundary (const DirichletBoundary &dirichlet_boundary, unsigned int q)
 
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
 
dof_id_type n_old_dofs () const
 
void constrain_p_dofs (unsigned int var, const Elem *elem, unsigned int s, unsigned int p)
 
void reinit (MeshBase &mesh)
 
void clear ()
 
void print_info (std::ostream &os=libMesh::out) const
 
std::string get_info () const
 
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 ()
 
static void print_info (std::ostream &out=libMesh::out)
 
static unsigned int n_objects ()
 
static void enable_print_counter_info ()
 
static void disable_print_counter_info ()
 

Public Attributes

CouplingMatrix_dof_coupling
 

Protected Types

typedef std::map< std::string, std::pair< unsigned int, unsigned int > > Counts
 

Protected Member Functions

void increment_constructor_count (const std::string &name)
 
void increment_destructor_count (const std::string &name)
 

Protected Attributes

const Parallel::Communicator_communicator
 

Static Protected Attributes

static Counts _counts
 
static Threads::atomic< unsigned int > _n_objects
 
static Threads::spin_mutex _mutex
 
static bool _enable_print_counter = true
 

Private Types

typedef DofObject *(DofMap::* dofobject_accessor) (MeshBase &mesh, dof_id_type i) const
 

Private Member Functions

void _dof_indices (const Elem *const 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
 
UniquePtr< SparsityPattern::Buildbuild_sparsity (const MeshBase &mesh) const
 
void invalidate_dofs (MeshBase &mesh) const
 
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)
 
void distribute_local_dofs_var_major (dof_id_type &next_free_dof, MeshBase &mesh)
 
void distribute_local_dofs_node_major (dof_id_type &next_free_dof, MeshBase &mesh)
 
void add_neighbors_to_send_list (MeshBase &mesh)
 
void build_constraint_matrix (DenseMatrix< Number > &C, std::vector< dof_id_type > &elem_dofs, const bool called_recursively=false) 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
 
void find_connected_dofs (std::vector< dof_id_type > &elem_dofs) const
 
void find_connected_dof_objects (std::vector< const DofObject * > &objs) const
 
void add_constraints_to_send_list ()
 
void check_dirichlet_bcid_consistency (const MeshBase &mesh, const DirichletBoundary &boundary) const
 

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
 
std::vector< VariableGroup_variable_groups
 
const unsigned int _sys_number
 
MeshBase_mesh
 
std::vector< SparseMatrix< Number > * > _matrices
 
std::vector< dof_id_type_first_df
 
std::vector< dof_id_type_end_df
 
std::vector< dof_id_type_first_scalar_df
 
std::vector< dof_id_type_send_list
 
AugmentSparsityPattern_augment_sparsity_pattern
 
void(* _extra_sparsity_function )(SparsityPattern::Graph &, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *)
 
void * _extra_sparsity_context
 
AugmentSendList_augment_send_list
 
void(* _extra_send_list_function )(std::vector< dof_id_type > &, void *)
 
void * _extra_send_list_context
 
UniquePtr< DefaultCoupling_default_coupling
 
UniquePtr< DefaultCoupling_default_evaluating
 
std::set< GhostingFunctor * > _algebraic_ghosting_functors
 
std::set< GhostingFunctor * > _coupling_functors
 
bool need_full_sparsity_pattern
 
UniquePtr< SparsityPattern::Build_sp
 
std::vector< dof_id_type > * _n_nz
 
std::vector< dof_id_type > * _n_oz
 
dof_id_type _n_dfs
 
dof_id_type _n_SCALAR_dofs
 
dof_id_type _n_old_dfs
 
std::vector< dof_id_type_first_old_df
 
std::vector< dof_id_type_end_old_df
 
std::vector< dof_id_type_first_old_scalar_df
 
DofConstraints _dof_constraints
 
DofConstraints _stashed_dof_constraints
 
DofConstraintValueMap _primal_constraint_values
 
AdjointDofConstraintValues _adjoint_constraint_values
 
NodeConstraints _node_constraints
 
UniquePtr< PeriodicBoundaries_periodic_boundaries
 
UniquePtr< DirichletBoundaries_dirichlet_boundaries
 
std::vector< DirichletBoundaries * > _adjoint_dirichlet_boundaries
 
bool _implicit_neighbor_dofs_initialized
 
bool _implicit_neighbor_dofs
 

Friends

class SparsityPattern::Build
 

Detailed Description

Manages the degrees of freedom (DOFs) in a simulation.

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

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 1281 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
Definition: dof_map.h:1402
ParallelObject(const Parallel::Communicator &comm_in)
bool _implicit_neighbor_dofs_initialized
Definition: dof_map.h:1630
const unsigned int _sys_number
Definition: dof_map.h:1407
bool _implicit_neighbor_dofs
Definition: dof_map.h:1631
UniquePtr< DefaultCoupling > _default_coupling
Definition: dof_map.h:1481
void * _extra_sparsity_context
Definition: dof_map.h:1458
std::vector< dof_id_type > _send_list
Definition: dof_map.h:1441
MeshBase & mesh
AugmentSparsityPattern * _augment_sparsity_pattern
Definition: dof_map.h:1446
const class libmesh_nullptr_t libmesh_nullptr
std::vector< dof_id_type > _end_old_df
Definition: dof_map.h:1566
void add_coupling_functor(GhostingFunctor &coupling_functor)
Definition: dof_map.C:1882
UniquePtr< DefaultCoupling > _default_evaluating
Definition: dof_map.h:1489
std::vector< dof_id_type > _first_old_df
Definition: dof_map.h:1561
std::vector< dof_id_type > _first_scalar_df
Definition: dof_map.h:1435
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:1585
std::vector< dof_id_type > * _n_nz
Definition: dof_map.h:1532
AugmentSendList * _augment_send_list
Definition: dof_map.h:1463
std::vector< dof_id_type > * _n_oz
Definition: dof_map.h:1538
bool need_full_sparsity_pattern
Definition: dof_map.h:1518
void add_algebraic_ghosting_functor(GhostingFunctor &ghosting_functor)
Definition: dof_map.C:1901
std::vector< dof_id_type > _first_old_scalar_df
Definition: dof_map.h:1572
void(* _extra_sparsity_function)(SparsityPattern::Graph &, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *)
Definition: dof_map.h:1451
dof_id_type _n_SCALAR_dofs
Definition: dof_map.h:1549
DofConstraints _dof_constraints
Definition: dof_map.h:1581
CouplingMatrix * _dof_coupling
Definition: dof_map.h:1229
std::vector< DirichletBoundaries * > _adjoint_dirichlet_boundaries
Definition: dof_map.h:1621
void * _extra_send_list_context
Definition: dof_map.h:1473
std::vector< SparseMatrix< Number > * > _matrices
Definition: dof_map.h:1419
UniquePtr< DirichletBoundaries > _dirichlet_boundaries
Definition: dof_map.h:1615
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:1583
std::vector< Variable > _variables
Definition: dof_map.h:1397
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:1581
dof_id_type _n_old_dfs
Definition: dof_map.h:1556
UniquePtr< PeriodicBoundaries > _periodic_boundaries
Definition: dof_map.h:1601
std::vector< dof_id_type > _end_df
Definition: dof_map.h:1429
std::vector< dof_id_type > _first_df
Definition: dof_map.h:1424
void(* _extra_send_list_function)(std::vector< dof_id_type > &, void *)
Definition: dof_map.h:1468
MeshBase & _mesh
Definition: dof_map.h:1412
dof_id_type _n_dfs
Definition: dof_map.h:1543
NodeConstraints _node_constraints
Definition: dof_map.h:1592
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
Definition: dof_map.h:1481
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Definition: mesh_base.C:304
UniquePtr< DefaultCoupling > _default_evaluating
Definition: dof_map.h:1489
void clear()
Definition: dof_map.C:839
std::vector< DirichletBoundaries * > _adjoint_dirichlet_boundaries
Definition: dof_map.h:1621
MeshBase & _mesh
Definition: dof_map.h:1412

Member Function Documentation

void libMesh::DofMap::_dof_indices ( const Elem *const  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 2250 of file dof_map.C.

References libMesh::Elem::active(), libMesh::Variable::active_on_subdomain(), libMesh::Elem::dim(), libMesh::DofObject::dof_number(), libMesh::FEInterface::extra_hanging_dofs(), libMesh::FEType::family, 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_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().

2261 {
2262  // This internal function is only useful on valid elements
2263  libmesh_assert(elem);
2264 
2265  const Variable & var = this->variable(v);
2266 
2267  if (var.active_on_subdomain(elem->subdomain_id()))
2268  {
2269  const ElemType type = elem->type();
2270  const unsigned int sys_num = this->sys_number();
2271  const unsigned int dim = elem->dim();
2272 
2273  // Increase the polynomial order on p refined elements
2274  FEType fe_type = var.type();
2275  fe_type.order = static_cast<Order>(fe_type.order + p_level);
2276 
2277  const bool extra_hanging_dofs =
2279 
2280 #ifdef DEBUG
2281  // The number of dofs per element is non-static for subdivision FE
2282  if (fe_type.family == SUBDIVISION)
2283  tot_size += n_nodes;
2284  else
2285  tot_size += FEInterface::n_dofs(dim,fe_type,type);
2286 #endif
2287 
2288  // Get the node-based DOF numbers
2289  for (unsigned int n=0; n<n_nodes; n++)
2290  {
2291  const Node * node = nodes[n];
2292 
2293  // There is a potential problem with h refinement. Imagine a
2294  // quad9 that has a linear FE on it. Then, on the hanging side,
2295  // it can falsely identify a DOF at the mid-edge node. This is why
2296  // we call FEInterface instead of node->n_comp() directly.
2297  const unsigned int nc = FEInterface::n_dofs_at_node (dim,
2298  fe_type,
2299  type,
2300  n);
2301 
2302  // If this is a non-vertex on a hanging node with extra
2303  // degrees of freedom, we use the non-vertex dofs (which
2304  // come in reverse order starting from the end, to
2305  // simplify p refinement)
2306  if (extra_hanging_dofs && !elem->is_vertex(n))
2307  {
2308  const int dof_offset = node->n_comp(sys_num,v) - nc;
2309 
2310  // We should never have fewer dofs than necessary on a
2311  // node unless we're getting indices on a parent element,
2312  // and we should never need the indices on such a node
2313  if (dof_offset < 0)
2314  {
2315  libmesh_assert(!elem->active());
2316  di.resize(di.size() + nc, DofObject::invalid_id);
2317  }
2318  else
2319  for (int i=node->n_comp(sys_num,v)-1; i>=dof_offset; i--)
2320  {
2321  libmesh_assert_not_equal_to (node->dof_number(sys_num,v,i),
2323  di.push_back(node->dof_number(sys_num,v,i));
2324  }
2325  }
2326  // If this is a vertex or an element without extra hanging
2327  // dofs, our dofs come in forward order coming from the
2328  // beginning
2329  else
2330  for (unsigned int i=0; i<nc; i++)
2331  {
2332  libmesh_assert_not_equal_to (node->dof_number(sys_num,v,i),
2334  di.push_back(node->dof_number(sys_num,v,i));
2335  }
2336  }
2337 
2338  // If there are any element-based DOF numbers, get them
2339  const unsigned int nc = FEInterface::n_dofs_per_elem(dim,
2340  fe_type,
2341  type);
2342  // We should never have fewer dofs than necessary on an
2343  // element unless we're getting indices on a parent element,
2344  // and we should never need those indices
2345  if (nc != 0)
2346  {
2347  if (elem->n_systems() > sys_num &&
2348  nc <= elem->n_comp(sys_num,v))
2349  {
2350  for (unsigned int i=0; i<nc; i++)
2351  {
2352  libmesh_assert_not_equal_to (elem->dof_number(sys_num,v,i),
2354 
2355  di.push_back(elem->dof_number(sys_num,v,i));
2356  }
2357  }
2358  else
2359  {
2360  libmesh_assert(!elem->active() || fe_type.family == LAGRANGE || fe_type.family == SUBDIVISION);
2361  di.resize(di.size() + nc, DofObject::invalid_id);
2362  }
2363  }
2364  }
2365 }
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:460
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:414
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:1656
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
Definition: dof_object.h:334
unsigned int sys_number() const
Definition: dof_map.h:1638
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
Definition: fe_interface.C:436
void 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 1364 of file dof_map_constraints.C.

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

4070 {
4071  unsigned int old_size = cast_int<unsigned int>
4073  for (unsigned int i = old_size; i <= qoi_index; ++i)
4075 
4076  _adjoint_dirichlet_boundaries[qoi_index]->push_back
4077  (new DirichletBoundary(dirichlet_boundary));
4078 }
Class for specifying Dirichlet boundary conditions as constraints.
std::vector< DirichletBoundaries * > _adjoint_dirichlet_boundaries
Definition: dof_map.h:1621
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 1901 of file dof_map.C.

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

Referenced by clear(), and DofMap().

1902 {
1903  _algebraic_ghosting_functors.insert(&algebraic_ghosting_functor);
1904  _mesh.add_ghosting_functor(algebraic_ghosting_functor);
1905 }
std::set< GhostingFunctor * > _algebraic_ghosting_functors
Definition: dof_map.h:1499
MeshBase & _mesh
Definition: dof_map.h:1412
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Definition: mesh_base.h:771
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 1341 of file dof_map_constraints.C.

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

Adds a copy of the user-defined row to the constraint matrix, using a homogeneous right-hand-side for the constraint equation. By default, produces an error if the DOF was already constrained.

Definition at line 805 of file dof_map.h.

808  { 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)
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 3947 of file dof_map_constraints.C.

References libMesh::n_processors().

3948 {
3949  // This function must be run on all processors at once
3950  parallel_object_only();
3951 
3952  // Return immediately if there's nothing to gather
3953  if (this->n_processors() == 1)
3954  return;
3955 
3956  // We might get to return immediately if none of the processors
3957  // found any constraints
3958  unsigned int has_constraints = !_dof_constraints.empty();
3959  this->comm().max(has_constraints);
3960  if (!has_constraints)
3961  return;
3962 
3963  for (DofConstraints::iterator i = _dof_constraints.begin();
3964  i != _dof_constraints.end(); ++i)
3965  {
3966  dof_id_type constrained_dof = i->first;
3967 
3968  // We only need the dependencies of our own constrained dofs
3969  if (constrained_dof < this->first_dof() ||
3970  constrained_dof >= this->end_dof())
3971  continue;
3972 
3973  DofConstraintRow & constraint_row = i->second;
3974  for (DofConstraintRow::const_iterator
3975  j=constraint_row.begin(); j != constraint_row.end();
3976  ++j)
3977  {
3978  dof_id_type constraint_dependency = j->first;
3979 
3980  // No point in adding one of our own dofs to the send_list
3981  if (constraint_dependency >= this->first_dof() &&
3982  constraint_dependency < this->end_dof())
3983  continue;
3984 
3985  _send_list.push_back(constraint_dependency);
3986  }
3987  }
3988 }
std::vector< dof_id_type > _send_list
Definition: dof_map.h:1441
processor_id_type n_processors() const
DofConstraints _dof_constraints
Definition: dof_map.h:1581
dof_id_type end_dof() const
Definition: dof_map.h:578
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
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 1882 of file dof_map.C.

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

Referenced by clear(), and DofMap().

1883 {
1884  _coupling_functors.insert(&coupling_functor);
1885  _mesh.add_ghosting_functor(coupling_functor);
1886 }
std::set< GhostingFunctor * > _coupling_functors
Definition: dof_map.h:1512
MeshBase & _mesh
Definition: dof_map.h:1412
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Definition: mesh_base.h:771
void libMesh::DofMap::add_dirichlet_boundary ( const DirichletBoundary dirichlet_boundary)

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

Definition at line 4062 of file dof_map_constraints.C.

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

4063 {
4064  _dirichlet_boundaries->push_back(new DirichletBoundary(dirichlet_boundary));
4065 }
Class for specifying Dirichlet boundary conditions as constraints.
UniquePtr< DirichletBoundaries > _dirichlet_boundaries
Definition: dof_map.h:1615
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 1567 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().

1568 {
1569  LOG_SCOPE("add_neighbors_to_send_list()", "DofMap");
1570 
1571  const unsigned int n_var = this->n_variables();
1572 
1573  MeshBase::const_element_iterator local_elem_it
1574  = mesh.active_local_elements_begin();
1575  const MeshBase::const_element_iterator local_elem_end
1576  = mesh.active_local_elements_end();
1577 
1578  GhostingFunctor::map_type elements_to_send;
1579 
1580  // Man, I wish we had guaranteed unique_ptr availability...
1581  std::set<CouplingMatrix *> temporary_coupling_matrices;
1582 
1583  // We need to add dofs to the send list if they've been directly
1584  // requested by an algebraic ghosting functor or they've been
1585  // indirectly requested by a coupling functor.
1586  this->merge_ghost_functor_outputs(elements_to_send,
1587  temporary_coupling_matrices,
1590  local_elem_it, local_elem_end, mesh.processor_id());
1591 
1592  this->merge_ghost_functor_outputs(elements_to_send,
1593  temporary_coupling_matrices,
1594  this->coupling_functors_begin(),
1595  this->coupling_functors_end(),
1596  local_elem_it, local_elem_end, mesh.processor_id());
1597 
1598  // Making a list of non-zero coupling matrix columns is an
1599  // O(N_var^2) operation. We cache it so we only have to do it once
1600  // per CouplingMatrix and not once per element.
1601  std::map<const CouplingMatrix *, std::vector<unsigned int> >
1602  column_variable_lists;
1603 
1604  GhostingFunctor::map_type::iterator etg_it = elements_to_send.begin();
1605  const GhostingFunctor::map_type::iterator etg_end = elements_to_send.end();
1606  for (; etg_it != etg_end; ++etg_it)
1607  {
1608  const Elem * const partner = etg_it->first;
1609 
1610  // We asked ghosting functors not to give us local elements
1611  libmesh_assert_not_equal_to
1612  (partner->processor_id(), this->processor_id());
1613 
1614  const CouplingMatrix * ghost_coupling = etg_it->second;
1615 
1616  // Loop over any present coupling matrix column variables if we
1617  // have a coupling matrix, or just add all variables to
1618  // send_list if not.
1619  if (ghost_coupling)
1620  {
1621  libmesh_assert_equal_to (ghost_coupling->size(), n_var);
1622 
1623  // Try to find a cached list of column variables.
1624  std::map<const CouplingMatrix *, std::vector<unsigned int> >::const_iterator
1625  column_variable_list = column_variable_lists.find(ghost_coupling);
1626 
1627  // If we didn't find it, then we need to create it.
1628  if (column_variable_list == column_variable_lists.end())
1629  {
1630  std::pair<std::map<const CouplingMatrix *, std::vector<unsigned int> >::iterator, bool>
1631  inserted_variable_list_pair = column_variable_lists.insert(std::make_pair(ghost_coupling,
1632  std::vector<unsigned int>()));
1633  column_variable_list = inserted_variable_list_pair.first;
1634 
1635  std::vector<unsigned int> & new_variable_list =
1636  inserted_variable_list_pair.first->second;
1637 
1638  std::vector<unsigned char> has_variable(n_var, false);
1639 
1640  for (unsigned int vi = 0; vi != n_var; ++vi)
1641  {
1642  ConstCouplingRow ccr(vi, *ghost_coupling);
1643 
1645  it = ccr.begin(),
1646  end = ccr.end();
1647  it != end; ++it)
1648  {
1649  const unsigned int vj = *it;
1650  has_variable[vj] = true;
1651  }
1652  }
1653  for (unsigned int vj = 0; vj != n_var; ++vj)
1654  {
1655  if (has_variable[vj])
1656  new_variable_list.push_back(vj);
1657  }
1658  }
1659 
1660  const std::vector<unsigned int> & variable_list =
1661  column_variable_list->second;
1662 
1663  for (std::size_t j=0; j != variable_list.size(); ++j)
1664  {
1665  const unsigned int vj=variable_list[j];
1666 
1667  std::vector<dof_id_type> di;
1668  this->dof_indices (partner, di, vj);
1669 
1670  // Insert the remote DOF indices into the send list
1671  for (std::size_t j=0; j != di.size(); ++j)
1672  if (di[j] < this->first_dof() ||
1673  di[j] >= this->end_dof())
1674  _send_list.push_back(di[j]);
1675  }
1676  }
1677  else
1678  {
1679  std::vector<dof_id_type> di;
1680  this->dof_indices (partner, di);
1681 
1682  // Insert the remote DOF indices into the send list
1683  for (std::size_t j=0; j != di.size(); ++j)
1684  if (di[j] < this->first_dof() ||
1685  di[j] >= this->end_dof())
1686  _send_list.push_back(di[j]);
1687  }
1688 
1689  }
1690 
1691  // We're now done with any merged coupling matrices we had to create.
1692  for (std::set<CouplingMatrix *>::iterator
1693  it = temporary_coupling_matrices.begin(),
1694  end = temporary_coupling_matrices.begin();
1695  it != end; ++it)
1696  delete *it;
1697 
1698  //-------------------------------------------------------------------------
1699  // Our coupling functors added dofs from neighboring elements to the
1700  // send list, but we may still need to add non-local dofs from local
1701  // elements.
1702  //-------------------------------------------------------------------------
1703 
1704  // Loop over the active local elements, adding all active elements
1705  // that neighbor an active local element to the send list.
1706  for ( ; local_elem_it != local_elem_end; ++local_elem_it)
1707  {
1708  const Elem * elem = *local_elem_it;
1709 
1710  std::vector<dof_id_type> di;
1711  this->dof_indices (elem, di);
1712 
1713  // Insert the remote DOF indices into the send list
1714  for (std::size_t j=0; j != di.size(); ++j)
1715  if (di[j] < this->first_dof() ||
1716  di[j] >= this->end_dof())
1717  _send_list.push_back(di[j]);
1718  }
1719 }
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_begin() const
Definition: dof_map.h:311
LIBMESH_BEST_UNORDERED_MAP< const Elem *, const CouplingMatrix * > map_type
std::set< GhostingFunctor * >::const_iterator coupling_functors_begin() const
Definition: dof_map.h:275
std::vector< dof_id_type > _send_list
Definition: dof_map.h:1441
MeshBase & mesh
IterBase * end
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:1496
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_end() const
Definition: dof_map.h:317
dof_id_type end_dof() const
Definition: dof_map.h:578
unsigned int n_variables() const
Definition: dof_map.h:477
std::set< GhostingFunctor * >::const_iterator coupling_functors_end() const
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
Definition: dof_map.C:2005
void libMesh::DofMap::add_periodic_boundary ( const PeriodicBoundaryBase periodic_boundary)

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

Definition at line 4196 of file dof_map_constraints.C.

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

4197 {
4198  // See if we already have a periodic boundary associated myboundary...
4199  PeriodicBoundaryBase * existing_boundary = _periodic_boundaries->boundary(periodic_boundary.myboundary);
4200 
4201  if (existing_boundary == libmesh_nullptr)
4202  {
4203  // ...if not, clone the input (and its inverse) and add them to the PeriodicBoundaries object
4204  PeriodicBoundaryBase * boundary = periodic_boundary.clone().release();
4205  PeriodicBoundaryBase * inverse_boundary = periodic_boundary.clone(PeriodicBoundaryBase::INVERSE).release();
4206 
4207  // _periodic_boundaries takes ownership of the pointers
4208  _periodic_boundaries->insert(std::make_pair(boundary->myboundary, boundary));
4209  _periodic_boundaries->insert(std::make_pair(inverse_boundary->myboundary, inverse_boundary));
4210  }
4211  else
4212  {
4213  // ...otherwise, merge this object's variable IDs with the existing boundary object's.
4214  existing_boundary->merge(periodic_boundary);
4215 
4216  // Do the same merging process for the inverse boundary. Note: the inverse better already exist!
4217  PeriodicBoundaryBase * inverse_boundary = _periodic_boundaries->boundary(periodic_boundary.pairedboundary);
4218  libmesh_assert(inverse_boundary);
4219  inverse_boundary->merge(periodic_boundary);
4220  }
4221 }
const class libmesh_nullptr_t libmesh_nullptr
libmesh_assert(j)
void merge(const PeriodicBoundaryBase &pb)
virtual UniquePtr< PeriodicBoundaryBase > clone(TransformationType t=FORWARD) const =0
UniquePtr< PeriodicBoundaries > _periodic_boundaries
Definition: dof_map.h:1601
Base class for all PeriodicBoundary implementations.
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 4226 of file dof_map_constraints.C.

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

4228 {
4229  libmesh_assert_equal_to (boundary.myboundary, inverse_boundary.pairedboundary);
4230  libmesh_assert_equal_to (boundary.pairedboundary, inverse_boundary.myboundary);
4231 
4232  // Allocate copies on the heap. The _periodic_boundaries object will manage this memory.
4233  // Note: this also means that the copy constructor for the PeriodicBoundary (or user class
4234  // derived therefrom) must be implemented!
4235  // PeriodicBoundary * p_boundary = new PeriodicBoundary(boundary);
4236  // PeriodicBoundary * p_inverse_boundary = new PeriodicBoundary(inverse_boundary);
4237 
4238  // We can't use normal copy construction since this leads to slicing with derived classes.
4239  // Use clone() "virtual constructor" instead. But, this *requires* user to override the clone()
4240  // method. Note also that clone() allocates memory. In this case, the _periodic_boundaries object
4241  // takes responsibility for cleanup.
4242  PeriodicBoundaryBase * p_boundary = boundary.clone().release();
4243  PeriodicBoundaryBase * p_inverse_boundary = inverse_boundary.clone().release();
4244 
4245  // Add the periodic boundary and its inverse to the PeriodicBoundaries data structure. The
4246  // PeriodicBoundaries data structure takes ownership of the pointers.
4247  _periodic_boundaries->insert(std::make_pair(p_boundary->myboundary, p_boundary));
4248  _periodic_boundaries->insert(std::make_pair(p_inverse_boundary->myboundary, p_inverse_boundary));
4249 }
virtual UniquePtr< PeriodicBoundaryBase > clone(TransformationType t=FORWARD) const =0
UniquePtr< PeriodicBoundaries > _periodic_boundaries
Definition: dof_map.h:1601
Base class for all PeriodicBoundary implementations.
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
Definition: dof_map.h:1402
std::vector< Variable > _variables
Definition: dof_map.h:1397
std::set<GhostingFunctor *>::const_iterator libMesh::DofMap::algebraic_ghosting_functors_begin ( ) const
inline

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
Definition: dof_map.h:1499
std::set<GhostingFunctor *>::const_iterator libMesh::DofMap::algebraic_ghosting_functors_end ( ) const
inline

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
Definition: dof_map.h:1499
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, not O(1); we don't cache enough information for O(1) right now.

Definition at line 2405 of file dof_map.C.

References _send_list, end_dof(), and first_dof().

2406 {
2407  // We're all semilocal unless we find a counterexample
2408  for (std::size_t i=0; i != dof_indices_in.size(); ++i)
2409  {
2410  const dof_id_type di = dof_indices_in[i];
2411  // If it's not in the local indices
2412  if (di < this->first_dof() ||
2413  di >= this->end_dof())
2414  {
2415  // and if it's not in the ghost indices, then we're not
2416  // semilocal
2417  if (!std::binary_search(_send_list.begin(), _send_list.end(), di))
2418  return false;
2419  }
2420  }
2421 
2422  return true;
2423 }
std::vector< dof_id_type > _send_list
Definition: dof_map.h:1441
dof_id_type end_dof() const
Definition: dof_map.h:578
dof_id_type first_dof() const
Definition: dof_map.h:538
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 2619 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(), 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().

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

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
Definition: dof_map.h:1473
void(* _extra_send_list_function)(std::vector< dof_id_type > &, void *)
Definition: dof_map.h:1468
void libMesh::DofMap::attach_extra_send_list_object ( DofMap::AugmentSendList asl)
inline

Attach an object to populate the send_list with extra entries. This should only add to the send list, but no checking is done to enforce this behavior.

This is an advanced function... use at your own peril!

Definition at line 364 of file dof_map.h.

365  {
366  _augment_send_list = &asl;
367  }
AugmentSendList * _augment_send_list
Definition: dof_map.h:1463
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 
)
inline

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

Care must be taken that when adding entries they are sorted into the Rows

Further, you must modify n_nz and n_oz properly!

This is an advanced function... use at your own peril!

Definition at line 350 of file dof_map.h.

void * _extra_sparsity_context
Definition: dof_map.h:1458
void(* _extra_sparsity_function)(SparsityPattern::Graph &, std::vector< dof_id_type > &n_nz, std::vector< dof_id_type > &n_oz, void *)
Definition: dof_map.h:1451
void libMesh::DofMap::attach_extra_sparsity_object ( DofMap::AugmentSparsityPattern asp)
inline

Attach an object to use to populate the sparsity pattern with extra entries.

Care must be taken that when adding entries they are sorted into the Rows

Further, you must modify n_nz and n_oz properly!

This is an advanced function... use at your own peril!

Definition at line 335 of file dof_map.h.

336  {
338  }
AugmentSparsityPattern * _augment_sparsity_pattern
Definition: dof_map.h:1446
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::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 }
libmesh_assert(j)
std::vector< dof_id_type > * _n_nz
Definition: dof_map.h:1532
std::vector< dof_id_type > * _n_oz
Definition: dof_map.h:1538
bool need_full_sparsity_pattern
Definition: dof_map.h:1518
UniquePtr< SparsityPattern::Build > _sp
Definition: dof_map.h:1524
virtual bool need_full_sparsity_pattern() const
std::vector< SparseMatrix< Number > * > _matrices
Definition: dof_map.h:1419
void attach_dof_map(const DofMap &dof_map)
virtual void update_sparsity_pattern(const SparsityPattern::Graph &)
const Parallel::Communicator & comm() const
unsigned int libMesh::DofMap::block_size ( ) const
inline
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 2366 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().

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

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

4166 {
4167  const std::set<boundary_id_type>& mesh_bcids = mesh.get_boundary_info().get_boundary_ids();
4168  const std::set<boundary_id_type>& dbc_bcids = boundary.b;
4169 
4170  // DirichletBoundary id sets should be consistent across all ranks
4171  libmesh_assert(mesh.comm().verify(dbc_bcids.size()));
4172 
4173  for (std::set<boundary_id_type>::const_iterator bid = dbc_bcids.begin();
4174  bid != dbc_bcids.end(); ++bid)
4175  {
4176  // DirichletBoundary id sets should be consistent across all ranks
4177  libmesh_assert(mesh.comm().verify(*bid));
4178 
4179  bool found_bcid = (mesh_bcids.find(*bid) != mesh_bcids.end());
4180 
4181  // On a distributed mesh, boundary id sets may *not* be
4182  // consistent across all ranks, since not all ranks see all
4183  // boundaries
4184  mesh.comm().max(found_bcid);
4185 
4186  if (!found_bcid)
4187  libmesh_error_msg("Could not find Dirichlet boundary id " << *bid << " in mesh!");
4188  }
4189 }
const BoundaryInfo & get_boundary_info() const
Definition: mesh_base.h:114
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 839 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().

840 {
841  // we don't want to clear
842  // the coupling matrix!
843  // It should not change...
844  //_dof_coupling->clear();
845  //
846  // But it would be inconsistent to leave our coupling settings
847  // through a clear()...
848  _dof_coupling = NULL;
849 
850  // Reset ghosting functor statuses
851  {
852  std::set<GhostingFunctor *>::iterator gf_it = this->coupling_functors_begin();
853  const std::set<GhostingFunctor *>::iterator gf_end = this->coupling_functors_end();
854  for (; gf_it != gf_end; ++gf_it)
855  {
856  GhostingFunctor * gf = *gf_it;
857  libmesh_assert(gf);
859  }
860  this->_coupling_functors.clear();
861 
862  // Go back to default coupling
863 
864  _default_coupling->set_dof_coupling(this->_dof_coupling);
865  _default_coupling->set_n_levels(this->use_coupled_neighbor_dofs(this->_mesh));
866 
868  }
869 
870 
871  {
872  std::set<GhostingFunctor *>::iterator gf_it = this->algebraic_ghosting_functors_begin();
873  const std::set<GhostingFunctor *>::iterator gf_end = this->algebraic_ghosting_functors_end();
874  for (; gf_it != gf_end; ++gf_it)
875  {
876  GhostingFunctor * gf = *gf_it;
877  libmesh_assert(gf);
879  }
880  this->_algebraic_ghosting_functors.clear();
881 
882  // Go back to default send_list generation
883 
884  // _default_evaluating->set_dof_coupling(this->_dof_coupling);
885  _default_evaluating->set_n_levels(1);
887  }
888 
889  _variables.clear();
890  _variable_groups.clear();
891  _first_df.clear();
892  _end_df.clear();
893  _first_scalar_df.clear();
894  _send_list.clear();
895  this->clear_sparsity();
897 
898 #ifdef LIBMESH_ENABLE_AMR
899 
900  _dof_constraints.clear();
901  _stashed_dof_constraints.clear();
904  _n_old_dfs = 0;
905  _first_old_df.clear();
906  _end_old_df.clear();
907  _first_old_scalar_df.clear();
908 
909 #endif
910 
911  _matrices.clear();
912 
913  _n_dfs = 0;
914 }
std::vector< VariableGroup > _variable_groups
Definition: dof_map.h:1402
UniquePtr< DefaultCoupling > _default_coupling
Definition: dof_map.h:1481
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_begin() const
Definition: dof_map.h:311
std::set< GhostingFunctor * >::const_iterator coupling_functors_begin() const
Definition: dof_map.h:275
std::vector< dof_id_type > _send_list
Definition: dof_map.h:1441
void remove_ghosting_functor(GhostingFunctor &ghosting_functor)
Definition: mesh_base.C:304
std::set< GhostingFunctor * > _algebraic_ghosting_functors
Definition: dof_map.h:1499
std::vector< dof_id_type > _end_old_df
Definition: dof_map.h:1566
void add_coupling_functor(GhostingFunctor &coupling_functor)
Definition: dof_map.C:1882
UniquePtr< DefaultCoupling > _default_evaluating
Definition: dof_map.h:1489
std::vector< dof_id_type > _first_old_df
Definition: dof_map.h:1561
std::vector< dof_id_type > _first_scalar_df
Definition: dof_map.h:1435
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:1585
libmesh_assert(j)
bool need_full_sparsity_pattern
Definition: dof_map.h:1518
void add_algebraic_ghosting_functor(GhostingFunctor &ghosting_functor)
Definition: dof_map.C:1901
std::vector< dof_id_type > _first_old_scalar_df
Definition: dof_map.h:1572
DofConstraints _dof_constraints
Definition: dof_map.h:1581
CouplingMatrix * _dof_coupling
Definition: dof_map.h:1229
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_end() const
Definition: dof_map.h:317
std::vector< SparseMatrix< Number > * > _matrices
Definition: dof_map.h:1419
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:1583
std::vector< Variable > _variables
Definition: dof_map.h:1397
DofConstraints _stashed_dof_constraints
Definition: dof_map.h:1581
dof_id_type _n_old_dfs
Definition: dof_map.h:1556
void clear_sparsity()
Definition: dof_map.C:1860
std::set< GhostingFunctor * > _coupling_functors
Definition: dof_map.h:1512
std::vector< dof_id_type > _end_df
Definition: dof_map.h:1429
std::vector< dof_id_type > _first_df
Definition: dof_map.h:1424
MeshBase & _mesh
Definition: dof_map.h:1412
std::set< GhostingFunctor * >::const_iterator coupling_functors_end() const
Definition: dof_map.h:281
bool use_coupled_neighbor_dofs(const MeshBase &mesh) const
Definition: dof_map.C:1766
dof_id_type _n_dfs
Definition: dof_map.h:1543
void libMesh::DofMap::clear_sparsity ( )

Clears the sparsity pattern

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

1861 {
1863  {
1864  libmesh_assert(_sp.get());
1865  libmesh_assert(!_n_nz || _n_nz == &_sp->n_nz);
1866  libmesh_assert(!_n_oz || _n_oz == &_sp->n_oz);
1867  _sp.reset();
1868  }
1869  else
1870  {
1871  libmesh_assert(!_sp.get());
1872  delete _n_nz;
1873  delete _n_oz;
1874  }
1877 }
const class libmesh_nullptr_t libmesh_nullptr
libmesh_assert(j)
std::vector< dof_id_type > * _n_nz
Definition: dof_map.h:1532
std::vector< dof_id_type > * _n_oz
Definition: dof_map.h:1538
bool need_full_sparsity_pattern
Definition: dof_map.h:1518
UniquePtr< SparsityPattern::Build > _sp
Definition: dof_map.h:1524
const Parallel::Communicator& libMesh::ParallelObject::comm ( ) const
inlineinherited
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_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(), libMesh::ImplicitSystem::add_matrix(), libMesh::System::add_vector(), libMesh::EigenSparseLinearSolver< T >::adjoint_solve(), libMesh::UnstructuredMesh::all_second_order(), libMesh::MeshTools::Modification::all_tri(), libMesh::LaplaceMeshSmoother::allgather_graph(), 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::DistributedVector< T >::clone(), libMesh::EigenSparseVector< T >::clone(), libMesh::LaspackVector< T >::clone(), libMesh::EpetraVector< T >::clone(), libMesh::PetscVector< T >::clone(), libMesh::EpetraVector< T >::close(), libMesh::Parallel::Sort< KeyType, IdxType >::communicate_bins(), 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::Problem_Interface::computeF(), libMesh::Problem_Interface::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), 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::EpetraVector< T >::EpetraVector(), libMesh::WeightedPatchRecoveryErrorEstimator::estimate_error(), libMesh::PatchRecoveryErrorEstimator::estimate_error(), libMesh::JumpErrorEstimator::estimate_error(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::MeshRefinement::flag_elements_by_elem_fraction(), libMesh::MeshRefinement::flag_elements_by_error_fraction(), libMesh::MeshRefinement::flag_elements_by_nelem_target(), libMesh::MeshCommunication::gather(), libMesh::MeshCommunication::gather_neighboring_elements(), libMesh::CondensedEigenSystem::get_eigenpair(), get_info(), libMesh::ImplicitSystem::get_linear_solver(), libMesh::EquationSystems::get_solution(), libMesh::LocationMap< T >::init(), libMesh::PetscDiffSolver::init(), libMesh::TimeSolver::init(), libMesh::TopologyMap::init(), libMesh::TaoOptimizationSolver< T >::init(), libMesh::PetscNonlinearSolver< T >::init(), libMesh::DistributedVector< T >::init(), libMesh::EpetraVector< T >::init(), libMesh::PetscVector< 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::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(), 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::DistributedVector< T >::max(), libMesh::FEMSystem::mesh_position_set(), libMesh::MeshSerializer::MeshSerializer(), libMesh::DistributedVector< T >::min(), 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(), 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(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::XdrIO::read(), libMesh::CheckpointIO::read_header(), 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::DistributedMesh::renumber_dof_objects(), libMesh::MeshCommunication::send_coarse_ghosts(), 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(), libMesh::MeshRefinement::test_unflagged(), libMesh::MeshTools::total_weight(), libMesh::MeshRefinement::uniformly_coarsen(), libMesh::NameBasedIO::write(), libMesh::XdrIO::write(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::DistributedVector< T >::zero_clone(), libMesh::LaspackVector< T >::zero_clone(), libMesh::EigenSparseVector< T >::zero_clone(), libMesh::EpetraVector< T >::zero_clone(), and libMesh::PetscVector< T >::zero_clone().

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

1824 {
1825  _sp = this->build_sparsity(mesh);
1826 
1827  // It is possible that some \p SparseMatrix implementations want to
1828  // see it. Let them see it before we throw it away.
1829  std::vector<SparseMatrix<Number> *>::const_iterator
1830  pos = _matrices.begin(),
1831  end = _matrices.end();
1832 
1833  // If we need the full sparsity pattern, then we share a view of its
1834  // arrays, and we pass it in to the matrices.
1836  {
1837  _n_nz = &_sp->n_nz;
1838  _n_oz = &_sp->n_oz;
1839 
1840  for (; pos != end; ++pos)
1841  (*pos)->update_sparsity_pattern (_sp->sparsity_pattern);
1842  }
1843  // If we don't need the full sparsity pattern anymore, steal the
1844  // arrays we do need and free the rest of the memory
1845  else
1846  {
1847  if (!_n_nz)
1848  _n_nz = new std::vector<dof_id_type>();
1849  _n_nz->swap(_sp->n_nz);
1850  if (!_n_oz)
1851  _n_oz = new std::vector<dof_id_type>();
1852  _n_oz->swap(_sp->n_oz);
1853 
1854  _sp.reset();
1855  }
1856 }
MeshBase & mesh
IterBase * end
std::vector< dof_id_type > * _n_nz
Definition: dof_map.h:1532
std::vector< dof_id_type > * _n_oz
Definition: dof_map.h:1538
bool need_full_sparsity_pattern
Definition: dof_map.h:1518
UniquePtr< SparsityPattern::Build > _sp
Definition: dof_map.h:1524
UniquePtr< SparsityPattern::Build > build_sparsity(const MeshBase &mesh) const
Definition: dof_map.C:55
std::vector< SparseMatrix< Number > * > _matrices
Definition: dof_map.h:1419
void libMesh::DofMap::constrain_element_dyad_matrix ( DenseVector< Number > &  v,
DenseVector< Number > &  w,
std::vector< dof_id_type > &  row_dofs,
bool  asymmetric_constraint_rows = true 
) const
inline

Constrains a dyadic element matrix B = v w'. This method requires the element matrix to be square, in which case the elem_dofs correspond to the global DOF indices of both the rows and columns of the element matrix. For this case the rows and columns of the matrix necessarily correspond to variables of the same approximation order.

Definition at line 2015 of file dof_map_constraints.C.

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

Referenced by get_primal_constraint_values().

2019 {
2020  libmesh_assert_equal_to (v.size(), row_dofs.size());
2021  libmesh_assert_equal_to (w.size(), row_dofs.size());
2022 
2023  // check for easy return
2024  if (this->_dof_constraints.empty())
2025  return;
2026 
2027  // The constrained RHS is built up as R^T F.
2029 
2030  this->build_constraint_matrix (R, row_dofs);
2031 
2032  LOG_SCOPE("cnstrn_elem_dyad_mat()", "DofMap");
2033 
2034  // It is possible that the vector is not constrained at all.
2035  if ((R.m() == v.size()) &&
2036  (R.n() == row_dofs.size())) // if the RHS is constrained
2037  {
2038  // Compute the matrix-vector products
2039  DenseVector<Number> old_v(v);
2040  DenseVector<Number> old_w(w);
2041 
2042  // compute matrix/vector product
2043  R.vector_mult_transpose(v, old_v);
2044  R.vector_mult_transpose(w, old_w);
2045 
2046  libmesh_assert_equal_to (row_dofs.size(), v.size());
2047  libmesh_assert_equal_to (row_dofs.size(), w.size());
2048 
2049  /* Constrain only v, not w. */
2050 
2051  for (std::size_t i=0; i<row_dofs.size(); i++)
2052  if (this->is_constrained_dof(row_dofs[i]))
2053  {
2054  // If the DOF is constrained
2055  libmesh_assert (_dof_constraints.find(row_dofs[i]) != _dof_constraints.end());
2056 
2057  v(i) = 0;
2058  }
2059  } // end if the RHS is constrained.
2060 }
unsigned int n() const
void vector_mult_transpose(DenseVector< T > &dest, const DenseVector< T > &arg) const
Definition: dense_matrix.C:438
virtual unsigned int size() const libmesh_override
Definition: dense_vector.h:87
libmesh_assert(j)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1723
unsigned int m() const
DofConstraints _dof_constraints
Definition: dof_map.h:1581
void build_constraint_matrix(DenseMatrix< Number > &C, std::vector< dof_id_type > &elem_dofs, const bool called_recursively=false) const
void libMesh::DofMap::constrain_element_matrix ( DenseMatrix< Number > &  matrix,
std::vector< dof_id_type > &  elem_dofs,
bool  asymmetric_constraint_rows = true 
) const
inline

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

If asymmetric_constraint_rows is set to true (as it is by default), constraint row equations will be reinforced in a way which breaks matrix symmetry but makes inexact linear solver solutions more likely to satisfy hanging node constraints.

Definition at line 1554 of file dof_map_constraints.C.

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

Referenced by get_primal_constraint_values().

1557 {
1558  libmesh_assert_equal_to (elem_dofs.size(), matrix.m());
1559  libmesh_assert_equal_to (elem_dofs.size(), matrix.n());
1560 
1561  // check for easy return
1562  if (this->_dof_constraints.empty())
1563  return;
1564 
1565  // The constrained matrix is built up as C^T K C.
1567 
1568 
1569  this->build_constraint_matrix (C, elem_dofs);
1570 
1571  LOG_SCOPE("constrain_elem_matrix()", "DofMap");
1572 
1573  // It is possible that the matrix is not constrained at all.
1574  if ((C.m() == matrix.m()) &&
1575  (C.n() == elem_dofs.size())) // It the matrix is constrained
1576  {
1577  // Compute the matrix-matrix-matrix product C^T K C
1578  matrix.left_multiply_transpose (C);
1579  matrix.right_multiply (C);
1580 
1581 
1582  libmesh_assert_equal_to (matrix.m(), matrix.n());
1583  libmesh_assert_equal_to (matrix.m(), elem_dofs.size());
1584  libmesh_assert_equal_to (matrix.n(), elem_dofs.size());
1585 
1586 
1587  for (std::size_t i=0; i<elem_dofs.size(); i++)
1588  // If the DOF is constrained
1589  if (this->is_constrained_dof(elem_dofs[i]))
1590  {
1591  for (unsigned int j=0; j<matrix.n(); j++)
1592  matrix(i,j) = 0.;
1593 
1594  matrix(i,i) = 1.;
1595 
1596  if (asymmetric_constraint_rows)
1597  {
1598  DofConstraints::const_iterator
1599  pos = _dof_constraints.find(elem_dofs[i]);
1600 
1601  libmesh_assert (pos != _dof_constraints.end());
1602 
1603  const DofConstraintRow & constraint_row = pos->second;
1604 
1605  // This is an overzealous assertion in the presence of
1606  // heterogenous constraints: we now can constrain "u_i = c"
1607  // with no other u_j terms involved.
1608  //
1609  // libmesh_assert (!constraint_row.empty());
1610 
1611  for (DofConstraintRow::const_iterator
1612  it=constraint_row.begin(); it != constraint_row.end();
1613  ++it)
1614  for (std::size_t j=0; j<elem_dofs.size(); j++)
1615  if (elem_dofs[j] == it->first)
1616  matrix(i,j) = -it->second;
1617  }
1618  }
1619  } // end if is constrained...
1620 }
unsigned int n() const
libmesh_assert(j)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1723
virtual void right_multiply(const DenseMatrixBase< T > &M2) libmesh_override
Definition: dense_matrix.C:210
unsigned int m() const
DofConstraints _dof_constraints
Definition: dof_map.h:1581
void build_constraint_matrix(DenseMatrix< Number > &C, std::vector< dof_id_type > &elem_dofs, const bool called_recursively=false) const
void left_multiply_transpose(const DenseMatrix< T > &A)
Definition: dense_matrix.C:85
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
Definition: dof_map.h:88
void libMesh::DofMap::constrain_element_matrix ( DenseMatrix< Number > &  matrix,
std::vector< dof_id_type > &  row_dofs,
std::vector< dof_id_type > &  col_dofs,
bool  asymmetric_constraint_rows = true 
) const
inline

Constrains the element matrix. This method allows the element matrix to be non-square, in which case the row_dofs and col_dofs may be of different size and correspond to variables approximated in different spaces.

Definition at line 1885 of file dof_map_constraints.C.

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

1889 {
1890  libmesh_assert_equal_to (row_dofs.size(), matrix.m());
1891  libmesh_assert_equal_to (col_dofs.size(), matrix.n());
1892 
1893  // check for easy return
1894  if (this->_dof_constraints.empty())
1895  return;
1896 
1897  // The constrained matrix is built up as R^T K C.
1900 
1901  // Safeguard against the user passing us the same
1902  // object for row_dofs and col_dofs. If that is done
1903  // the calls to build_matrix would fail
1904  std::vector<dof_id_type> orig_row_dofs(row_dofs);
1905  std::vector<dof_id_type> orig_col_dofs(col_dofs);
1906 
1907  this->build_constraint_matrix (R, orig_row_dofs);
1908  this->build_constraint_matrix (C, orig_col_dofs);
1909 
1910  LOG_SCOPE("constrain_elem_matrix()", "DofMap");
1911 
1912  row_dofs = orig_row_dofs;
1913  col_dofs = orig_col_dofs;
1914 
1915  bool constraint_found = false;
1916 
1917  // K_constrained = R^T K C
1918 
1919  if ((R.m() == matrix.m()) &&
1920  (R.n() == row_dofs.size()))
1921  {
1922  matrix.left_multiply_transpose (R);
1923  constraint_found = true;
1924  }
1925 
1926  if ((C.m() == matrix.n()) &&
1927  (C.n() == col_dofs.size()))
1928  {
1929  matrix.right_multiply (C);
1930  constraint_found = true;
1931  }
1932 
1933  // It is possible that the matrix is not constrained at all.
1934  if (constraint_found)
1935  {
1936  libmesh_assert_equal_to (matrix.m(), row_dofs.size());
1937  libmesh_assert_equal_to (matrix.n(), col_dofs.size());
1938 
1939 
1940  for (std::size_t i=0; i<row_dofs.size(); i++)
1941  if (this->is_constrained_dof(row_dofs[i]))
1942  {
1943  for (unsigned int j=0; j<matrix.n(); j++)
1944  {
1945  if (row_dofs[i] != col_dofs[j])
1946  matrix(i,j) = 0.;
1947  else // If the DOF is constrained
1948  matrix(i,j) = 1.;
1949  }
1950 
1951  if (asymmetric_constraint_rows)
1952  {
1953  DofConstraints::const_iterator
1954  pos = _dof_constraints.find(row_dofs[i]);
1955 
1956  libmesh_assert (pos != _dof_constraints.end());
1957 
1958  const DofConstraintRow & constraint_row = pos->second;
1959 
1960  libmesh_assert (!constraint_row.empty());
1961 
1962  for (DofConstraintRow::const_iterator
1963  it=constraint_row.begin(); it != constraint_row.end();
1964  ++it)
1965  for (std::size_t j=0; j<col_dofs.size(); j++)
1966  if (col_dofs[j] == it->first)
1967  matrix(i,j) = -it->second;
1968  }
1969  }
1970  } // end if is constrained...
1971 }
unsigned int n() const
libmesh_assert(j)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1723
virtual void right_multiply(const DenseMatrixBase< T > &M2) libmesh_override
Definition: dense_matrix.C:210
unsigned int m() const
DofConstraints _dof_constraints
Definition: dof_map.h:1581
void build_constraint_matrix(DenseMatrix< Number > &C, std::vector< dof_id_type > &elem_dofs, const bool called_recursively=false) const
void left_multiply_transpose(const DenseMatrix< T > &A)
Definition: dense_matrix.C:85
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
Definition: dof_map.h:88
void libMesh::DofMap::constrain_element_matrix_and_vector ( DenseMatrix< Number > &  matrix,
DenseVector< Number > &  rhs,
std::vector< dof_id_type > &  elem_dofs,
bool  asymmetric_constraint_rows = true 
) const
inline

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

Definition at line 1624 of file dof_map_constraints.C.

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

Referenced by get_primal_constraint_values().

1628 {
1629  libmesh_assert_equal_to (elem_dofs.size(), matrix.m());
1630  libmesh_assert_equal_to (elem_dofs.size(), matrix.n());
1631  libmesh_assert_equal_to (elem_dofs.size(), rhs.size());
1632 
1633  // check for easy return
1634  if (this->_dof_constraints.empty())
1635  return;
1636 
1637  // The constrained matrix is built up as C^T K C.
1638  // The constrained RHS is built up as C^T F
1640 
1641  this->build_constraint_matrix (C, elem_dofs);
1642 
1643  LOG_SCOPE("cnstrn_elem_mat_vec()", "DofMap");
1644 
1645  // It is possible that the matrix is not constrained at all.
1646  if ((C.m() == matrix.m()) &&
1647  (C.n() == elem_dofs.size())) // It the matrix is constrained
1648  {
1649  // Compute the matrix-matrix-matrix product C^T K C
1650  matrix.left_multiply_transpose (C);
1651  matrix.right_multiply (C);
1652 
1653 
1654  libmesh_assert_equal_to (matrix.m(), matrix.n());
1655  libmesh_assert_equal_to (matrix.m(), elem_dofs.size());
1656  libmesh_assert_equal_to (matrix.n(), elem_dofs.size());
1657 
1658 
1659  for (std::size_t i=0; i<elem_dofs.size(); i++)
1660  if (this->is_constrained_dof(elem_dofs[i]))
1661  {
1662  for (unsigned int j=0; j<matrix.n(); j++)
1663  matrix(i,j) = 0.;
1664 
1665  // If the DOF is constrained
1666  matrix(i,i) = 1.;
1667 
1668  // This will put a nonsymmetric entry in the constraint
1669  // row to ensure that the linear system produces the
1670  // correct value for the constrained DOF.
1671  if (asymmetric_constraint_rows)
1672  {
1673  DofConstraints::const_iterator
1674  pos = _dof_constraints.find(elem_dofs[i]);
1675 
1676  libmesh_assert (pos != _dof_constraints.end());
1677 
1678  const DofConstraintRow & constraint_row = pos->second;
1679 
1680  // p refinement creates empty constraint rows
1681  // libmesh_assert (!constraint_row.empty());
1682 
1683  for (DofConstraintRow::const_iterator
1684  it=constraint_row.begin(); it != constraint_row.end();
1685  ++it)
1686  for (std::size_t j=0; j<elem_dofs.size(); j++)
1687  if (elem_dofs[j] == it->first)
1688  matrix(i,j) = -it->second;
1689  }
1690  }
1691 
1692 
1693  // Compute the matrix-vector product C^T F
1694  DenseVector<Number> old_rhs(rhs);
1695 
1696  // compute matrix/vector product
1697  C.vector_mult_transpose(rhs, old_rhs);
1698  } // end if is constrained...
1699 }
unsigned int n() const
void vector_mult_transpose(DenseVector< T > &dest, const DenseVector< T > &arg) const
Definition: dense_matrix.C:438
virtual unsigned int size() const libmesh_override
Definition: dense_vector.h:87
libmesh_assert(j)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1723
virtual void right_multiply(const DenseMatrixBase< T > &M2) libmesh_override
Definition: dense_matrix.C:210
unsigned int m() const
DofConstraints _dof_constraints
Definition: dof_map.h:1581
void build_constraint_matrix(DenseMatrix< Number > &C, std::vector< dof_id_type > &elem_dofs, const bool called_recursively=false) const
void left_multiply_transpose(const DenseMatrix< T > &A)
Definition: dense_matrix.C:85
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
Definition: dof_map.h:88
void libMesh::DofMap::constrain_element_vector ( DenseVector< Number > &  rhs,
std::vector< dof_id_type > &  dofs,
bool  asymmetric_constraint_rows = true 
) const
inline

Constrains the element vector.

Definition at line 1975 of file dof_map_constraints.C.

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

Referenced by get_primal_constraint_values().

1978 {
1979  libmesh_assert_equal_to (rhs.size(), row_dofs.size());
1980 
1981  // check for easy return
1982  if (this->_dof_constraints.empty())
1983  return;
1984 
1985  // The constrained RHS is built up as R^T F.
1987 
1988  this->build_constraint_matrix (R, row_dofs);
1989 
1990  LOG_SCOPE("constrain_elem_vector()", "DofMap");
1991 
1992  // It is possible that the vector is not constrained at all.
1993  if ((R.m() == rhs.size()) &&
1994  (R.n() == row_dofs.size())) // if the RHS is constrained
1995  {
1996  // Compute the matrix-vector product
1997  DenseVector<Number> old_rhs(rhs);
1998  R.vector_mult_transpose(rhs, old_rhs);
1999 
2000  libmesh_assert_equal_to (row_dofs.size(), rhs.size());
2001 
2002  for (std::size_t i=0; i<row_dofs.size(); i++)
2003  if (this->is_constrained_dof(row_dofs[i]))
2004  {
2005  // If the DOF is constrained
2006  libmesh_assert (_dof_constraints.find(row_dofs[i]) != _dof_constraints.end());
2007 
2008  rhs(i) = 0;
2009  }
2010  } // end if the RHS is constrained.
2011 }
unsigned int n() const
void vector_mult_transpose(DenseVector< T > &dest, const DenseVector< T > &arg) const
Definition: dense_matrix.C:438
virtual unsigned int size() const libmesh_override
Definition: dense_vector.h:87
libmesh_assert(j)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1723
unsigned int m() const
DofConstraints _dof_constraints
Definition: dof_map.h:1581
void build_constraint_matrix(DenseMatrix< Number > &C, std::vector< dof_id_type > &elem_dofs, const bool called_recursively=false) 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 2064 of file dof_map_constraints.C.

2065 {
2066  // check for easy return
2067  if (this->_dof_constraints.empty())
2068  return;
2069 
2070  // All the work is done by \p build_constraint_matrix. We just need
2071  // a dummy matrix.
2073  this->build_constraint_matrix (R, dofs);
2074 }
DofConstraints _dof_constraints
Definition: dof_map.h:1581
void build_constraint_matrix(DenseMatrix< Number > &C, std::vector< dof_id_type > &elem_dofs, const bool called_recursively=false) const
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 3997 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(), 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().

4001 {
4002  // We're constraining dofs on elem which correspond to p refinement
4003  // levels above p - this only makes sense if elem's p refinement
4004  // level is above p.
4005  libmesh_assert_greater (elem->p_level(), p);
4006  libmesh_assert_less (s, elem->n_sides());
4007 
4008  const unsigned int sys_num = this->sys_number();
4009  const unsigned int dim = elem->dim();
4010  ElemType type = elem->type();
4011  FEType low_p_fe_type = this->variable_type(var);
4012  FEType high_p_fe_type = this->variable_type(var);
4013  low_p_fe_type.order = static_cast<Order>(low_p_fe_type.order + p);
4014  high_p_fe_type.order = static_cast<Order>(high_p_fe_type.order +
4015  elem->p_level());
4016 
4017  const unsigned int n_nodes = elem->n_nodes();
4018  for (unsigned int n = 0; n != n_nodes; ++n)
4019  if (elem->is_node_on_side(n, s))
4020  {
4021  const Node & node = elem->node_ref(n);
4022  const unsigned int low_nc =
4023  FEInterface::n_dofs_at_node (dim, low_p_fe_type, type, n);
4024  const unsigned int high_nc =
4025  FEInterface::n_dofs_at_node (dim, high_p_fe_type, type, n);
4026 
4027  // since we may be running this method concurrently
4028  // on multiple threads we need to acquire a lock
4029  // before modifying the _dof_constraints object.
4030  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
4031 
4032  if (elem->is_vertex(n))
4033  {
4034  // Add "this is zero" constraint rows for high p vertex
4035  // dofs
4036  for (unsigned int i = low_nc; i != high_nc; ++i)
4037  {
4038  _dof_constraints[node.dof_number(sys_num,var,i)].clear();
4039  _primal_constraint_values.erase(node.dof_number(sys_num,var,i));
4040  }
4041  }
4042  else
4043  {
4044  const unsigned int total_dofs = node.n_comp(sys_num, var);
4045  libmesh_assert_greater_equal (total_dofs, high_nc);
4046  // Add "this is zero" constraint rows for high p
4047  // non-vertex dofs, which are numbered in reverse
4048  for (unsigned int j = low_nc; j != high_nc; ++j)
4049  {
4050  const unsigned int i = total_dofs - j - 1;
4051  _dof_constraints[node.dof_number(sys_num,var,i)].clear();
4052  _primal_constraint_values.erase(node.dof_number(sys_num,var,i));
4053  }
4054  }
4055  }
4056 }
Manages the family, order, etc. parameters for a given FE.
Definition: fe_type.h:178
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
A geometric point in (x,y,z) space associated with a DOF.
Definition: node.h:52
virtual ElemType type() const =0
unsigned int p_level() const
Definition: elem.h:2224
const FEType & variable_type(const unsigned int c) const
Definition: dof_map.h:1686
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:802
OrderWrapper order
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
Definition: threads.C:29
const Node & node_ref(const unsigned int i) const
Definition: elem.h:1752
DofConstraints _dof_constraints
Definition: dof_map.h:1581
virtual unsigned int n_sides() const =0
unsigned int sys_number() const
Definition: dof_map.h:1638
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:1583
virtual unsigned int dim() const =0
unsigned int n_comp(const unsigned int s, const unsigned int var) const
Definition: dof_object.h:772
DofConstraints::const_iterator libMesh::DofMap::constraint_rows_begin ( ) const
inline
Returns
An iterator pointing to the first DoF constraint row.

Definition at line 813 of file dof_map.h.

814  { return _dof_constraints.begin(); }
DofConstraints _dof_constraints
Definition: dof_map.h:1581
DofConstraints::const_iterator libMesh::DofMap::constraint_rows_end ( ) const
inline
Returns
An iterator pointing just past the last DoF constraint row.

Definition at line 819 of file dof_map.h.

820  { return _dof_constraints.end(); }
DofConstraints _dof_constraints
Definition: dof_map.h:1581
std::set<GhostingFunctor *>::const_iterator libMesh::DofMap::coupling_functors_begin ( ) const
inline

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
Definition: dof_map.h:1512
std::set<GhostingFunctor *>::const_iterator libMesh::DofMap::coupling_functors_end ( ) const
inline

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
Definition: dof_map.h:1512
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 1184 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().

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

Default algebraic ghosting functor

Definition at line 323 of file dof_map.h.

323 { return *_default_evaluating; }
UniquePtr< DefaultCoupling > _default_evaluating
Definition: dof_map.h:1489
DefaultCoupling& libMesh::DofMap::default_coupling ( )
inline

Default coupling functor

Definition at line 287 of file dof_map.h.

287 { return *_default_coupling; }
UniquePtr< DefaultCoupling > _default_coupling
Definition: dof_map.h:1481
void libMesh::ReferenceCounter::disable_print_counter_info ( )
staticinherited
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 918 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::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::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().

919 {
920  // This function must be run on all processors at once
921  parallel_object_only();
922 
923  // Log how long it takes to distribute the degrees of freedom
924  LOG_SCOPE("distribute_dofs()", "DofMap");
925 
926  libmesh_assert (mesh.is_prepared());
927 
928  const processor_id_type proc_id = this->processor_id();
929  const processor_id_type n_proc = this->n_processors();
930 
931  // libmesh_assert_greater (this->n_variables(), 0);
932  libmesh_assert_less (proc_id, n_proc);
933 
934  // re-init in case the mesh has changed
935  this->reinit(mesh);
936 
937  // By default distribute variables in a
938  // var-major fashion, but allow run-time
939  // specification
940  bool node_major_dofs = libMesh::on_command_line ("--node_major_dofs");
941 
942  // The DOF counter, will be incremented as we encounter
943  // new degrees of freedom
944  dof_id_type next_free_dof = 0;
945 
946  // Clear the send list before we rebuild it
947  _send_list.clear();
948 
949  // Set temporary DOF indices on this processor
950  if (node_major_dofs)
951  this->distribute_local_dofs_node_major (next_free_dof, mesh);
952  else
953  this->distribute_local_dofs_var_major (next_free_dof, mesh);
954 
955  // Get DOF counts on all processors
956  std::vector<dof_id_type> dofs_on_proc(n_proc, 0);
957  this->comm().allgather(next_free_dof, dofs_on_proc);
958 
959  // Resize and fill the _first_df and _end_df arrays
960 #ifdef LIBMESH_ENABLE_AMR
963 #endif
964 
965  _first_df.resize(n_proc);
966  _end_df.resize (n_proc);
967 
968  // Get DOF offsets
969  _first_df[0] = 0;
970  for (processor_id_type i=1; i < n_proc; ++i)
971  _first_df[i] = _end_df[i-1] = _first_df[i-1] + dofs_on_proc[i-1];
972  _end_df[n_proc-1] = _first_df[n_proc-1] + dofs_on_proc[n_proc-1];
973 
974  // Clear all the current DOF indices
975  // (distribute_dofs expects them cleared!)
976  this->invalidate_dofs(mesh);
977 
978  next_free_dof = _first_df[proc_id];
979 
980  // Set permanent DOF indices on this processor
981  if (node_major_dofs)
982  this->distribute_local_dofs_node_major (next_free_dof, mesh);
983  else
984  this->distribute_local_dofs_var_major (next_free_dof, mesh);
985 
986  libmesh_assert_equal_to (next_free_dof, _end_df[proc_id]);
987 
988  //------------------------------------------------------------
989  // At this point, all n_comp and dof_number values on local
990  // DofObjects should be correct, but a DistributedMesh might have
991  // incorrect values on non-local DofObjects. Let's request the
992  // correct values from each other processor.
993 
994  if (this->n_processors() > 1)
995  {
996  this->set_nonlocal_dof_objects(mesh.nodes_begin(),
997  mesh.nodes_end(),
999 
1000  this->set_nonlocal_dof_objects(mesh.elements_begin(),
1001  mesh.elements_end(),
1003  }
1004 
1005 #ifdef DEBUG
1006  {
1007  const unsigned int
1008  sys_num = this->sys_number();
1009 
1010  // Processors should all agree on DoF ids for the newly numbered
1011  // system.
1013 
1014  // DoF processor ids should match DofObject processor ids
1015  MeshBase::const_node_iterator node_it = mesh.nodes_begin();
1016  const MeshBase::const_node_iterator node_end = mesh.nodes_end();
1017  for ( ; node_it != node_end; ++node_it)
1018  {
1019  DofObject const * const dofobj = *node_it;
1020  const processor_id_type obj_proc_id = dofobj->processor_id();
1021 
1022  for (unsigned int v=0; v != dofobj->n_vars(sys_num); ++v)
1023  for (unsigned int c=0; c != dofobj->n_comp(sys_num,v); ++c)
1024  {
1025  const dof_id_type dofid = dofobj->dof_number(sys_num,v,c);
1026  libmesh_assert_greater_equal (dofid, this->first_dof(obj_proc_id));
1027  libmesh_assert_less (dofid, this->end_dof(obj_proc_id));
1028  }
1029  }
1030 
1031  MeshBase::const_element_iterator elem_it = mesh.elements_begin();
1032  const MeshBase::const_element_iterator elem_end = mesh.elements_end();
1033  for ( ; elem_it != elem_end; ++elem_it)
1034  {
1035  DofObject const * const dofobj = *elem_it;
1036  const processor_id_type obj_proc_id = dofobj->processor_id();
1037 
1038  for (unsigned int v=0; v != dofobj->n_vars(sys_num); ++v)
1039  for (unsigned int c=0; c != dofobj->n_comp(sys_num,v); ++c)
1040  {
1041  const dof_id_type dofid = dofobj->dof_number(sys_num,v,c);
1042  libmesh_assert_greater_equal (dofid, this->first_dof(obj_proc_id));
1043  libmesh_assert_less (dofid, this->end_dof(obj_proc_id));
1044  }
1045  }
1046  }
1047 #endif
1048 
1049  // Set the total number of degrees of freedom, then start finding
1050  // SCALAR degrees of freedom
1051 #ifdef LIBMESH_ENABLE_AMR
1052  _n_old_dfs = _n_dfs;
1054 #endif
1055  _n_dfs = _end_df[n_proc-1];
1056  _first_scalar_df.clear();
1058  dof_id_type current_SCALAR_dof_index = n_dofs() - n_SCALAR_dofs();
1059 
1060  // Calculate and cache the initial DoF indices for SCALAR variables.
1061  // This is an O(N_vars) calculation so we want to do it once per
1062  // renumbering rather than once per SCALAR_dof_indices() call
1063 
1064  for (unsigned int v=0; v<this->n_variables(); v++)
1065  if (this->variable(v).type().family == SCALAR)
1066  {
1067  _first_scalar_df[v] = current_SCALAR_dof_index;
1068  current_SCALAR_dof_index += this->variable(v).type().order.get_order();
1069  }
1070 
1071  // Allow our GhostingFunctor objects to reinit if necessary
1072  {
1073  std::set<GhostingFunctor *>::iterator gf_it = this->algebraic_ghosting_functors_begin();
1074  const std::set<GhostingFunctor *>::iterator gf_end = this->algebraic_ghosting_functors_end();
1075  for (; gf_it != gf_end; ++gf_it)
1076  {
1077  GhostingFunctor * gf = *gf_it;
1078  libmesh_assert(gf);
1079  gf->dofmap_reinit();
1080  }
1081  }
1082 
1083  {
1084  std::set<GhostingFunctor *>::iterator gf_it = this->coupling_functors_begin();
1085  const std::set<GhostingFunctor *>::iterator gf_end = this->coupling_functors_end();
1086  for (; gf_it != gf_end; ++gf_it)
1087  {
1088  GhostingFunctor * gf = *gf_it;
1089  libmesh_assert(gf);
1090  gf->dofmap_reinit();
1091  }
1092  }
1093 
1094  // Note that in the add_neighbors_to_send_list nodes on processor
1095  // boundaries that are shared by multiple elements are added for
1096  // each element.
1098 
1099  // Here we used to clean up that data structure; now System and
1100  // EquationSystems call that for us, after we've added constraint
1101  // dependencies to the send_list too.
1102  // this->sort_send_list ();
1103 }
DofObject * elem_ptr(MeshBase &mesh, dof_id_type i) const
Definition: dof_map.C:297
FEFamily family
Definition: fe_type.h:203
int get_order() const
Definition: fe_type.h:77
void distribute_local_dofs_node_major(dof_id_type &next_free_dof, MeshBase &mesh)
Definition: dof_map.C:1195
const FEType & type() const
Definition: variable.h:119
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_begin() const
Definition: dof_map.h:311
std::set< GhostingFunctor * >::const_iterator coupling_functors_begin() const
Definition: dof_map.h:275
std::vector< dof_id_type > _send_list
Definition: dof_map.h:1441
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
Definition: dof_map.h:1566
OrderWrapper order
Definition: fe_type.h:197
void invalidate_dofs(MeshBase &mesh) const
Definition: dof_map.C:818
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:1656
dof_id_type n_dofs() const
Definition: dof_map.h:510
std::vector< dof_id_type > _first_old_df
Definition: dof_map.h:1561
std::vector< dof_id_type > _first_scalar_df
Definition: dof_map.h:1435
libmesh_assert(j)
void add_neighbors_to_send_list(MeshBase &mesh)
Definition: dof_map.C:1567
std::vector< dof_id_type > _first_old_scalar_df
Definition: dof_map.h:1572
void libmesh_assert_valid_dof_ids(const MeshBase &mesh, unsigned int sysnum)
Definition: mesh_tools.C:1454
void set_nonlocal_dof_objects(iterator_type objects_begin, iterator_type objects_end, MeshBase &mesh, dofobject_accessor objects)
Definition: dof_map.C:305
static const dof_id_type invalid_id
Definition: dof_object.h:334
void reinit(MeshBase &mesh)
Definition: dof_map.C:455
unsigned int sys_number() const
Definition: dof_map.h:1638
std::set< GhostingFunctor * >::const_iterator algebraic_ghosting_functors_end() const
Definition: dof_map.h:317
dof_id_type end_dof() const
Definition: dof_map.h:578
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
Definition: dof_map.h:1556
std::vector< dof_id_type > _end_df
Definition: dof_map.h:1429
dof_id_type n_SCALAR_dofs() const
Definition: dof_map.h:515
std::vector< dof_id_type > _first_df
Definition: dof_map.h:1424
std::set< GhostingFunctor * >::const_iterator coupling_functors_end() const
Definition: dof_map.h:281
void distribute_local_dofs_var_major(dof_id_type &next_free_dof, MeshBase &mesh)
Definition: dof_map.C:1349
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
Definition: dof_map.h:1543
void allgather(const T &send, std::vector< T > &recv) const
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 1195 of file dof_map.C.

References _n_SCALAR_dofs, libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), libMesh::Variable::active_on_subdomain(), libMesh::FEType::family, libMesh::OrderWrapper::get_order(), libMesh::DofObject::invalid_id, libMesh::libmesh_assert(), libMesh::MeshBase::local_nodes_begin(), libMesh::MeshBase::local_nodes_end(), mesh, libMesh::DofObject::n_comp(), libMesh::DofObject::n_comp_group(), n_nodes, libMesh::Elem::n_nodes(), libMesh::ParallelObject::n_processors(), libMesh::DofObject::n_var_groups(), n_variable_groups(), libMesh::VariableGroup::n_variables(), libMesh::Elem::node_ref(), libMesh::FEType::order, libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::SCALAR, libMesh::DofObject::set_vg_dof_base(), libMesh::Elem::subdomain_id(), sys_number(), libMesh::Variable::type(), variable_group(), and libMesh::DofObject::vg_dof_base().

Referenced by distribute_dofs().

1197 {
1198  const unsigned int sys_num = this->sys_number();
1199  const unsigned int n_var_groups = this->n_variable_groups();
1200 
1201  //-------------------------------------------------------------------------
1202  // First count and assign temporary numbers to local dofs
1203  MeshBase::element_iterator elem_it = mesh.active_local_elements_begin();
1204  const MeshBase::element_iterator elem_end = mesh.active_local_elements_end();
1205 
1206  for ( ; elem_it != elem_end; ++elem_it)
1207  {
1208  // Only number dofs connected to active
1209  // elements on this processor.
1210  Elem * elem = *elem_it;
1211  const unsigned int n_nodes = elem->n_nodes();
1212 
1213  // First number the nodal DOFS
1214  for (unsigned int n=0; n<n_nodes; n++)
1215  {
1216  Node & node = elem->node_ref(n);
1217 
1218  for (unsigned vg=0; vg<n_var_groups; vg++)
1219  {
1220  const VariableGroup & vg_description(this->variable_group(vg));
1221 
1222  if ((vg_description.type().family != SCALAR) &&
1223  (vg_description.active_on_subdomain(elem->subdomain_id())))
1224  {
1225  // assign dof numbers (all at once) if this is
1226  // our node and if they aren't already there
1227  if ((node.n_comp_group(sys_num,vg) > 0) &&
1228  (node.processor_id() == this->processor_id()) &&
1229  (node.vg_dof_base(sys_num,vg) ==
1231  {
1232  node.set_vg_dof_base(sys_num, vg,
1233  next_free_dof);
1234  next_free_dof += (vg_description.n_variables()*
1235  node.n_comp_group(sys_num,vg));
1236  //node.debug_buffer();
1237  }
1238  }
1239  }
1240  }
1241 
1242  // Now number the element DOFS
1243  for (unsigned vg=0; vg<n_var_groups; vg++)
1244  {
1245  const VariableGroup & vg_description(this->variable_group(vg));
1246 
1247  if ((vg_description.type().family != SCALAR) &&
1248  (vg_description.active_on_subdomain(elem->subdomain_id())))
1249  if (elem->n_comp_group(sys_num,vg) > 0)
1250  {
1251  libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1253 
1254  elem->set_vg_dof_base(sys_num,
1255  vg,
1256  next_free_dof);
1257 
1258  next_free_dof += (vg_description.n_variables()*
1259  elem->n_comp(sys_num,vg));
1260  }
1261  }
1262  } // done looping over elements
1263 
1264 
1265  // we may have missed assigning DOFs to nodes that we own
1266  // but to which we have no connected elements matching our
1267  // variable restriction criterion. this will happen, for example,
1268  // if variable V is restricted to subdomain S. We may not own
1269  // any elements which live in S, but we may own nodes which are
1270  // *connected* to elements which do. in this scenario these nodes
1271  // will presently have unnumbered DOFs. we need to take care of
1272  // them here since we own them and no other processor will touch them.
1273  {
1274  MeshBase::node_iterator node_it = mesh.local_nodes_begin();
1275  const MeshBase::node_iterator node_end = mesh.local_nodes_end();
1276 
1277  for (; node_it != node_end; ++node_it)
1278  {
1279  Node * node = *node_it;
1280  libmesh_assert(node);
1281 
1282  for (unsigned vg=0; vg<n_var_groups; vg++)
1283  {
1284  const VariableGroup & vg_description(this->variable_group(vg));
1285 
1286  if (node->n_comp_group(sys_num,vg))
1287  if (node->vg_dof_base(sys_num,vg) == DofObject::invalid_id)
1288  {
1289  node->set_vg_dof_base (sys_num,
1290  vg,
1291  next_free_dof);
1292 
1293  next_free_dof += (vg_description.n_variables()*
1294  node->n_comp(sys_num,vg));
1295  }
1296  }
1297  }
1298  }
1299 
1300  // Finally, count up the SCALAR dofs
1301  this->_n_SCALAR_dofs = 0;
1302  for (unsigned vg=0; vg<n_var_groups; vg++)
1303  {
1304  const VariableGroup & vg_description(this->variable_group(vg));
1305 
1306  if (vg_description.type().family == SCALAR)
1307  {
1308  this->_n_SCALAR_dofs += (vg_description.n_variables()*
1309  vg_description.type().order.get_order());
1310  continue;
1311  }
1312  }
1313 
1314  // Only increment next_free_dof if we're on the processor
1315  // that holds this SCALAR variable
1316  if (this->processor_id() == (this->n_processors()-1))
1317  next_free_dof += _n_SCALAR_dofs;
1318 
1319 #ifdef DEBUG
1320  {
1321  // libMesh::out << "next_free_dof=" << next_free_dof << std::endl
1322  // << "_n_SCALAR_dofs=" << _n_SCALAR_dofs << std::endl;
1323 
1324  // Make sure we didn't miss any nodes
1325  MeshTools::libmesh_assert_valid_procids<Node>(mesh);
1326 
1327  MeshBase::node_iterator node_it = mesh.local_nodes_begin();
1328  const MeshBase::node_iterator node_end = mesh.local_nodes_end();
1329  for (; node_it != node_end; ++node_it)
1330  {
1331  Node * obj = *node_it;
1332  libmesh_assert(obj);
1333  unsigned int n_var_g = obj->n_var_groups(this->sys_number());
1334  for (unsigned int vg=0; vg != n_var_g; ++vg)
1335  {
1336  unsigned int n_comp_g =
1337  obj->n_comp_group(this->sys_number(), vg);
1338  dof_id_type my_first_dof = n_comp_g ?
1339  obj->vg_dof_base(this->sys_number(), vg) : 0;
1340  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
1341  }
1342  }
1343  }
1344 #endif // DEBUG
1345 }
processor_id_type n_processors() const
MeshBase & mesh
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:1646
libmesh_assert(j)
const dof_id_type n_nodes
Definition: tecplot_io.C:67
dof_id_type _n_SCALAR_dofs
Definition: dof_map.h:1549
static const dof_id_type invalid_id
Definition: dof_object.h:334
unsigned int n_variable_groups() const
Definition: dof_map.h:469
unsigned int sys_number() const
Definition: dof_map.h:1638
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 1349 of file dof_map.C.

References _n_SCALAR_dofs, libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), libMesh::Variable::active_on_subdomain(), libMesh::FEType::family, libMesh::OrderWrapper::get_order(), libMesh::DofObject::invalid_id, libMesh::libmesh_assert(), libMesh::MeshBase::local_nodes_begin(), libMesh::MeshBase::local_nodes_end(), merge_ghost_functor_outputs(), mesh, libMesh::DofObject::n_comp_group(), n_nodes, libMesh::Elem::n_nodes(), libMesh::ParallelObject::n_processors(), libMesh::DofObject::n_var_groups(), n_variable_groups(), libMesh::VariableGroup::n_variables(), libMesh::Elem::node_ref(), libMesh::FEType::order, libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::SCALAR, libMesh::DofObject::set_vg_dof_base(), libMesh::Elem::subdomain_id(), sys_number(), libMesh::Variable::type(), variable_group(), and libMesh::DofObject::vg_dof_base().

Referenced by distribute_dofs().

1351 {
1352  const unsigned int sys_num = this->sys_number();
1353  const unsigned int n_var_groups = this->n_variable_groups();
1354 
1355  //-------------------------------------------------------------------------
1356  // First count and assign temporary numbers to local dofs
1357  for (unsigned vg=0; vg<n_var_groups; vg++)
1358  {
1359  const VariableGroup & vg_description(this->variable_group(vg));
1360 
1361  const unsigned int n_vars_in_group = vg_description.n_variables();
1362 
1363  // Skip the SCALAR dofs
1364  if (vg_description.type().family == SCALAR)
1365  continue;
1366 
1367  MeshBase::element_iterator elem_it = mesh.active_local_elements_begin();
1368  const MeshBase::element_iterator elem_end = mesh.active_local_elements_end();
1369 
1370  for ( ; elem_it != elem_end; ++elem_it)
1371  {
1372  // Only number dofs connected to active
1373  // elements on this processor.
1374  Elem * elem = *elem_it;
1375 
1376  // ... and only variables which are active on
1377  // on this element's subdomain
1378  if (!vg_description.active_on_subdomain(elem->subdomain_id()))
1379  continue;
1380 
1381  const unsigned int n_nodes = elem->n_nodes();
1382 
1383  // First number the nodal DOFS
1384  for (unsigned int n=0; n<n_nodes; n++)
1385  {
1386  Node & node = elem->node_ref(n);
1387 
1388  // assign dof numbers (all at once) if this is
1389  // our node and if they aren't already there
1390  if ((node.n_comp_group(sys_num,vg) > 0) &&
1391  (node.processor_id() == this->processor_id()) &&
1392  (node.vg_dof_base(sys_num,vg) ==
1394  {
1395  node.set_vg_dof_base(sys_num, vg, next_free_dof);
1396 
1397  next_free_dof += (n_vars_in_group*
1398  node.n_comp_group(sys_num,vg));
1399  }
1400  }
1401 
1402  // Now number the element DOFS
1403  if (elem->n_comp_group(sys_num,vg) > 0)
1404  {
1405  libmesh_assert_equal_to (elem->vg_dof_base(sys_num,vg),
1407 
1408  elem->set_vg_dof_base(sys_num,
1409  vg,
1410  next_free_dof);
1411 
1412  next_free_dof += (n_vars_in_group*
1413  elem->n_comp_group(sys_num,vg));
1414  }
1415  } // end loop on elements
1416 
1417  // we may have missed assigning DOFs to nodes that we own
1418  // but to which we have no connected elements matching our
1419  // variable restriction criterion. this will happen, for example,
1420  // if variable V is restricted to subdomain S. We may not own
1421  // any elements which live in S, but we may own nodes which are
1422  // *connected* to elements which do. in this scenario these nodes
1423  // will presently have unnumbered DOFs. we need to take care of
1424  // them here since we own them and no other processor will touch them.
1425  {
1426  MeshBase::node_iterator node_it = mesh.local_nodes_begin();
1427  const MeshBase::node_iterator node_end = mesh.local_nodes_end();
1428 
1429  for (; node_it != node_end; ++node_it)
1430  {
1431  Node * node = *node_it;
1432  libmesh_assert(node);
1433 
1434  if (node->n_comp_group(sys_num,vg))
1435  if (node->vg_dof_base(sys_num,vg) == DofObject::invalid_id)
1436  {
1437  node->set_vg_dof_base (sys_num,
1438  vg,
1439  next_free_dof);
1440 
1441  next_free_dof += (n_vars_in_group*
1442  node->n_comp_group(sys_num,vg));
1443  }
1444  }
1445  }
1446  } // end loop on variable groups
1447 
1448  // Finally, count up the SCALAR dofs
1449  this->_n_SCALAR_dofs = 0;
1450  for (unsigned vg=0; vg<n_var_groups; vg++)
1451  {
1452  const VariableGroup & vg_description(this->variable_group(vg));
1453 
1454  if (vg_description.type().family == SCALAR)
1455  {
1456  this->_n_SCALAR_dofs += (vg_description.n_variables()*
1457  vg_description.type().order.get_order());
1458  continue;
1459  }
1460  }
1461 
1462  // Only increment next_free_dof if we're on the processor
1463  // that holds this SCALAR variable
1464  if (this->processor_id() == (this->n_processors()-1))
1465  next_free_dof += _n_SCALAR_dofs;
1466 
1467 #ifdef DEBUG
1468  {
1469  // Make sure we didn't miss any nodes
1470  MeshTools::libmesh_assert_valid_procids<Node>(mesh);
1471 
1472  MeshBase::node_iterator node_it = mesh.local_nodes_begin();
1473  const MeshBase::node_iterator node_end = mesh.local_nodes_end();
1474  for (; node_it != node_end; ++node_it)
1475  {
1476  Node * obj = *node_it;
1477  libmesh_assert(obj);
1478  unsigned int n_var_g = obj->n_var_groups(this->sys_number());
1479  for (unsigned int vg=0; vg != n_var_g; ++vg)
1480  {
1481  unsigned int n_comp_g =
1482  obj->n_comp_group(this->sys_number(), vg);
1483  dof_id_type my_first_dof = n_comp_g ?
1484  obj->vg_dof_base(this->sys_number(), vg) : 0;
1485  libmesh_assert_not_equal_to (my_first_dof, DofObject::invalid_id);
1486  }
1487  }
1488  }
1489 #endif // DEBUG
1490 }
processor_id_type n_processors() const
MeshBase & mesh
const VariableGroup & variable_group(const unsigned int c) const
Definition: dof_map.h:1646
libmesh_assert(j)
const dof_id_type n_nodes
Definition: tecplot_io.C:67
dof_id_type _n_SCALAR_dofs
Definition: dof_map.h:1549
static const dof_id_type invalid_id
Definition: dof_object.h:334
unsigned int n_variable_groups() const
Definition: dof_map.h:469
unsigned int sys_number() const
Definition: dof_map.h:1638
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 2005 of file dof_map.C.

References _dof_indices(), libMesh::Elem::active(), libMesh::Variable::active_on_subdomain(), libMesh::FEType::family, libMesh::MeshTools::Subdivision::find_one_ring(), libMesh::Elem::get_nodes(), libMesh::Tri3Subdivision::is_ghost(), libMesh::libmesh_assert(), 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(), 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(), libMesh::MeshFunction::discontinuous_gradient(), libMesh::MeshFunction::discontinuous_value(), DMCreateDomainDecomposition_libMesh(), DMCreateFieldDecomposition_libMesh(), dof_indices(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::EquationSystems::get_solution(), libMesh::MeshFunction::gradient(), libMesh::SparsityPattern::Build::handle_vi_vj(), libMesh::MeshFunction::hessian(), libMesh::SystemSubsetBySubdomain::init(), is_evaluable(), libMesh::System::local_dof_indices(), 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::FEMContext::pre_fe_reinit(), libMesh::HPCoarsenTest::select_refinement(), libMesh::EnsightIO::write_scalar_ascii(), and libMesh::EnsightIO::write_vector_ascii().

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

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

2171 {
2172  // We allow node==NULL to request just SCALAR dofs
2173  // libmesh_assert(elem);
2174 
2175  LOG_SCOPE("dof_indices(Node)", "DofMap");
2176 
2177  // Clear the DOF indices vector
2178  di.clear();
2179 
2180  const unsigned int n_vars = this->n_variables();
2181  const unsigned int sys_num = this->sys_number();
2182 
2183  // Get the dof numbers
2184  for (unsigned int v=0; v<n_vars; v++)
2185  {
2186  const Variable & var = this->variable(v);
2187  if (var.type().family == SCALAR)
2188  {
2189  std::vector<dof_id_type> di_new;
2190  this->SCALAR_dof_indices(di_new,v);
2191  di.insert( di.end(), di_new.begin(), di_new.end());
2192  }
2193  else
2194  {
2195  const int n_comp = node->n_comp(sys_num,v);
2196  for (int i=0; i != n_comp; ++i)
2197  {
2198  libmesh_assert_not_equal_to
2199  (node->dof_number(sys_num,v,i),
2201  di.push_back(node->dof_number(sys_num,v,i));
2202  }
2203  }
2204  }
2205 }
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:1656
const unsigned int n_vars
Definition: tecplot_io.C:68
static const dof_id_type invalid_id
Definition: dof_object.h:334
unsigned int sys_number() const
Definition: dof_map.h:1638
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
Definition: dof_map.C:2369
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 2208 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().

2211 {
2212  if (vn == libMesh::invalid_uint)
2213  {
2214  this->dof_indices(node, di);
2215  return;
2216  }
2217 
2218  // We allow node==NULL to request just SCALAR dofs
2219  // libmesh_assert(elem);
2220 
2221  LOG_SCOPE("dof_indices(Node)", "DofMap");
2222 
2223  // Clear the DOF indices vector
2224  di.clear();
2225 
2226  const unsigned int sys_num = this->sys_number();
2227 
2228  // Get the dof numbers
2229  const Variable & var = this->variable(vn);
2230  if (var.type().family == SCALAR)
2231  {
2232  std::vector<dof_id_type> di_new;
2233  this->SCALAR_dof_indices(di_new,vn);
2234  di.insert( di.end(), di_new.begin(), di_new.end());
2235  }
2236  else
2237  {
2238  const int n_comp = node->n_comp(sys_num,vn);
2239  for (int i=0; i != n_comp; ++i)
2240  {
2241  libmesh_assert_not_equal_to
2242  (node->dof_number(sys_num,vn,i),
2244  di.push_back(node->dof_number(sys_num,vn,i));
2245  }
2246  }
2247 }
const unsigned int invalid_uint
Definition: libmesh.h:184
const Variable & variable(const unsigned int c) const
Definition: dof_map.h:1656
static const dof_id_type invalid_id
Definition: dof_object.h:334
unsigned int sys_number() const
Definition: dof_map.h:1638
void SCALAR_dof_indices(std::vector< dof_id_type > &di, const unsigned int vn, const bool old_dofs=false) const
Definition: dof_map.C:2369
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2005
processor_id_type libMesh::DofMap::dof_owner ( const dof_id_type  dof) const
inline
Returns
The processor id that owns the dof index dof

Definition at line 584 of file dof_map.h.

References libMesh::libmesh_assert().

585  { std::vector<dof_id_type>::const_iterator ub =
586  std::upper_bound(_end_df.begin(), _end_df.end(), dof);
587  libmesh_assert (ub != _end_df.end());
588  return (ub - _end_df.begin());
589  }
libmesh_assert(j)
std::vector< dof_id_type > _end_df
Definition: dof_map.h:1429
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 }
dof_id_type libMesh::DofMap::end_dof ( const processor_id_type  proc) const
inline
dof_id_type libMesh::DofMap::end_dof ( ) const
inline

Definition at line 578 of file dof_map.h.

References libMesh::processor_id().

Referenced by add_neighbors_to_send_list(), all_semilocal_indices(), distribute_dofs(), get_info(), is_evaluable(), and local_variable_indices().

579  { return this->end_dof(this->processor_id()); }
dof_id_type end_dof() const
Definition: dof_map.h:578
processor_id_type processor_id() const
dof_id_type libMesh::DofMap::end_old_dof ( const processor_id_type  proc) const
inline
Returns
The first old dof index that is after all indices local to processor proc.

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

Definition at line 598 of file dof_map.h.

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

599  { libmesh_assert_less (proc, _end_old_df.size()); return _end_old_df[proc]; }
std::vector< dof_id_type > _end_old_df
Definition: dof_map.h:1566
dof_id_type libMesh::DofMap::end_old_dof ( ) const
inline

Definition at line 601 of file dof_map.h.

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

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

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

References libMesh::NumericVector< T >::close(), libMesh::NumericVector< T >::closed(), libMesh::NumericVector< T >::get(), libMesh::GHOSTED, libMesh::libmesh_assert(), libmesh_nullptr, libMesh::NumericVector< T >::localize(), libMesh::PARALLEL, libMesh::SERIAL, libMesh::NumericVector< T >::set(), libMesh::NumericVector< T >::size(), and libMesh::NumericVector< T >::type().

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

2179 {
2180  parallel_object_only();
2181 
2182  if (!this->n_constrained_dofs())
2183  return;
2184 
2185  LOG_SCOPE("enforce_adjoint_constraints_exactly()", "DofMap");
2186 
2187  NumericVector<Number> * v_local = libmesh_nullptr; // will be initialized below
2188  NumericVector<Number> * v_global = libmesh_nullptr; // will be initialized below
2190  if (v.type() == SERIAL)
2191  {
2192  v_built = NumericVector<Number>::build(this->comm());
2193  v_built->init(this->n_dofs(), this->n_local_dofs(), true, PARALLEL);
2194  v_built->close();
2195 
2196  for (dof_id_type i=v_built->first_local_index();
2197  i<v_built->last_local_index(); i++)
2198  v_built->set(i, v(i));
2199  v_built->close();
2200  v_global = v_built.get();
2201 
2202  v_local = &v;
2203  libmesh_assert (v_local->closed());
2204  }
2205  else if (v.type() == PARALLEL)
2206  {
2207  v_built = NumericVector<Number>::build(this->comm());
2208  v_built->init (v.size(), v.size(), true, SERIAL);
2209  v.localize(*v_built);
2210  v_built->close();
2211  v_local = v_built.get();
2212 
2213  v_global = &v;
2214  }
2215  else if (v.type() == GHOSTED)
2216  {
2217  v_local = &v;
2218  v_global = &v;
2219  }
2220  else // unknown v.type()
2221  libmesh_error_msg("ERROR: Unknown v.type() == " << v.type());
2222 
2223  // We should never hit these asserts because we should error-out in
2224  // else clause above. Just to be sure we don't try to use v_local
2225  // and v_global uninitialized...
2226  libmesh_assert(v_local);
2227  libmesh_assert(v_global);
2228 
2229  // Do we have any non_homogeneous constraints?
2230  const AdjointDofConstraintValues::const_iterator
2231  adjoint_constraint_map_it = _adjoint_constraint_values.find(q);
2232  const DofConstraintValueMap * constraint_map =
2233  (adjoint_constraint_map_it == _adjoint_constraint_values.end()) ?
2234  libmesh_nullptr : &adjoint_constraint_map_it->second;
2235 
2236  DofConstraints::const_iterator c_it = _dof_constraints.begin();
2237  const DofConstraints::const_iterator c_end = _dof_constraints.end();
2238 
2239  for ( ; c_it != c_end; ++c_it)
2240  {
2241  dof_id_type constrained_dof = c_it->first;
2242  if (constrained_dof < this->first_dof() ||
2243  constrained_dof >= this->end_dof())
2244  continue;
2245 
2246  const DofConstraintRow constraint_row = c_it->second;
2247 
2248  Number exact_value = 0;
2249  if (constraint_map)
2250  {
2251  const DofConstraintValueMap::const_iterator
2252  adjoint_constraint_it =
2253  constraint_map->find(constrained_dof);
2254  if (adjoint_constraint_it != constraint_map->end())
2255  exact_value = adjoint_constraint_it->second;
2256  }
2257 
2258  for (DofConstraintRow::const_iterator
2259  j=constraint_row.begin(); j != constraint_row.end();
2260  ++j)
2261  exact_value += j->second * (*v_local)(j->first);
2262 
2263  v_global->set(constrained_dof, exact_value);
2264  }
2265 
2266  // If the old vector was serial, we probably need to send our values
2267  // to other processors
2268  if (v.type() == SERIAL)
2269  {
2270 #ifndef NDEBUG
2271  v_global->close();
2272 #endif
2273  v_global->localize (v);
2274  }
2275  v.close();
2276 }
virtual bool closed() const
virtual numeric_index_type size() const =0
dof_id_type n_constrained_dofs() const
const class libmesh_nullptr_t libmesh_nullptr
dof_id_type n_dofs() const
Definition: dof_map.h:510
AdjointDofConstraintValues _adjoint_constraint_values
Definition: dof_map.h:1585
libmesh_assert(j)
std::unique_ptr< T > UniquePtr
Definition: auto_ptr.h:46
static UniquePtr< NumericVector< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package())
DofConstraints _dof_constraints
Definition: dof_map.h:1581
virtual void close()=0
dof_id_type end_dof() const
Definition: dof_map.h:578
virtual void get(const std::vector< numeric_index_type > &index, T *values) const
const Parallel::Communicator & comm() const
dof_id_type n_local_dofs() const
Definition: dof_map.h:520
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
Definition: dof_map.h:88
ParallelType type() const
virtual void set(const numeric_index_type i, const T value)=0
virtual void localize(std::vector< T > &v_local) const =0
dof_id_type first_dof() const
Definition: dof_map.h:538
uint8_t dof_id_type
Definition: id_types.h:64
void libMesh::DofMap::enforce_constraints_exactly ( const System system,
NumericVector< Number > *  v = libmesh_nullptr,
bool  homogeneous = false 
) const
inline

Constrains the numeric vector v, which represents a solution defined on the mesh. This may need to be used after a linear solve, if your linear solver's solutions do not satisfy your DoF constraints to a tight enough tolerance.

If v == 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 2078 of file dof_map_constraints.C.

References libMesh::NumericVector< T >::close(), libMesh::NumericVector< T >::closed(), 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().

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(), DMlibMeshFunction(), DMlibMeshJacobian(), get_primal_constraint_values(), 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().

2081 {
2082  parallel_object_only();
2083 
2084  if (!this->n_constrained_dofs())
2085  return;
2086 
2087  LOG_SCOPE("enforce_constraints_exactly()","DofMap");
2088 
2089  if (!v)
2090  v = system.solution.get();
2091 
2092  NumericVector<Number> * v_local = libmesh_nullptr; // will be initialized below
2093  NumericVector<Number> * v_global = libmesh_nullptr; // will be initialized below
2095  if (v->type() == SERIAL)
2096  {
2097  v_built = NumericVector<Number>::build(this->comm());
2098  v_built->init(this->n_dofs(), this->n_local_dofs(), true, PARALLEL);
2099  v_built->close();
2100 
2101  for (dof_id_type i=v_built->first_local_index();
2102  i<v_built->last_local_index(); i++)
2103  v_built->set(i, (*v)(i));
2104  v_built->close();
2105  v_global = v_built.get();
2106 
2107  v_local = v;
2108  libmesh_assert (v_local->closed());
2109  }
2110  else if (v->type() == PARALLEL)
2111  {
2112  v_built = NumericVector<Number>::build(this->comm());
2113  v_built->init (v->size(), v->size(), true, SERIAL);
2114  v->localize(*v_built);
2115  v_built->close();
2116  v_local = v_built.get();
2117 
2118  v_global = v;
2119  }
2120  else if (v->type() == GHOSTED)
2121  {
2122  v_local = v;
2123  v_global = v;
2124  }
2125  else // unknown v->type()
2126  libmesh_error_msg("ERROR: Unknown v->type() == " << v->type());
2127 
2128  // We should never hit these asserts because we should error-out in
2129  // else clause above. Just to be sure we don't try to use v_local
2130  // and v_global uninitialized...
2131  libmesh_assert(v_local);
2132  libmesh_assert(v_global);
2133  libmesh_assert_equal_to (this, &(system.get_dof_map()));
2134 
2135  DofConstraints::const_iterator c_it = _dof_constraints.begin();
2136  const DofConstraints::const_iterator c_end = _dof_constraints.end();
2137 
2138  for ( ; c_it != c_end; ++c_it)
2139  {
2140  dof_id_type constrained_dof = c_it->first;
2141  if (constrained_dof < this->first_dof() ||
2142  constrained_dof >= this->end_dof())
2143  continue;
2144 
2145  const DofConstraintRow constraint_row = c_it->second;
2146 
2147  Number exact_value = 0;
2148  if (!homogeneous)
2149  {
2150  DofConstraintValueMap::const_iterator rhsit =
2151  _primal_constraint_values.find(constrained_dof);
2152  if (rhsit != _primal_constraint_values.end())
2153  exact_value = rhsit->second;
2154  }
2155  for (DofConstraintRow::const_iterator
2156  j=constraint_row.begin(); j != constraint_row.end();
2157  ++j)
2158  exact_value += j->second * (*v_local)(j->first);
2159 
2160  v_global->set(constrained_dof, exact_value);
2161  }
2162 
2163  // If the old vector was serial, we probably need to send our values
2164  // to other processors
2165  if (v->type() == SERIAL)
2166  {
2167 #ifndef NDEBUG
2168  v_global->close();
2169 #endif
2170  v_global->localize (*v);
2171  }
2172  v->close();
2173 }
virtual bool closed() const
virtual numeric_index_type size() const =0
dof_id_type n_constrained_dofs() const
const class libmesh_nullptr_t libmesh_nullptr
dof_id_type n_dofs() const
Definition: dof_map.h:510
libmesh_assert(j)
std::unique_ptr< T > UniquePtr
Definition: auto_ptr.h:46
static UniquePtr< NumericVector< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package())
const DofMap & get_dof_map() const
Definition: system.h:2028
DofConstraints _dof_constraints
Definition: dof_map.h:1581
UniquePtr< NumericVector< Number > > solution
Definition: system.h:1521
virtual void close()=0
dof_id_type end_dof() const
Definition: dof_map.h:578
virtual void get(const std::vector< numeric_index_type > &index, T *values) const
const Parallel::Communicator & comm() const
DofConstraintValueMap _primal_constraint_values
Definition: dof_map.h:1583
dof_id_type n_local_dofs() const
Definition: dof_map.h:520
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
Definition: dof_map.h:88
ParallelType type() const
virtual void set(const numeric_index_type i, const T value)=0
virtual void localize(std::vector< T > &v_local) const =0
dof_id_type first_dof() const
Definition: dof_map.h:538
uint8_t dof_id_type
Definition: id_types.h:64
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 1919 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().

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

2691 {
2692  typedef std::set<dof_id_type> RCSet;
2693 
2694  // First insert the DOFS we already depend on into the set.
2695  RCSet dof_set (elem_dofs.begin(), elem_dofs.end());
2696 
2697  bool done = true;
2698 
2699  // Next insert any dofs those might be constrained in terms
2700  // of. Note that in this case we may not be done: Those may
2701  // in turn depend on others. So, we need to repeat this process
2702  // in that case until the system depends only on unconstrained
2703  // degrees of freedom.
2704  for (std::size_t i=0; i<elem_dofs.size(); i++)
2705  if (this->is_constrained_dof(elem_dofs[i]))
2706  {
2707  // If the DOF is constrained
2708  DofConstraints::const_iterator
2709  pos = _dof_constraints.find(elem_dofs[i]);
2710 
2711  libmesh_assert (pos != _dof_constraints.end());
2712 
2713  const DofConstraintRow & constraint_row = pos->second;
2714 
2715  // adaptive p refinement currently gives us lots of empty constraint
2716  // rows - we should optimize those DoFs away in the future. [RHS]
2717  //libmesh_assert (!constraint_row.empty());
2718 
2719  DofConstraintRow::const_iterator it = constraint_row.begin();
2720  DofConstraintRow::const_iterator it_end = constraint_row.end();
2721 
2722 
2723  // Add the DOFs this dof is constrained in terms of.
2724  // note that these dofs might also be constrained, so
2725  // we will need to call this function recursively.
2726  for ( ; it != it_end; ++it)
2727  if (!dof_set.count (it->first))
2728  {
2729  dof_set.insert (it->first);
2730  done = false;
2731  }
2732  }
2733 
2734 
2735  // If not done then we need to do more work
2736  // (obviously :-) )!
2737  if (!done)
2738  {
2739  // Fill the vector with the contents of the set
2740  elem_dofs.clear();
2741  elem_dofs.insert (elem_dofs.end(),
2742  dof_set.begin(), dof_set.end());
2743 
2744 
2745  // May need to do this recursively. It is possible
2746  // that we just replaced a constrained DOF with another
2747  // constrained DOF.
2748  this->find_connected_dofs (elem_dofs);
2749 
2750  } // end if (!done)
2751 }
libmesh_assert(j)
bool is_constrained_dof(const dof_id_type dof) const
Definition: dof_map.h:1723
DofConstraints _dof_constraints
Definition: dof_map.h:1581
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
Definition: dof_map.h:88
void find_connected_dofs(std::vector< dof_id_type > &elem_dofs) const
Definition: dof_map.C:2690
dof_id_type libMesh::DofMap::first_dof ( ) const
inline

Definition at line 538 of file dof_map.h.

References libMesh::processor_id().

Referenced by add_neighbors_to_send_list(), all_semilocal_indices(), distribute_dofs(), get_info(), is_evaluable(), and local_variable_indices().

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
inline
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
Definition: dof_map.h:1561
dof_id_type libMesh::DofMap::first_old_dof ( ) const
inline

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

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

3695 {
3696  typedef std::set<dof_id_type> DoF_RCSet;
3697 
3698  // If we have heterogenous adjoint constraints we need to
3699  // communicate those too.
3700  const unsigned int max_qoi_num =
3701  _adjoint_constraint_values.empty() ?
3702  0 : _adjoint_constraint_values.rbegin()->first;
3703 
3704  // We have to keep recursing while the unexpanded set is
3705  // nonempty on *any* processor
3706  bool unexpanded_set_nonempty = !unexpanded_dofs.empty();
3707  this->comm().max(unexpanded_set_nonempty);
3708 
3709  while (unexpanded_set_nonempty)
3710  {
3711  // Let's make sure we don't lose sync in this loop.
3712  parallel_object_only();
3713 
3714  // Request sets
3715  DoF_RCSet dof_request_set;
3716 
3717  // Request sets to send to each processor
3718  std::vector<std::vector<dof_id_type> >
3719  requested_dof_ids(this->n_processors());
3720 
3721  // And the sizes of each
3722  std::vector<dof_id_type>
3723  dof_ids_on_proc(this->n_processors(), 0);
3724 
3725  // Fill (and thereby sort and uniq!) the main request sets
3726  for (DoF_RCSet::iterator i = unexpanded_dofs.begin();
3727  i != unexpanded_dofs.end(); ++i)
3728  {
3729  const dof_id_type unexpanded_dof = *i;
3730  DofConstraints::const_iterator
3731  pos = _dof_constraints.find(unexpanded_dof);
3732 
3733  // If we were asked for a DoF and we don't already have a
3734  // constraint for it, then we need to check for one.
3735  if (pos == _dof_constraints.end())
3736  {
3737  if (((unexpanded_dof < this->first_dof()) ||
3738  (unexpanded_dof >= this->end_dof())) &&
3739  !_dof_constraints.count(unexpanded_dof))
3740  dof_request_set.insert(unexpanded_dof);
3741</