SundanceDOFMapBase.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                              Sundance
00005 //                 Copyright (2005) Sandia Corporation
00006 // 
00007 // Copyright (year first published) Sandia Corporation.  Under the terms 
00008 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 
00009 // retains certain rights in this software.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //                                                                                 
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA                                                                                
00025 // Questions? Contact Kevin Long (krlong@sandia.gov), 
00026 // Sandia National Laboratories, Livermore, California, USA
00027 // 
00028 // ************************************************************************
00029 /* @HEADER@ */
00030 
00031 #ifndef SUNDANCE_DOFMAPBASE_H
00032 #define SUNDANCE_DOFMAPBASE_H
00033 
00034 #include "SundanceDefs.hpp"
00035 #include "SundanceMesh.hpp"
00036 #include "SundanceCellSet.hpp"
00037 #include "SundanceCellFilter.hpp"
00038 #include "SundanceMapStructure.hpp"
00039 #include "SundanceObjectWithVerbosity.hpp"
00040 
00041 namespace Teuchos {class Time;}
00042 
00043 namespace Sundance
00044 {
00045 using namespace Teuchos;
00046 
00047 /** \brief Base interface for implementations of a degree of freedom map.
00048  *
00049  * A degree of freedom (DOF) map is a parallel-aware object that takes
00050  * takes DOFs on individual cells in the whole mesh, and creates global
00051  * IDs for them on the whole mesh across processes.
00052  *
00053  * A DOF map is constructed out of a mesh and assignment of various
00054  * discrete functions with various basis-es assigned to the different
00055  * cells in the mesh;
00056  *
00057  * This interface assumes that the global DOFs owned in this process are
00058  * ordered sequentially so the DOFs owned in this process are given by
00059  * <tt>this->lowestLocalDOF() + k</tt>, for <tt>k =
00060  * 0...this->numLocalDOFs()-1()</tt>, where <tt>this->numLocalDOFs()</tt>
00061  * is the number of DOFs owned by this process.  Therefore, any DOF with
00062  * value less than <tt>this->numLocalDOFs()</tt> and greater than or equal
00063  * to <tt>this->lowestLocalDOF()+this->numLocalDOFs()</tt> are necessarily
00064  * ghosted DOFs.  ??? ToDo: I don't think the above is correct! ???
00065  * 
00066  * ToDo: Finish documentation!
00067  *
00068  * \section Sundance_DOFMapBase_Defintions_sec Definitions
00069  *
00070  * <ul>
00071  *
00072  * <li><b>Degree of Freedom (DOF)</b>: ???
00073  *
00074  * <li><b>Homogeneous DOF Map</b>: ???
00075  *
00076  * </ul>
00077  *
00078  * \section Sundance_DOFMapBase_ToDo_sec Possible Refactorings
00079  *
00080  * <ul>
00081  *
00082  * <li>Inherit this base class from Teuchos::Describable and remove the
00083  * print() function, replacing it with the override to
00084  * Teuchos::Describable::describe()?
00085  *
00086  * <li>Break off the default implementation in this class into another
00087  * subclass (called something like <tt>DOFMapDefaultBase</tt>) and then
00088  * make this interface a true abstract interface?  There are lots of
00089  * advantages to having pure interface classes (e.g. less documenation,
00090  * standard delegation subclasses etc.).
00091  *
00092  * <li>Add a public function to return the <tt>MeshBase</tt> object?  Is
00093  * there any reason not to give the client access to the <tt>MeshBase</tt>
00094  * object?  If you do this, then you can remove the <tt>isRemote()</tt>
00095  * function and let the client just query the map object directly.
00096  *
00097  * <li>Refactor this interface and all objects accessed to only use
00098  * absrract interfaces and not handle classes?  This would involve the
00099  * same principle as is used in Thyra.  Is this workable?
00100  *
00101  * <li>Add some function somewhere to return the total number of functions
00102  * that is defined on the mesh.  This is needed to write precise
00103  * preconditions and postconditions for many of the functions.  For
00104  * example, a function <tt>this->numTotalFunctions()</tt> would be very
00105  * helpful in this regard.
00106  *
00107  * <li>???
00108  *
00109  * </ul>
00110  */
00111 class DOFMapBase : public Sundance::Printable
00112 {
00113 public:
00114 
00115   /** \brief . */
00116   DOFMapBase(const Mesh& mesh, int setupVerb);
00117       
00118   /** \brief .
00119    *
00120    * ToDo: Remove this virtual destructor since this interface already
00121    * inherits from a base interface that has a virtual destructor.
00122    */
00123   virtual ~DOFMapBase(){;}
00124 
00125   /** \brief Return <tt>true</tt> if the given cell is really owned by
00126    * another process and is only ghosted in this process (and optionally
00127    * return the owning process ID).
00128    *
00129    * \param  cellDim
00130    *           [in] The dimension of the cell.  
00131    * \param  cellLID
00132    *           [in] The LID of the cell in this process.  See
00133    *           <tt>MeshBase</tt> for more details, preconditions, etc.
00134    * \param  ownerProcID
00135    *           [out] The process rank ID which owns the cell
00136    *           <tt>(cellDim,cellLID)</tt>.
00137    *
00138    * <b>Preconditions:</b> See <tt>MeshBase</tt>
00139    *
00140    * ToDo: Change the <tt>ownerProcID</tt> argument to <tt>int*</tt> and
00141    * given it a default value of <tt>NULL</tt> so that it can be ignored
00142    * by the client.
00143    *
00144    * ToDo: Consider removing this function and just calling on the mesh
00145    * object directly.
00146    *
00147    * ToDo: Change name to <tt>isRemoteCell()</tt>? 
00148    */
00149   bool isRemote(int cellDim, int cellLID, int& ownerProcID) const 
00150     {return (ownerProcID=mesh_.ownerProcID(cellDim, cellLID)) != localProcID_;}
00151       
00152   /** \brief Get the global DOFs for a single function on a single
00153    * cell.
00154    *
00155    * \param  cellDim
00156    *           [in] The dimension of the cell
00157    * \param  cellLID
00158    *           [in] Local ID (LID) of the cell
00159    * \param  funcID
00160    *           [in] Function ID for which DOFs are requested
00161    * \param  dofs
00162    *           [out] Global IDs for DOFs of the requested function
00163    *           on the requested cell.
00164    *
00165    * 
00166    *
00167    */
00168   virtual void getDOFsForCell(int cellDim, int cellLID,
00169     int funcID,
00170     Array<int>& dofs) const;
00171 
00172   /** \brief Return the global DOFs for a batch of cells for a given set
00173    * of functions on those cells.
00174    *
00175    * \param  cellDim
00176    *           [in] The dimension of the cells in the batch of cells
00177    * \param  cellLIDs
00178    *           [in] Local IDs (LIDs) for the batch of cells
00179    * \param  requestedFuncSet
00180    *           [in] Set of function IDs for which DOFs are requested.
00181    *           Note that this must be equal to the allowed set of
00182    *           requested functions
00183    *           <tt>this->allowedFuncsOnCellBatch(cellDim,cellLIDs)</tt>.
00184    * \param  dofs
00185    *           [out] Global IDs for DOFs of the requested functions on the
00186    *           batch of cells.  The size of this array on output is \code
00187    *           dofs.size()==mapStructure.numBasisChunks() \endcode. The
00188    *           global DOFs for cell <tt>cellLIDs[c]</tt> (where <tt>0 <= c
00189    *           < cellLIDs.size()</tt>) for the cell for the basis chunk
00190    *           <tt>basisChunk</tt> (where <tt>0 <= basisChunk <
00191    *           mapStructure.numBasisChunks()</tt>) are given by \code
00192    *           dofs[c*nDOFsPerCell[c]+k] \endcode, where \code
00193    *           k=0...nDOFsPerCell[c]-1 \endcode and \code nDOFsPerCell[c]
00194    *           = mapStructure.basis(basisChunk).nNodes( spatialDim,
00195    *           this->mesh()->cellType(cellDim) ) *
00196    *           mapStructure.numFuncs(basisChunk) \endcode.  Note that the
00197    *           array <tt>nDOFsPerCell</tt> used above is not actually
00198    *           computed here or returned by this interface.  It is only
00199    *           used abstractly to define the <tt>dofs</tt> array above.
00200    * \param  nNodes
00201    *           [out] Array giving the number of coefficients for each type
00202    *           of basis family in <tt>mapStructure</tt> for each function.
00203    *           The size of this array on return is
00204    *           <tt>nNodes.size()==mapStructure.numBasisChunks()</tt> and
00205    *           <tt>nNodes[b]==mapStructure.basis(b).nNodes(spatialDim,cellType)</tt>,
00206    *           for <tt>b=0...mapStructure.numBasisChunks()-1</tt>.
00207    *
00208    * <b>Preconditions:</b><ul>
00209    * <li><tt>requestedFuncSet.setDifference(
00210    *           this->allowedFuncsOnCellBatch(cellDim,cellLIDs) ).size() == 0</tt>
00211    * <li>???Others???
00212    * </ul>
00213    *
00214    * \returns The map structure that groups sets of different functions
00215    * according with respect to those that have the same basis family.
00216    * Above, we will refer to this returned object as <tt>mapStructure</tt>
00217    * where <tt>mapStructure = *returnVal</tt>.
00218    *
00219    * ToDo: Remove the argument requestedFuncSet since all current use
00220    * cases and implemenations asume that all of the functions are
00221    * requested and returned.
00222    *
00223    * ToDo: Remove the nNodes return argument since this information can be
00224    * gotten just from the return <tt>mapStructure</tt> object.
00225    * Specifically, <tt>nNodes[basisChunk] =
00226    * mapStructure.basis(basisChunk).nNodes(spatialDim,cellType)</tt> so
00227    * what is the point in returning this array?  Since this is needed for
00228    * a whole batch of cells, it is cheap to just grab this from the
00229    * returned <tt>mapStructure</tt> object as shown above.
00230    */
00231   virtual RCP<const MapStructure> 
00232   getDOFsForCellBatch(
00233     int cellDim, const Array<int>& cellLIDs,
00234     const Set<int>& requestedFuncSet,
00235     Array<Array<int> >& dofs,
00236     Array<int>& nNodes,
00237     int verb
00238     ) const = 0 ;
00239 
00240   /** \brief Return the set of a function IDs for a batch of cells for
00241    * which DOFs can be obtained.
00242    *
00243    * \param  cellDim
00244    *           [in] The dimension of the cells in the batch of cells
00245    * \param  cellLIDs
00246    *           [in] Local IDs (LIDs) for the batch of cells
00247    */
00248   virtual RCP<const Set<int> >
00249   allowedFuncsOnCellBatch(int cellDim,
00250     const Array<int>& cellLIDs) const = 0 ;
00251 
00252   /** \brief Return an array of cell filters that gives, for each function
00253    * ID, the cells that the function lives on.
00254    *
00255    * \returns A reference to an array of size <tt>returnVal.size() ==
00256    * numTotalFunctcions</tt> where <tt>returnVal[funcID]</tt> gives a
00257    * handle to a <tt>CellFilterBase</tt> object where the function
00258    * <tt>funcID</tt> lives, where <tt>0 <= funcID <
00259    * numTotalFunctions</tt>.
00260    */
00261   virtual const Array<CellFilter>& funcDomains() const = 0 ;
00262 
00263   /** \brief Return the lowest DOF for DOFs owned in this process. */
00264   int lowestLocalDOF() const {return lowestLocalDOF_;}
00265 
00266   /** \brief Returns <tt>true</tt> if the given global DOF is owned in
00267    * this process.
00268    */
00269   bool isLocalDOF(int dof) const 
00270     {return (lowestLocalDOF_ <= dof && dof < lowestLocalDOF_+numLocalDOFs_);}
00271 
00272   /** \brief Return the number of DOFs owned in this process.
00273    *
00274    * ToDo: Is this the number of owned + ghosted DOFs or is it just owned
00275    * DOFs?
00276    */
00277   int numLocalDOFs() const {return numLocalDOFs_;}
00278 
00279   /** \brief Return the global number of DOFs over all processes.
00280    *
00281    * <b>Postconditions:</b><ul>
00282    * <li><tt>returnVal >= this->numLocalDOFs()</tt>
00283    * </ul>
00284    */
00285   int numDOFs() const {return numDOFs_;}
00286 
00287   /** \brief Return an array of the global DOFs for the DOFs that are
00288    * locally accessed in this process.
00289    *
00290    * <b>Postconditions:</b><ul>
00291    * <li><tt>returnVal->size() == ( this->numDOFs() - this->numLocalDOFs() )</tt>
00292    * <li><tt>returnVal[k] < this->lowsetLocalDOF() &&
00293    *     this->lowsetLocalDOF() + this->numLocalDOFs() <= returnVal[k]</tt>,
00294    *     for <tt>k=0...(this->numDOFs()-this->numLocalDOFs())-1</tt>.
00295    * </ul>
00296    *
00297    * ToDo: Change the return type to <tt>RCP<const Array<int> ></tt> since
00298    * I doubt that the client is allowed to change this array through this
00299    * function!
00300    *
00301    * ToDo: Change the name of this function to something like
00302    * <tt>getGhostDOFs()</tt>?
00303    */
00304   const RCP<Array<int> >& ghostIndices() const 
00305     {return ghostIndices_;}
00306 
00307   /** \brief Print the DOF map.
00308    *
00309    * ToDo: Replace this with override of Teuchos::Describable::describe().
00310    */
00311   virtual void print(std::ostream& os) const = 0 ;
00312 
00313   /** \brief Returns <tt>true</tt> if the map is homogeneous.
00314    *
00315    * See above defintion for a "Homogeneous" map.
00316    */
00317   virtual bool isHomogeneous() const {return false;}
00318 
00319 
00320   int setupVerb() const {return setupVerb_;}
00321 protected:
00322 
00323   void setLowestLocalDOF(int low) {lowestLocalDOF_ = low;}
00324 
00325   void setNumLocalDOFs(int numDOFs) {numLocalDOFs_ = numDOFs;}
00326 
00327   void setTotalNumDOFs(int numDOFs) {numDOFs_ = numDOFs;}
00328 
00329   const Mesh& mesh() const {return mesh_;}
00330 
00331   const MPIComm& comm() const {return mesh().comm();}
00332 
00333   void addGhostIndex(int dof) {ghostIndices_->append(dof);}
00334 
00335   static Teuchos::Time& dofLookupTimer() ;
00336 
00337   static Teuchos::Time& batchedDofLookupTimer() ;
00338 
00339 
00340 
00341 private:
00342 
00343   int setupVerb_;
00344 
00345   int localProcID_;
00346 
00347   Mesh mesh_;
00348 
00349   int lowestLocalDOF_;
00350 
00351   int numLocalDOFs_;
00352 
00353   int numDOFs_;
00354 
00355   RCP<Array<int> > ghostIndices_;
00356 
00357 };
00358 }
00359 
00360 
00361 #endif

Site Contact