$extrastylesheet
00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 00020 #ifndef LIBMESH_DOF_MAP_H 00021 #define LIBMESH_DOF_MAP_H 00022 00023 // Local Includes ----------------------------------- 00024 #include "libmesh/libmesh_common.h" 00025 #include "libmesh/auto_ptr.h" 00026 #include "libmesh/enum_order.h" 00027 #include "libmesh/reference_counted_object.h" 00028 #include "libmesh/libmesh.h" // libMesh::invalid_uint 00029 #include "libmesh/variable.h" 00030 #include "libmesh/threads.h" 00031 #include "libmesh/threads_allocators.h" 00032 #include "libmesh/elem_range.h" 00033 #include "libmesh/sparsity_pattern.h" 00034 #include "libmesh/parallel_object.h" 00035 00036 // C++ Includes ----------------------------------- 00037 #include <algorithm> 00038 #include <cstddef> 00039 #include <iterator> 00040 #include <map> 00041 #include <string> 00042 #include <vector> 00043 00044 namespace libMesh 00045 { 00046 00047 // Forward Declarations 00048 class CouplingMatrix; 00049 class DirichletBoundary; 00050 class DirichletBoundaries; 00051 class DofMap; 00052 class DofObject; 00053 class Elem; 00054 class FEType; 00055 class MeshBase; 00056 class Mesh; 00057 class PeriodicBoundaryBase; 00058 class PeriodicBoundaries; 00059 namespace SparsityPattern { class Build; } 00060 class System; 00061 template <typename T> class DenseVectorBase; 00062 template <typename T> class DenseVector; 00063 template <typename T> class DenseMatrix; 00064 template <typename T> class SparseMatrix; 00065 template <typename T> class NumericVector; 00066 00067 00068 00069 // ------------------------------------------------------------ 00070 // Do we need constraints for anything? 00071 00072 #if defined(LIBMESH_ENABLE_AMR) || \ 00073 defined(LIBMESH_ENABLE_PERIODIC) || \ 00074 defined(LIBMESH_ENABLE_DIRICHLET) 00075 # define LIBMESH_ENABLE_CONSTRAINTS 1 00076 #endif 00077 00078 // ------------------------------------------------------------ 00079 // AMR constraint matrix types 00080 00081 #ifdef LIBMESH_ENABLE_CONSTRAINTS 00082 00085 typedef std::map<dof_id_type, Real, 00086 std::less<dof_id_type>, 00087 Threads::scalable_allocator<std::pair<const dof_id_type, Real> > > DofConstraintRow; 00088 00095 class DofConstraints : public std::map<dof_id_type, 00096 DofConstraintRow, 00097 std::less<dof_id_type>, 00098 Threads::scalable_allocator<std::pair<const dof_id_type, DofConstraintRow> > > 00099 { 00100 }; 00101 00107 class DofConstraintValueMap : 00108 public std::map<dof_id_type, Number, 00109 std::less<dof_id_type>, 00110 Threads::scalable_allocator<std::pair<const dof_id_type, Number> > > 00111 { 00112 }; 00113 00118 class AdjointDofConstraintValues : 00119 public std::map<unsigned int, DofConstraintValueMap, 00120 std::less<unsigned int>, 00121 Threads::scalable_allocator 00122 <std::pair<const unsigned int, DofConstraintValueMap> > > 00123 { 00124 }; 00125 00126 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS 00127 00133 typedef std::map<const Node *, Real, 00134 std::less<const Node *>, 00135 Threads::scalable_allocator<std::pair<const Node * const, Real> > > NodeConstraintRow; 00136 00143 class NodeConstraints : public std::map<const Node *, 00144 std::pair<NodeConstraintRow,Point>, 00145 std::less<const Node *>, 00146 Threads::scalable_allocator<std::pair<const Node * const, std::pair<NodeConstraintRow,Point> > > > 00147 { 00148 }; 00149 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS 00150 00151 #endif // LIBMESH_ENABLE_CONSTRAINTS 00152 00153 00154 00155 // ------------------------------------------------------------ 00156 // DofMap class definition 00157 00167 class DofMap : public ReferenceCountedObject<DofMap>, 00168 public ParallelObject 00169 { 00170 public: 00171 00177 explicit 00178 DofMap(const unsigned int sys_number, 00179 const ParallelObject &parent_decomp); 00180 00184 ~DofMap(); 00185 00190 class AugmentSparsityPattern 00191 { 00192 public: 00193 virtual ~AugmentSparsityPattern () {} 00194 00198 virtual void augment_sparsity_pattern (SparsityPattern::Graph & sparsity, 00199 std::vector<dof_id_type> & n_nz, 00200 std::vector<dof_id_type> & n_oz) = 0; 00201 }; 00202 00207 class AugmentSendList 00208 { 00209 public: 00210 virtual ~AugmentSendList () {} 00211 00215 virtual void augment_send_list (std::vector<dof_id_type> & send_list) = 0; 00216 }; 00217 00223 void attach_matrix (SparseMatrix<Number>& matrix); 00224 00229 bool is_attached (SparseMatrix<Number>& matrix); 00230 00236 void distribute_dofs (MeshBase&); 00237 00243 void compute_sparsity (const MeshBase&); 00244 00248 void clear_sparsity(); 00249 00260 void attach_extra_sparsity_object (DofMap::AugmentSparsityPattern &asp) 00261 { 00262 _augment_sparsity_pattern = &asp; 00263 } 00264 00275 void attach_extra_sparsity_function(void (*func)(SparsityPattern::Graph & sparsity, 00276 std::vector<dof_id_type> & n_nz, 00277 std::vector<dof_id_type> & n_oz, 00278 void *), 00279 void * context = NULL) 00280 { _extra_sparsity_function = func; _extra_sparsity_context = context; } 00281 00289 void attach_extra_send_list_object (DofMap::AugmentSendList &asl) 00290 { 00291 _augment_send_list = &asl; 00292 } 00293 00298 void attach_extra_send_list_function(void (*func)(std::vector<dof_id_type> &, void *), void * context = NULL) 00299 { _extra_send_list_function = func; _extra_send_list_context = context; } 00300 00307 void prepare_send_list (); 00308 00316 const std::vector<dof_id_type>& get_send_list() const { return _send_list; } 00317 00324 const std::vector<dof_id_type>& get_n_nz() const { 00325 libmesh_assert(_n_nz); 00326 return *_n_nz; 00327 } 00328 00335 const std::vector<dof_id_type>& get_n_oz() const { 00336 libmesh_assert(_n_oz); 00337 return *_n_oz; 00338 } 00339 00340 // /** 00341 // * Add an unknown of order \p order and finite element type 00342 // * \p type to the system of equations. 00343 // */ 00344 // void add_variable (const Variable &var); 00345 00350 void add_variable_group (const VariableGroup &var_group); 00351 00355 const VariableGroup& variable_group (const unsigned int c) const; 00356 00360 const Variable& variable (const unsigned int c) const; 00361 00365 Order variable_order (const unsigned int c) const; 00366 00370 Order variable_group_order (const unsigned int vg) const; 00371 00375 const FEType& variable_type (const unsigned int c) const; 00376 00380 const FEType& variable_group_type (const unsigned int vg) const; 00381 00387 unsigned int n_variable_groups() const 00388 { return cast_int<unsigned int>(_variable_groups.size()); } 00389 00395 unsigned int n_variables() const 00396 { return cast_int<unsigned int>(_variables.size()); } 00397 00403 bool has_blocked_representation() const 00404 { 00405 #ifdef LIBMESH_ENABLE_BLOCKED_STORAGE 00406 return ((this->n_variable_groups() == 1) && (this->n_variables() > 1)); 00407 #else 00408 return false; 00409 #endif 00410 } 00411 00416 unsigned int block_size() const 00417 { 00418 #ifdef LIBMESH_ENABLE_BLOCKED_STORAGE 00419 return (this->has_blocked_representation() ? this->n_variables() : 1); 00420 #else 00421 return 1; 00422 #endif 00423 } 00424 00428 dof_id_type n_dofs() const { return _n_dfs; } 00429 00433 dof_id_type n_SCALAR_dofs() const { return _n_SCALAR_dofs; } 00434 00438 dof_id_type n_local_dofs () const 00439 { return this->n_dofs_on_processor (this->processor_id()); } 00440 00444 dof_id_type n_dofs_on_processor(const processor_id_type proc) const { 00445 libmesh_assert_less (proc, _first_df.size()); 00446 return cast_int<dof_id_type>(_end_df[proc] - _first_df[proc]); 00447 } 00448 00452 dof_id_type first_dof(const processor_id_type proc) const 00453 { libmesh_assert_less (proc, _first_df.size()); return _first_df[proc]; } 00454 00455 dof_id_type first_dof() const 00456 { return this->first_dof(this->processor_id()); } 00457 00458 #ifdef LIBMESH_ENABLE_AMR 00459 00462 dof_id_type first_old_dof(const processor_id_type proc) const 00463 { libmesh_assert_less (proc, _first_old_df.size()); return _first_old_df[proc]; } 00464 00465 dof_id_type first_old_dof() const 00466 { return this->first_old_dof(this->processor_id()); } 00467 00468 #endif //LIBMESH_ENABLE_AMR 00469 00475 dof_id_type last_dof(const processor_id_type proc) const { 00476 libmesh_deprecated(); 00477 libmesh_assert_less (proc, _end_df.size()); 00478 return cast_int<dof_id_type>(_end_df[proc] - 1); 00479 } 00480 00481 dof_id_type last_dof() const 00482 { return this->last_dof(this->processor_id()); } 00483 00489 dof_id_type end_dof(const processor_id_type proc) const 00490 { libmesh_assert_less (proc, _end_df.size()); return _end_df[proc]; } 00491 00492 dof_id_type end_dof() const 00493 { return this->end_dof(this->processor_id()); } 00494 00495 #ifdef LIBMESH_ENABLE_AMR 00496 00501 dof_id_type end_old_dof(const processor_id_type proc) const 00502 { libmesh_assert_less (proc, _end_old_df.size()); return _end_old_df[proc]; } 00503 00504 dof_id_type end_old_dof() const 00505 { return this->end_old_dof(this->processor_id()); } 00506 00507 #endif //LIBMESH_ENABLE_AMR 00508 00513 void dof_indices (const Elem* const elem, 00514 std::vector<dof_id_type>& di) const; 00515 00520 void dof_indices (const Elem* const elem, 00521 std::vector<dof_id_type>& di, 00522 const unsigned int vn) const; 00523 00530 void SCALAR_dof_indices (std::vector<dof_id_type>& di, 00531 const unsigned int vn, 00532 const bool old_dofs=false) const; 00533 00540 bool all_semilocal_indices (const std::vector<dof_id_type>& dof_indices) const; 00541 00549 void set_implicit_neighbor_dofs(bool implicit_neighbor_dofs); 00550 00557 bool use_coupled_neighbor_dofs(const MeshBase& mesh) const; 00558 00569 void extract_local_vector (const NumericVector<Number>& Ug, 00570 const std::vector<dof_id_type>& dof_indices, 00571 DenseVectorBase<Number>& Ue) const; 00572 00577 void local_variable_indices(std::vector<dof_id_type>& idx, 00578 const MeshBase& mesh, 00579 unsigned int var_num) const; 00580 00581 #ifdef LIBMESH_ENABLE_CONSTRAINTS 00582 00583 //-------------------------------------------------------------------- 00584 // Constraint-specific methods 00589 dof_id_type n_constrained_dofs() const; 00590 00595 dof_id_type n_local_constrained_dofs() const; 00596 00597 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS 00598 00602 dof_id_type n_constrained_nodes() const 00603 { return cast_int<dof_id_type>(_node_constraints.size()); } 00604 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS 00605 00611 void create_dof_constraints (const MeshBase&, Real time=0); 00612 00616 void allgather_recursive_constraints (MeshBase&); 00617 00621 void scatter_constraints (MeshBase&); 00622 00630 void process_constraints (MeshBase&); 00631 00636 void add_constraint_row (const dof_id_type dof_number, 00637 const DofConstraintRow& constraint_row, 00638 const Number constraint_rhs, 00639 const bool forbid_constraint_overwrite); 00640 00651 void add_adjoint_constraint_row (const unsigned int qoi_index, 00652 const dof_id_type dof_number, 00653 const DofConstraintRow& constraint_row, 00654 const Number constraint_rhs, 00655 const bool forbid_constraint_overwrite); 00656 00662 void add_constraint_row (const dof_id_type dof_number, 00663 const DofConstraintRow& constraint_row, 00664 const bool forbid_constraint_overwrite = true) 00665 { add_constraint_row(dof_number, constraint_row, 0., forbid_constraint_overwrite); } 00666 00670 DofConstraints::const_iterator constraint_rows_begin() const 00671 { return _dof_constraints.begin(); } 00672 00676 DofConstraints::const_iterator constraint_rows_end() const 00677 { return _dof_constraints.end(); } 00678 00679 void stash_dof_constraints() 00680 { 00681 libmesh_assert(_stashed_dof_constraints.empty()); 00682 _dof_constraints.swap(_stashed_dof_constraints); 00683 } 00684 00685 void unstash_dof_constraints() 00686 { 00687 libmesh_assert(_dof_constraints.empty()); 00688 _dof_constraints.swap(_stashed_dof_constraints); 00689 } 00690 00691 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS 00692 00695 NodeConstraints::const_iterator node_constraint_rows_begin() const 00696 { return _node_constraints.begin(); } 00697 00701 NodeConstraints::const_iterator node_constraint_rows_end() const 00702 { return _node_constraints.end(); } 00703 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS 00704 00709 bool is_constrained_dof (const dof_id_type dof) const; 00710 00715 bool has_heterogenous_adjoint_constraints (const unsigned int qoi_num) const; 00716 00722 Number has_heterogenous_adjoint_constraint (const unsigned int qoi_num, 00723 const dof_id_type dof) const; 00724 00729 DofConstraintValueMap & get_primal_constraint_values(); 00730 00735 bool is_constrained_node (const Node* node) const; 00736 00743 void print_dof_constraints(std::ostream& os=libMesh::out, 00744 bool print_nonlocal=false) const; 00745 00751 std::string get_local_constraints(bool print_nonlocal=false) const; 00752 00753 00762 std::pair<Real, Real> max_constraint_error(const System &system, 00763 NumericVector<Number> *v = NULL) const; 00764 00765 #endif // LIBMESH_ENABLE_CONSTRAINTS 00766 00767 //-------------------------------------------------------------------- 00768 // Constraint-specific methods 00769 // Some of these methods are enabled (but inlined away to nothing) 00770 // when constraints are disabled at configure-time. This is to 00771 // increase API compatibility of user code with different library 00772 // builds. 00773 00787 void constrain_element_matrix (DenseMatrix<Number>& matrix, 00788 std::vector<dof_id_type>& elem_dofs, 00789 bool asymmetric_constraint_rows = true) const; 00790 00797 void constrain_element_matrix (DenseMatrix<Number>& matrix, 00798 std::vector<dof_id_type>& row_dofs, 00799 std::vector<dof_id_type>& col_dofs, 00800 bool asymmetric_constraint_rows = true) const; 00801 00805 void constrain_element_vector (DenseVector<Number>& rhs, 00806 std::vector<dof_id_type>& dofs, 00807 bool asymmetric_constraint_rows = true) const; 00808 00817 void constrain_element_matrix_and_vector (DenseMatrix<Number>& matrix, 00818 DenseVector<Number>& rhs, 00819 std::vector<dof_id_type>& elem_dofs, 00820 bool asymmetric_constraint_rows = true) const; 00821 00845 void heterogenously_constrain_element_matrix_and_vector (DenseMatrix<Number>& matrix, 00846 DenseVector<Number>& rhs, 00847 std::vector<dof_id_type>& elem_dofs, 00848 bool asymmetric_constraint_rows = true, 00849 int qoi_index = -1) const; 00850 00872 void heterogenously_constrain_element_vector (const DenseMatrix<Number>& matrix, 00873 DenseVector<Number>& rhs, 00874 std::vector<dof_id_type>& elem_dofs, 00875 bool asymmetric_constraint_rows = true, 00876 int qoi_index = -1) const; 00877 00878 00879 00888 void constrain_element_dyad_matrix (DenseVector<Number>& v, 00889 DenseVector<Number>& w, 00890 std::vector<dof_id_type>& row_dofs, 00891 bool asymmetric_constraint_rows = true) const; 00892 00899 void constrain_nothing (std::vector<dof_id_type>& dofs) const; 00900 00914 void enforce_constraints_exactly (const System &system, 00915 NumericVector<Number> *v = NULL, 00916 bool homogeneous = false) const; 00917 00924 void enforce_adjoint_constraints_exactly (NumericVector<Number> &v, 00925 unsigned int q) const; 00926 00927 00928 00929 #ifdef LIBMESH_ENABLE_PERIODIC 00930 00931 //-------------------------------------------------------------------- 00932 // PeriodicBoundary-specific methods 00933 00937 void add_periodic_boundary (const PeriodicBoundaryBase& periodic_boundary); 00938 00945 void add_periodic_boundary (const PeriodicBoundaryBase& boundary, const PeriodicBoundaryBase& inverse_boundary); 00946 00951 bool is_periodic_boundary (const boundary_id_type boundaryid) const; 00952 00953 PeriodicBoundaries * get_periodic_boundaries() 00954 { 00955 return _periodic_boundaries; 00956 } 00957 00958 #endif // LIBMESH_ENABLE_PERIODIC 00959 00960 00961 #ifdef LIBMESH_ENABLE_DIRICHLET 00962 00963 //-------------------------------------------------------------------- 00964 // DirichletBoundary-specific methods 00965 00969 void add_dirichlet_boundary (const DirichletBoundary& dirichlet_boundary); 00970 00976 void add_adjoint_dirichlet_boundary (const DirichletBoundary& dirichlet_boundary, 00977 unsigned int q); 00978 00982 void remove_dirichlet_boundary (const DirichletBoundary& dirichlet_boundary); 00983 00988 void remove_adjoint_dirichlet_boundary (const DirichletBoundary& dirichlet_boundary, 00989 unsigned int q); 00990 00991 const DirichletBoundaries * get_dirichlet_boundaries() const 00992 { 00993 return _dirichlet_boundaries; 00994 } 00995 00996 DirichletBoundaries * get_dirichlet_boundaries() 00997 { 00998 return _dirichlet_boundaries; 00999 } 01000 01001 bool has_adjoint_dirichlet_boundaries(unsigned int q) const; 01002 01003 const DirichletBoundaries * 01004 get_adjoint_dirichlet_boundaries(unsigned int q) const; 01005 01006 DirichletBoundaries * 01007 get_adjoint_dirichlet_boundaries(unsigned int q); 01008 01009 #endif // LIBMESH_ENABLE_DIRICHLET 01010 01011 01012 #ifdef LIBMESH_ENABLE_AMR 01013 01014 //-------------------------------------------------------------------- 01015 // AMR-specific methods 01016 01025 // void augment_send_list_for_projection(const MeshBase &); 01026 01033 void old_dof_indices (const Elem* const elem, 01034 std::vector<dof_id_type>& di, 01035 const unsigned int vn = libMesh::invalid_uint) const; 01040 dof_id_type n_old_dofs() const { return _n_old_dfs; } 01041 01047 void constrain_p_dofs (unsigned int var, 01048 const Elem *elem, 01049 unsigned int s, 01050 unsigned int p); 01051 01052 #endif // LIBMESH_ENABLE_AMR 01053 01057 void reinit (MeshBase& mesh); 01058 01062 void clear (); 01063 01067 void print_info(std::ostream& os=libMesh::out) const; 01068 01072 std::string get_info() const; 01073 01087 CouplingMatrix* _dof_coupling; 01088 01092 unsigned int sys_number() const; 01093 01094 private: 01095 01103 void _dof_indices (const Elem* const elem, std::vector<dof_id_type>& di, 01104 const unsigned int v, 01105 const Node * const * nodes, 01106 unsigned int n_nodes 01107 #ifdef DEBUG 01108 , 01109 std::size_t & tot_size 01110 #endif 01111 ) const; 01112 01116 UniquePtr<SparsityPattern::Build> build_sparsity(const MeshBase& mesh) const; 01117 01121 void invalidate_dofs(MeshBase& mesh) const; 01122 01126 DofObject* node_ptr(MeshBase& mesh, dof_id_type i) const; 01127 01131 DofObject* elem_ptr(MeshBase& mesh, dof_id_type i) const; 01132 01136 typedef DofObject* (DofMap::*dofobject_accessor) 01137 (MeshBase& mesh, dof_id_type i) const; 01138 01142 template<typename iterator_type> 01143 void set_nonlocal_dof_objects(iterator_type objects_begin, 01144 iterator_type objects_end, 01145 MeshBase &mesh, 01146 dofobject_accessor objects); 01147 01156 void distribute_local_dofs_var_major (dof_id_type& next_free_dof, 01157 MeshBase& mesh); 01158 01171 void distribute_local_dofs_node_major (dof_id_type& next_free_dof, 01172 MeshBase& mesh); 01173 01178 void add_neighbors_to_send_list(MeshBase& mesh); 01179 01180 #ifdef LIBMESH_ENABLE_CONSTRAINTS 01181 01192 void build_constraint_matrix (DenseMatrix<Number>& C, 01193 std::vector<dof_id_type>& elem_dofs, 01194 const bool called_recursively=false) const; 01195 01211 void build_constraint_matrix_and_vector (DenseMatrix<Number>& C, 01212 DenseVector<Number>& H, 01213 std::vector<dof_id_type>& elem_dofs, 01214 int qoi_index = -1, 01215 const bool called_recursively=false) const; 01216 01221 void find_connected_dofs (std::vector<dof_id_type> &elem_dofs) const; 01222 01227 void find_connected_dof_objects (std::vector<const DofObject *> &objs) const; 01228 01234 void add_constraints_to_send_list(); 01235 01236 #endif // LIBMESH_ENABLE_CONSTRAINTS 01237 01241 std::vector<Variable> _variables; 01242 01246 std::vector<VariableGroup> _variable_groups; 01247 01251 const unsigned int _sys_number; 01252 01258 std::vector<SparseMatrix<Number>* > _matrices; 01259 01263 std::vector<dof_id_type> _first_df; 01264 01268 std::vector<dof_id_type> _end_df; 01269 01274 std::vector<dof_id_type> _first_scalar_df; 01275 01280 std::vector<dof_id_type> _send_list; 01281 01285 AugmentSparsityPattern *_augment_sparsity_pattern; 01286 01290 void (*_extra_sparsity_function)(SparsityPattern::Graph &, 01291 std::vector<dof_id_type> & n_nz, 01292 std::vector<dof_id_type> & n_oz, 01293 void *); 01297 void * _extra_sparsity_context; 01298 01302 AugmentSendList *_augment_send_list; 01303 01307 void (*_extra_send_list_function)(std::vector<dof_id_type> &, void *); 01308 01312 void * _extra_send_list_context; 01313 01318 bool need_full_sparsity_pattern; 01319 01324 UniquePtr<SparsityPattern::Build> _sp; 01325 01332 std::vector<dof_id_type>* _n_nz; 01333 01338 std::vector<dof_id_type>* _n_oz; 01339 01343 dof_id_type _n_dfs; 01344 01349 dof_id_type _n_SCALAR_dofs; 01350 01351 #ifdef LIBMESH_ENABLE_AMR 01352 01356 dof_id_type _n_old_dfs; 01357 01361 std::vector<dof_id_type> _first_old_df; 01362 01366 std::vector<dof_id_type> _end_old_df; 01367 01372 std::vector<dof_id_type> _first_old_scalar_df; 01373 01374 #endif 01375 01376 #ifdef LIBMESH_ENABLE_CONSTRAINTS 01377 01381 DofConstraints _dof_constraints, _stashed_dof_constraints; 01382 01383 DofConstraintValueMap _primal_constraint_values; 01384 01385 AdjointDofConstraintValues _adjoint_constraint_values; 01386 #endif 01387 01388 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS 01389 01392 NodeConstraints _node_constraints; 01393 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS 01394 01395 01396 #ifdef LIBMESH_ENABLE_PERIODIC 01397 01401 PeriodicBoundaries *_periodic_boundaries; 01402 #endif 01403 01404 #ifdef LIBMESH_ENABLE_DIRICHLET 01405 01409 DirichletBoundaries *_dirichlet_boundaries; 01410 01415 std::vector<DirichletBoundaries *> _adjoint_dirichlet_boundaries; 01416 #endif 01417 01418 friend class SparsityPattern::Build; 01419 01424 bool _implicit_neighbor_dofs_initialized; 01425 bool _implicit_neighbor_dofs; 01426 }; 01427 01428 01429 // ------------------------------------------------------------ 01430 // Dof Map inline member functions 01431 inline 01432 unsigned int DofMap::sys_number() const 01433 { 01434 return _sys_number; 01435 } 01436 01437 01438 01439 inline 01440 const VariableGroup & DofMap::variable_group (const unsigned int g) const 01441 { 01442 libmesh_assert_less (g, _variable_groups.size()); 01443 01444 return _variable_groups[g]; 01445 } 01446 01447 01448 01449 inline 01450 const Variable & DofMap::variable (const unsigned int c) const 01451 { 01452 libmesh_assert_less (c, _variables.size()); 01453 01454 return _variables[c]; 01455 } 01456 01457 01458 01459 inline 01460 Order DofMap::variable_order (const unsigned int c) const 01461 { 01462 libmesh_assert_less (c, _variables.size()); 01463 01464 return _variables[c].type().order; 01465 } 01466 01467 01468 01469 inline 01470 Order DofMap::variable_group_order (const unsigned int vg) const 01471 { 01472 libmesh_assert_less (vg, _variable_groups.size()); 01473 01474 return _variable_groups[vg].type().order; 01475 } 01476 01477 01478 01479 inline 01480 const FEType& DofMap::variable_type (const unsigned int c) const 01481 { 01482 libmesh_assert_less (c, _variables.size()); 01483 01484 return _variables[c].type(); 01485 } 01486 01487 01488 01489 inline 01490 const FEType& DofMap::variable_group_type (const unsigned int vg) const 01491 { 01492 libmesh_assert_less (vg, _variable_groups.size()); 01493 01494 return _variable_groups[vg].type(); 01495 } 01496 01497 01498 01499 inline 01500 bool DofMap::is_constrained_node (const Node* 01501 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS 01502 node 01503 #endif 01504 ) const 01505 { 01506 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS 01507 if (_node_constraints.count(node)) 01508 return true; 01509 #endif 01510 01511 return false; 01512 } 01513 01514 #ifdef LIBMESH_ENABLE_CONSTRAINTS 01515 01516 inline 01517 bool DofMap::is_constrained_dof (const dof_id_type dof) const 01518 { 01519 if (_dof_constraints.count(dof)) 01520 return true; 01521 01522 return false; 01523 } 01524 01525 01526 inline 01527 bool DofMap::has_heterogenous_adjoint_constraints (const unsigned int qoi_num) const 01528 { 01529 AdjointDofConstraintValues::const_iterator it = 01530 _adjoint_constraint_values.find(qoi_num); 01531 if (it == _adjoint_constraint_values.end()) 01532 return false; 01533 if (it->second.empty()) 01534 return false; 01535 01536 return true; 01537 } 01538 01539 01540 inline 01541 Number DofMap::has_heterogenous_adjoint_constraint (const unsigned int qoi_num, 01542 const dof_id_type dof) const 01543 { 01544 AdjointDofConstraintValues::const_iterator it = 01545 _adjoint_constraint_values.find(qoi_num); 01546 if (it != _adjoint_constraint_values.end()) 01547 { 01548 DofConstraintValueMap::const_iterator rhsit = 01549 it->second.find(dof); 01550 if (rhsit == it->second.end()) 01551 return 0; 01552 else 01553 return rhsit->second; 01554 } 01555 01556 return 0; 01557 } 01558 01559 01560 01561 inline 01562 DofConstraintValueMap & DofMap::get_primal_constraint_values() 01563 { 01564 return _primal_constraint_values; 01565 } 01566 01567 01568 01569 #else 01570 01571 //-------------------------------------------------------------------- 01572 // Constraint-specific methods get inlined into nothing if 01573 // constraints are disabled, so there's no reason for users not to 01574 // use them. 01575 01576 inline void DofMap::constrain_element_matrix (DenseMatrix<Number>&, 01577 std::vector<dof_id_type>&, 01578 bool) const {} 01579 01580 inline void DofMap::constrain_element_matrix (DenseMatrix<Number>&, 01581 std::vector<dof_id_type>&, 01582 std::vector<dof_id_type>&, 01583 bool) const {} 01584 01585 inline void DofMap::constrain_element_vector (DenseVector<Number>&, 01586 std::vector<dof_id_type>&, 01587 bool) const {} 01588 01589 inline void DofMap::constrain_element_matrix_and_vector (DenseMatrix<Number>&, 01590 DenseVector<Number>&, 01591 std::vector<dof_id_type>&, 01592 bool) const {} 01593 01594 inline void DofMap::constrain_element_dyad_matrix (DenseVector<Number>&, 01595 DenseVector<Number>&, 01596 std::vector<dof_id_type>&, 01597 bool) const {} 01598 01599 inline void DofMap::enforce_constraints_exactly (const System &, 01600 NumericVector<Number> *, 01601 bool = false) const {} 01602 01603 inline void DofMap::enforce_adjoint_constraints_exactly (NumericVector<Number> &, 01604 unsigned int) const {} 01605 01606 #endif // LIBMESH_ENABLE_CONSTRAINTS 01607 01608 } // namespace libMesh 01609 01610 #endif // LIBMESH_DOF_MAP_H