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_MESHBASE_H 00032 #define SUNDANCE_MESHBASE_H 00033 00034 #include "SundanceDefs.hpp" 00035 #include "SundancePoint.hpp" 00036 #include "SundanceSet.hpp" 00037 #include "SundanceMap.hpp" 00038 #include "SundanceCellType.hpp" 00039 #include "SundanceObjectWithVerbosity.hpp" 00040 #include "SundanceObjectWithInstanceID.hpp" 00041 #include "Teuchos_MPIComm.hpp" 00042 #include "Teuchos_Array.hpp" 00043 #include "SundanceCellReorderer.hpp" 00044 #include "SundanceCellReordererImplemBase.hpp" 00045 00046 namespace Sundance { 00047 00048 00049 /** Identifier for ordering convention */ 00050 enum MeshEntityOrder {UFCMeshOrder, ExodusMeshOrder}; 00051 00052 class MaximalCofacetBatch; 00053 00054 using namespace Teuchos; 00055 00056 class CellJacobianBatch; 00057 00058 00059 /** \brief Abstract interface to a mesh. 00060 * 00061 * \section Sundance_MeshBase_Outline_sec Outline 00062 * 00063 * <ul> 00064 * <li>\ref Sundance_MeshBase_Introduction_sec 00065 * <li>\ref Sundance_MeshBase_Definitions_sec 00066 * <li>\ref Sundance_MeshBase_Common_Function_Arguments_sec 00067 * <li>\ref Sundance_MeshBase_Refactorings_sec 00068 * </ul> 00069 * 00070 * \section Sundance_MeshBase_Introduction_sec Introduction 00071 * 00072 * A mesh is a collection of connected cells (also called elements). This 00073 * mesh interface is designed to allow for the representation of 1D, 2D, and 3D (and 00074 * even higher dimensional) meshes. A mesh contains both topological 00075 * information and geometric information about the cells and their subparts 00076 * (i.e. facets). Topological information refers to information about how 00077 * cells of various types and dimensions are connected to each other within 00078 * the mesh. Geometric information refers to information about the position, 00079 * size, and shape of cells within the mesh. 00080 * 00081 * Currently, this interface only handles meshes where all cells of a given 00082 * cell dimension have the same cell type. For example, this only allows 00083 * meshes with all triangles or all quads in 2D or all tetrahedrals in 3D. 00084 * 00085 * \todo Add some diagrams to show different cell types to help define cells, 00086 * facets, co-facets, vertices, etc. 00087 * 00088 * \section Sundance_MeshBase_Definitions_sec Definitions 00089 * 00090 * The following definitions are used in the specification of this mesh 00091 * interface. 00092 * 00093 *<ul> 00094 * 00095 * <li><b>Topological information</b> 00096 * 00097 * <ul> 00098 * 00099 * <li><b>Spatial Dimension (spatialDim)</b>: The maximum cell dimension of 00100 * any cell type in the mesh. For example, a 3D mesh will have 00101 * spatialDim=3, a 2D mesh will have spatialDim=2 and a 1D mesh will have 00102 * spatialDim=1. Typically, when we use the short hand 1D, 2D or 3D, we are 00103 * referring to the spatial dimension of the mesh. Note that 4D and 00104 * higher-dimensional meshes are also representable by this interface in 00105 * principle with some small changes (e.g. like making the size of a point 00106 * more flexible) 00107 * 00108 * <li><b>Cell</b>: A mesh object of some dimension. For example, in a 3D 00109 * mesh, cells are things like elements, faces, edges, and nodes. 00110 * 00111 * <li><b>Cell Type (cellType)</b>: An enumeration of type <tt>CellType</tt> 00112 * that lists some common cell types. For example, common cell types are 00113 * things like vertexes (0D), lines or edges (1D), triangles (2D), and 00114 * quadrilaterals (2D). 00115 * 00116 * <li><b>Cell Dimension (cellDim)</b>: The dimension of a cell. More 00117 * formally, the cell dimension is equal to the number of lower level facet 00118 * types in the cell. For example, A 3D tetrahedral cell (or element) has 00119 * cellDim=3 and it has the three lower-level facet types faces (cellDim=2), 00120 * edges (cellDim=1), and vertexes (cellDim=0). 00121 * 00122 * <li><b>Relative Cell</b>: The term "relative cell" is used below to refer 00123 * to the cell object for which we consider other cells called "facets" and 00124 * "co-facets". 00125 * 00126 * <li><b>Facet</b>: A lower dimensional cell directly connected to and 00127 * contained within a relative <em>parent</em> cell. For example, a 3D cell 00128 * (element) has three different facet types: faces (facetDim=2), edges 00129 * (facetDim=1), and vertexes (facetDim=0). A face (cellDim=2) relative 00130 * cell (or a 2D element) has two different facet types: edges (facetDim=1), 00131 * and vertexes (facetDim=0). A particular relative cell 00132 * <tt>(cellDim,cellLID)</tt> has 00133 * <tt>nf=numFacets(cellDim,cellLID,facetDim)</tt> facets of a particular 00134 * dimension <tt>facetDim</tt>. 00135 * 00136 * <li><b>Facet Dim (facetDim)</b>: The cell dimension of a given facet. 00137 * For example, the dimension of a face facet of a 3D element is facetDim=2. 00138 * 00139 * <li><b>Facet Index (facetIndex)</b>: This is the local index of the facet 00140 * with respect to its relative parent cell. For example, a 3D brick 00141 * relative cell/element will have 6 faces which can be accessed using the 00142 * facet indexes 0, 1, 2, 3, 4, and 5. 00143 * 00144 * <li><b>Co-facet</b>: A higher dimensional cell of which the given 00145 * relative cell is a facet. For example, the co-facets of a relative 00146 * face cell in a 3D mesh are the one or two 3D element cells that share 00147 * this face. In the case of a boundary face in a 3D mesh, only one 00148 * co-facet is connected to the boundary cell and that is its boundary 00149 * element. Note that in 3D, edges can have many different face and element 00150 * co-facets. There are some important properties of co-facets. Relative 00151 * cells of dimension cellDim=spatialDim-1 will have either one or two 00152 * co-facets of dimension cofacetDim=spatialDim. Therefore, relative cells 00153 * of the dimension cellDim=spatialDim-1 that have only one co-facet must be 00154 * a boundary cell (i.e. a boundary face in 3D, a boundary edge in 2D, or a 00155 * boundary vertex in 1D). Note that relative cells with dimension 00156 * cellDim=spatialDim-n, where n >=2, can have more than two co-facets in 00157 * general. 00158 * 00159 * <li><b>Co-facet Dimension (cofacetDim)</b>: The cell dimension of a 00160 * co-facet cell. 00161 * 00162 * <li><b>Maximal co-facet</b>: A co-facet of a relative cell whose 00163 * dimension is equal to the spatial dimension of the mesh. 00164 * 00165 * <em>Assertion</em>: <tt>maxCofacetDim == spatialDim</tt>. 00166 * 00167 * <li><b>Vertex</b>: A zero dimensional cell (cellDim=0). 00168 * 00169 * <em>Assertion</em>: <tt>vertexCellDim == 0</tt>. 00170 * 00171 * <li><b>Element</b>: The term "element" is used to refer to cells whose 00172 * dimension is equal to the spatial dimension of the mesh. Warning, the 00173 * term "element" is an overloaded term and is also used to refer to an 00174 * entry in an array of objects. 00175 * 00176 * <li><b>Facet orientation (facetOrientation)</b>: The orientation of a 00177 * facet with respect to its parent cell. This is given as an integer value 00178 * that requires agreement of interpretation. In 2D, an edge for instance 00179 * will have just a positive and a negative orientation. In 3D, a face can 00180 * have more than two orientations and each orientation is a permutation of 00181 * the different nodal listings on the face. The facet orientation integer 00182 * value is typically interpreted as an index into an array of possible 00183 * orientations. The mesh reader/creator and the assembly code have to 00184 * agree on how these orientations are interpreted. 00185 * 00186 * <li><b>Co-facet index (cofacetIndex)</b>: The relative index of a 00187 * co-facet of some relative cell. For example, an internal face in a 3D 00188 * mesh will have two co-facet element objects which can be accessed using 00189 * the co-facet indexes 0 and 1. 00190 * 00191 * <li><b>Label</b>: Every cell can be given a single integer value that 00192 * can be used in a variety of ways. For example, boundary faces in 3D can 00193 * be given an integer label to specify different types of boundary 00194 * conditions. This integer could also be used with bit manipulation to 00195 * allow for multiple classifications for a single cell. 00196 * 00197 * <li><b>Intermediate Cell</b>: An intermediate cell is a cell that has a 00198 * dimension cellDim in the range 0 < cellDim < spatialDim. For example, in 00199 * a 3D mesh, faces and edges are intermediate cell types. 00200 * 00201 * </ul> 00202 * 00203 * <li><b>Geometric information</b> 00204 * 00205 * <ul> 00206 * 00207 * <li><b>Point</b>: A point is an array of coordinate positions. Currently 00208 * this is stored as a array with three doubles (i.e. x=0, y=1, and z=2). 00209 * For 2D meshes only the x=0 and y=1 positions are used. For 1D meshes, 00210 * only the x=0 position is used. 00211 * 00212 * <li><b>Cell Centroid</b>: A point that represents the geometric center of 00213 * a cell. 00214 * 00215 * <li> <b>Cell Diameter</b>: The cell diameter is defined as the maximum 00216 * line segment that can be drawn in the cell. This gives a measure of how 00217 * big the cell is and, for instance, can be used in some types of 00218 * finite-element stabilization methods. 00219 * 00220 * <li><b>Cell Curvature</b>: The curvature of cell refers to the shape of a 00221 * cell. This is typically used to represent the shapes of faces in 3D or 00222 * edges in 2D which is critical in the implementation of higher-order 00223 * higher-order discrimination methods. Cell curvature is currently not 00224 * supported by this mesh interface but could be in the future. 00225 * 00226 * <li><b>Reference Cell</b>: The term "reference cell" is used below to 00227 * refer that a cell type's reference cell which is a geometric description 00228 * of the cell in a simple coordinate system. By using a standard 00229 * definition of a "reference cell", we can decouple different types of 00230 * mathematical operations defined of a cell of a certain basic type (e.g. 00231 * triangles and quadrilaterals in 2D, and tetrahedral and bricks in 3D). 00232 * Typically, the nodes of a reference cell will have coordinates that 00233 * integer multiples of one (including zero). 00234 * 00235 * <li><b>Cell Jacobian</b>: The cell Jacobian is a transformation matrix 00236 * that maps cell vertex coordinate values (i.e. points) from the reference 00237 * cell to the physical cell. The inverse of the cell Jacobian maps points 00238 * from the physical cell to the reference cell. A cell with the cell 00239 * dimension cellDim has a cell Jacobian matrix of dimension cellDim x 00240 * cellDim. 00241 * 00242 * </ul> 00243 * 00244 * <li><b>Parallel Information</b> 00245 * 00246 * <ul> 00247 * 00248 * <li><b>Cell Ownership</b>: The ownership of a cell refers to which 00249 * process owns the cell. All other processes that need to access that cell 00250 * get a "ghost" copy of the cell locally. 00251 * 00252 * <li><b>Ghost Cell</b>: A ghost cell is a cell that is not owned by the 00253 * local process that is copied to a process in order to perform certain 00254 * computations. 00255 * 00256 * <li><b>Cell Local ID (cellLID)</b>: The LID of a cell is an index to 00257 * the cell within the local process and these IDs are typically ordered 00258 * from 0 to numLocalCells-1. Local cells can include both owned cells and 00259 * ghosted cells. 00260 * 00261 * <li><b>Cell Global ID (cellGID)</b>: The global ID of a cell is an index 00262 * that is unique across all processes and is used as a process-independent 00263 * identifier for the cell. 00264 * 00265 * </ul> 00266 * 00267 * </ul> 00268 * 00269 * \section Sundance_MeshBase_Common_Function_Arguments_sec Common Function Arguments and Pre/Post-Conditions 00270 * 00271 * Below, a common set of Mesh arguments are described along with relevant 00272 * pre- and post conditions. 00273 * 00274 * <ul> 00275 * 00276 * <li><b>cellDim</b> [in] The dimension of a cell 00277 * 00278 * <em>Precondition</em>: <tt>0 <= cellDim <= spatialDim</tt> 00279 * 00280 * <li><b>cellLID(s)</b> [in] Local ID (LID) of a cell(s). 00281 * 00282 * <em>Precondition</em>: <tt>0 <= cellLID < numCells(cellDim)</tt>, where 00283 * <tt>cellDim</tt> is the dimension of the given cell. 00284 * 00285 * <li><b>cellGID</b> [in] Global ID (GID) of a cell which is unique across 00286 * processes. 00287 * 00288 * <em>Precondition</em>: <tt>??? <= cellGID < ???</tt> (How do we write 00289 * this?). 00290 * 00291 * <li><b>facetDim</b> [in] The dimension of a given facet cell. 00292 * 00293 * <em>Precondition</em>: <tt>0 <= facetDim < cellDim</tt>, where 00294 * <tt>cellDim</tt> is the dimension of the relative cell 00295 * 00296 * <li><b>facetIndex</b> [in] Local index of the facet with respect to its 00297 * parent relative cell. 00298 * 00299 * <em>Precondition</em>: <tt>0 <= facetIndex < 00300 * numFacets(cellDim,cellLID,facetDim)</tt>, where <tt>facetDim</tt> is the 00301 * dimension of the facet of the relative parent cell 00302 * <tt>(cellDim,cellLID)</tt> 00303 * 00304 * <li><b>facetOrientation(s)</b> [out] The orientation of a facet with 00305 * respect to its parent cell. This is given as an integer value that 00306 * requires agreement of interpretation (see above). 00307 * 00308 * <li><b>cofacetDim</b> [in] Cell dimension of a co-facet cell. 00309 * 00310 * <em>Precondition</em>: <tt>0 <= cellDim < cofacetDim <= spatialDim</tt>, 00311 * where <tt>cellDim</tt> is the dimension of the relative cell 00312 * 00313 * <li><b>cofacetIndex</b> [in] Relative index of a co-facet of some relative 00314 * cell. 00315 * 00316 * <em>Precondition</em>: <tt>0 <= cofacetIndex < 00317 * numMaxCofacets(cellDim,cellLID)</tt>, where <tt>(cellDim,cellLID)</tt> is 00318 * the relative cell. 00319 * 00320 * </ul> 00321 * 00322 * \section Sundance_MeshBase_Refactorings_sec Possible Refactorings 00323 * 00324 * <ul> 00325 * 00326 * <li>Copy ObjectWithInstanceID base class into a special Nihilo tools 00327 * package or into Teuchos. 00328 * 00329 * <li>Inherit MeshBase from Teuchos::VerboseObject instead of 00330 * ObjectWithVerbosity. 00331 * 00332 * <li>Remove any concrete implementations and data from this base interface 00333 * to provide a clean abstract interface. This would include removing the 00334 * constructor. 00335 * 00336 * <li>Either remove the non-batch access functions all together, or make the 00337 * namings of batch and non-batch access functions more consistent. 00338 * 00339 * <li>Have all of the functions return just a single return value or when 00340 * more than one object is returned, return all values from the argument list. 00341 * Or, when the value that is being returned from the argument list is only 00342 * occasionally returned, change it to a pointer type and give it a default 00343 * value of NULL so that it can be safely ignored! This will actually speed 00344 * up performance in some cases. For example, <tt>facetOrientation</tt> is a 00345 * return argument that is often ignored and would benefit from making it an 00346 * optional argument. 00347 * 00348 * <li>Remove the staggered output function since the Teuchos::FancyOStream 00349 * should handle parallel output from every process well. 00350 * 00351 * <li>Add a new cell type called a "general" cell for very irregular cells 00352 * that defy fixed classification. This could be used to represent many of 00353 * the irregular cells that remain after non-conforming mesh refinement. 00354 * 00355 * <li>Make sure to tell the DOF map how to interpret the facet orientation 00356 * integers. Currently the interpretation is hard coded in Sundance. These 00357 * permutations need to be enumerated in a C++ enum and the DOF map must be 00358 * given the array of these enums to interpret the orientation integer values. 00359 * To be 100 percent safe, we need a way of allowing the mesh to directly 00360 * return the interpretation of these orientations. What you can do is to 00361 * require that the int value be an index into an an array of enumeration 00362 * values that corresponds to the cell type. This would require an enum type 00363 * and an array of enum values for every facet cell type. For the current 00364 * cell types for regular elements, this would be no problem. However, for 00365 * the facets of a "general" cell type, the facets may also be classified as 00366 * "general" cell types and therefore may not allow such an orientation array 00367 * to be defined. 00368 * 00369 * <li>Clearly define the coordinate system of the reference cell of each of 00370 * the standard cell types in order to clearly define interpretation of the 00371 * reference points passed into the <tt>pushForward()</tt> function. Without 00372 * a clear definition of the reference cell, these reference points are 00373 * meaningless. Actually, for maximal flexibility, each cell type should 00374 * define, at runtime, the coordinate system for the reference cell. Or, we 00375 * must just all agree on a single set of standard definitions of reference cells 00376 * for different cell types. 00377 * 00378 * </ul> 00379 */ 00380 class MeshBase 00381 : public ObjectWithClassVerbosity<MeshBase> 00382 , public ObjectWithInstanceID<MeshBase> 00383 { 00384 public: 00385 00386 /** \name Constructors/Destructor */ 00387 //@{ 00388 00389 /** \brief . */ 00390 MeshBase(int dim, const MPIComm& comm, 00391 const MeshEntityOrder& meshOrder); 00392 00393 /** \brief . */ 00394 virtual ~MeshBase(){;} 00395 00396 //@} 00397 00398 /** \name Topological Information */ 00399 //@{ 00400 00401 /** \brief Get the ordering convention used by this mesh */ 00402 const MeshEntityOrder& meshOrder() const {return order_;} 00403 00404 /** \brief Get the spatial dimension of the mesh 00405 * 00406 * <b>Postconditions:</b><ul> 00407 * <li><tt>0 < returnVal <= 3</tt> 00408 * </ul> 00409 */ 00410 int spatialDim() const {return dim_;} 00411 00412 /** \brief Get the number of local cells having dimension cellDim. 00413 * 00414 * \todo Change this to <tt>numLocalCells(cellDim)</tt>. 00415 */ 00416 virtual int numCells(int cellDim) const = 0 ; 00417 00418 /** \brief Return the number of facets of the given relative cell. 00419 * 00420 * \param cellDim 00421 * [in] The dimension of the relative cell 00422 * \param cellLID 00423 * [in] The LID of the relative cell 00424 * \param facetDim 00425 * [in] The dimension of the facets for the 00426 * relative cell 00427 * 00428 * <b>Postconditions:</b><ul> 00429 * <li><tt>returnVal >= 2</tt>: Every cell has two or more 00430 * facets of a given dimension. 00431 * </ul> 00432 */ 00433 virtual int numFacets(int cellDim, int cellLID, 00434 int facetDim) const = 0 ; 00435 00436 /** \brief Return the LID of a single facet cell (and optionally its 00437 * orientation) with respect to a relative parent cell. 00438 * 00439 * \param cellDim 00440 * [in] Dimension of the parent cell whose facets 00441 * are being obtained. 00442 * \param cellLID 00443 * [in] Local ID of the parent cell whose facets 00444 * are being obtained 00445 * \param facetDim 00446 * [in] Dimension of the desired facet. 00447 * \param facetIndex 00448 * [in] The relative index into the list of the 00449 * cell's facets. 00450 * \param facetOrientation 00451 * [out] The orientation of the facet w.r.t the 00452 * parent cell. 00453 * 00454 * \todo Change the facetOrientation argument to be a raw pointer that can 00455 * be NULL and therefore easily ignored. 00456 */ 00457 virtual int facetLID(int cellDim, int cellLID, 00458 int facetDim, int facetIndex, 00459 int& facetOrientation) const = 0 ; 00460 00461 /** \brief Return an array containing the LIDs of facets of dimension 00462 * facetDim for the given batch of relative parent cells. 00463 * 00464 * \param cellDim 00465 * [in] Dimension of the relative parent cells whose facets 00466 * are being obtained 00467 * \param cellLIDs 00468 * [in] Array of LIDs for the relative parent cells 00469 * \param facetDim 00470 * [in] Dimension of the desired facets 00471 * \param facetLIDs 00472 * [out] On exit this array gives the local facet IDs 00473 * for all of the cells given in cellLIDs in one flat array 00474 * with size = <tt>cellLIDs.size()*nf</tt>, where 00475 * <tt>nf=numFacets(cellDim,cellLIDs[j],facetDim)</tt>) where 00476 * <tt>j</tt> can be any index <tt>0 <= j < numCells(cellDim)</tt>. 00477 * Specifically, the local facet IDs for <tt>cellLIDs[k]</tt>, where 00478 * <tt>k=0...cellLIDs.size()-1</tt>, is given 00479 * by <tt>facetLIDs[k*nf+j]</tt>, where <tt>j=0...nf-1</tt>. 00480 * \param facetOrientations 00481 * [out] On exist, if <tt>facetDim > 0</tt>, this array gives 00482 * the integer orientation of the facet with respect to 00483 * its parent cell (see above definition of "Facet Orientation"). 00484 * Oon exist this array will be 00485 * resized to size = <tt>cellLIDs.size()*nf</tt>, where 00486 * <tt>nf=numFacets(cellDim,cellLID,facetDim)</tt>). 00487 * Specifically, the local facet orientation for the cell cellLIDs[k], where 00488 * <tt>k=0...cellLIDs.size()-1</tt>, is given 00489 * by <tt>facetOrientations[k*nf+j]</tt>, where <tt>j=0...nf-1</tt>. 00490 * If <tt>facetDim==0</tt> then this array is ignored. 00491 * 00492 * <b>Warning!</b> This function will only work for homogeneous cell types! 00493 * 00494 * \todo Change the facetOrientation argument to an <tt>Array<int>*</tt> 00495 * type so that it can be NULL and therefore ignored (which is a common use 00496 * case). 00497 */ 00498 virtual void getFacetLIDs(int cellDim, 00499 const Array<int>& cellLIDs, 00500 int facetDim, 00501 Array<int>& facetLIDs, 00502 Array<int>& facetOrientations) const = 0 ; 00503 00504 /** \brief Return an array containing the LIDs of the facets of 00505 * dimension facetDim of the single relative parent cell (optionally also 00506 * returning the facet orientations). 00507 * 00508 * \param cellDim 00509 * [in] Dimension of the parent cell whose facets 00510 * are being obtained. 00511 * \param cellLID 00512 * [in] Local ID of the parent cell whose facets 00513 * are being obtained 00514 * \param facetDim 00515 * [in] Dimension of the desired facets 00516 * \param facetLIDs 00517 * [out] On exit this array gives the local facet IDs 00518 * for the parent cell 00519 * with size = <tt>nf</tt>, where 00520 * <tt>nf=numFacets(cellDim,cellLID,facetDim)</tt>. 00521 * \param facetOrientations 00522 * [out] On exist, if <tt>facetDim > 0</tt>, this array gives 00523 * the integer orientation of the facet with respect to 00524 * its parent cell (see above definition of "Facet Orientation"). 00525 * On exist this array will be 00526 * resized to size = <tt>nf</tt>, where 00527 * <tt>nf=numFacets(cellDim,cellLID,facetDim)</tt>). 00528 * If <tt>facetDim==0</tt> this this array argument is ignored! 00529 * 00530 * The default implementation loops over calls to 00531 * <tt>facetLID()</tt>. Subclasses can provide a more efficient 00532 * implementation if desired. 00533 * 00534 * \todo Rename to something like getSingleCellFacetLIDs(...). 00535 * 00536 * \todo Change the facetOrientation argument to an <tt>Array<int>*</tt> 00537 * type so that it can be NULL and therefore ignored (which is a common use 00538 * case). 00539 */ 00540 void getFacetArray(int cellDim, int cellLID, int facetDim, 00541 Array<int>& facetLIDs, 00542 Array<int>& facetOrientations) const ; 00543 00544 /** \brief Return a view of an array of LIDs for a maximum-dimensional 00545 * cell's zero-dimensional facets (i.e. vertexes). 00546 * 00547 * \param maxCellLID 00548 * [in] Local ID of the maximum dimensional cell (i.e. element). 00549 * 00550 * <b>Preconditions:</b><ul> 00551 * <li>The cell <tt>maxCellLID</tt> must be a maximum-dimensional cell! 00552 * </ul> 00553 * 00554 * \returns A raw pointer into an array which stores the local process IDs 00555 * of the vertices. These IDs are the local process IDs, not the facet 00556 * indexes relative to the relative parent cell. The dimension of this 00557 * array is determined by the cell type given by 00558 * <tt>cellType(maxCellLID)</tt>. 00559 * 00560 * \todo Return this array as a Teuchos::ArrayView<int> object which will 00561 * have the dimension embedded in it and will have full range checking! 00562 * 00563 * \todo Rename to something like getMaxCellZeroFacetsLIDsView(...). 00564 */ 00565 virtual const int* elemZeroFacetView(int maxCellLID) const = 0 ; 00566 00567 /** \brief Return the number of maximal co-facets of the given cell. 00568 * 00569 * <b>Preconditions:</b><ul> 00570 * <li><tt>0 <= cellDim < spatialDim()</tt> 00571 * </ul> 00572 * 00573 * Note that if <tt>cellDim==spatialDim()-1</tt> and <tt>returnVal==1</tt> then 00574 * this cell must be a boundary cell (i.e. a boundary face in 3D, a boundary 00575 * edge in 1D, or a boundary node in 1D)! 00576 */ 00577 virtual int numMaxCofacets(int cellDim, int cellLID) const = 0; 00578 00579 /** \brief Return the LID of a maximal co-facet of a cell. 00580 * 00581 * \param cellDim 00582 * [in] Dimension of the cell whose co-facets are being obtained 00583 * \param cellLID 00584 * [in] Local ID of the cell whose co-facets are being obtained 00585 * \param cofacetIndex 00586 * [in] Index into the list of the cell's co-facets. 00587 * \param facetIndex 00588 * [out] Returns the local index into the facet array 00589 * for the relative cell (cellDim,cellLID) with respect 00590 * to the maximal co-facet. In other words 00591 * <tt>cellLID==facetLID(spatialDim(),returnVal,cellDim,facetIndex)</tt>. 00592 * 00593 * <b>Preconditions:</b><ul> 00594 * <li><tt>0 <= cellDim < spatialDim()</tt> 00595 * </ul> 00596 * 00597 * \returns The LID of the requested maximal co-facet. 00598 * 00599 * \todo Make the <tt>facetIndex</tt> an <tt>int*</tt> argument and give it a 00600 * default value of <tt>NUL</tt> so that it can be easily ignored! 00601 */ 00602 virtual int maxCofacetLID(int cellDim, int cellLID, 00603 int cofacetIndex, 00604 int& facetIndex) const = 0 ; 00605 /** 00606 * Get the LIDs of the maximal cofacets for a batch of codimension-one 00607 * cells. 00608 * 00609 * \param cellLIDs [in] array of LIDs of the cells whose cofacets are 00610 * being obtained 00611 * \param cofacets [out] 00612 * \param facetIndex [out] index of each calling cell 00613 * into the list of its maximal cofacet's facets 00614 */ 00615 virtual void getMaxCofacetLIDs(const Array<int>& cellLIDs, 00616 MaximalCofacetBatch& cofacets) const = 0 ; 00617 00618 /** \brief Return an array of the LIDs of all of the co-facets for a 00619 * given relative cell. 00620 * 00621 * \param cellDim 00622 * [in] Dimension of the relative cell whose co-facets are being obtained 00623 * \param cellLID 00624 * [in] Local index of the relative cell whose co-facets are being obtained 00625 * \param cofacetDim 00626 * [in] Dimension of the co-facets to get 00627 * \param cofacetLIDs 00628 * [out] Array containing the LIDs of the co-facets 00629 * for the given relative cell (cellDim,cellLID). 00630 * 00631 * \todo Change name to <tt>getCofacetArray()</tt> to be consistent with 00632 * <tt>getFacetArray()</tt>! 00633 */ 00634 virtual void getCofacets(int cellDim, int cellLID, 00635 int cofacetDim, Array<int>& cofacetLIDs) const = 0 ; 00636 00637 /** \brief Get the cell type of the given cell dimension. 00638 * 00639 * Note: This function by its very definition assumes that all cells of a 00640 * given dimension have the same cell type within a mesh! 00641 * 00642 * \todo This function must be changed in order to deal with mixed cell 00643 * types with the same cellDim! 00644 */ 00645 virtual CellType cellType(int cellDim) const = 0 ; 00646 00647 /** \brief Get the label of the given cell. 00648 * 00649 * \todo Change to getLabel(...)? 00650 */ 00651 virtual int label(int cellDim, int cellLID) const = 0 ; 00652 00653 /** \brief Get the labels for a batch of cells. 00654 * 00655 * \param cellDim 00656 * [in] Dimension of the parent cell whose facets 00657 * are being obtained 00658 * \param cellLIDs 00659 * [in] Array of cell LIDs 00660 * \param labels 00661 * [out] On exit, contains an array (<tt>size=cellLIDs.size()</tt>) 00662 * of the labels for each of the given cells. 00663 */ 00664 virtual void getLabels(int cellDim, const Array<int>& cellLIDs, 00665 Array<int>& labels) const = 0 ; 00666 00667 /** \brief Set the label for the given cell. 00668 * 00669 * \todo Move this out of this base interface and into a mesh loading 00670 * interface? 00671 */ 00672 virtual void setLabel(int cellDim, int cellLID, int label) = 0 ; 00673 00674 /** Get the list of all labels defined for cells of the given dimension */ 00675 virtual Set<int> getAllLabelsForDimension(int cellDim) const = 0 ; 00676 00677 /** 00678 * Get the cells associated with a specified label. The array 00679 * cellLID will be filled with those cells of dimension cellDim 00680 * having the given label. 00681 */ 00682 virtual void getLIDsForLabel(int cellDim, int label, Array<int>& cellLIDs) const = 0 ; 00683 //@} 00684 00685 /** \name Geometric Information */ 00686 //@{ 00687 00688 /** \brief Return the position of a local vertex. 00689 * 00690 * \param vertexLID 00691 * [in] The LID of the vertex. 00692 * 00693 * <b>Preconditions:</b><ul> 00694 * <li><tt>0 <= vertexLID < this->numCells(0)</tt> 00695 * </ul> 00696 * 00697 * \todo Change the name of this function to 00698 * <tt>getVertexPosition(...)</tt>. 00699 */ 00700 virtual Point nodePosition(int vertexLID) const = 0 ; 00701 00702 /** \brief Return a const view into an raw array for the position of a local 00703 * vertex. 00704 * 00705 * \param vertexLID [in] The LID of the vertex 00706 * 00707 * <b>Preconditions:</b><ul> 00708 * <li><tt>0 <= vertexLID < this->numCells(0)</tt> 00709 * </ul> 00710 * 00711 * \returns a raw pointer into an array of doubles of length 00712 * <tt>spatialDim</tt>. 00713 * 00714 * \todo Return this array as a Teuchos::ArrayView<double> object which will 00715 * have the dimension embedded in it and will have full range checking! 00716 * 00717 * \todo Change this function name to <tt>getVertexPositionView()</tt>. 00718 */ 00719 virtual const double* nodePositionView(int vertexLID) const = 0 ; 00720 00721 /** \brief Return the centroid of a cell. 00722 * 00723 * The default implementation just averages the positions of the 00724 * zero-dimensional facets (i.e. vertexes). 00725 */ 00726 virtual Point centroid(int cellDim, int cellLID) const ; 00727 00728 /** \brief Compute (or get) the Jacobians for a batch of cells. 00729 * 00730 * \param cellDim 00731 * [in] Dimension of the cells whose Jacobians are to be computed 00732 * \param cellLID 00733 * [in] Local IDs of the cells for which Jacobians are to be computed 00734 * \param jBatch 00735 * [out] Batch of cell Jacobians. 00736 * 00737 * Warning! The default implementation returns an empty batch of cell 00738 * Jacobians! 00739 * 00740 * \todo Add a query function to tell if this feature is supported and then 00741 * add a precondition based on this query function! 00742 */ 00743 00744 virtual void getJacobians(int cellDim, const Array<int>& cellLID, 00745 CellJacobianBatch& jBatch) const { ; } 00746 00747 //bvbw virtual void getJacobians( 00748 // int cellDim, const Array<int>& cellLID, 00749 // CellJacobianBatch& jBatch 00750 // ) const 00751 // { jBatch.resize(0,0,0); } 00752 00753 /** \brief Compute the diameters of a batch of cells. 00754 * 00755 * \param cellDim 00756 * [in] Dimension of the cells whose diameters are to be computed 00757 * \param cellLIDs 00758 * [in] Local IDs of the cells for which diameters are to be computed 00759 * \param diameters 00760 * [out] Array (<tt>size = cellLIDs.size()</tt>) of cell diameters. 00761 * 00762 * Warning! The default implementation returns an empty array of cell 00763 * diameters! 00764 * ToDo: Change the default implementation to compute diameters based on 00765 * calls to the node position accessors. Going through the Mesh interface in 00766 * that way will be less efficient than a low-level implementation, but 00767 * would be a reasonable intermediate step for mesh developers. 00768 * - KL 5 Aug 2007. 00769 */ 00770 virtual void getCellDiameters( 00771 int cellDim, const Array<int>& cellLIDs, 00772 Array<double>& diameters 00773 ) const 00774 { diameters.resize(0); } 00775 00776 00777 /** 00778 * Get the outward normals for the batch of cells of dimension 00779 * spatialDim()-1. If any cell in the batch is not on the boundary, 00780 * an exception is thrown. 00781 * 00782 * \param cellLIDs [in] LIDs for the cells whose normals are to be 00783 * computed. 00784 * \param outwardNormals [out] Outward normal unit vectors for each 00785 * cell in the batch. 00786 */ 00787 virtual void outwardNormals( 00788 const Array<int>& cellLIDs, 00789 Array<Point>& outwardNormals 00790 ) const ; 00791 00792 /** 00793 * Get tangent vectors for a batch of edges 00794 * 00795 * \param cellLIDs [in] LIDs for the cells whose tangents are to be 00796 * computed. 00797 * \param tangentVectors [out] Unit tangents for each cell 00798 */ 00799 virtual void tangentsToEdges( 00800 const Array<int>& cellLIDs, 00801 Array<Point>& tangenVectors 00802 ) const ; 00803 00804 00805 /** \brief Map points from a reference cell to physical points for a batch 00806 * of cells. 00807 * 00808 * \param cellDim 00809 * [in] Dimension of the cells 00810 * \param cellLIDs 00811 * [in] Local IDs of a batch of cells 00812 * \param refPts 00813 * [in] Array of points on the single reference cell with respect 00814 * to the reference cell's coordinate system. Note that the 00815 * interpretation of these reference points is strictly determined 00816 * by the coordinate system of the cell type 00817 * <tt>cellType(cellDim)</tt> and must be clearly defined by this 00818 * interface. 00819 * \param physPts 00820 * [out] Array (<tt>size = cellLIDs.size()*refPts.size()</tt>) of 00821 * the physical points given in a flat array for the batch of 00822 * cells. Specifically, the physical points for each cell 00823 * <tt>cellLIDs[k]</tt>, for <tt>k=0...cellLIDs.size()-1</tt>, is 00824 * given by <tt>physPts[k*nrp+j]</tt>, for <tt>j=0...nrp-1</tt> 00825 * and <tt>nrp=refPts.size()</tt>. 00826 * 00827 * Warning! The default implementation returns an empty array of physical 00828 * points! 00829 * 00830 * \todo Add a query function to tell if this feature is supported and then 00831 * add a precondition based on this query function! 00832 */ 00833 virtual void pushForward( 00834 int cellDim, const Array<int>& cellLIDs, 00835 const Array<Point>& refPts, 00836 Array<Point>& physPts 00837 ) const 00838 { physPts.resize(0); } 00839 00840 //@} 00841 00842 /** \name Parallel Information */ 00843 //@{ 00844 00845 /** \brief Return the MPI communicator over which this mesh is distributed. */ 00846 const MPIComm& comm() const {return comm_;} 00847 00848 /** \brief Return the rank of the processor that owns the given cell. 00849 * 00850 * If <tt>returnVal==comm().getRank()</tt> then this cell is owned by this 00851 * process. 00852 */ 00853 virtual int ownerProcID(int cellDim, int cellLID) const = 0 ; 00854 00855 /** \brief Determine whether a given cell GID exists on this processor. */ 00856 virtual bool hasGID(int cellDim, int cellGID) const = 0 ; 00857 00858 /** \brief Find the LID of a cell given its GID. 00859 * 00860 * \param cellDim 00861 * [in] Dimension of the cell 00862 * \param cellGID 00863 * [in] Global ID of the cell 00864 * 00865 * <b>Preconditions:</b><ul> 00866 * <li>hasGID(cellDim,cellGID)==true</tt> 00867 * </ul> 00868 * 00869 * <b>Postconditions:</b><ul> 00870 * <li>0 <= returnVal < numCells(cellDim)</tt> 00871 * </ul> 00872 */ 00873 virtual int mapGIDToLID(int cellDim, int cellGID) const = 0 ; 00874 00875 /** \brief Find the global ID of a cell given its LID. 00876 * 00877 * \param cellDim 00878 * [in] Dimension of the cell 00879 * \param cellLID 00880 * [in] Local ID of the cell 00881 * 00882 * <b>Postconditions:</b><ul> 00883 * <li><tt>returnVal >= 0 </tt> 00884 * </ul> 00885 */ 00886 virtual int mapLIDToGID(int cellDim, int cellLID) const = 0 ; 00887 00888 /** \brief Return if cells of dimension cellDim have been assigned global 00889 * IDs or not. 00890 * 00891 * \param cellDim 00892 * [in] Dimension of the cell 00893 */ 00894 virtual bool hasIntermediateGIDs(int cellDim) const = 0 ; 00895 00896 /** \brief Assign global IDs to cells of dimension cellDim. 00897 * 00898 * \param cellDim 00899 * [in] Dimension of the cell 00900 * 00901 * <b>Postconditions:</b><ul> 00902 * <li><tt>hasIntermediateGIDs(cellDim)==true</tt> 00903 * </ul> 00904 */ 00905 virtual void assignIntermediateCellGIDs(int cellDim) = 0 ; 00906 00907 //@} 00908 00909 /** \name Reordering */ 00910 //@{ 00911 00912 /** \brief Set the reordering strategy to be used with this mesh. */ 00913 void setReorderer(const CellReorderer& reorderer) 00914 {reorderer_ = reorderer.createInstance(this);} 00915 00916 /** \brief Get the reordering strategy to be used with this mesh. */ 00917 const CellReordererImplemBase* reorderer() const 00918 {return reorderer_.get();} 00919 00920 //@} 00921 00922 00923 00924 /** \name Functions for Mesh with hanging nodes */ 00925 //@{ 00926 /** Function returns true if the mesh allows hanging nodes (by refinement), 00927 * false otherwise */ 00928 virtual bool allowsHangingHodes() const { return false; } 00929 00930 /** Function returns true if the specified element is a "hanging" element 00931 * false otherwise <br> 00932 * @param cellDim [in] should be between 0 , D-1 00933 * @param cellLID [in] the local ID of the element */ 00934 virtual bool isElementHangingNode(int cellDim , int cellLID) const { return false; } 00935 00936 /** Returns the index in the parent maxdim Cell of the refinement tree 00937 * @param maxCellLID [in] the LID of the cell */ 00938 virtual int indexInParent(int maxCellLID) const { return 0; } 00939 00940 /** How many children has a refined element. <br> 00941 * This function provides information of either we have bi or trisection */ 00942 virtual int maxChildren() const { return 0;} 00943 00944 /** Function returns the facets of the parent cell (needed for HN treatment) <br> 00945 * @param childCellLID [in] the LID of the maxdim cell, whos parents facets we want 00946 * @param dimFacets [in] the dimension of the facets which we want to have 00947 * @param facetsLIDs [out] the LID of the parents facets (all) in the defined order 00948 * @param parentCellLIDs [out] the maxdim parent cell LID */ 00949 virtual void returnParentFacets( int childCellLID , int dimFacets , 00950 Array<int> &facetsLIDs , int &parentCellLIDs ) const { } 00951 //@} 00952 00953 00954 00955 /** \name Store special weights in the mesh (for Adaptive Cell Integration) */ 00956 //@{ 00957 00958 /** returns the status of the special weights if they are valid <br> 00959 * These weights are usually computed for one setting of the curve (Adaptive Cell Integration)*/ 00960 virtual bool IsSpecialWeightValid() const {return validWeights_;} 00961 00962 /** specifies if the special weights are valid <br> 00963 * if this is false then usually the special weights have to be recomputed */ 00964 virtual void setSpecialWeightValid(bool& val) const { validWeights_ = val;} 00965 00966 /** removes the special weights */ 00967 virtual void removeSpecialWeights(int& dim, int& cellLID) const { 00968 Array<double> nothing; 00969 nothing.resize(0); 00970 specialWeights_[dim].put(cellLID,nothing); 00971 } 00972 00973 /** verifies if the specified cell with the given dimension has special weights */ 00974 virtual bool hasSpecialWeight(int& dim, int& cellLID) const { 00975 if (specialWeights_[dim].containsKey(cellLID)) 00976 return ((specialWeights_[dim].get(cellLID).size() > 0)); 00977 else 00978 return false; 00979 } 00980 00981 /** Sets the special weights */ 00982 virtual void setSpecialWeight(int& dim, int& cellLID, Array<double>& w) const { 00983 specialWeights_[dim].put(cellLID,w); 00984 } 00985 00986 /** Returns the special weights */ 00987 virtual void getSpecialWeight(int& dim, int& cellLID, Array<double>& w) const { 00988 w = specialWeights_[dim].get(cellLID); 00989 } 00990 //@} 00991 00992 00993 /** \name Store the intersection/quadrature points for the curve/surf integral <br> 00994 * for a curve or surf integral we need some quadrature points along the curve in one curve <br> 00995 * These */ 00996 //@{ 00997 00998 /** */ 00999 virtual bool IsCurvePointsValid() const {return curvePoints_Are_Valid_;} 01000 01001 /** */ 01002 virtual void setCurvePointsValid(bool& val) const { curvePoints_Are_Valid_ = val;} 01003 01004 /** removes the intersection points*/ 01005 virtual void removeCurvePoints(int maxCellLID , int curveID) const{ 01006 // TODO: 01007 } 01008 01009 /** verifies if the specified maxCell has already precalculated quadrature point for one curve */ 01010 virtual bool hasCurvePoints(int maxCellLID , int curveID) const; 01011 01012 /** Sets the points, curve derivatives and curve normals for one maxCell needed for curve/surf integral*/ 01013 virtual void setCurvePoints(int maxCellLID, int curveID , Array<Point>& points , Array<Point>& derivs , Array<Point>& normals) const; 01014 01015 /** Gets the points, curve derivatives and curve normals for one maxCell needed for curve/surf integral*/ 01016 virtual void getCurvePoints(int maxCellLID, int curveID , Array<Point>& points , Array<Point>& derivs , Array<Point>& normals) const; 01017 01018 private: 01019 virtual int mapCurveID_to_Index(int curveID) const; 01020 public: 01021 //@} 01022 01023 /** \name Output */ 01024 //@{ 01025 01026 /** \brief Set whether to stagger output in parallel. Set to true for readable 01027 * output in parallel debugging sessions. 01028 * 01029 * This should be normally, as it causes one synchronization point per 01030 * process. 01031 * 01032 * \todo Get rid of this once we update to use Teuchos::FancyOStream since 01033 * parallel outputting will be done in a readable way automatically! 01034 */ 01035 static bool& staggerOutput() {static bool rtn=false; return rtn;} 01036 01037 //@} 01038 01039 private: 01040 01041 int dim_; 01042 01043 MPIComm comm_; 01044 01045 MeshEntityOrder order_; 01046 01047 RCP<CellReordererImplemBase> reorderer_; 01048 01049 01050 01051 /** flag to indicate if the weights stored are valid */ 01052 mutable bool validWeights_; 01053 01054 /** Object to store the special weights for integration */ 01055 mutable Array < Sundance::Map< int , Array<double> > > specialWeights_; 01056 01057 01058 01059 /** true if the curve did not moved, false if those points are not reusable*/ 01060 mutable bool curvePoints_Are_Valid_; 01061 01062 /** how many curves are participating in curve integrals*/ 01063 mutable int nrCurvesForIntegral_; 01064 01065 /** store intersection informations to calculate the curve integral*/ 01066 mutable Array < Sundance::Map< int , Array<Point> > > curvePoints_; 01067 01068 /** store directional derivative informations to calculate the curve integral*/ 01069 mutable Array < Sundance::Map< int , Array<Point> > > curveDerivative_; 01070 01071 /** store normal directional used in the curve or in the surf integral <br> 01072 * in case of the surf integral it is the cross product from the integral */ 01073 mutable Array < Sundance::Map< int , Array<Point> > > curveNormal_; 01074 01075 /** map the curve ID to index in the previous arrays */ 01076 mutable Sundance::Map< int , int > curveID_to_ArrayIndex_; 01077 }; 01078 01079 01080 } // namespace Sundance 01081 01082 #endif