MFEM v2.0
mesh.hpp
Go to the documentation of this file.
00001 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
00002 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
00003 // reserved. See file COPYRIGHT for details.
00004 //
00005 // This file is part of the MFEM library. For more information and source code
00006 // availability see http://mfem.googlecode.com.
00007 //
00008 // MFEM is free software; you can redistribute it and/or modify it under the
00009 // terms of the GNU Lesser General Public License (as published by the Free
00010 // Software Foundation) version 2.1 dated February 1999.
00011 
00012 #ifndef MFEM_MESH
00013 #define MFEM_MESH
00014 
00015 // Data type mesh
00016 
00017 class NURBSExtension;
00018 class FiniteElementSpace;
00019 class GridFunction;
00020 
00021 #ifdef MFEM_USE_MPI
00022 class ParMesh;
00023 #endif
00024 
00025 class Mesh
00026 {
00027 #ifdef MFEM_USE_MPI
00028    friend class ParMesh;
00029 #endif
00030    friend class NURBSExtension;
00031 
00032 protected:
00033    int Dim;
00034 
00035    int NumOfVertices, NumOfElements, NumOfBdrElements;
00036    int NumOfEdges, NumOfFaces;
00037 
00038    int State, WantTwoLevelState;
00039 
00040    // 0 = Empty, 1 = Standard (NetGen), 2 = TrueGrid
00041    int meshgen;
00042 
00043    int c_NumOfVertices, c_NumOfElements, c_NumOfBdrElements;
00044    int f_NumOfVertices, f_NumOfElements, f_NumOfBdrElements;
00045    int c_NumOfEdges, c_NumOfFaces;
00046    int f_NumOfEdges, f_NumOfFaces;
00047 
00048    Array<Element *> elements;
00049    Array<Vertex> vertices;
00050    Array<Element *> boundary;
00051    Array<Element *> faces;
00052 
00053    class FaceInfo { public: int Elem1No, Elem2No, Elem1Inf, Elem2Inf; };
00054    Array<FaceInfo> faces_info;
00055 
00056    Table *el_to_edge;
00057    Table *el_to_face;
00058    Table *el_to_el;
00059    Array<int> be_to_edge;  // for 2D
00060    Table *bel_to_edge;     // for 3D
00061    Array<int> be_to_face;
00062    mutable Table *face_edge;
00063    mutable Table *edge_vertex;
00064 
00065    Table *c_el_to_edge, *f_el_to_edge, *c_bel_to_edge, *f_bel_to_edge;
00066    Array<int> fc_be_to_edge; // swapped with be_to_edge when switching state
00067    Table *c_el_to_face, *f_el_to_face; // for 3D two-level state
00068    Array<FaceInfo> fc_faces_info;      // for 3D two-level state
00069 
00070    IsoparametricTransformation Transformation, Transformation2;
00071    IsoparametricTransformation FaceTransformation;
00072    FaceElementTransformations FaceElemTr;
00073 
00074    GridFunction *Nodes;
00075    int own_nodes;
00076 
00077 #ifdef MFEM_USE_MEMALLOC
00078    friend class Tetrahedron;
00079 
00080    MemAlloc <Tetrahedron, 1024> TetMemory;
00081    MemAlloc <BisectedElement, 1024> BEMemory;
00082 #endif
00083 
00084    Element *NewElement(int geom);
00085 
00086    void Init();
00087 
00088    void InitTables();
00089 
00090    void DeleteTables();
00091 
00094    void DeleteCoarseTables();
00095 
00096    Element *ReadElement(istream &);
00097    static void PrintElement(Element *, ostream &);
00098 
00100    double GetLength(int i, int j) const;
00101 
00104    void GetElementJacobian(int i, DenseMatrix &J);
00105 
00106    void MarkForRefinement();
00107    void MarkTriMeshForRefinement();
00108    void MarkTetMeshForRefinement();
00109 
00110    STable3D *GetFacesTable();
00111    STable3D *GetElementToFaceTable(int ret_ftbl = 0);
00112 
00115    void RedRefinement(int i, const DSTable &v_to_v,
00116                       int *edge1, int *edge2, int *middle)
00117    { UniformRefinement(i, v_to_v, edge1, edge2, middle); }
00118 
00121    void GreenRefinement(int i, const DSTable &v_to_v,
00122                         int *edge1, int *edge2, int *middle)
00123    { Bisection(i, v_to_v, edge1, edge2, middle); }
00124 
00126    void Bisection(int i, const DSTable &, int *, int *, int *);
00127 
00129    void Bisection(int i, const DSTable &, int *);
00130 
00132    void UniformRefinement(int i, const DSTable &, int *, int *, int *);
00133 
00136    void AverageVertices (int * indexes, int n, int result);
00137 
00139    void UpdateNodes();
00140 
00142    virtual void QuadUniformRefinement();
00143 
00145    virtual void HexUniformRefinement();
00146 
00148    virtual void NURBSUniformRefinement();
00149 
00151    void LoadPatchTopo(istream &input, Array<int> &edge_to_knot);
00152 
00153    void UpdateNURBS();
00154 
00155    void PrintTopo(ostream &out, const Array<int> &e_to_k) const;
00156 
00157    void BisectTriTrans (DenseMatrix &pointmat, Triangle *tri,
00158                         int child);
00159 
00160    void BisectTetTrans (DenseMatrix &pointmat, Tetrahedron *tet,
00161                         int child);
00162 
00163    int GetFineElemPath (int i, int j);
00164 
00165    int GetBisectionHierarchy (Element *E);
00166 
00167    FiniteElement *GetTransformationFEforElementType (int);
00168 
00170    void GetLocalSegToTriTransformation (IsoparametricTransformation &loc,
00171                                         int i);
00172    void GetLocalSegToQuadTransformation (IsoparametricTransformation &loc,
00173                                          int i);
00175    void GetLocalTriToTetTransformation (IsoparametricTransformation &loc,
00176                                         int i);
00178    void GetLocalQuadToHexTransformation (IsoparametricTransformation &loc,
00179                                          int i);
00180 
00182    static int GetTriOrientation (const int * base, const int * test);
00184    static int GetQuadOrientation (const int * base, const int * test);
00185 
00186    static void GetElementArrayEdgeTable(const Array<Element*> &elem_array,
00187                                         const DSTable &v_to_v,
00188                                         Table &el_to_edge);
00189 
00193    void GetVertexToVertexTable(DSTable &) const;
00194 
00200    int GetElementToEdgeTable(Table &, Array<int> &);
00201 
00203    void AddSegmentFaceElement (int lf, int gf, int el, int v0, int v1);
00204 
00205    void AddTriangleFaceElement (int lf, int gf, int el,
00206                                 int v0, int v1, int v2);
00207 
00208    void AddQuadFaceElement (int lf, int gf, int el,
00209                             int v0, int v1, int v2, int v3);
00210 
00211    // shift cyclically 3 integers left-to-right
00212    inline static void ShiftL2R(int &, int &, int &);
00213    // shift cyclically 3 integers so that the smallest is first
00214    inline static void Rotate3(int &, int &, int &);
00215 
00216    void FreeElement (Element *E);
00217 
00218    void GenerateFaces();
00219 
00220 public:
00221 
00222    enum { NORMAL, TWO_LEVEL_COARSE, TWO_LEVEL_FINE };
00223 
00224    Array<int> attributes;
00225    Array<int> bdr_attributes;
00226 
00227    NURBSExtension *NURBSext;
00228 
00229    Mesh() { Init(); InitTables(); meshgen = 0; Dim = 0; }
00230 
00231    Mesh (int _Dim, int NVert, int NElem, int NBdrElem = 0);
00232    void AddVertex (double *);
00233    void AddElement (Element *elem)  { elements[NumOfElements++] = elem; }
00234    void AddTri (int *vi, int attr = 1);
00235    void AddTriangle (int *vi, int attr = 1);
00236    void AddQuad (int *vi, int attr = 1);
00237    void AddTet (int *vi, int attr = 1);
00238    void AddHex (int *vi, int attr = 1);
00239    void AddBdrSegment (int *vi, int attr = 1);
00240    void AddBdrTriangle (int *vi, int attr = 1);
00241    void AddBdrQuad (int *vi, int attr = 1);
00242    void GenerateBoundaryElements();
00243    void FinalizeTriMesh (int generate_edges = 0, int refine = 0);
00244    void FinalizeQuadMesh (int generate_edges = 0, int refine = 0);
00245    void FinalizeTetMesh (int generate_edges = 0, int refine = 0);
00246    void FinalizeHexMesh (int generate_edges = 0, int refine = 0);
00247 
00248    void SetAttributes();
00249 
00254    Mesh(int nx, int ny, Element::Type type, int generate_edges = 0,
00255         double sx = 1.0, double sy = 1.0);
00256 
00258    explicit Mesh(int n);
00259 
00263    Mesh ( istream &input, int generate_edges = 0, int refine = 1);
00264 
00266    Mesh(Mesh *mesh_array[], int num_pieces);
00267 
00268    /* This is similar to the above mesh constructor, but here the current
00269       mesh is destroyed and another one created based on the data stream
00270       again given in netgen format. If generate_edges = 0 (default) edges
00271       are not generated, if 1 edges are generated. */
00272    void Load ( istream &input, int generate_edges = 0, int refine = 1);
00273 
00274    void SetNodalFESpace(FiniteElementSpace *nfes);
00275    void SetNodalGridFunction(GridFunction *nodes);
00276    const FiniteElementSpace *GetNodalFESpace();
00277 
00279    inline int MeshGenerator() { return meshgen; }
00280 
00282    inline int GetNV() const { return NumOfVertices; }
00283 
00285    inline int GetNE() const { return NumOfElements; }
00286 
00288    inline int GetNBE() const { return NumOfBdrElements; }
00289 
00291    inline int GetNEdges() const { return NumOfEdges; }
00292 
00293    inline int GetNFaces() const { return NumOfFaces; }
00294 
00296    inline int EulerNumber() const
00297    { return NumOfVertices - NumOfEdges + NumOfFaces - NumOfElements; }
00299    inline int EulerNumber2D() const
00300    { return NumOfVertices - NumOfEdges + NumOfElements; }
00301 
00302    int Dimension() const { return Dim; }
00303 
00305    const double *GetVertex(int i) const { return vertices[i](); }
00306    double *GetVertex(int i) { return vertices[i](); }
00307 
00308    const Element *GetElement(int i) const { return elements[i]; }
00309 
00310    Element *GetElement(int i) { return elements[i]; }
00311 
00312    const Element *GetBdrElement(int i) const { return boundary[i]; }
00313 
00314    Element *GetBdrElement(int i) { return boundary[i]; }
00315 
00316    const Element *GetFace(int i) const { return faces[i]; }
00317 
00318    int GetFaceBaseGeometry(int i) const;
00319 
00320    int GetElementBaseGeometry(int i) const
00321    { return elements[i]->GetGeometryType(); }
00322 
00323    int GetBdrElementBaseGeometry(int i) const
00324    { return boundary[i]->GetGeometryType(); }
00325 
00327    void GetElementVertices(int i, Array<int> &dofs) const
00328    { elements[i]->GetVertices(dofs); }
00329 
00331    void GetBdrElementVertices(int i, Array<int> &dofs) const
00332    { boundary[i]->GetVertices(dofs); }
00333 
00335    void GetElementEdges(int i, Array<int> &, Array<int> &) const;
00336 
00338    void GetBdrElementEdges(int i, Array<int> &, Array<int> &) const;
00339 
00341    void GetFaceEdges(int i, Array<int> &, Array<int> &) const;
00342 
00344    void GetFaceVertices(int i, Array<int> &vert) const
00345    { faces[i] -> GetVertices (vert); }
00346 
00348    void GetEdgeVertices(int i, Array<int> &vert) const;
00349 
00351    Table *GetFaceEdgeTable() const;
00352 
00354    Table *GetEdgeVertexTable() const;
00355 
00357    void GetElementFaces(int i, Array<int> &, Array<int> &) const;
00358 
00360    void GetBdrElementFace(int i, int *, int *) const;
00361 
00364    int GetBdrElementEdgeIndex(int i) const;
00365 
00367    int GetElementType(int i) const;
00368 
00370    int GetBdrElementType(int i) const;
00371 
00372    /* Return point matrix of element i of dimension Dim X #dofs, where for
00373       every degree of freedom we give its coordinates in space of dimension
00374       Dim. */
00375    void GetPointMatrix(int i, DenseMatrix &pointmat) const;
00376 
00377    /* Return point matrix of boundary element i of dimension Dim X #dofs,
00378       where for every degree of freedom we give its coordinates in space
00379       of dimension Dim. */
00380    void GetBdrPointMatrix(int i, DenseMatrix &pointmat) const;
00381 
00384    void GetElementTransformation(int i, IsoparametricTransformation *ElTr);
00385 
00387    ElementTransformation *GetElementTransformation(int i);
00388 
00391    void GetElementTransformation(int i, const Vector &nodes,
00392                                  IsoparametricTransformation *ElTr);
00393 
00395    ElementTransformation * GetBdrElementTransformation(int i);
00396 
00399    void GetFaceTransformation(int i, IsoparametricTransformation *FTr);
00400 
00402    ElementTransformation *GetFaceTransformation(int FaceNo);
00403 
00422    FaceElementTransformations *GetFaceElementTransformations(int FaceNo,
00423                                                              int mask = 31);
00424 
00425    FaceElementTransformations *GetInteriorFaceTransformations (int FaceNo)
00426    { if (faces_info[FaceNo].Elem2No < 0) return NULL;
00427       return GetFaceElementTransformations (FaceNo); };
00428 
00429    FaceElementTransformations *GetBdrFaceTransformations (int BdrElemNo);
00430 
00431    void GetFaceElements (int Face, int *Elem1, int *Elem2);
00432    void GetFaceInfos (int Face, int *Inf1, int *Inf2);
00433 
00435    void CheckElementOrientation ();
00437    void CheckBdrElementOrientation ();
00438 
00440    int GetAttribute(int i) const { return elements[i]->GetAttribute();}
00441 
00443    int GetBdrAttribute(int i) const { return boundary[i]->GetAttribute(); }
00444 
00445    const Table &ElementToElementTable();
00446 
00447    const Table &ElementToFaceTable() const;
00448 
00449    const Table &ElementToEdgeTable() const;
00450 
00452    Table *GetVertexToElementTable();
00453 
00462    virtual void ReorientTetMesh();
00463 
00464    int *CartesianPartitioning(int nxyz[]);
00465    int *GeneratePartitioning(int nparts, int part_method = 1);
00466    void CheckPartitioning(int *partitioning);
00467 
00468    void CheckDisplacements(const Vector &displacements, double &tmax);
00469    void MoveVertices(const Vector &displacements);
00470    void GetVertices(Vector &vert_coord) const;
00471    void SetVertices(const Vector &vert_coord);
00472 
00473    // Node operations for curved mesh.
00474    // They call the corresponding '...Vertices' method if the
00475    // mesh is not curved (i.e. Nodes == NULL).
00476    void MoveNodes(const Vector &displacements);
00477    void GetNodes(Vector &node_coord) const;
00478    void SetNodes(const Vector &node_coord);
00479 
00481    GridFunction* GetNodes() { return Nodes; }
00482    // use the provided GridFunction as Nodes
00483    void NewNodes(GridFunction &nodes);
00484 
00486    virtual void LocalRefinement(const Array<int> &marked_el, int type = 3);
00487 
00488    void UniformRefinement();
00489 
00490    // NURBS mesh refinement methods
00491    void KnotInsert(Array<KnotVector *> &kv);
00492    void DegreeElevate(int t);
00493 
00496    void UseTwoLevelState (int use)
00497    {
00498       if (!use && State != Mesh::NORMAL)
00499          SetState (Mesh::NORMAL);
00500       WantTwoLevelState = use;
00501    }
00502 
00504    void SetState (int s);
00505 
00508    int GetNumFineElems (int i);
00509 
00511    int GetRefinementType (int i);
00512 
00515    int GetFineElem (int i, int j);
00516 
00520    ElementTransformation * GetFineElemTrans (int i, int j);
00521 
00523    virtual void PrintXG(ostream &out = cout) const;
00524 
00526    virtual void Print(ostream &out = cout) const;
00527 
00529    void PrintVTK(ostream &out);
00530 
00535    void PrintVTK(ostream &out, int ref, int field_data=0);
00536 
00537    void GetElementColoring(Array<int> &colors, int el0 = 0);
00538 
00542    void PrintWithPartitioning (int *partitioning,
00543                                ostream &out, int elem_attr = 0) const;
00544 
00545    void PrintElementsWithPartitioning (int *partitioning,
00546                                        ostream &out,
00547                                        int interior_faces = 0);
00548 
00549    void ScaleSubdomains (double sf);
00550    void ScaleElements (double sf);
00551 
00552    void Transform(void (*f)(const Vector&, Vector&));
00553 
00556    double GetElementSize(int i, int type = 0);
00557 
00558    double GetElementSize(int i, const Vector &dir);
00559 
00560    double GetElementVolume(int i);
00561 
00562    void PrintCharacteristics(Vector *Vh = NULL, Vector *Vk = NULL);
00563 
00565    virtual ~Mesh();
00566 };
00567 
00568 
00569 // inline functions
00570 inline void Mesh::ShiftL2R(int &a, int &b, int &c)
00571 {
00572    int t = a;
00573    a = c;  c = b;  b = t;
00574 }
00575 
00576 inline void Mesh::Rotate3(int &a, int &b, int &c)
00577 {
00578    if (a < b)
00579    {
00580       if (a > c)
00581          ShiftL2R(a, b, c);
00582    }
00583    else
00584    {
00585       if (b < c)
00586          ShiftL2R(c, b, a);
00587       else
00588          ShiftL2R(a, b, c);
00589    }
00590 }
00591 
00592 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines