MFEM v2.0
|
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