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