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