MFEM  v3.3.2
Finite element discretization library
 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.org.
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 "../general/globals.hpp"
18 #include "../linalg/densemat.hpp"
19 #include "element.hpp"
20 #include "vertex.hpp"
21 #include "../fem/geom.hpp"
22 
23 #include <vector>
24 #include <map>
25 #include <iostream>
26 
27 namespace mfem
28 {
29 
30 /** Represents the index of an element to refine, plus a refinement type.
31  The refinement type is needed for anisotropic refinement of quads and hexes.
32  Bits 0,1 and 2 of 'ref_type' specify whether the element should be split
33  in the X, Y and Z directions, respectively (Z is ignored for quads). */
34 struct Refinement
35 {
36  int index; ///< Mesh element number
37  char ref_type; ///< refinement XYZ bit mask (7 = full isotropic)
38 
39  Refinement(int index, int type = 7) : index(index), ref_type(type) {}
40 };
41 
42 /// Defines the position of a fine element within a coarse element.
43 struct Embedding
44 {
45  int parent; ///< element index in the coarse mesh
46  int matrix; ///< index into CoarseFineTransformations::point_matrices
47 
48  Embedding(int elem, int matrix = 0) : parent(elem), matrix(matrix) {}
49 };
50 
51 /// Defines the coarse-fine transformations of all fine elements.
53 {
54  DenseTensor point_matrices; ///< matrices for IsoparametricTransformation
55  Array<Embedding> embeddings; ///< fine element positions in their parents
56 
57  void Clear() { point_matrices.Clear(); embeddings.DeleteAll(); }
58  long MemoryUsage() const;
59 };
60 
61 
62 /** \brief A class for non-conforming AMR on higher-order hexahedral,
63  * quadrilateral or triangular meshes.
64  *
65  * The class is used as follows:
66  *
67  * 1. NCMesh is constructed from elements of an existing Mesh. The elements
68  * are copied and become roots of the refinement hierarchy.
69  *
70  * 2. Some elements are refined with the Refine() method. Both isotropic and
71  * anisotropic refinements of quads/hexes are supported.
72  *
73  * 3. A new Mesh is created from NCMesh containing the leaf elements.
74  * This new mesh may have non-conforming (hanging) edges and faces.
75  *
76  * 4. FiniteElementSpace asks NCMesh for a list of conforming, master and
77  * slave edges/faces and creates the conforming interpolation matrix P.
78  *
79  * 5. A continuous/conforming solution is obtained by solving P'*A*P x = P'*b.
80  *
81  * 6. Repeat from step 2.
82  */
83 class NCMesh
84 {
85 public:
86  /** Initialize with elements from 'mesh'. If an already nonconforming mesh
87  is being loaded, 'vertex_parents' must point to a stream at the appropriate
88  section of the mesh file which contains the vertex hierarchy. */
89  NCMesh(const Mesh *mesh, std::istream *vertex_parents = NULL);
90 
91  NCMesh(const NCMesh &other); // deep copy
92 
93  virtual ~NCMesh();
94 
95  int Dimension() const { return Dim; }
96  int SpaceDimension() const { return spaceDim; }
97 
98  /** Perform the given batch of refinements. Please note that in the presence
99  of anisotropic splits additional refinements may be necessary to keep
100  the mesh consistent. However, the function always performs at least the
101  requested refinements. */
102  virtual void Refine(const Array<Refinement> &refinements);
103 
104  /** Check the mesh and potentially refine some elements so that the maximum
105  difference of refinement levels between adjacent elements is not greater
106  than 'max_nc_level'. */
107  virtual void LimitNCLevel(int max_nc_level);
108 
109  /** Return a list of derefinement opportunities. Each row of the table
110  contains Mesh indices of existing elements that can be derefined to form
111  a single new coarse element. Row numbers are then passed to Derefine.
112  This function works both in serial and parallel. */
113  const Table &GetDerefinementTable();
114 
115  /** Check derefinements returned by GetDerefinementTable and mark those that
116  can be done safely so that the maximum NC level condition is not violated.
117  On return, level_ok.Size() == deref_table.Size() and contains 0/1s. */
118  virtual void CheckDerefinementNCLevel(const Table &deref_table,
119  Array<int> &level_ok, int max_nc_level);
120 
121  /** Perform a subset of the possible derefinements (see GetDerefinementTable).
122  Note that if anisotropic refinements are present in the mesh, some of the
123  derefinements may have to be skipped to preserve mesh consistency. */
124  virtual void Derefine(const Array<int> &derefs);
125 
126 
127  // master/slave lists
128 
129  /// Identifies a vertex/edge/face in both Mesh and NCMesh.
130  struct MeshId
131  {
132  int index; ///< Mesh number
133  int element; ///< NCMesh::Element containing this vertex/edge/face
134  int local; ///< local number within 'element'
135 
136  MeshId(int index = -1, int element = -1, int local = -1)
138  };
139 
140  /** Nonconforming edge/face that has more than one neighbor. The neighbors
141  are stored in NCList::slaves[i], slaves_begin <= i < slaves_end. */
142  struct Master : public MeshId
143  {
144  int slaves_begin, slaves_end; ///< slave faces
145 
146  Master(int index, int element, int local, int sb, int se)
147  : MeshId(index, element, local), slaves_begin(sb), slaves_end(se) {}
148  };
149 
150  /** Nonconforming edge/face within a bigger edge/face.
151  NOTE: only the 'index' member of MeshId is currently valid for slaves. */
152  struct Slave : public MeshId
153  {
154  int master; ///< master number (in Mesh numbering)
155  int edge_flags; ///< edge orientation flags
156  DenseMatrix point_matrix; ///< position within the master edge/face
157 
158  Slave(int index, int element, int local)
159  : MeshId(index, element, local), master(-1), edge_flags(0) {}
160 
161  /// Return the point matrix oriented according to the master and slave edges
162  void OrientedPointMatrix(DenseMatrix &oriented_matrix) const;
163  };
164 
165  /// Lists all edges/faces in the nonconforming mesh.
166  struct NCList
167  {
168  std::vector<MeshId> conforming;
169  std::vector<Master> masters;
170  std::vector<Slave> slaves;
171  // TODO: switch to Arrays when fixed for non-POD types
172  // TODO: make a list of unique slave matrices to save memory (+ time later)
173 
174  void Clear() { conforming.clear(); masters.clear(); slaves.clear(); }
175  bool Empty() const { return !conforming.size() && !masters.size(); }
176  std::size_t TotalSize() const
177  { return conforming.size() + masters.size() + slaves.size(); }
178  long MemoryUsage() const;
179  };
180 
181  /// Return the current list of conforming and nonconforming faces.
183  {
184  if (face_list.Empty()) { BuildFaceList(); }
185  return face_list;
186  }
187 
188  /// Return the current list of conforming and nonconforming edges.
190  {
191  if (edge_list.Empty()) { BuildEdgeList(); }
192  return edge_list;
193  }
194 
195 
196  // coarse/fine transforms
197 
198  /** Remember the current layer of leaf elements before the mesh is refined.
199  Needed by GetRefinementTransforms(), must be called before Refine(). */
200  void MarkCoarseLevel();
201 
202  /** After refinement, calculate the relation of each fine element to its
203  parent coarse element. Note that Refine() or LimitNCLevel() can be called
204  multiple times between MarkCoarseLevel() and this function. */
206 
207  /** After derefinement, calculate the relations of previous fine elements
208  (some of which may no longer exist) to the current leaf elements.
209  Unlike for refinement, Derefine() may only be called once before this
210  function so there is no MarkFineLevel(). */
212 
213  /// Free all internal data created by the above three functions.
214  void ClearTransforms();
215 
216 
217  // utility
218 
219  /** Given an edge (by its vertex indices v1 and v2) return the first
220  (geometric) parent edge that exists in the Mesh or -1 if there is no such
221  parent. */
222  int GetEdgeMaster(int v1, int v2) const;
223 
224  /** Get a list of vertices (2D/3D) and edges (3D) that coincide with boundary
225  elements with the specified attributes (marked in 'bdr_attr_is_ess').
226  In 3D this function also reveals "hidden" boundary edges. In parallel it
227  helps identifying boundary vertices/edges affected by non-local boundary
228  elements. */
229  virtual void GetBoundaryClosure(const Array<int> &bdr_attr_is_ess,
230  Array<int> &bdr_vertices,
231  Array<int> &bdr_edges);
232 
233  /// Return the type of elements in the mesh.
234  int GetElementGeometry() const { return elements[0].geom; }
235 
236  /// Return the distance of leaf 'i' from the root.
237  int GetElementDepth(int i) const;
238 
239  /// I/O: Print the "vertex_parents" section of the mesh file (ver. >= 1.1).
240  void PrintVertexParents(std::ostream &out) const;
241 
242  /// I/O: Print the "coarse_elements" section of the mesh file (ver. >= 1.1).
243  void PrintCoarseElements(std::ostream &out) const;
244 
245  /** I/O: Load the vertex parent hierarchy from a mesh file. NOTE: called
246  indirectly through the constructor. */
247  void LoadVertexParents(std::istream &input);
248 
249  /// I/O: Load the element refinement hierarchy from a mesh file.
250  void LoadCoarseElements(std::istream &input);
251 
252  /// I/O: Set positions of all vertices (used by mesh loader).
253  void SetVertexPositions(const Array<mfem::Vertex> &vertices);
254 
255  /// Return total number of bytes allocated.
256  long MemoryUsage() const;
257 
258  int PrintMemoryDetail() const;
259 
260  void PrintStats(std::ostream &out = mfem::out) const;
261 
262 
263 protected: // interface for Mesh to be able to construct itself from NCMesh
264 
265  friend class Mesh;
266 
267  /// Return the basic Mesh arrays for the current finest level.
268  void GetMeshComponents(Array<mfem::Vertex>& mvertices,
269  Array<mfem::Element*>& melements,
270  Array<mfem::Element*>& mboundary) const;
271 
272  /** Get edge and face numbering from 'mesh' (i.e., set all Edge::index and
273  Face::index) after a new mesh was created from us. */
274  virtual void OnMeshUpdated(Mesh *mesh);
275 
276 
277 protected: // implementation
278 
279  int Dim, spaceDim; ///< dimensions of the elements and the vertex coordinates
280  bool Iso; ///< true if the mesh only contains isotropic refinements
281 
282  /** A Node can hold a vertex, an edge, or both. Elements directly point to
283  their corner nodes, but edge nodes also exist and can be accessed using
284  a hash-table given their two end-point node IDs. All nodes can be
285  accessed in this way, with the exception of top-level vertex nodes.
286  When an element is being refined, the mid-edge nodes are readily
287  available with this mechanism. The new elements "sign in" to the nodes
288  by increasing the reference counts of their vertices and edges. The
289  parent element "signs off" its nodes by decrementing the ref counts. */
290  struct Node : public Hashed2
291  {
294 
295  Node() : vert_refc(0), edge_refc(0), vert_index(-1), edge_index(-1) {}
296  ~Node();
297 
298  bool HasVertex() const { return vert_refc > 0; }
299  bool HasEdge() const { return edge_refc > 0; }
300 
301  // decrease vertex/edge ref count, return false if Node should be deleted
302  bool UnrefVertex() { --vert_refc; return vert_refc || edge_refc; }
303  bool UnrefEdge() { --edge_refc; return vert_refc || edge_refc; }
304  };
305 
306  /** Similarly to nodes, faces can be accessed by hashing their four vertex
307  node IDs. A face knows about the one or two elements that are using it.
308  A face that is not on the boundary and only has one element referencing
309  it is either a master or a slave face. */
310  struct Face : public Hashed4
311  {
312  int attribute; ///< boundary element attribute, -1 if internal face
313  int index; ///< face number in the Mesh
314  int elem[2]; ///< up to 2 elements sharing the face
315 
316  Face() : attribute(-1), index(-1) { elem[0] = elem[1] = -1; }
317 
318  bool Boundary() const { return attribute >= 0; }
319  bool Unused() const { return elem[0] < 0 && elem[1] < 0;}
320 
321  // add or remove an element from the 'elem[2]' array
322  void RegisterElement(int e);
323  void ForgetElement(int e);
324 
325  /// Return one of elem[0] or elem[1] and make sure the other is -1.
326  int GetSingleElement() const;
327  };
328 
329  /** This is an element in the refinement hierarchy. Each element has
330  either been refined and points to its children, or is a leaf and points
331  to its vertex nodes. */
332  struct Element
333  {
334  char geom; ///< Geometry::Type of the element
335  char ref_type; ///< bit mask of X,Y,Z refinements (bits 0,1,2 respectively)
336  char flag; ///< generic flag/marker, can be used by algorithms
337  int index; ///< element number in the Mesh, -1 if refined
338  int rank; ///< processor number (ParNCMesh), -1 if undefined/unknown
340  union
341  {
342  int node[8]; ///< element corners (if ref_type == 0)
343  int child[8]; ///< 2-8 children (if ref_type != 0)
344  };
345  int parent; ///< parent element, -1 if this is a root element, -2 if free
346 
347  Element(int geom, int attr);
348  };
349 
350 
351  // primary data
352 
353  HashTable<Node> nodes; // associative container holding all Nodes
354  HashTable<Face> faces; // associative container holding all Faces
355 
359 
360  BlockArray<Element> elements; // storage for all Elements
361  Array<int> free_element_ids; // free element ids - indices into 'elements'
362 
364 
365  // the first 'root_count' entries of 'elements' is the coarse mesh
367 
368  // coordinates of top-level vertices (organized as triples)
370 
371 
372  // secondary data
373 
374  /** Apart from the primary data structure, which is the element/node/face
375  hierarchy, there is secondary data that is derived from the primary
376  data and needs to be updated when the primary data changes. Update()
377  takes care of that and needs to be called after refinement and
378  derefinement. Secondary data includes: leaf_elements, vertex_nodeId,
379  face_list, edge_list, and everything in ParNCMesh. */
380  virtual void Update();
381 
382  Array<int> leaf_elements; // finest level, calculated by UpdateLeafElements
383  Array<int> vertex_nodeId; // vertex-index to node-id map, see UpdateVertices
384 
385  NCList face_list; ///< lazy-initialized list of faces, see GetFaceList
386  NCList edge_list; ///< lazy-initialized list of edges, see GetEdgeList
387 
388  Array<int> boundary_faces; ///< subset of all faces, set by BuildFaceList
389 
390  Table element_vertex; ///< leaf-element to vertex table, see FindSetNeighbors
391 
392 
393  virtual void UpdateVertices(); ///< update Vertex::index and vertex_nodeId
394 
395  void CollectLeafElements(int elem, int state);
396  void UpdateLeafElements();
397 
398  virtual void AssignLeafIndices();
399 
400  virtual bool IsGhost(const Element &el) const { return false; }
401  virtual int GetNumGhosts() const { return 0; }
402 
403 
404  // refinement/derefinement
405 
406  Array<Refinement> ref_stack; ///< stack of scheduled refinements (temporary)
407 
408  Table derefinements; ///< possible derefinements, see GetDerefinementTable
409 
410  void RefineElement(int elem, char ref_type);
411  void DerefineElement(int elem);
412 
413  int AddElement(const Element &el)
414  {
415  if (free_element_ids.Size())
416  {
417  int idx = free_element_ids.Last();
419  elements[idx] = el;
420  return idx;
421  }
422  return elements.Append(el);
423  }
424  void FreeElement(int id)
425  {
427  elements[id].parent = -2; // mark the element as free
428  }
429 
430  int NewHexahedron(int n0, int n1, int n2, int n3,
431  int n4, int n5, int n6, int n7,
432  int attr,
433  int fattr0, int fattr1, int fattr2,
434  int fattr3, int fattr4, int fattr5);
435 
436  int NewQuadrilateral(int n0, int n1, int n2, int n3,
437  int attr,
438  int eattr0, int eattr1, int eattr2, int eattr3);
439 
440  int NewTriangle(int n0, int n1, int n2,
441  int attr, int eattr0, int eattr1, int eattr2);
442 
443  mfem::Element* NewMeshElement(int geom) const;
444 
445  int GetMidEdgeNode(int vn1, int vn2);
446  int GetMidFaceNode(int en1, int en2, int en3, int en4);
447 
448  int FaceSplitType(int v1, int v2, int v3, int v4, int mid[4]
449  = NULL /*optional output of mid-edge nodes*/) const;
450 
451  void ForceRefinement(int vn1, int vn2, int vn3, int vn4);
452 
453  void CheckAnisoFace(int vn1, int vn2, int vn3, int vn4,
454  int mid12, int mid34, int level = 0);
455 
456  void CheckIsoFace(int vn1, int vn2, int vn3, int vn4,
457  int en1, int en2, int en3, int en4, int midf);
458 
459  void RefElement(int elem);
460  void UnrefElement(int elem, Array<int> &elemFaces);
461 
462  Face* GetFace(Element &elem, int face_no);
463  void RegisterFaces(int elem, int *fattr = NULL);
464  void DeleteUnusedFaces(const Array<int> &elemFaces);
465 
466  int FindAltParents(int node1, int node2);
467 
468  bool NodeSetX1(int node, int* n);
469  bool NodeSetX2(int node, int* n);
470  bool NodeSetY1(int node, int* n);
471  bool NodeSetY2(int node, int* n);
472  bool NodeSetZ1(int node, int* n);
473  bool NodeSetZ2(int node, int* n);
474 
475  void CollectDerefinements(int elem, Array<Connection> &list);
476 
477 
478  // face/edge lists
479 
480  static int find_node(const Element &el, int node);
481  static int find_element_edge(const Element &el, int vn0, int vn1);
482  static int find_hex_face(int a, int b, int c);
483 
484  int ReorderFacePointMat(int v0, int v1, int v2, int v3,
485  int elem, DenseMatrix& mat) const;
486  struct PointMatrix;
487  void TraverseFace(int vn0, int vn1, int vn2, int vn3,
488  const PointMatrix& pm, int level);
489 
490  void TraverseEdge(int vn0, int vn1, double t0, double t1, int flags,
491  int level);
492 
493  virtual void BuildFaceList();
494  virtual void BuildEdgeList();
495 
496  virtual void ElementSharesEdge(int elem, int enode) {} // ParNCMesh
497  virtual void ElementSharesFace(int elem, int face) {} // ParNCMesh
498 
499 
500  // neighbors / element_vertex table
501 
502  /** Return all vertex-, edge- and face-neighbors of a set of elements.
503  The neighbors are returned as a list (neighbors != NULL), as a set
504  (neighbor_set != NULL), or both. The sizes of the set arrays must match
505  that of leaf_elements. The function is intended to be used for large
506  sets of elements and its complexity is linear in the number of leaf
507  elements in the mesh. */
508  void FindSetNeighbors(const Array<char> &elem_set,
509  Array<int> *neighbors, /* append */
510  Array<char> *neighbor_set = NULL);
511 
512  /** Return all vertex-, edge- and face-neighbors of a single element.
513  You can limit the number of elements being checked using 'search_set'.
514  The complexity of the function is linear in the size of the search set.*/
515  void FindNeighbors(int elem,
516  Array<int> &neighbors, /* append */
517  const Array<int> *search_set = NULL);
518 
519  /** Expand a set of elements by all vertex-, edge- and face-neighbors.
520  The output array 'expanded' will contain all items from 'elems'
521  (provided they are in 'search_set') plus their neighbors. The neighbor
522  search can be limited to the optional search set. The complexity is
523  linear in the sum of the sizes of 'elems' and 'search_set'. */
524  void NeighborExpand(const Array<int> &elems,
525  Array<int> &expanded,
526  const Array<int> *search_set = NULL);
527 
528 
529  void CollectEdgeVertices(int v0, int v1, Array<int> &indices);
530  void CollectFaceVertices(int v0, int v1, int v2, int v3,
531  Array<int> &indices);
533 
535  {
537  }
538 
539 
540  // coarse/fine transformations
541 
542  struct Point
543  {
544  int dim;
545  double coord[3];
546 
547  Point() { dim = 0; }
548 
549  Point(double x, double y)
550  { dim = 2; coord[0] = x; coord[1] = y; }
551 
552  Point(double x, double y, double z)
553  { dim = 3; coord[0] = x; coord[1] = y; coord[2] = z; }
554 
555  Point(const Point& p0, const Point& p1)
556  {
557  dim = p0.dim;
558  for (int i = 0; i < dim; i++)
559  {
560  coord[i] = (p0.coord[i] + p1.coord[i]) * 0.5;
561  }
562  }
563 
564  Point(const Point& p0, const Point& p1, const Point& p2, const Point& p3)
565  {
566  dim = p0.dim;
567  MFEM_ASSERT(p1.dim == dim && p2.dim == dim && p3.dim == dim, "");
568  for (int i = 0; i < dim; i++)
569  {
570  coord[i] = (p0.coord[i] + p1.coord[i] + p2.coord[i] + p3.coord[i])
571  * 0.25;
572  }
573  }
574 
575  Point& operator=(const Point& src)
576  {
577  dim = src.dim;
578  for (int i = 0; i < dim; i++) { coord[i] = src.coord[i]; }
579  return *this;
580  }
581  };
582 
583  struct PointMatrix
584  {
585  int np;
587 
588  PointMatrix(const Point& p0, const Point& p1, const Point& p2)
589  { np = 3; points[0] = p0; points[1] = p1; points[2] = p2; }
590 
591  PointMatrix(const Point& p0, const Point& p1, const Point& p2, const Point& p3)
592  { np = 4; points[0] = p0; points[1] = p1; points[2] = p2; points[3] = p3; }
593 
594  PointMatrix(const Point& p0, const Point& p1, const Point& p2,
595  const Point& p3, const Point& p4, const Point& p5,
596  const Point& p6, const Point& p7)
597  {
598  np = 8;
599  points[0] = p0; points[1] = p1; points[2] = p2; points[3] = p3;
600  points[4] = p4; points[5] = p5; points[6] = p6; points[7] = p7;
601  }
602 
603  Point& operator()(int i) { return points[i]; }
604  const Point& operator()(int i) const { return points[i]; }
605 
606  void GetMatrix(DenseMatrix& point_matrix) const;
607  };
608 
612 
613  static const PointMatrix& GetGeomIdentity(int geom);
614 
615  void GetPointMatrix(int geom, const char* ref_path, DenseMatrix& matrix);
616 
617  typedef std::map<std::string, int> RefPathMap;
618 
619  void TraverseRefinements(int elem, int coarse_index,
620  std::string &ref_path, RefPathMap &map);
621 
622  /// storage for data returned by Get[De]RefinementTransforms()
624 
625  /// state of leaf_elements before Refine(), set by MarkCoarseLevel()
627 
628  void InitDerefTransforms();
629  void SetDerefMatrixCodes(int parent, Array<int> &fine_coarse);
630 
631 
632  // vertex temporary data, used by GetMeshComponents
633 
634  struct TmpVertex
635  {
636  bool valid, visited;
637  double pos[3];
638  TmpVertex() : valid(false), visited(false) {}
639  };
640 
642 
643  const double *CalcVertexPos(int node) const;
644 
645 
646  // utility
647 
648  int GetEdgeMaster(int node) const;
649 
650  void FindFaceNodes(int face, int node[4]);
651 
652  int EdgeSplitLevel(int vn1, int vn2) const;
653  void FaceSplitLevel(int vn1, int vn2, int vn3, int vn4,
654  int& h_level, int& v_level) const;
655 
656  void CountSplits(int elem, int splits[3]) const;
657  void GetLimitRefinements(Array<Refinement> &refinements, int max_level);
658 
659  int PrintElements(std::ostream &out, int elem, int &coarse_id) const;
660  void CopyElements(int elem, const BlockArray<Element> &tmp_elements,
661  Array<int> &index_map);
662 
663 
664 public: // TODO: maybe make this part of mfem::Geometry?
665 
666  /** This holds in one place the constants about the geometries we support
667  (triangles, quads, cubes) */
668  struct GeomInfo
669  {
670  int nv, ne, nf, nfv; // number of: vertices, edges, faces, face vertices
671  int edges[12][2]; // edge vertices (up to 12 edges)
672  int faces[6][4]; // face vertices (up to 6 faces)
673 
675  GeomInfo() : initialized(false) {}
676  void Initialize(const mfem::Element* elem);
677  };
678 
680 
681 #ifdef MFEM_DEBUG
682 public:
683  void DebugNeighbors(Array<char> &elem_set);
684 
685  /// Print the space-filling curve formed by the sequence of leaf elements.
686  void DebugLeafOrder() const;
687 #endif
688 
689  friend class ParNCMesh; // for ParNCMesh::ElementSet
690  friend struct CompareRanks;
691 };
692 
693 }
694 
695 #endif
NCList face_list
lazy-initialized list of faces, see GetFaceList
Definition: ncmesh.hpp:385
void CollectLeafElements(int elem, int state)
Definition: ncmesh.cpp:1423
NCList edge_list
lazy-initialized list of edges, see GetEdgeList
Definition: ncmesh.hpp:386
NCMesh(const Mesh *mesh, std::istream *vertex_parents=NULL)
Definition: ncmesh.cpp:68
int Size() const
Logical size of the array.
Definition: array.hpp:110
CoarseFineTransformations transforms
storage for data returned by Get[De]RefinementTransforms()
Definition: ncmesh.hpp:623
int NewQuadrilateral(int n0, int n1, int n2, int n3, int attr, int eattr0, int eattr1, int eattr2, int eattr3)
Definition: ncmesh.cpp:464
int elem[2]
up to 2 elements sharing the face
Definition: ncmesh.hpp:314
char ref_type
refinement XYZ bit mask (7 = full isotropic)
Definition: ncmesh.hpp:37
TmpVertex * tmp_vertex
Definition: ncmesh.hpp:641
Array< double > top_vertex_pos
Definition: ncmesh.hpp:369
void SetDerefMatrixCodes(int parent, Array< int > &fine_coarse)
Definition: ncmesh.cpp:1353
const CoarseFineTransformations & GetDerefinementTransforms()
Definition: ncmesh.cpp:2793
char flag
generic flag/marker, can be used by algorithms
Definition: ncmesh.hpp:336
bool HasEdge() const
Definition: ncmesh.hpp:299
PointMatrix(const Point &p0, const Point &p1, const Point &p2)
Definition: ncmesh.hpp:588
Point(const Point &p0, const Point &p1)
Definition: ncmesh.hpp:555
static const int NumGeom
Definition: geom.hpp:34
void PrintVertexParents(std::ostream &out) const
I/O: Print the &quot;vertex_parents&quot; section of the mesh file (ver. &gt;= 1.1).
Definition: ncmesh.cpp:3114
void GetPointMatrix(int geom, const char *ref_path, DenseMatrix &matrix)
Definition: ncmesh.cpp:2415
virtual void LimitNCLevel(int max_nc_level)
Definition: ncmesh.cpp:3099
int index
element number in the Mesh, -1 if refined
Definition: ncmesh.hpp:337
PointMatrix(const Point &p0, const Point &p1, const Point &p2, const Point &p3)
Definition: ncmesh.hpp:591
const Geometry::Type geom
virtual int GetNumGhosts() const
Definition: ncmesh.hpp:401
void CopyElements(int elem, const BlockArray< Element > &tmp_elements, Array< int > &index_map)
Definition: ncmesh.cpp:3226
void ForceRefinement(int vn1, int vn2, int vn3, int vn4)
Definition: ncmesh.cpp:549
int GetElementGeometry() const
Return the type of elements in the mesh.
Definition: ncmesh.hpp:234
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:594
Lists all edges/faces in the nonconforming mesh.
Definition: ncmesh.hpp:166
void DebugLeafOrder() const
Print the space-filling curve formed by the sequence of leaf elements.
Definition: ncmesh.cpp:3449
void GetMeshComponents(Array< mfem::Vertex > &mvertices, Array< mfem::Element * > &melements, Array< mfem::Element * > &mboundary) const
Return the basic Mesh arrays for the current finest level.
Definition: ncmesh.cpp:1524
void TraverseEdge(int vn0, int vn1, double t0, double t1, int flags, int level)
Definition: ncmesh.cpp:1867
void ClearTransforms()
Free all internal data created by the above three functions.
Definition: ncmesh.cpp:2836
Table derefinements
possible derefinements, see GetDerefinementTable
Definition: ncmesh.hpp:408
Data type dense matrix using column-major storage.
Definition: densemat.hpp:23
void CollectFaceVertices(int v0, int v1, int v2, int v3, Array< int > &indices)
Definition: ncmesh.cpp:2022
void InitDerefTransforms()
Definition: ncmesh.cpp:1338
char geom
Geometry::Type of the element.
Definition: ncmesh.hpp:334
BlockArray< Element >::iterator elem_iterator
Definition: ncmesh.hpp:363
void OrientedPointMatrix(DenseMatrix &oriented_matrix) const
Return the point matrix oriented according to the master and slave edges.
Definition: ncmesh.cpp:1986
void CheckAnisoFace(int vn1, int vn2, int vn3, int vn4, int mid12, int mid34, int level=0)
Definition: ncmesh.cpp:583
static PointMatrix pm_tri_identity
Definition: ncmesh.hpp:609
void FreeElement(int id)
Definition: ncmesh.hpp:424
void CountSplits(int elem, int splits[3]) const
Definition: ncmesh.cpp:3021
void CollectDerefinements(int elem, Array< Connection > &list)
Definition: ncmesh.cpp:1225
const Point & operator()(int i) const
Definition: ncmesh.hpp:604
std::vector< MeshId > conforming
Definition: ncmesh.hpp:168
Point & operator()(int i)
Definition: ncmesh.hpp:603
void GetLimitRefinements(Array< Refinement > &refinements, int max_level)
Definition: ncmesh.cpp:3069
int PrintMemoryDetail() const
Definition: ncmesh.cpp:3375
double coord[3]
Definition: ncmesh.hpp:545
bool UnrefVertex()
Definition: ncmesh.hpp:302
int spaceDim
dimensions of the elements and the vertex coordinates
Definition: ncmesh.hpp:279
Array< int > vertex_nodeId
Definition: ncmesh.hpp:383
int attribute
boundary element attribute, -1 if internal face
Definition: ncmesh.hpp:312
void FindFaceNodes(int face, int node[4])
Definition: ncmesh.cpp:2899
int index
Mesh element number.
Definition: ncmesh.hpp:36
int master
master number (in Mesh numbering)
Definition: ncmesh.hpp:154
const NCList & GetFaceList()
Return the current list of conforming and nonconforming faces.
Definition: ncmesh.hpp:182
virtual void ElementSharesEdge(int elem, int enode)
Definition: ncmesh.hpp:496
virtual void OnMeshUpdated(Mesh *mesh)
Definition: ncmesh.cpp:1599
A parallel extension of the NCMesh class.
Definition: pncmesh.hpp:65
void CollectEdgeVertices(int v0, int v1, Array< int > &indices)
Definition: ncmesh.cpp:2010
void DebugNeighbors(Array< char > &elem_set)
Definition: ncmesh.cpp:2364
Array< Refinement > ref_stack
stack of scheduled refinements (temporary)
Definition: ncmesh.hpp:406
bool Empty() const
Definition: ncmesh.hpp:175
Point(const Point &p0, const Point &p1, const Point &p2, const Point &p3)
Definition: ncmesh.hpp:564
MeshId(int index=-1, int element=-1, int local=-1)
Definition: ncmesh.hpp:136
virtual bool IsGhost(const Element &el) const
Definition: ncmesh.hpp:400
void CheckIsoFace(int vn1, int vn2, int vn3, int vn4, int en1, int en2, int en3, int en4, int midf)
Definition: ncmesh.cpp:649
int root_count
Definition: ncmesh.hpp:366
Face * GetFace(Element &elem, int face_no)
Definition: ncmesh.cpp:344
void TraverseRefinements(int elem, int coarse_index, std::string &ref_path, RefPathMap &map)
Definition: ncmesh.cpp:2726
int PrintElements(std::ostream &out, int elem, int &coarse_id) const
Definition: ncmesh.cpp:3186
Refinement(int index, int type=7)
Definition: ncmesh.hpp:39
int index
face number in the Mesh
Definition: ncmesh.hpp:313
const Table & GetDerefinementTable()
Definition: ncmesh.cpp:1258
Table element_vertex
leaf-element to vertex table, see FindSetNeighbors
Definition: ncmesh.hpp:390
DenseTensor point_matrices
matrices for IsoparametricTransformation
Definition: ncmesh.hpp:54
int local
local number within &#39;element&#39;
Definition: ncmesh.hpp:134
int FindAltParents(int node1, int node2)
Definition: ncmesh.cpp:366
int Append(const T &el)
Append element to array, resize if necessary.
Definition: array.hpp:548
void GetMatrix(DenseMatrix &point_matrix) const
Definition: ncmesh.cpp:2379
int AddElement(const Element &el)
Definition: ncmesh.hpp:413
bool NodeSetY1(int node, int *n)
Definition: ncmesh.cpp:536
virtual void Derefine(const Array< int > &derefs)
Definition: ncmesh.cpp:1302
void FindNeighbors(int elem, Array< int > &neighbors, const Array< int > *search_set=NULL)
Definition: ncmesh.cpp:2221
std::vector< Master > masters
Definition: ncmesh.hpp:169
Array< int > coarse_elements
state of leaf_elements before Refine(), set by MarkCoarseLevel()
Definition: ncmesh.hpp:626
virtual void UpdateVertices()
update Vertex::index and vertex_nodeId
Definition: ncmesh.cpp:1372
void RegisterFaces(int elem, int *fattr=NULL)
Definition: ncmesh.cpp:305
std::size_t TotalSize() const
Definition: ncmesh.hpp:176
Element(int geom, int attr)
Definition: ncmesh.cpp:423
Array< Embedding > embeddings
fine element positions in their parents
Definition: ncmesh.hpp:55
virtual void BuildEdgeList()
Definition: ncmesh.cpp:1906
const CoarseFineTransformations & GetRefinementTransforms()
Definition: ncmesh.cpp:2756
void LoadCoarseElements(std::istream &input)
I/O: Load the element refinement hierarchy from a mesh file.
Definition: ncmesh.cpp:3246
Identifies a vertex/edge/face in both Mesh and NCMesh.
Definition: ncmesh.hpp:130
int parent
parent element, -1 if this is a root element, -2 if free
Definition: ncmesh.hpp:345
void MarkCoarseLevel()
Definition: ncmesh.cpp:2712
Slave(int index, int element, int local)
Definition: ncmesh.hpp:158
Master(int index, int element, int local, int sb, int se)
Definition: ncmesh.hpp:146
int Size() const
Returns the number of TYPE I elements.
Definition: table.hpp:89
A class for non-conforming AMR on higher-order hexahedral, quadrilateral or triangular meshes...
Definition: ncmesh.hpp:83
virtual ~NCMesh()
Definition: ncmesh.cpp:200
virtual void GetBoundaryClosure(const Array< int > &bdr_attr_is_ess, Array< int > &bdr_vertices, Array< int > &bdr_edges)
Definition: ncmesh.cpp:2922
int element
NCMesh::Element containing this vertex/edge/face.
Definition: ncmesh.hpp:133
Embedding(int elem, int matrix=0)
Definition: ncmesh.hpp:48
static GeomInfo GI[Geometry::NumGeom]
Definition: ncmesh.hpp:679
HashTable< Node >::iterator node_iterator
Definition: ncmesh.hpp:356
int slaves_end
slave faces
Definition: ncmesh.hpp:144
bool NodeSetY2(int node, int *n)
Definition: ncmesh.cpp:539
int NewTriangle(int n0, int n1, int n2, int attr, int eattr0, int eattr1, int eattr2)
Definition: ncmesh.cpp:489
void DeleteUnusedFaces(const Array< int > &elemFaces)
Definition: ncmesh.cpp:319
virtual void ElementSharesFace(int elem, int face)
Definition: ncmesh.hpp:497
bool Iso
true if the mesh only contains isotropic refinements
Definition: ncmesh.hpp:280
Point(double x, double y, double z)
Definition: ncmesh.hpp:552
bool HasVertex() const
Definition: ncmesh.hpp:298
std::map< std::string, int > RefPathMap
Definition: ncmesh.hpp:617
int FaceSplitType(int v1, int v2, int v3, int v4, int mid[4]=NULL) const
Definition: ncmesh.cpp:1645
int SpaceDimension() const
Definition: ncmesh.hpp:96
std::vector< Slave > slaves
Definition: ncmesh.hpp:170
virtual void BuildFaceList()
Definition: ncmesh.cpp:1796
void DerefineElement(int elem)
Definition: ncmesh.cpp:1119
int ReorderFacePointMat(int v0, int v1, int v2, int v3, int elem, DenseMatrix &mat) const
Definition: ncmesh.cpp:1714
void SetVertexPositions(const Array< mfem::Vertex > &vertices)
I/O: Set positions of all vertices (used by mesh loader).
Definition: ncmesh.cpp:3163
int edge_flags
edge orientation flags
Definition: ncmesh.hpp:155
HashTable< Node >::const_iterator node_const_iterator
Definition: ncmesh.hpp:357
bool Boundary() const
Definition: ncmesh.hpp:318
void RegisterElement(int e)
Definition: ncmesh.cpp:330
static const PointMatrix & GetGeomIdentity(int geom)
Definition: ncmesh.cpp:2402
mfem::Element * NewMeshElement(int geom) const
Definition: ncmesh.cpp:1487
void DeleteLast()
Delete the last entry.
Definition: array.hpp:152
void UpdateLeafElements()
Definition: ncmesh.cpp:1464
bool NodeSetZ2(int node, int *n)
Definition: ncmesh.cpp:545
long MemoryUsage() const
Definition: ncmesh.cpp:3336
void BuildElementToVertexTable()
Definition: ncmesh.cpp:2046
HashTable< Node > nodes
Definition: ncmesh.hpp:353
bool NodeSetZ1(int node, int *n)
Definition: ncmesh.cpp:542
void ForgetElement(int e)
Definition: ncmesh.cpp:337
int GetMidFaceNode(int en1, int en2, int en3, int en4)
Definition: ncmesh.cpp:521
void RefineElement(int elem, char ref_type)
Definition: ncmesh.cpp:666
int NewHexahedron(int n0, int n1, int n2, int n3, int n4, int n5, int n6, int n7, int attr, int fattr0, int fattr1, int fattr2, int fattr3, int fattr4, int fattr5)
Definition: ncmesh.cpp:435
Array< int > boundary_faces
subset of all faces, set by BuildFaceList
Definition: ncmesh.hpp:388
int child[8]
2-8 children (if ref_type != 0)
Definition: ncmesh.hpp:343
Array< int > leaf_elements
Definition: ncmesh.hpp:382
static PointMatrix pm_quad_identity
Definition: ncmesh.hpp:610
void TraverseFace(int vn0, int vn1, int vn2, int vn3, const PointMatrix &pm, int level)
Definition: ncmesh.cpp:1747
int EdgeSplitLevel(int vn1, int vn2) const
Definition: ncmesh.cpp:2981
static int find_element_edge(const Element &el, int vn0, int vn1)
Definition: ncmesh.cpp:1682
void Initialize(const mfem::Element *elem)
Definition: ncmesh.cpp:29
Array< int > free_element_ids
Definition: ncmesh.hpp:361
bool NodeSetX2(int node, int *n)
Definition: ncmesh.cpp:533
int parent
element index in the coarse mesh
Definition: ncmesh.hpp:45
Point(double x, double y)
Definition: ncmesh.hpp:549
virtual void AssignLeafIndices()
Definition: ncmesh.cpp:1478
static PointMatrix pm_hex_identity
Definition: ncmesh.hpp:611
static int find_hex_face(int a, int b, int c)
Definition: ncmesh.cpp:1698
int Dimension() const
Definition: ncmesh.hpp:95
virtual void CheckDerefinementNCLevel(const Table &deref_table, Array< int > &level_ok, int max_nc_level)
Definition: ncmesh.cpp:1273
T & Last()
Return the last element in the array.
Definition: array.hpp:581
void NeighborExpand(const Array< int > &elems, Array< int > &expanded, const Array< int > *search_set=NULL)
Definition: ncmesh.cpp:2304
BlockArray< Element > elements
Definition: ncmesh.hpp:360
void FindSetNeighbors(const Array< char > &elem_set, Array< int > *neighbors, Array< char > *neighbor_set=NULL)
Definition: ncmesh.cpp:2118
virtual void Update()
Definition: ncmesh.cpp:189
long MemoryUsage() const
Return total number of bytes allocated.
Definition: ncmesh.cpp:3355
void PrintCoarseElements(std::ostream &out) const
I/O: Print the &quot;coarse_elements&quot; section of the mesh file (ver. &gt;= 1.1).
Definition: ncmesh.cpp:3212
Defines the coarse-fine transformations of all fine elements.
Definition: ncmesh.hpp:52
const NCList & GetEdgeList()
Return the current list of conforming and nonconforming edges.
Definition: ncmesh.hpp:189
void UpdateElementToVertexTable()
Definition: ncmesh.hpp:534
friend struct CompareRanks
Definition: ncmesh.hpp:690
int GetElementDepth(int i) const
Return the distance of leaf &#39;i&#39; from the root.
Definition: ncmesh.cpp:2887
HashTable< Face >::iterator face_iterator
Definition: ncmesh.hpp:358
char ref_type
bit mask of X,Y,Z refinements (bits 0,1,2 respectively)
Definition: ncmesh.hpp:335
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition: globals.hpp:64
bool Unused() const
Definition: ncmesh.hpp:319
static int find_node(const Element &el, int node)
Definition: ncmesh.cpp:1672
int index
Mesh number.
Definition: ncmesh.hpp:132
void LoadVertexParents(std::istream &input)
Definition: ncmesh.cpp:3141
int GetMidEdgeNode(int vn1, int vn2)
Definition: ncmesh.cpp:513
Rank 3 tensor (array of matrices)
Definition: densemat.hpp:634
Abstract data type element.
Definition: element.hpp:27
void UnrefElement(int elem, Array< int > &elemFaces)
Definition: ncmesh.cpp:262
Point & operator=(const Point &src)
Definition: ncmesh.hpp:575
void PrintStats(std::ostream &out=mfem::out) const
Definition: ncmesh.cpp:3396
int GetSingleElement() const
Return one of elem[0] or elem[1] and make sure the other is -1.
Definition: ncmesh.cpp:352
const double * CalcVertexPos(int node) const
Definition: ncmesh.cpp:1499
int rank
processor number (ParNCMesh), -1 if undefined/unknown
Definition: ncmesh.hpp:338
bool NodeSetX1(int node, int *n)
Definition: ncmesh.cpp:530
int node[8]
element corners (if ref_type == 0)
Definition: ncmesh.hpp:342
DenseMatrix point_matrix
position within the master edge/face
Definition: ncmesh.hpp:156
HashTable< Face > faces
Definition: ncmesh.hpp:354
Defines the position of a fine element within a coarse element.
Definition: ncmesh.hpp:43
void RefElement(int elem)
Definition: ncmesh.cpp:231
void FaceSplitLevel(int vn1, int vn2, int vn3, int vn4, int &h_level, int &v_level) const
Definition: ncmesh.cpp:2988
virtual void Refine(const Array< Refinement > &refinements)
Definition: ncmesh.cpp:1075
int matrix
index into CoarseFineTransformations::point_matrices
Definition: ncmesh.hpp:46
int GetEdgeMaster(int v1, int v2) const
Definition: ncmesh.cpp:2878