SundanceMeshBase.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_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

Site Contact