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 Playa::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 . */
00126   const Mesh& mesh() const {return mesh_;}
00127   
00128   /** \brief Return <tt>true</tt> if the given cell is really owned by
00129    * another process and is only ghosted in this process (and optionally
00130    * return the owning process ID).
00131    *
00132    * \param  cellDim
00133    *           [in] The dimension of the cell.  
00134    * \param  cellLID
00135    *           [in] The LID of the cell in this process.  See
00136    *           <tt>MeshBase</tt> for more details, preconditions, etc.
00137    * \param  ownerProcID
00138    *           [out] The process rank ID which owns the cell
00139    *           <tt>(cellDim,cellLID)</tt>.
00140    *
00141    * <b>Preconditions:</b> See <tt>MeshBase</tt>
00142    *
00143    * ToDo: Change the <tt>ownerProcID</tt> argument to <tt>int*</tt> and
00144    * given it a default value of <tt>NULL</tt> so that it can be ignored
00145    * by the client.
00146    *
00147    * ToDo: Consider removing this function and just calling on the mesh
00148    * object directly.
00149    *
00150    * ToDo: Change name to <tt>isRemoteCell()</tt>? 
00151    */
00152   bool isRemote(int cellDim, int cellLID, int& ownerProcID) const 
00153     {return (ownerProcID=mesh_.ownerProcID(cellDim, cellLID)) != localProcID_;}
00154       
00155   /** \brief Get the global DOFs for a single function on a single
00156    * cell.
00157    *
00158    * \param  cellDim
00159    *           [in] The dimension of the cell
00160    * \param  cellLID
00161    *           [in] Local ID (LID) of the cell
00162    * \param  funcID
00163    *           [in] Function ID for which DOFs are requested
00164    * \param  dofs
00165    *           [out] Global IDs for DOFs of the requested function
00166    *           on the requested cell.
00167    *
00168    * 
00169    *
00170    */
00171   virtual void getDOFsForCell(int cellDim, int cellLID,
00172     int funcID,
00173     Array<int>& dofs) const;
00174 
00175   /** \brief Return the global DOFs for a batch of cells for a given set
00176    * of functions on those cells.
00177    *
00178    * \param  cellDim
00179    *           [in] The dimension of the cells in the batch of cells
00180    * \param  cellLIDs
00181    *           [in] Local IDs (LIDs) for the batch of cells
00182    * \param  requestedFuncSet
00183    *           [in] Set of function IDs for which DOFs are requested.
00184    *           Note that this must be equal to the allowed set of
00185    *           requested functions
00186    *           <tt>this->allowedFuncsOnCellBatch(cellDim,cellLIDs)</tt>.
00187    * \param  dofs
00188    *           [out] Global IDs for DOFs of the requested functions on the
00189    *           batch of cells.  The size of this array on output is \code
00190    *           dofs.size()==mapStructure.numBasisChunks() \endcode. The
00191    *           global DOFs for cell <tt>cellLIDs[c]</tt> (where <tt>0 <= c
00192    *           < cellLIDs.size()</tt>) for the cell for the basis chunk
00193    *           <tt>basisChunk</tt> (where <tt>0 <= basisChunk <
00194    *           mapStructure.numBasisChunks()</tt>) are given by \code
00195    *           dofs[c*nDOFsPerCell[c]+k] \endcode, where \code
00196    *           k=0...nDOFsPerCell[c]-1 \endcode and \code nDOFsPerCell[c]
00197    *           = mapStructure.basis(basisChunk).nNodes( spatialDim,
00198    *           this->mesh()->cellType(cellDim) ) *
00199    *           mapStructure.numFuncs(basisChunk) \endcode.  Note that the
00200    *           array <tt>nDOFsPerCell</tt> used above is not actually
00201    *           computed here or returned by this interface.  It is only
00202    *           used abstractly to define the <tt>dofs</tt> array above.
00203    * \param  nNodes
00204    *           [out] Array giving the number of coefficients for each type
00205    *           of basis family in <tt>mapStructure</tt> for each function.
00206    *           The size of this array on return is
00207    *           <tt>nNodes.size()==mapStructure.numBasisChunks()</tt> and
00208    *           <tt>nNodes[b]==mapStructure.basis(b).nNodes(spatialDim,cellType)</tt>,
00209    *           for <tt>b=0...mapStructure.numBasisChunks()-1</tt>.
00210    *
00211    * <b>Preconditions:</b><ul>
00212    * <li><tt>requestedFuncSet.setDifference(
00213    *           this->allowedFuncsOnCellBatch(cellDim,cellLIDs) ).size() == 0</tt>
00214    * <li>???Others???
00215    * </ul>
00216    *
00217    * \returns The map structure that groups sets of different functions
00218    * according with respect to those that have the same basis family.
00219    * Above, we will refer to this returned object as <tt>mapStructure</tt>
00220    * where <tt>mapStructure = *returnVal</tt>.
00221    *
00222    * ToDo: Remove the argument requestedFuncSet since all current use
00223    * cases and implemenations asume that all of the functions are
00224    * requested and returned.
00225    *
00226    * ToDo: Remove the nNodes return argument since this information can be
00227    * gotten just from the return <tt>mapStructure</tt> object.
00228    * Specifically, <tt>nNodes[basisChunk] =
00229    * mapStructure.basis(basisChunk).nNodes(spatialDim,cellType)</tt> so
00230    * what is the point in returning this array?  Since this is needed for
00231    * a whole batch of cells, it is cheap to just grab this from the
00232    * returned <tt>mapStructure</tt> object as shown above.
00233    */
00234   virtual RCP<const MapStructure> 
00235   getDOFsForCellBatch(
00236     int cellDim, const Array<int>& cellLIDs,
00237     const Set<int>& requestedFuncSet,
00238     Array<Array<int> >& dofs,
00239     Array<int>& nNodes,
00240     int verb
00241     ) const = 0 ;
00242 
00243   /** \brief Return the set of a function IDs for a batch of cells for
00244    * which DOFs can be obtained.
00245    *
00246    * \param  cellDim
00247    *           [in] The dimension of the cells in the batch of cells
00248    * \param  cellLIDs
00249    *           [in] Local IDs (LIDs) for the batch of cells
00250    */
00251   virtual RCP<const Set<int> >
00252   allowedFuncsOnCellBatch(int cellDim,
00253     const Array<int>& cellLIDs) const = 0 ;
00254 
00255   /** \brief Return an array of cell filters that gives, for each function
00256    * ID, the cells that the function lives on.
00257    *
00258    * \returns A reference to an array of size <tt>returnVal.size() ==
00259    * numTotalFunctcions</tt> where <tt>returnVal[funcID]</tt> gives a
00260    * handle to a <tt>CellFilterBase</tt> object where the function
00261    * <tt>funcID</tt> lives, where <tt>0 <= funcID <
00262    * numTotalFunctions</tt>.
00263    */
00264   virtual const Array<CellFilter>& funcDomains() const = 0 ;
00265 
00266   /** \brief Return the lowest DOF for DOFs owned in this process. */
00267   int lowestLocalDOF() const {return lowestLocalDOF_;}
00268 
00269   /** \brief Returns <tt>true</tt> if the given global DOF is owned in
00270    * this process.
00271    */
00272   bool isLocalDOF(int dof) const 
00273     {return (lowestLocalDOF_ <= dof && dof < lowestLocalDOF_+numLocalDOFs_);}
00274 
00275   /** \brief Return the number of DOFs owned in this process.
00276    *
00277    * ToDo: Is this the number of owned + ghosted DOFs or is it just owned
00278    * DOFs?
00279    */
00280   int numLocalDOFs() const {return numLocalDOFs_;}
00281 
00282   /** \brief Return the global number of DOFs over all processes.
00283    *
00284    * <b>Postconditions:</b><ul>
00285    * <li><tt>returnVal >= this->numLocalDOFs()</tt>
00286    * </ul>
00287    */
00288   int numDOFs() const {return numDOFs_;}
00289 
00290   /** \brief Return an array of the global DOFs for the DOFs that are
00291    * locally accessed in this process.
00292    *
00293    * <b>Postconditions:</b><ul>
00294    * <li><tt>returnVal->size() == ( this->numDOFs() - this->numLocalDOFs() )</tt>
00295    * <li><tt>returnVal[k] < this->lowsetLocalDOF() &&
00296    *     this->lowsetLocalDOF() + this->numLocalDOFs() <= returnVal[k]</tt>,
00297    *     for <tt>k=0...(this->numDOFs()-this->numLocalDOFs())-1</tt>.
00298    * </ul>
00299    *
00300    * ToDo: Change the return type to <tt>RCP<const Array<int> ></tt> since
00301    * I doubt that the client is allowed to change this array through this
00302    * function!
00303    *
00304    * ToDo: Change the name of this function to something like
00305    * <tt>getGhostDOFs()</tt>?
00306    */
00307   const RCP<Array<int> >& ghostIndices() const 
00308     {return ghostIndices_;}
00309 
00310   /** \brief Print the DOF map.
00311    *
00312    * ToDo: Replace this with override of Teuchos::Describable::describe().
00313    */
00314   virtual void print(std::ostream& os) const = 0 ;
00315 
00316   /** \brief Returns <tt>true</tt> if the map is homogeneous.
00317    *
00318    * See above defintion for a "Homogeneous" map.
00319    */
00320   virtual bool isHomogeneous() const {return false;}
00321 
00322   /**
00323    * \brief The largest dimension cell supported by this DOF map. Usually, this will
00324    * be the spatial dimension of the mesh. However, for functions defined only on a surface,
00325    * curve, or point set it may be lower. Such maps should override the default. 
00326    */
00327   virtual int cellDim() const {return mesh_.spatialDim();}
00328 
00329 
00330   int setupVerb() const {return setupVerb_;}
00331 protected:
00332 
00333   void setLowestLocalDOF(int low) {lowestLocalDOF_ = low;}
00334 
00335   void setNumLocalDOFs(int numDOFs) {numLocalDOFs_ = numDOFs;}
00336 
00337   void setTotalNumDOFs(int numDOFs) {numDOFs_ = numDOFs;}
00338 
00339   const MPIComm& comm() const {return mesh().comm();}
00340 
00341   void addGhostIndex(int dof) {ghostIndices_->append(dof);}
00342 
00343   static Teuchos::Time& dofLookupTimer() ;
00344 
00345   static Teuchos::Time& batchedDofLookupTimer() ;
00346 
00347 
00348 
00349 private:
00350 
00351   int setupVerb_;
00352 
00353   int localProcID_;
00354 
00355   Mesh mesh_;
00356 
00357   int lowestLocalDOF_;
00358 
00359   int numLocalDOFs_;
00360 
00361   int numDOFs_;
00362 
00363   RCP<Array<int> > ghostIndices_;
00364 
00365 };
00366 }
00367 
00368 
00369 #endif

Site Contact