Sandia Home
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

SundanceBasicSimplicialMesh.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_BASICSIMPLICIALMESH_H
00032 #define SUNDANCE_BASICSIMPLICIALMESH_H
00033 
00034 
00035 #ifndef DOXYGEN_DEVELOPER_ONLY
00036 
00037 
00038 #include "SundanceDefs.hpp"
00039 #include "SundanceMeshBase.hpp"
00040 #include "SundanceSet.hpp"
00041 #include "SundanceBasicVertexView.hpp"
00042 #include "SundanceArrayOfTuples.hpp"
00043 #include "SundanceIncrementallyCreatableMesh.hpp"
00044 #include "Teuchos_Array.hpp"
00045 #include "Teuchos_Hashtable.hpp"
00046 
00047 namespace SundanceStdMesh
00048 {
00049   namespace Internal
00050   {
00051     /**
00052      * A no-frills parallel simplicial mesh
00053      */
00054     class BasicSimplicialMesh : public IncrementallyCreatableMesh
00055     {
00056     public:
00057       /** */
00058       BasicSimplicialMesh(int dim, const MPIComm& comm);
00059 
00060       /** */
00061       virtual ~BasicSimplicialMesh(){;}
00062 
00063       /** 
00064        * Get the number of cells having dimension dim
00065        */
00066       virtual int numCells(int dim) const  ;
00067 
00068       /** 
00069        * Return the position of the i-th node
00070        */
00071       virtual Point nodePosition(int i) const {return points_[i];}
00072 
00073       /** 
00074        * Return a view of the i-th node's position
00075        */
00076       const double* nodePositionView(int i) const {return &(points_[i][0]);}
00077 
00078      
00079 
00080       /** 
00081        * Compute the jacobians of a batch of cells, returning the 
00082        * result via reference argument
00083        *
00084        * @param cellDim dimension of the cells whose Jacobians are to
00085        * be computed
00086        * @param cellLID local indices of the cells for which Jacobians
00087        * are to be computed
00088        * @param jBatch reference to the resulting Jacobian batch
00089        */
00090       virtual void getJacobians(int cellDim, const Array<int>& cellLID,
00091                                 CellJacobianBatch& jBatch) const  ;
00092 
00093       /** 
00094        * Compute the diameters of a batch of cells,
00095        * result via reference argument
00096        *
00097        * @param cellDim dimension of the cells whose diameters are to
00098        * be computed
00099        * @param cellLID local indices of the cells for which diameters
00100        * are to be computed
00101        * @param diameters reference to the array of cell diameters
00102        */
00103       virtual void getCellDiameters(int cellDim, const Array<int>& cellLID,
00104                                     Array<double>& diameters) const ;
00105 
00106 
00107       /**
00108        * Map reference quadrature points to physical points on the
00109        * given cells. 
00110        */
00111       virtual void pushForward(int cellDim, const Array<int>& cellLID,
00112                                const Array<Point>& refQuadPts,
00113                                Array<Point>& physQuadPts) const ;
00114 
00115       
00116 
00117       /** 
00118        * Return the rank of the processor that owns the given cell
00119        */
00120       virtual int ownerProcID(int cellDim, int cellLID) const  ;
00121 
00122       
00123 
00124       /** 
00125        * Return the number of facets of the given cell
00126        */
00127       virtual int numFacets(int cellDim, int cellLID, 
00128                             int facetDim) const  ;
00129 
00130       /** 
00131        * Return the local ID of a facet cell
00132        * @param cellDim dimension of the cell whose facets are being obtained
00133        * @param cellLID local index of the cell whose
00134        * facets are being obtained
00135        * @param facetDim dimension of the desired facet
00136        * @param facetIndex index into the list of the cell's facets
00137        * @param facetOrientation orientation of the facet as seen from
00138        * the given cell (returned via reference)
00139        */
00140       virtual int facetLID(int cellDim, int cellLID,
00141                            int facetDim, int facetIndex,
00142                            int& facetOrientation) const  ;
00143 
00144 
00145       /** 
00146        * Return by reference argument an array containing
00147        * the LIDs of the facetDim-dimensional facets of the
00148        * given batch of cells 
00149        */
00150       virtual void getFacetLIDs(int cellDim, 
00151                                 const Array<int>& cellLID,
00152                                 int facetDim,
00153                                 Array<int>& facetLID,
00154                                 Array<int>& facetOrientations) const ;
00155 
00156       /** 
00157        * Return a view of an element's zero-dimensional facets
00158        */
00159       const int* elemZeroFacetView(int cellLID) const 
00160       {return &(elemVerts_.value(cellLID, 0));}
00161 
00162       /** 
00163        * Return the number of maximal cofacets of the given cell
00164        */
00165       virtual int numMaxCofacets(int cellDim, int cellLID) const  ;
00166 
00167       /** 
00168        * Return the local ID of a maximal cofacet cell
00169        * @param cellDim dimension of the cell whose cofacets are being obtained
00170        * @param cellLID local index of the cell whose
00171        * cofacets are being obtained
00172        * @param cofacetIndex which maximal cofacet to get
00173        * @param cofacetIndex index of the cell cellLID into the list of the 
00174        * maximal cell's facets
00175        */
00176       virtual int maxCofacetLID(int cellDim, int cellLID,
00177                              int cofacetIndex,
00178                              int& facetIndex) const  ;
00179 
00180       
00181       /** 
00182        * Find the cofacets of the given cell
00183        * @param cellDim dimension of the cell whose cofacets are being obtained
00184        * @param cellLID local index of the cell whose
00185        * cofacets are being obtained
00186        * @param cofacetDim dimension of the cofacets to get
00187        * @param cofacetLIDs LIDs of the cofacet
00188        */
00189       void getCofacets(int cellDim, int cellLID,
00190                        int cofacetDim, Array<int>& cofacetLIDs) const ;
00191       
00192       /** 
00193        * Find the local ID of a cell given its global index
00194        */
00195       virtual int mapGIDToLID(int cellDim, int globalIndex) const  ;
00196 
00197       /** 
00198        * Determine whether a given cell GID exists on this processor
00199        */
00200       virtual bool hasGID(int cellDim, int globalIndex) const ;
00201 
00202     
00203 
00204       /** 
00205        * Find the global ID of a cell given its local index
00206        */
00207       virtual int mapLIDToGID(int cellDim, int localIndex) const  ;
00208 
00209       /**
00210        * Get the type of the given cell
00211        */
00212       virtual CellType cellType(int cellDim) const  ;
00213 
00214 
00215       /** Get the label of the given cell */
00216       virtual int label(int cellDim, int cellLID) const ;
00217 
00218       /** Get the labels for a batch of cells */
00219       virtual void getLabels(int cellDim, const Array<int>& cellLID, 
00220                              Array<int>& labels) const ;
00221 
00222       /** \name Incremental creation methods */
00223       //@{
00224       /** 
00225         * Add new new vertex to the mesh.
00226         * \param globalIndex the GID of the new vertex
00227         * \param x the spatial position of the new vertex
00228         * \param ownerProcID the processor that "owns" this vertex 
00229         * \param label a label for this vertex (optionally used in setting 
00230         * loads, boundary conditions, etc)
00231         * \return the LID of the vertex.
00232         */
00233       virtual int addVertex(int globalIndex, const Point& x,
00234                             int ownerProcID, int label);
00235 
00236       /** 
00237        * Add a new element to the mesh.
00238        * \param globalIndex the GID of the new element
00239        * \param vertexGIDs tuple of GIDs for the vertices defining this element. 
00240        * \param ownerProcID the processor that "owns" this element
00241        * \param label a label for this element (optionally used in setting loads, 
00242        * material properties, etc)
00243        * \return the LID of the element
00244        */
00245       virtual int addElement(int globalIndex, const Array<int>& vertexGIDs,
00246                              int ownerProcID, int label);
00247 
00248       /** Set the label of the given cell */
00249       virtual void setLabel(int cellDim, int cellLID, int label)
00250       {
00251         labels_[cellDim][cellLID] = label;
00252       }
00253 
00254       /** Optional preallocation of space for an estimated number of vertices */
00255       virtual void estimateNumVertices(int numVertices);
00256 
00257       /** Optional preallocation of space for an estimated number of elements */
00258       virtual void estimateNumElements(int numElements);
00259 
00260       /** Coordinate intermediate cell definitions across processors  */
00261       virtual void assignIntermediateCellGIDs(int cellDim) ;
00262 
00263       /** */
00264       virtual bool hasIntermediateGIDs(int dim) const 
00265       {
00266         if (dim==1) return hasEdgeGIDs_;
00267         return hasFaceGIDs_;
00268       }
00269       
00270       //@}
00271     private:
00272 
00273       /** 
00274        * Add a new face, first checking to see if it already exists. 
00275        * This function is called from within addElement(),
00276        * not by the user, and is therefore private.
00277        *
00278        * \param vertLID{1,2,3} The LIDs for the three vertices of the face 
00279        * \param edgeLID{1,2,3} The LIDs for the three edges of the face 
00280        * \param rotation An integer specifying the permutation that transforms
00281        * the sorted ordering of vertGID{1,2,3} to the order given by the
00282        * element definition. Initial value is not used; value is
00283        * returned by reference argument.
00284        * \return LID of this face
00285        */
00286       int addFace(int vertLID1, int vertLID2, int vertLID3,
00287                   int edgeLID1, int edgeLID2, int edgeLID3,
00288                   int elemLID,
00289                   int elemGID,
00290                   int& rotation);
00291 
00292       /**
00293        * Add a new edge, first checking to see if it already exists. 
00294        * This function is called from within addElement(),
00295        * not by the user, and is therefore private.
00296        *
00297        * \param vertLID{1,2} 
00298        * \param elemLID LID of the element that is adding the edge
00299        * \param elemGID GID of the element that is adding the edge
00300        * \param myFacetNumber facet number of the edge within the element
00301        * \return LID of this edge
00302        */
00303       int addEdge(int vertLID1, int vertLID2, int elemLID, int elemGID, 
00304                   int myFacetNumber);
00305 
00306       /** 
00307        * Check for the presence of the edge (vertLID1, vertLID2) in the mesh.
00308        * \return the edge LID if the edge exists, -1 otherwise
00309        */
00310       int checkForExistingEdge(int vertLID1, int vertLID2);
00311 
00312       /** 
00313        * Check for the presence of the face (vertLID1, int vertLID2, int vertLID3),
00314        * returning information on orientation of the face as defined by the calling
00315        * element. 
00316        */
00317       int checkForExistingFace(int vertLID1, int vertLID2, int vertLID3,
00318                                int edgeLID1, int edgeLID2, int edgeLID3,
00319                                int* sortedVertGIDs,
00320                                int* reorderedVertLIDs,
00321                                int* reorderedEdgeLIDs,
00322                                int& rotation) ;
00323 
00324       /** 
00325        * Check whether the face defined by the given vertices exists
00326        * in the mesh. Returns -1 if the face does not exist.
00327        * Called during the synchronization of intermediate cell GIDs.
00328        * \param vertGID{1,2,3} the global indices of the vertices defining the face
00329        * \return the LID of the face
00330        */
00331       int lookupFace(int vertGID1, int vertGID2, int vertGID3) ;
00332 
00333       /** */
00334       void synchronizeGIDNumbering(int dim, int localCount) ;
00335       
00336       /** */
00337       void resolveEdgeOwnership(int cellDim);
00338 
00339       /** */
00340       string cellStr(int dim, const int* verts) const ;
00341 
00342       /** */
00343       string cellToStr(int dim, int cellLID) const ;
00344 
00345       /** */
00346       string printCells(int dim) const ;
00347 
00348       /** */
00349       void synchronizeNeighborLists();
00350       
00351       
00352 
00353       /** Number of cells of each dimension. */
00354       Array<int> numCells_;
00355     
00356       /** coordinates of vertices. The index into the array is the vertex LID .*/
00357       Array<Point> points_;
00358 
00359       /** pairs of local vertex indices for the edges, each pair ordered
00360        * from lower to higher <i>global</i> vertex index in order to define
00361        * an absolute edge orientation. Because global vertex indices are used, all
00362        * processors will agree on this orientation, regardless of the orientation
00363        * of the edge as seen by the element first defining it. 
00364        * The first index into this 2D array is the edge LID, the second the vertex 
00365        * number within the edge. 
00366        * */
00367       ArrayOfTuples<int> edgeVerts_;
00368 
00369       /** Tuples of local vertex indices for the faces, with each tuple ordered from
00370        * lowest to highest <i>global</i> index in order to define an absolute edge
00371        * orientation. Because global vertex indices are used, all
00372        * processors will agree on this orientation, regardless of the orientation
00373        * of the face as seen by the element first defining it. 
00374        * The first index into this 2D array is the face LID, the second the
00375        * vertex number within the face. */
00376       ArrayOfTuples<int> faceVertLIDs_;
00377 
00378       /** Tuples of global vertex indices for the faces, with each tuple ordered from
00379        * lowest to highest <i>global</i> index in order to define an absolute edge
00380        * orientation. Because global vertex indices are used, all
00381        * processors will agree on this orientation, regardless of the orientation
00382        * of the face as seen by the element first defining it. 
00383        * The first index into this 2D array is the face LID, the second the
00384        * vertex number within the face. 
00385        *
00386        * Notice that we duplicate the face vertex storage, storing both the
00387        * vertex LIDs and vertex GIDs for each face. This lets us do quick comparison
00388        * with the sorted GID array in order to identify pre-existing faces, while
00389        * also making it possible to retrieve face vertex LID information without
00390        * doing hashtable lookups.
00391        *
00392        */
00393       ArrayOfTuples<int> faceVertGIDs_;
00394     
00395       /** Tuples of local indices for the edges of all faces. The first index
00396        * into this 2D array is the face LID, the second the edge number. */
00397       ArrayOfTuples<int> faceEdges_;
00398     
00399       /** Tuples of edge signs for the faces. The edge sign indicates 
00400        * whether the orientation of the edge as given by moving around the face 
00401        * is parallel or antiparallel to the absolute orientation of the edge. */
00402       ArrayOfTuples<int> faceEdgeSigns_;
00403     
00404       /** tuples of local vertex indices for the elements. The first index into this
00405        * 2D array is the element LID, the second is the vertex number.  */
00406       ArrayOfTuples<int> elemVerts_;
00407 
00408       /** tuples of local edge indices for the elements. The first index into
00409        * this 2D array is the element LID, the second is the edge number. */
00410       ArrayOfTuples<int> elemEdges_;
00411 
00412       /** tuples of edge orientations for the elements, indicating whether 
00413        * the orientation of the edge as given by moving around the element 
00414        * is parallel or antiparallel to the absolute orientation of the edge. 
00415        * The first index into this 2D array is the element LID, the second 
00416        * the edge number. 
00417        * */
00418       ArrayOfTuples<int> elemEdgeSigns_;
00419 
00420       /** tuples of face LIDs for the elements. The first index is the
00421        * element LID, the second the face number. */
00422       ArrayOfTuples<int> elemFaces_;
00423 
00424       /** tuples of face rotations for the elements, defined relative to the 
00425        * absolute orientation of the face. */
00426       ArrayOfTuples<int> elemFaceRotations_;
00427 
00428       /** table for mapping vertex set -> face index */
00429       Hashtable<VertexView, int> vertexSetToFaceIndexMap_;
00430 
00431       /** array of face cofacets for the edges. The first index
00432        * is the edge LID, the second the cofacet number. */
00433       Array<Array<int> > edgeFaces_;
00434 
00435       /** array of element cofacets for the edges. The first index
00436        * is the edge LID, the second the cofacet number. */
00437       Array<Array<int> > edgeCofacets_;
00438 
00439       /** array of element cofacets for the faces. The first index is the
00440        * face LID, the second the cofacet number. */
00441       Array<Array<int> > faceCofacets_;
00442 
00443       /** array of edge cofacets for the vertices. The first index is the 
00444        * vertex LID, the second the edge cofacet number. */
00445       Array<Array<int> > vertEdges_;
00446 
00447       /** array of face cofacet LIDs for the vertices. The first index is the 
00448        * vertex LID, the second the cofacet number. */
00449       Array<Array<int> > vertFaces_;
00450 
00451       /** array of maximal cofacets for the vertices. The first index is the
00452        * vertex LID, the second the cafacet number. */
00453       Array<Array<int> > vertCofacets_;
00454 
00455       /** array of edge partners for the vertices. The partners are other
00456        * vertices sharing an edge with the specified vertex. */
00457       Array<Array<int> > vertEdgePartners_;
00458 
00459       /** map from local to global cell indices. The first index into this
00460        * 2D array is the cell dimension, the second the cell LID. */
00461       Array<Array<int> > LIDToGIDMap_;
00462 
00463       /** map from global to local cell indices. The array index is the 
00464        * cell dimension. The hashtable key is the cell GID, the value the
00465        * cell LID. */
00466       Array<Hashtable<int, int> > GIDToLIDMap_;
00467     
00468       /** Array of labels for the cells */
00469       Array<Array<int> > labels_;
00470 
00471       /** Array of owning processor IDs for the cells. Each cell is owned by
00472        * a single processor that is responsible for assigning global indices,
00473        * DOF numbers, and so on. */
00474       Array<Array<int> > ownerProcID_;
00475       
00476       /** 
00477        * Pointer to the pointer at the base of the face vertex GID array. This is
00478        * used to get small-array "views" of the face vertex GID array without
00479        * making copies, resulting in a significant performance improvement
00480        * in the vertex set hashtable lookups to identify pre-existing faces. 
00481        *
00482        * We use double rather than single indirection here because as elements
00483        * are added, the face vertex GID array will often be resized, thus changing
00484        * the base pointer. Each vertex set "view" keeps a pointer to the base pointer,
00485        * so that it always remains synchronized with the array of face vertices. 
00486        * 
00487        * IMPORTANT: any time faceVertGIDs_ is resized, faceVertGIDBase_[0] must
00488        * be reset to the base of the faceVertGIDs_ array so that the vertex
00489        * sets are pointing to the right place.
00490        */
00491       Array<int*> faceVertGIDBase_;
00492 
00493 
00494       /** flag indicating whether the edge GIDs have been synchronized */
00495       bool hasEdgeGIDs_;
00496 
00497       /** flag indicating whether the face GIDs have been synchronized */
00498       bool hasFaceGIDs_;
00499 
00500       /** Set of all neighbor processors sharing data with this one */
00501       Set<int> neighbors_;
00502 
00503       /** Whether the neighbor lists have been synchronized across 
00504        * processors */
00505       bool neighborsAreSynchronized_;
00506 
00507 
00508       /** 
00509        * Sort the 3 vertices of a face in order of increasing GID
00510        * \param vertGID{1,2,3} the three vertices
00511        * \param sortedVertGIDs array in which the sorted vertices are to be returned
00512        */
00513       void getSortedFaceVertices(int vertGID1, int vertGID2, int vertGID3,
00514                                  int* sortedVertGIDs) const ;
00515 
00516 
00517       /** 
00518        * Sort the the vertices of a face in order or increasing GID, reordering
00519        * the LIDs of the vertices and associated edges following the GID ordering.
00520        * Also, return a rotation flag describing the permutation between
00521        * the unsorted and sorted arrays. 
00522        */
00523       void getSortedFaceVertices(int a, int b, int c,
00524                                  int la, int lb, int lc,
00525                                  int eAB, int eBC, int eCA, 
00526                                  int* sortedVertGIDs,
00527                                  int* reorderedVertLIDs,
00528                                  int* reorderedEdgeLIDs,
00529                                  int& rotation) const ;
00530 
00531       /** Helper function to stuff three numbers into an array */
00532       inline void fillSortedArray(int a, int b, int c, int* s) const
00533       {
00534         s[0] = a;
00535         s[1] = b;
00536         s[2] = c;
00537       }
00538 
00539 
00540     };
00541   }
00542 
00543 }
00544 
00545 
00546 
00547 #endif /* DOXYGEN_DEVELOPER_ONLY */
00548 
00549 #endif

© Sandia Corporation | Site Contact | Privacy and Security