$extrastylesheet
dof_map.h
Go to the documentation of this file.
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