SundanceBasicSimplicialMesh.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #ifndef SUNDANCE_BASICSIMPLICIALMESH_H
00043 #define SUNDANCE_BASICSIMPLICIALMESH_H
00044 
00045 
00046 
00047 #include "SundanceDefs.hpp"
00048 #include "SundanceMeshBase.hpp"
00049 #include "SundanceSet.hpp"
00050 #include "SundanceBasicVertexView.hpp"
00051 #include "SundanceArrayOfTuples.hpp"
00052 #include "SundanceIncrementallyCreatableMesh.hpp"
00053 #include "Teuchos_Array.hpp"
00054 #include "Teuchos_Hashtable.hpp"
00055 
00056 namespace Sundance
00057 {
00058 
00059 /**
00060  * A no-frills parallel simplicial mesh
00061  */
00062 class BasicSimplicialMesh : public IncrementallyCreatableMesh
00063 {
00064 public:
00065   /** */
00066   BasicSimplicialMesh(int dim, const MPIComm& comm, 
00067     const MeshEntityOrder& order);
00068 
00069   /** */
00070   virtual ~BasicSimplicialMesh(){;}
00071 
00072   /** 
00073    * Get the number of cells having dimension dim
00074    */
00075   virtual int numCells(int dim) const  ;
00076 
00077   /** 
00078    * Return the position of the i-th node
00079    */
00080   virtual Point nodePosition(int i) const {return points_[i];}
00081 
00082   /** 
00083    * Return a view of the i-th node's position
00084    */
00085   const double* nodePositionView(int i) const {return &(points_[i][0]);}
00086 
00087      
00088 
00089   /** 
00090    * Compute the jacobians of a batch of cells, returning the 
00091    * result via reference argument
00092    *
00093    * @param cellDim dimension of the cells whose Jacobians are to
00094    * be computed
00095    * @param cellLID local indices of the cells for which Jacobians
00096    * are to be computed
00097    * @param jBatch reference to the resulting Jacobian batch
00098    */
00099   virtual void getJacobians(int cellDim, const Array<int>& cellLID,
00100     CellJacobianBatch& jBatch) const  ;
00101 
00102   /** 
00103    * Compute the diameters of a batch of cells,
00104    * result via reference argument
00105    *
00106    * @param cellDim dimension of the cells whose diameters are to
00107    * be computed
00108    * @param cellLID local indices of the cells for which diameters
00109    * are to be computed
00110    * @param diameters reference to the array of cell diameters
00111    */
00112   virtual void getCellDiameters(int cellDim, const Array<int>& cellLID,
00113     Array<double>& diameters) const ;
00114 
00115 
00116   /**
00117    * Map reference quadrature points to physical points on the
00118    * given cells. 
00119    */
00120   virtual void pushForward(int cellDim, const Array<int>& cellLID,
00121     const Array<Point>& refQuadPts,
00122     Array<Point>& physQuadPts) const ;
00123 
00124       
00125 
00126   /** 
00127    * Return the rank of the processor that owns the given cell
00128    */
00129   virtual int ownerProcID(int cellDim, int cellLID) const  ;
00130 
00131       
00132 
00133   /** 
00134    * Return the number of facets of the given cell
00135    */
00136   virtual int numFacets(int cellDim, int cellLID, 
00137     int facetDim) const  ;
00138 
00139   /** 
00140    * Return the local ID of a facet cell
00141    * @param cellDim dimension of the cell whose facets are being obtained
00142    * @param cellLID local index of the cell whose
00143    * facets are being obtained
00144    * @param facetDim dimension of the desired facet
00145    * @param facetIndex index into the list of the cell's facets
00146    * @param facetOrientation orientation of the facet as seen from
00147    * the given cell (returned via reference)
00148    */
00149   virtual int facetLID(int cellDim, int cellLID,
00150     int facetDim, int facetIndex,
00151     int& facetOrientation) const  ;
00152 
00153 
00154   /** 
00155    * Return by reference argument an array containing
00156    * the LIDs of the facetDim-dimensional facets of the
00157    * given batch of cells 
00158    */
00159   virtual void getFacetLIDs(int cellDim, 
00160     const Array<int>& cellLID,
00161     int facetDim,
00162     Array<int>& facetLID,
00163     Array<int>& facetOrientations) const ;
00164 
00165   /** 
00166    * Return a view of an element's zero-dimensional facets
00167    */
00168   const int* elemZeroFacetView(int cellLID) const 
00169     {return &(elemVerts_.value(cellLID, 0));}
00170 
00171   /** 
00172    * Return the number of maximal cofacets of the given cell
00173    */
00174   virtual int numMaxCofacets(int cellDim, int cellLID) const  ;
00175 
00176   /** 
00177    * Return the local ID of a maximal cofacet cell
00178    * @param cellDim dimension of the cell whose cofacets are being obtained
00179    * @param cellLID local index of the cell whose
00180    * cofacets are being obtained
00181    * @param cofacetIndex which maximal cofacet to get
00182    * @param cofacetIndex index of the cell cellLID into the list of the 
00183    * maximal cell's facets
00184    */
00185   virtual int maxCofacetLID(int cellDim, int cellLID,
00186     int cofacetIndex,
00187     int& facetIndex) const  ;
00188 
00189 #ifdef MOVED_TO_BASE_CLASS
00190   /** 
00191    * Get the LIDs of the maximal cofacets for a batch of codimension-one
00192    * cells.
00193    *
00194    * \param cellLIDs [in] array of LIDs of the cells whose cofacets are 
00195    * being obtained
00196    * \param cofacets [out] the batch of cofacets
00197    */
00198   virtual void getMaxCofacetLIDs(const Array<int>& cellLIDs,
00199     MaximalCofacetBatch& cofacets) const ;
00200 #endif
00201       
00202   /** 
00203    * Find the cofacets of the given cell
00204    * @param cellDim dimension of the cell whose cofacets are being obtained
00205    * @param cellLID local index of the cell whose
00206    * cofacets are being obtained
00207    * @param cofacetDim dimension of the cofacets to get
00208    * @param cofacetLIDs LIDs of the cofacet
00209    */
00210   void getCofacets(int cellDim, int cellLID,
00211     int cofacetDim, Array<int>& cofacetLIDs) const ;
00212       
00213   /** 
00214    * Find the local ID of a cell given its global index
00215    */
00216   virtual int mapGIDToLID(int cellDim, int globalIndex) const  ;
00217 
00218   /** 
00219    * Determine whether a given cell GID exists on this processor
00220    */
00221   virtual bool hasGID(int cellDim, int globalIndex) const ;
00222 
00223     
00224 
00225   /** 
00226    * Find the global ID of a cell given its local index
00227    */
00228   virtual int mapLIDToGID(int cellDim, int localIndex) const  ;
00229 
00230   /**
00231    * Get the type of the given cell
00232    */
00233   virtual CellType cellType(int cellDim) const  ;
00234 
00235 
00236   /** Get the label of the given cell */
00237   virtual int label(int cellDim, int cellLID) const ;
00238 
00239   /** Get the labels for a batch of cells */
00240   virtual void getLabels(int cellDim, const Array<int>& cellLID, 
00241     Array<int>& labels) const ;
00242 
00243       
00244 
00245   /** Get the list of all labels defined for cells of the given dimension */
00246   virtual Set<int> getAllLabelsForDimension(int cellDim) const ;
00247 
00248   /** 
00249    * Get the cells associated with a specified label. The array 
00250    * cellLID will be filled with those cells of dimension cellDim
00251    * having the given label.
00252    */
00253   virtual void getLIDsForLabel(int cellDim, int label, Array<int>& cellLIDs) const ;
00254 
00255   /** \name Incremental creation methods */
00256   //@{
00257   /** 
00258    * Add new new vertex to the mesh.
00259    * \param globalIndex the GID of the new vertex
00260    * \param x the spatial position of the new vertex
00261    * \param ownerProcID the processor that "owns" this vertex 
00262    * \param label a label for this vertex (optionally used in setting 
00263    * loads, boundary conditions, etc)
00264    * \return the LID of the vertex.
00265    */
00266   virtual int addVertex(int globalIndex, const Point& x,
00267     int ownerProcID, int label);
00268 
00269   /** 
00270    * Add a new element to the mesh.
00271    * \param globalIndex the GID of the new element
00272    * \param vertexGIDs tuple of GIDs for the vertices defining this element. 
00273    * \param ownerProcID the processor that "owns" this element
00274    * \param label a label for this element (optionally used in setting loads, 
00275    * material properties, etc)
00276    * \return the LID of the element
00277    */
00278   virtual int addElement(int globalIndex, const Array<int>& vertexGIDs,
00279     int ownerProcID, int label);
00280 
00281   /** Set the label of the given cell */
00282   virtual void setLabel(int cellDim, int cellLID, int label)
00283     {
00284       labels_[cellDim][cellLID] = label;
00285     }
00286 
00287   /** Optional preallocation of space for an estimated number of vertices */
00288   virtual void estimateNumVertices(int numVertices);
00289 
00290   /** Optional preallocation of space for an estimated number of elements */
00291   virtual void estimateNumElements(int numElements);
00292 
00293   /** Coordinate intermediate cell definitions across processors  */
00294   virtual void assignIntermediateCellGIDs(int cellDim) ;
00295 
00296   /** */
00297   virtual bool hasIntermediateGIDs(int dim) const 
00298     {
00299       if (dim==1) return hasEdgeGIDs_;
00300       return hasFaceGIDs_;
00301     }
00302       
00303   //@}
00304 private:
00305 
00306   /** 
00307    * Add a new face, first checking to see if it already exists. 
00308    * This function is called from within addElement(),
00309    * not by the user, and is therefore private.
00310    *
00311    * \param vertGID The sorted GIDs for the three vertices of the face 
00312    * \param vertLID The LIDs for the three vertices of the face 
00313    * \param edgeLID{1,2,3} The LIDs for the three edges of the face 
00314    * \return LID of this face
00315    */
00316   int addFace(const Array<int>& vertLID, 
00317     const Array<int>& vertGID,
00318     const Array<int>& edgeGID,
00319     int elemLID,
00320     int elemGID);
00321 
00322   /**
00323    * Add a new edge, first checking to see if it already exists. 
00324    * This function is called from within addElement(),
00325    * not by the user, and is therefore private.
00326    *
00327    * \param vertLID{1,2} 
00328    * \param elemLID LID of the element that is adding the edge
00329    * \param elemGID GID of the element that is adding the edge
00330    * \param myFacetNumber facet number of the edge within the element
00331    * \return LID of this edge
00332    */
00333   int addEdge(int vertLID1, int vertLID2, int elemLID, int elemGID, 
00334     int myFacetNumber);
00335 
00336   /** 
00337    * Check for the presence of the edge (vertLID1, vertLID2) in the mesh.
00338    * \return the edge LID if the edge exists, -1 otherwise
00339    */
00340   int checkForExistingEdge(int vertLID1, int vertLID2);
00341 
00342   /** 
00343    * Check whether the face defined by the given vertices exists
00344    * in the mesh. Returns -1 if the face does not exist.
00345    * Called during the synchronization of intermediate cell GIDs.
00346    * \param vertGID{1,2,3} the global indices of the vertices defining the face
00347    * \return the LID of the face
00348    */
00349   int lookupFace(const Array<int>& vertGID) ;
00350 
00351   /** */
00352   void synchronizeGIDNumbering(int dim, int localCount) ;
00353       
00354   /** */
00355   void resolveEdgeOwnership(int cellDim);
00356 
00357   /** */
00358   std::string cellStr(int dim, const int* verts) const ;
00359 
00360   /** */
00361   std::string cellToStr(int dim, int cellLID) const ;
00362 
00363   /** */
00364   std::string printCells(int dim) const ;
00365 
00366   /** */
00367   void synchronizeNeighborLists();
00368       
00369       
00370 
00371   /** Number of cells of each dimension. */
00372   Array<int> numCells_;
00373     
00374   /** coordinates of vertices. The index into the array is the vertex LID .*/
00375   Array<Point> points_;
00376 
00377   /** pairs of local vertex indices for the edges, each pair ordered
00378    * from lower to higher <i>global</i> vertex index in order to define
00379    * an absolute edge orientation. Because global vertex indices are used, all
00380    * processors will agree on this orientation, regardless of the orientation
00381    * of the edge as seen by the element first defining it. 
00382    * The first index into this 2D array is the edge LID, the second the vertex 
00383    * number within the edge. 
00384    * */
00385   ArrayOfTuples<int> edgeVerts_;
00386 
00387   /** Tuples of local vertex indices for the faces, with each tuple ordered from
00388    * lowest to highest <i>global</i> index in order to define an absolute edge
00389    * orientation. Because global vertex indices are used, all
00390    * processors will agree on this orientation, regardless of the orientation
00391    * of the face as seen by the element first defining it. 
00392    * The first index into this 2D array is the face LID, the second the
00393    * vertex number within the face. */
00394   ArrayOfTuples<int> faceVertLIDs_;
00395 
00396   /** Tuples of global vertex indices for the faces, with each tuple ordered from
00397    * lowest to highest <i>global</i> index in order to define an absolute edge
00398    * orientation. Because global vertex indices are used, all
00399    * processors will agree on this orientation, regardless of the orientation
00400    * of the face as seen by the element first defining it. 
00401    * The first index into this 2D array is the face LID, the second the
00402    * vertex number within the face. 
00403    *
00404    * Notice that we duplicate the face vertex storage, storing both the
00405    * vertex LIDs and vertex GIDs for each face. This lets us do quick comparison
00406    * with the sorted GID array in order to identify pre-existing faces, while
00407    * also making it possible to retrieve face vertex LID information without
00408    * doing hashtable lookups.
00409    *
00410    */
00411   ArrayOfTuples<int> faceVertGIDs_;
00412     
00413   /** Tuples of local indices for the edges of all faces. The first index
00414    * into this 2D array is the face LID, the second the edge number. */
00415   ArrayOfTuples<int> faceEdges_;
00416     
00417   /** Tuples of edge signs for the faces. The edge sign indicates 
00418    * whether the orientation of the edge as given by moving around the face 
00419    * is parallel or antiparallel to the absolute orientation of the edge. */
00420   ArrayOfTuples<int> faceEdgeSigns_;
00421     
00422   /** tuples of local vertex indices for the elements. The first index into this
00423    * 2D array is the element LID, the second is the vertex number.  */
00424   ArrayOfTuples<int> elemVerts_;
00425 
00426   /** tuples of local edge indices for the elements. The first index into
00427    * this 2D array is the element LID, the second is the edge number. */
00428   ArrayOfTuples<int> elemEdges_;
00429 
00430   /** tuples of edge orientations for the elements, indicating whether 
00431    * the orientation of the edge as given by moving around the element 
00432    * is parallel or antiparallel to the absolute orientation of the edge. 
00433    * The first index into this 2D array is the element LID, the second 
00434    * the edge number. 
00435    * */
00436   ArrayOfTuples<int> elemEdgeSigns_;
00437 
00438   /** tuples of face LIDs for the elements. The first index is the
00439    * element LID, the second the face number. */
00440   ArrayOfTuples<int> elemFaces_;
00441 
00442   /** tuples of face rotations for the elements, defined relative to the 
00443    * absolute orientation of the face. */
00444   ArrayOfTuples<int> elemFaceRotations_;
00445 
00446   /** table for mapping vertex set -> face index */
00447   Hashtable<VertexView, int> vertexSetToFaceIndexMap_;
00448 
00449   /** array of face cofacets for the edges. The first index
00450    * is the edge LID, the second the cofacet number. */
00451   Array<Array<int> > edgeFaces_;
00452 
00453   /** array of element cofacets for the edges. The first index
00454    * is the edge LID, the second the cofacet number. */
00455   Array<Array<int> > edgeCofacets_;
00456 
00457   /** array of element cofacets for the faces. The first index is the
00458    * face LID, the second the cofacet number. */
00459   Array<Array<int> > faceCofacets_;
00460 
00461   /** array of edge cofacets for the vertices. The first index is the 
00462    * vertex LID, the second the edge cofacet number. */
00463   Array<Array<int> > vertEdges_;
00464 
00465   /** array of face cofacet LIDs for the vertices. The first index is the 
00466    * vertex LID, the second the cofacet number. */
00467   Array<Array<int> > vertFaces_;
00468 
00469   /** array of maximal cofacets for the vertices. The first index is the
00470    * vertex LID, the second the cafacet number. */
00471   Array<Array<int> > vertCofacets_;
00472 
00473   /** array of edge partners for the vertices. The partners are other
00474    * vertices sharing an edge with the specified vertex. */
00475   Array<Array<int> > vertEdgePartners_;
00476 
00477   /** map from local to global cell indices. The first index into this
00478    * 2D array is the cell dimension, the second the cell LID. */
00479   Array<Array<int> > LIDToGIDMap_;
00480 
00481   /** map from global to local cell indices. The array index is the 
00482    * cell dimension. The hashtable key is the cell GID, the value the
00483    * cell LID. */
00484   Array<Hashtable<int, int> > GIDToLIDMap_;
00485     
00486   /** Array of labels for the cells */
00487   Array<Array<int> > labels_;
00488 
00489   /** Array of owning processor IDs for the cells. Each cell is owned by
00490    * a single processor that is responsible for assigning global indices,
00491    * DOF numbers, and so on. */
00492   Array<Array<int> > ownerProcID_;
00493       
00494   /** 
00495    * Pointer to the pointer at the base of the face vertex GID array. This is
00496    * used to get small-array "views" of the face vertex GID array without
00497    * making copies, resulting in a significant performance improvement
00498    * in the vertex set hashtable lookups to identify pre-existing faces. 
00499    *
00500    * We use double rather than single indirection here because as elements
00501    * are added, the face vertex GID array will often be resized, thus changing
00502    * the base pointer. Each vertex set "view" keeps a pointer to the base pointer,
00503    * so that it always remains synchronized with the array of face vertices. 
00504    * 
00505    * IMPORTANT: any time faceVertGIDs_ is resized, faceVertGIDBase_[0] must
00506    * be reset to the base of the faceVertGIDs_ array so that the vertex
00507    * sets are pointing to the right place.
00508    */
00509   Array<int*> faceVertGIDBase_;
00510 
00511 
00512   /** flag indicating whether the edge GIDs have been synchronized */
00513   bool hasEdgeGIDs_;
00514 
00515   /** flag indicating whether the face GIDs have been synchronized */
00516   bool hasFaceGIDs_;
00517 
00518   /** Set of all neighbor processors sharing data with this one */
00519   Set<int> neighbors_;
00520 
00521   /** Whether the neighbor lists have been synchronized across 
00522    * processors */
00523   bool neighborsAreSynchronized_;
00524 
00525 
00526 };
00527 
00528 }
00529 
00530 
00531 
00532 
00533 #endif

Site Contact