MFEM  v3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
ncmesh.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.googlecode.com.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 #ifndef MFEM_NCMESH
13 #define MFEM_NCMESH
14 
15 #include "../config/config.hpp"
16 #include "../general/hash.hpp"
17 #include "../linalg/densemat.hpp"
18 #include "element.hpp"
19 #include "vertex.hpp"
20 #include "../fem/geom.hpp"
21 
22 namespace mfem
23 {
24 
25 // TODO: these won't be needed once this module is purely geometric
26 class SparseMatrix;
27 class Mesh;
28 class IsoparametricTransformation;
29 class FiniteElementSpace;
30 
35 struct Refinement
36 {
37  int index;
38  int ref_type;
39 
40  Refinement(int index, int type = 7)
41  : index(index), ref_type(type) {}
42 };
43 
44 
65 class NCMesh
66 {
67 public:
68  NCMesh(const Mesh *mesh);
69 
70  int Dimension() const { return Dim; }
71 
76  void Refine(const Array<Refinement> &refinements);
77 
79  //void Derefine(Element* elem);
80 
83  void LimitNCLevel(int max_level);
84 
92  SparseMatrix **cR_ptr = NULL);
93 
99  {
102 
104  bool IsIdentity() const { return !point_matrix.Data(); }
105  };
106 
111 
113  void ClearCoarseLevel() { coarse_elements.DeleteAll(); }
114 
120  FineTransform* GetFineTransforms();
121 
125  int GetEdgeMaster(int v1, int v2) const;
126 
128  long MemoryUsage();
129 
130  ~NCMesh();
131 
132 
133 protected: // interface for Mesh to be able to construct itself from us
134 
136  Array<mfem::Element*>& elements,
137  Array<mfem::Element*>& boundary);
138 
139  void SetEdgeIndicesFromMesh(Mesh *mesh);
140  void SetFaceIndicesFromMesh(Mesh *mesh);
141 
142  friend class Mesh;
143 
144 
145 protected: // implementation
146 
147  int Dim;
148 
151  struct RefCount
152  {
154 
155  RefCount() : ref_count(0) {}
156 
157  int Ref() {
158  return ++ref_count;
159  }
160  int Unref() {
161  int ret = --ref_count;
162  if (!ret) delete this;
163  return ret;
164  }
165  };
166 
169  struct Vertex : public RefCount
170  {
171  double pos[3];
172  int index;
173 
174  Vertex() {}
175  Vertex(double x, double y, double z) : index(-1)
176  { pos[0] = x, pos[1] = y, pos[2] = z; }
177  };
178 
180  struct Edge : public RefCount
181  {
182  int attribute;
183  int index;
184 
185  Edge() : attribute(-1), index(-1) {}
186  bool Boundary() const { return attribute >= 0; }
187  };
188 
199  struct Node : public Hashed2<Node>
200  {
203 
204  Node(int id) : Hashed2<Node>(id), vertex(NULL), edge(NULL) {}
205 
206  // Bump ref count on a vertex or an edge, or create them. Used when an
207  // element starts using a vertex or an edge.
208  void RefVertex();
209  void RefEdge();
210 
211  // Decrement ref on vertex or edge when an element is not using them
212  // anymore. The vertex, edge or the whole Node can autodestruct.
213  // (The hash-table pointer needs to be known then to remove the node.)
216 
217  ~Node();
218  };
219 
220  struct Element;
221 
226  struct Face : public RefCount, public Hashed4<Face>
227  {
228  int attribute;
229  int index;
230  Element* elem[2];
231 
232  Face(int id) : Hashed4<Face>(id), attribute(-1), index(-1)
233  { elem[0] = elem[1] = NULL; }
234 
235  bool Boundary() const { return attribute >= 0; }
236 
237  // add or remove an element from the 'elem[2]' array
238  void RegisterElement(Element* e);
239  void ForgetElement(Element* e);
240 
241  // return one of elem[0] or elem[1] and make sure the other is NULL
242  Element* GetSingleElement() const;
243 
244  // overloaded Unref without auto-destruction
245  int Unref() { return --ref_count; }
246  };
247 
251  struct Element
252  {
253  int geom; // Geometry::Type of the element
255  int ref_type; // bit mask of X,Y,Z refinements (bits 0,1,2, respectively)
256  int index; // element number in the Mesh, -1 if refined
257  union
258  {
259  Node* node[8]; // element corners (if ref_type == 0)
260  Element* child[8]; // 2-8 children (if ref_type != 0)
261  };
262 
263  Element(int geom, int attr);
264  };
265 
266  Array<Element*> root_elements; // initialized by constructor
267  Array<Element*> leaf_elements; // finest level, updated by UpdateLeafElements
268  Array<Element*> coarse_elements; // coarse level, set by MarkCoarseLevel
269 
270  Array<int> vertex_nodeId; // vertex-index to node-id map
271 
272  HashTable<Node> nodes; // associative container holding all Nodes
273  HashTable<Face> faces; // associative container holding all Faces
274 
276  {
278  int ref_type;
279 
281  : elem(elem), ref_type(type) {}
282  };
283 
285 
286  void Refine(Element* elem, int ref_type);
287 
288  void UpdateVertices(); // update the indices of vertices and vertex_nodeId
289 
290  void GetLeafElements(Element* e);
291  void UpdateLeafElements();
292 
293  void DeleteHierarchy(Element* elem);
294 
295  Element* NewHexahedron(Node* n0, Node* n1, Node* n2, Node* n3,
296  Node* n4, Node* n5, Node* n6, Node* n7,
297  int attr,
298  int fattr0, int fattr1, int fattr2,
299  int fattr3, int fattr4, int fattr5);
300 
301  Element* NewQuadrilateral(Node* n0, Node* n1, Node* n2, Node* n3,
302  int attr,
303  int eattr0, int eattr1, int eattr2, int eattr3);
304 
305  Element* NewTriangle(Node* n0, Node* n1, Node* n2,
306  int attr, int eattr0, int eattr1, int eattr2);
307 
308  Vertex* NewVertex(Node* v1, Node* v2);
309 
310  Node* GetMidEdgeVertex(Node* v1, Node* v2);
312  Node* GetMidFaceVertex(Node* e1, Node* e2, Node* e3, Node* e4);
313 
314  int FaceSplitType(Node* v1, Node* v2, Node* v3, Node* v4,
315  Node* mid[4] = NULL /* optional output of mid-edge nodes*/);
316 
317  void ForceRefinement(Node* v1, Node* v2, Node* v3, Node* v4);
318 
319  void CheckAnisoFace(Node* v1, Node* v2, Node* v3, Node* v4,
320  Node* mid12, Node* mid34, int level = 0);
321 
322  void CheckIsoFace(Node* v1, Node* v2, Node* v3, Node* v4,
323  Node* e1, Node* e2, Node* e3, Node* e4, Node* midf);
324 
325  void RefElementNodes(Element *elem);
326  void UnrefElementNodes(Element *elem);
327  void RegisterFaces(Element* elem);
328 
329  Node* PeekAltParents(Node* v1, Node* v2);
330 
331  bool NodeSetX1(Node* node, Node** n);
332  bool NodeSetX2(Node* node, Node** n);
333  bool NodeSetY1(Node* node, Node** n);
334  bool NodeSetY2(Node* node, Node** n);
335  bool NodeSetZ1(Node* node, Node** n);
336  bool NodeSetZ2(Node* node, Node** n);
337 
338 
339  // interpolation
340 
341  struct Dependency
342  {
343  int dof;
344  double coef;
345 
346  Dependency(int dof, double coef)
347  : dof(dof), coef(coef) {}
348  };
349 
351 
354  struct DofData
355  {
356  bool finalized;
358 
359  DofData() : finalized(false) {}
360  bool Independent() const { return !dep_list.Size(); }
361  };
362 
364 
366 
367  static int find_node(Element* elem, Node* node);
368 
369  void ReorderFacePointMat(Node* v0, Node* v1, Node* v2, Node* v3,
370  Element* elem, DenseMatrix& pm);
371 
372  void AddDependencies(Array<int>& master_dofs, Array<int>& slave_dofs,
373  DenseMatrix& I);
374 
375  void ConstrainEdge(Node* v0, Node* v1, double t0, double t1,
376  Array<int>& master_dofs, int level);
377 
378  struct PointMatrix;
379 
380  void ConstrainFace(Node* v0, Node* v1, Node* v2, Node* v3,
381  const PointMatrix &pm,
382  Array<int>& master_dofs, int level);
383 
384  void ProcessMasterEdge(Node* node[2], Node* edge);
385  void ProcessMasterFace(Node* node[4], Face* face);
386 
387  bool DofFinalizable(DofData& vd);
388 
389 
390  // coarse to fine transformations
391 
392  struct Point
393  {
394  int dim;
395  double coord[3];
396 
398  { dim = 0; }
399 
400  Point(double x, double y)
401  { dim = 2; coord[0] = x; coord[1] = y; }
402 
403  Point(double x, double y, double z)
404  { dim = 3; coord[0] = x; coord[1] = y; coord[2] = z; }
405 
406  Point(const Point& p0, const Point& p1)
407  {
408  dim = p0.dim;
409  for (int i = 0; i < dim; i++)
410  coord[i] = (p0.coord[i] + p1.coord[i]) * 0.5;
411  }
412 
413  Point(const Point& p0, const Point& p1, const Point& p2, const Point& p3)
414  {
415  dim = p0.dim;
416  for (int i = 0; i < dim; i++)
417  coord[i] = (p0.coord[i] + p1.coord[i] + p2.coord[i] + p3.coord[i])
418  * 0.25;
419  }
420 
421  Point& operator=(const Point& src)
422  {
423  dim = src.dim;
424  for (int i = 0; i < dim; i++)
425  coord[i] = src.coord[i];
426  return *this;
427  }
428  };
429 
430  struct PointMatrix
431  {
432  int np;
434 
435  PointMatrix(const Point& p0, const Point& p1, const Point& p2)
436  { np = 3; points[0] = p0; points[1] = p1; points[2] = p2; }
437 
438  PointMatrix(const Point& p0, const Point& p1, const Point& p2, const Point& p3)
439  { np = 4; points[0] = p0; points[1] = p1; points[2] = p2; points[3] = p3; }
440 
441  PointMatrix(const Point& p0, const Point& p1, const Point& p2,
442  const Point& p3, const Point& p4, const Point& p5,
443  const Point& p6, const Point& p7)
444  {
445  np = 8;
446  points[0] = p0; points[1] = p1; points[2] = p2; points[3] = p3;
447  points[4] = p4; points[5] = p5; points[6] = p6; points[7] = p7;
448  }
449 
450  Point& operator()(int i) { return points[i]; }
451  const Point& operator()(int i) const { return points[i]; }
452 
453  void GetMatrix(DenseMatrix& point_matrix) const;
454  };
455 
456  void GetFineTransforms(Element* elem, int coarse_index,
457  FineTransform *transforms, const PointMatrix &pm);
458 
459  int GetEdgeMaster(Node *n) const;
460 
461  // utility
462 
463  void FaceSplitLevel(Node* v1, Node* v2, Node* v3, Node* v4,
464  int& h_level, int& v_level);
465 
466  void CountSplits(Element* elem, int splits[3]);
467 
468  int CountElements(Element* elem);
469 
470 };
471 
472 }
473 
474 #endif
void ReorderFacePointMat(Node *v0, Node *v1, Node *v2, Node *v3, Element *elem, DenseMatrix &pm)
Definition: ncmesh.cpp:1251
void LimitNCLevel(int max_level)
Definition: ncmesh.cpp:2007
int Size() const
Logical size of the array.
Definition: array.hpp:108
Element * NewHexahedron(Node *n0, Node *n1, Node *n2, Node *n3, Node *n4, Node *n5, Node *n6, Node *n7, int attr, int fattr0, int fattr1, int fattr2, int fattr3, int fattr4, int fattr5)
Definition: ncmesh.cpp:371
DepList dep_list
list of other DOFs this DOF depends on
Definition: ncmesh.hpp:357
void GetVerticesElementsBoundary(Array< mfem::Vertex > &vertices, Array< mfem::Element * > &elements, Array< mfem::Element * > &boundary)
Definition: ncmesh.cpp:1092
int index
edge number in the Mesh
Definition: ncmesh.hpp:183
Array< Element * > coarse_elements
Definition: ncmesh.hpp:268
bool finalized
true if cP matrix row is known for this DOF
Definition: ncmesh.hpp:356
FiniteElementSpace * space
Definition: ncmesh.hpp:365
PointMatrix(const Point &p0, const Point &p1, const Point &p2)
Definition: ncmesh.hpp:435
FineTransform * GetFineTransforms()
Definition: ncmesh.cpp:1870
SparseMatrix * GetInterpolation(FiniteElementSpace *space, SparseMatrix **cR_ptr=NULL)
Definition: ncmesh.cpp:1470
Dependency(int dof, double coef)
Definition: ncmesh.hpp:346
Point(const Point &p0, const Point &p1)
Definition: ncmesh.hpp:406
Node * PeekAltParents(Node *v1, Node *v2)
Definition: ncmesh.cpp:309
void SetEdgeIndicesFromMesh(Mesh *mesh)
Definition: ncmesh.cpp:1166
PointMatrix(const Point &p0, const Point &p1, const Point &p2, const Point &p3)
Definition: ncmesh.hpp:438
PointMatrix(const Point &p0, const Point &p1, const Point &p2, const Point &p3, const Point &p4, const Point &p5, const Point &p6, const Point &p7)
Definition: ncmesh.hpp:441
Array< RefStackItem > ref_stack
stack of scheduled refinements
Definition: ncmesh.hpp:284
int attribute
boundary element attribute, -1 if internal edge
Definition: ncmesh.hpp:182
bool IsIdentity() const
As an optimization, identity transform is &quot;stored&quot; as empty matrix.
Definition: ncmesh.hpp:104
bool Boundary() const
Definition: ncmesh.hpp:186
Data type dense matrix.
Definition: densemat.hpp:22
void RefElementNodes(Element *elem)
Definition: ncmesh.cpp:209
static int find_node(Element *elem, Node *node)
Definition: ncmesh.cpp:1225
void GetLeafElements(Element *e)
Definition: ncmesh.cpp:1068
int index
vertex number in the Mesh
Definition: ncmesh.hpp:172
void ConstrainEdge(Node *v0, Node *v1, double t0, double t1, Array< int > &master_dofs, int level)
Definition: ncmesh.cpp:1313
const Point & operator()(int i) const
Definition: ncmesh.hpp:451
bool DofFinalizable(DofData &vd)
Definition: ncmesh.cpp:1460
Point & operator()(int i)
Definition: ncmesh.hpp:450
void ProcessMasterEdge(Node *node[2], Node *edge)
Definition: ncmesh.cpp:1426
double coord[3]
Definition: ncmesh.hpp:395
Vertex * NewVertex(Node *v1, Node *v2)
Definition: ncmesh.cpp:450
bool NodeSetY1(Node *node, Node **n)
Definition: ncmesh.cpp:505
void ClearCoarseLevel()
Free the internally stored array of coarse leaf elements.
Definition: ncmesh.hpp:113
Array< int > vertex_nodeId
Definition: ncmesh.hpp:270
int attribute
boundary element attribute, -1 if internal face
Definition: ncmesh.hpp:228
int index
Mesh element number.
Definition: ncmesh.hpp:37
Element * NewQuadrilateral(Node *n0, Node *n1, Node *n2, Node *n3, int attr, int eattr0, int eattr1, int eattr2, int eattr3)
Definition: ncmesh.cpp:399
int coarse_index
coarse Mesh element index
Definition: ncmesh.hpp:100
Array< Dependency > DepList
Definition: ncmesh.hpp:350
Point(const Point &p0, const Point &p1, const Point &p2, const Point &p3)
Definition: ncmesh.hpp:413
Vertex(double x, double y, double z)
Definition: ncmesh.hpp:175
void ConstrainFace(Node *v0, Node *v1, Node *v2, Node *v3, const PointMatrix &pm, Array< int > &master_dofs, int level)
Definition: ncmesh.cpp:1357
Refinement(int index, int type=7)
Definition: ncmesh.hpp:40
int index
face number in the Mesh
Definition: ncmesh.hpp:229
Data type sparse matrix.
Definition: sparsemat.hpp:38
void ProcessMasterFace(Node *node[4], Face *face)
Definition: ncmesh.cpp:1444
Element * elem[2]
up to 2 elements sharing the face
Definition: ncmesh.hpp:230
bool Independent() const
Definition: ncmesh.hpp:360
void GetMatrix(DenseMatrix &point_matrix) const
Definition: ncmesh.cpp:1619
void CheckAnisoFace(Node *v1, Node *v2, Node *v3, Node *v4, Node *mid12, Node *mid34, int level=0)
Definition: ncmesh.cpp:550
DofData * dof_data
DOF temporary data.
Definition: ncmesh.hpp:363
void UpdateVertices()
Definition: ncmesh.cpp:1050
void RegisterElement(Element *e)
Definition: ncmesh.cpp:262
DenseMatrix point_matrix
for use in IsoparametricTransformation
Definition: ncmesh.hpp:101
void AddDependencies(Array< int > &master_dofs, Array< int > &slave_dofs, DenseMatrix &I)
Definition: ncmesh.cpp:1286
Element(int geom, int attr)
Definition: ncmesh.cpp:359
void MarkCoarseLevel()
Definition: ncmesh.hpp:110
int CountElements(Element *elem)
Definition: ncmesh.cpp:2037
A class for non-conforming AMR on higher-order hexahedral, quadrilateral or triangular meshes...
Definition: ncmesh.hpp:65
bool NodeSetX1(Node *node, Node **n)
Definition: ncmesh.cpp:499
void RegisterFaces(Element *elem)
Definition: ncmesh.cpp:282
void DeleteHierarchy(Element *elem)
Definition: ncmesh.cpp:157
Vertex * vertex
Definition: ncmesh.hpp:201
RefStackItem(Element *elem, int type)
Definition: ncmesh.hpp:280
Point(double x, double y, double z)
Definition: ncmesh.hpp:403
double * Data() const
Returns vector of the elements.
Definition: densemat.hpp:69
void UnrefEdge(HashTable< Node > &nodes)
Definition: ncmesh.cpp:194
void ForceRefinement(Node *v1, Node *v2, Node *v3, Node *v4)
Definition: ncmesh.cpp:518
Abstract finite element space.
Definition: fespace.hpp:61
bool Boundary() const
Definition: ncmesh.hpp:235
double pos[3]
3D position
Definition: ncmesh.hpp:171
Element * child[8]
Definition: ncmesh.hpp:260
Array< Element * > leaf_elements
Definition: ncmesh.hpp:267
void CountSplits(Element *elem, int splits[3])
Definition: ncmesh.cpp:1986
void UpdateLeafElements()
Definition: ncmesh.cpp:1084
bool NodeSetZ1(Node *node, Node **n)
Definition: ncmesh.cpp:511
Node * GetMidEdgeVertexSimple(Node *v1, Node *v2)
Definition: ncmesh.cpp:472
HashTable< Node > nodes
Definition: ncmesh.hpp:272
void UnrefElementNodes(Element *elem)
Definition: ncmesh.cpp:235
void CheckIsoFace(Node *v1, Node *v2, Node *v3, Node *v4, Node *e1, Node *e2, Node *e3, Node *e4, Node *midf)
Definition: ncmesh.cpp:601
int FaceSplitType(Node *v1, Node *v2, Node *v3, Node *v4, Node *mid[4]=NULL)
Definition: ncmesh.cpp:1196
Node * GetMidFaceVertex(Node *e1, Node *e2, Node *e3, Node *e4)
Definition: ncmesh.cpp:481
bool NodeSetZ2(Node *node, Node **n)
Definition: ncmesh.cpp:514
bool NodeSetX2(Node *node, Node **n)
Definition: ncmesh.cpp:502
void SetFaceIndicesFromMesh(Mesh *mesh)
Definition: ncmesh.cpp:1180
long MemoryUsage()
Definition: ncmesh.cpp:2049
Element * NewTriangle(Node *n0, Node *n1, Node *n2, int attr, int eattr0, int eattr1, int eattr2)
Definition: ncmesh.cpp:426
NCMesh(const Mesh *mesh)
Definition: ncmesh.cpp:61
Point(double x, double y)
Definition: ncmesh.hpp:400
int Dimension() const
Definition: ncmesh.hpp:70
Array< Element * > root_elements
Definition: ncmesh.hpp:266
Node * GetMidEdgeVertex(Node *v1, Node *v2)
Definition: ncmesh.cpp:463
Element * GetSingleElement() const
Definition: ncmesh.cpp:295
void ForgetElement(Element *e)
Definition: ncmesh.cpp:272
bool NodeSetY2(Node *node, Node **n)
Definition: ncmesh.cpp:508
int ref_type
refinement XYZ bit mask (7 = full isotropic)
Definition: ncmesh.hpp:38
Abstract data type element.
Definition: element.hpp:27
Point & operator=(const Point &src)
Definition: ncmesh.hpp:421
void FaceSplitLevel(Node *v1, Node *v2, Node *v3, Node *v4, int &h_level, int &v_level)
Definition: ncmesh.cpp:1954
HashTable< Face > faces
Definition: ncmesh.hpp:273
void Refine(const Array< Refinement > &refinements)
Definition: ncmesh.cpp:1005
int GetEdgeMaster(int v1, int v2) const
Definition: ncmesh.cpp:1946
void UnrefVertex(HashTable< Node > &nodes)
Definition: ncmesh.cpp:187