MFEM  v4.5.1 Finite element discretization library
ncmesh.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
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 "../general/sort_pairs.hpp"
19 #include "../linalg/densemat.hpp"
20 #include "element.hpp"
21 #include "vertex.hpp"
22 #include "../fem/geom.hpp"
23
24 #include <vector>
25 #include <map>
26 #include <iostream>
27
28 namespace mfem
29 {
30
31 /** Represents the index of an element to refine, plus a refinement type.
32  The refinement type is needed for anisotropic refinement of quads and hexes.
33  Bits 0,1 and 2 of 'ref_type' specify whether the element should be split
34  in the X, Y and Z directions, respectively (Z is ignored for quads). */
35 struct Refinement
36 {
37  enum : char { X = 1, Y = 2, Z = 4, XY = 3, XZ = 5, YZ = 6, XYZ = 7 };
38  int index; ///< Mesh element number
39  char ref_type; ///< refinement XYZ bit mask (7 = full isotropic)
40
41  Refinement() = default;
42
43  Refinement(int index, int type = Refinement::XYZ)
44  : index(index), ref_type(type) {}
45 };
46
47
48 /// Defines the position of a fine element within a coarse element.
49 struct Embedding
50 {
51  /// Coarse %Element index in the coarse mesh.
52  int parent;
53
54  /** The (geom, matrix) pair determines the sub-element transformation for the
55  fine element: CoarseFineTransformations::point_matrices[geom](matrix) is
56  the point matrix of the region within the coarse element reference domain.*/
57  unsigned geom : 4;
58  unsigned matrix : 27;
59
60  /// For internal use: 0 if regular fine element, 1 if parallel ghost element.
61  unsigned ghost : 1;
62
63  Embedding() = default;
64  Embedding(int elem, Geometry::Type geom, int matrix = 0, bool ghost = false)
65  : parent(elem), geom(geom), matrix(matrix), ghost(ghost) {}
66 };
67
68
69 /// Defines the coarse-fine transformations of all fine elements.
71 {
72  /// Fine element positions in their parents.
74
75  /** A "dictionary" of matrices for IsoparametricTransformation. Use
76  Embedding::{geom,matrix} to access a fine element point matrix. */
78
79  /** Invert the 'embeddings' array: create a Table with coarse elements as
80  rows and fine elements as columns. If 'want_ghosts' is false, parallel
81  ghost fine elements are not included in the table. */
82  void MakeCoarseToFineTable(Table &coarse_to_fine,
83  bool want_ghosts = false) const;
84
85  void Clear();
86  bool IsInitialized() const;
87  std::size_t MemoryUsage() const;
88
89  MFEM_DEPRECATED
90  void GetCoarseToFineMap(const Mesh &fine_mesh, Table &coarse_to_fine) const
91  { MakeCoarseToFineTable(coarse_to_fine, true); (void) fine_mesh; }
92 };
93
94 void Swap(CoarseFineTransformations &a, CoarseFineTransformations &b);
95
96 struct MatrixMap; // for internal use
97
98
99 /** \brief A class for non-conforming AMR. The class is not used directly
100  * by the user, rather it is an extension of the Mesh class.
101  *
102  * In general, the class is used by MFEM as follows:
103  *
104  * 1. NCMesh is constructed from elements of an existing Mesh. The elements
105  * are copied and become roots of the refinement hierarchy.
106  *
107  * 2. Some elements are refined with the Refine() method. Both isotropic and
108  * anisotropic refinements of quads/hexes are supported.
109  *
110  * 3. A new Mesh is created from NCMesh containing the leaf elements.
111  * This new Mesh may have non-conforming (hanging) edges and faces and
112  * is the one seen by the user.
113  *
114  * 4. FiniteElementSpace asks NCMesh for a list of conforming, master and
115  * slave edges/faces and creates the conforming interpolation matrix P.
116  *
117  * 5. A continuous/conforming solution is obtained by solving P'*A*P x = P'*b.
118  *
119  * 6. Repeat from step 2.
120  */
121 class NCMesh
122 {
123 public:
124  //// Initialize with elements from an existing 'mesh'.
125  explicit NCMesh(const Mesh *mesh);
126
128  from \param[in] input . \param[in] version is 10 for the v1.0 NC format,
129  or 1 for the legacy v1.1 format. \param[out] curved is set to 1 if the
130  curvature GridFunction follows after mesh data. \param[out] is_nc (again
131  treated as a boolean) is set to 0 if the legacy v1.1 format in fact
132  defines a conforming mesh. See Mesh::Loader for details. */
133  NCMesh(std::istream &input, int version, int &curved, int &is_nc);
134
135  /// Deep copy of another instance.
136  NCMesh(const NCMesh &other);
137
138  /// Copy assignment not supported
139  NCMesh& operator=(NCMesh&) = delete;
140
141  virtual ~NCMesh();
142
143  /// Return the dimension of the NCMesh.
144  int Dimension() const { return Dim; }
145  /// Return the space dimension of the NCMesh.
146  int SpaceDimension() const { return spaceDim; }
147
148  /// Return the number of vertices in the NCMesh.
149  int GetNVertices() const { return NVertices; }
150  /// Return the number of edges in the NCMesh.
151  int GetNEdges() const { return NEdges; }
152  /// Return the number of (2D) faces in the NCMesh.
153  int GetNFaces() const { return NFaces; }
154  virtual int GetNGhostElements() const { return 0; }
155
156  /** Perform the given batch of refinements. Please note that in the presence
157  of anisotropic splits additional refinements may be necessary to keep
158  the mesh consistent. However, the function always performs at least the
159  requested refinements. */
160  virtual void Refine(const Array<Refinement> &refinements);
161
162  /** Check the mesh and potentially refine some elements so that the maximum
163  difference of refinement levels between adjacent elements is not greater
164  than 'max_nc_level'. */
165  virtual void LimitNCLevel(int max_nc_level);
166
167  /** Return a list of derefinement opportunities. Each row of the table
168  contains Mesh indices of existing elements that can be derefined to form
169  a single new coarse element. Row numbers are then passed to Derefine.
170  This function works both in serial and parallel. */
171  const Table &GetDerefinementTable();
172
173  /** Check derefinements returned by GetDerefinementTable and mark those that
174  can be done safely so that the maximum NC level condition is not violated.
175  On return, level_ok.Size() == deref_table.Size() and contains 0/1s. */
176  virtual void CheckDerefinementNCLevel(const Table &deref_table,
177  Array<int> &level_ok, int max_nc_level);
178
179  /** Perform a subset of the possible derefinements (see GetDerefinementTable).
180  Note that if anisotropic refinements are present in the mesh, some of the
181  derefinements may have to be skipped to preserve mesh consistency. */
182  virtual void Derefine(const Array<int> &derefs);
183
184  // master/slave lists
185
186  /// Identifies a vertex/edge/face in both Mesh and NCMesh.
187  struct MeshId
188  {
189  int index; ///< Mesh number
190  int element; ///< NCMesh::Element containing this vertex/edge/face
191  signed char local; ///< local number within 'element'
192  signed char geom; ///< Geometry::Type (faces only) (char to save RAM)
193
194  Geometry::Type Geom() const { return Geometry::Type(geom); }
195
196  MeshId() = default;
197  MeshId(int index, int element, int local, int geom = -1)
198  : index(index), element(element), local(local), geom(geom) {}
199  };
200
201  /** Nonconforming edge/face that has more than one neighbor. The neighbors
202  are stored in NCList::slaves[i], slaves_begin <= i < slaves_end. */
203  struct Master : public MeshId
204  {
205  int slaves_begin, slaves_end; ///< slave faces
206
207  Master() = default;
208  Master(int index, int element, int local, int geom, int sb, int se)
209  : MeshId(index, element, local, geom)
210  , slaves_begin(sb), slaves_end(se) {}
211  };
212
213  /// Nonconforming edge/face within a bigger edge/face.
214  struct Slave : public MeshId
215  {
216  int master; ///< master number (in Mesh numbering)
217  unsigned matrix : 24; ///< index into NCList::point_matrices[geom]
218  unsigned edge_flags : 8; ///< orientation flags, see OrientedPointMatrix
219
220  Slave() = default;
221  Slave(int index, int element, int local, int geom)
222  : MeshId(index, element, local, geom)
223  , master(-1), matrix(0), edge_flags(0) {}
224  };
225
226  /// Lists all edges/faces in the nonconforming mesh.
227  struct NCList
228  {
232
233  /// List of unique point matrices for each slave geometry.
235
236  /// Return the point matrix oriented according to the master and slave edges
237  void OrientedPointMatrix(const Slave &slave,
238  DenseMatrix &oriented_matrix) const;
239
240  void Clear();
241  bool Empty() const { return !conforming.Size() && !masters.Size(); }
242  long TotalSize() const;
243  std::size_t MemoryUsage() const;
244
245  const MeshId& LookUp(int index, int *type = NULL) const;
246
247  ~NCList() { Clear(); }
248  private:
249  mutable Array<int> inv_index;
250  };
251
252  /// Return the current list of conforming and nonconforming faces.
254  {
255  if (face_list.Empty()) { BuildFaceList(); }
256  return face_list;
257  }
258
259  /// Return the current list of conforming and nonconforming edges.
261  {
262  if (edge_list.Empty()) { BuildEdgeList(); }
263  return edge_list;
264  }
265
266  /** Return a list of vertices (in 'conforming'); this function is provided
267  for uniformity/completeness. Needed in ParNCMesh/ParFESpace. */
269  {
270  if (vertex_list.Empty()) { BuildVertexList(); }
271  return vertex_list;
272  }
273
274  /// Return vertex/edge/face list (entity = 0/1/2, respectively).
275  const NCList& GetNCList(int entity)
276  {
277  switch (entity)
278  {
279  case 0: return GetVertexList();
280  case 1: return GetEdgeList();
281  default: return GetFaceList();
282  }
283  }
284
285
286  // coarse/fine transforms
287
288  /** Remember the current layer of leaf elements before the mesh is refined.
289  Needed by GetRefinementTransforms(), must be called before Refine(). */
290  void MarkCoarseLevel();
291
292  /** After refinement, calculate the relation of each fine element to its
293  parent coarse element. Note that Refine() or LimitNCLevel() can be called
294  multiple times between MarkCoarseLevel() and this function. */
296
297  /** After derefinement, calculate the relations of previous fine elements
298  (some of which may no longer exist) to the current leaf elements.
299  Unlike for refinement, Derefine() may only be called once before this
300  function so there is no MarkFineLevel(). */
302
303  /// Free all internal data created by the above three functions.
304  void ClearTransforms();
305
306
307  // grid ordering
308
309  /** Return a space filling curve for a rectangular grid of elements.
310  Implemented is a generalized Hilbert curve for arbitrary grid dimensions.
311  If the width is odd, height should be odd too, otherwise one diagonal
312  (vertex-neighbor) step cannot be avoided in the curve. Even dimensions
313  are recommended. */
314  static void GridSfcOrdering2D(int width, int height,
315  Array<int> &coords);
316
317  /** Return a space filling curve for a 3D rectangular grid of elements.
318  The Hilbert-curve-like algorithm works well for even dimensions. For odd
319  width/height/depth it tends to produce some diagonal (edge-neighbor)
320  steps. Even dimensions are recommended. */
321  static void GridSfcOrdering3D(int width, int height, int depth,
322  Array<int> &coords);
323
324
325  // utility
326
327  /// Return Mesh vertex indices of an edge identified by 'edge_id'.
328  void GetEdgeVertices(const MeshId &edge_id, int vert_index[2],
329  bool oriented = true) const;
330
331  /** Return "NC" orientation of an edge. As opposed to standard Mesh edge
332  orientation based on vertex IDs, "NC" edge orientation follows the local
333  edge orientation within the element 'edge_id.element' and is thus
334  processor independent. TODO: this seems only partially true? */
335  int GetEdgeNCOrientation(const MeshId &edge_id) const;
336
337  /** Return Mesh vertex and edge indices of a face identified by 'face_id'.
338  The return value is the number of face vertices. */
339  int GetFaceVerticesEdges(const MeshId &face_id,
340  int vert_index[4], int edge_index[4],
341  int edge_orientation[4]) const;
342
343  /** Given an edge (by its vertex indices v1 and v2) return the first
344  (geometric) parent edge that exists in the Mesh or -1 if there is no such
345  parent. */
346  int GetEdgeMaster(int v1, int v2) const;
347
348  /** Get a list of vertices (2D/3D) and edges (3D) that coincide with boundary
349  elements with the specified attributes (marked in 'bdr_attr_is_ess').
350  In 3D this function also reveals "hidden" boundary edges. In parallel it
351  helps identifying boundary vertices/edges affected by non-local boundary
352  elements. */
353  virtual void GetBoundaryClosure(const Array<int> &bdr_attr_is_ess,
354  Array<int> &bdr_vertices,
355  Array<int> &bdr_edges);
356
357  /// Return element geometry type. @a index is the Mesh element number.
359  { return elements[leaf_elements[index]].Geom(); }
360
361  /// Return face geometry type. @a index is the Mesh face number.
363  { return Geometry::Type(face_geom[index]); }
364
365  /// Return the number of root elements.
366  int GetNumRootElements() { return root_state.Size(); }
367
368  /// Return the distance of leaf 'i' from the root.
369  int GetElementDepth(int i) const;
370
371  /** Return the size reduction compared to the root element (ignoring local
372  stretching and curvature). */
373  int GetElementSizeReduction(int i) const;
374
375  /// Return the faces and face attributes of leaf element 'i'.
377  Array<int> &fattr) const;
378
379
380  /// I/O: Print the mesh in "MFEM NC mesh v1.0" format.
381  void Print(std::ostream &out) const;
382
383  /// I/O: Return true if the mesh was loaded from the legacy v1.1 format.
384  bool IsLegacyLoaded() const { return Legacy; }
385
386  /// I/O: Return a map from old (v1.1) vertex indices to new vertex indices.
387  void LegacyToNewVertexOrdering(Array<int> &order) const;
388
389  /// Save memory by releasing all non-essential and cached data.
390  virtual void Trim();
391
393  std::size_t MemoryUsage() const;
394
395  int PrintMemoryDetail() const;
396
397  typedef std::int64_t RefCoord;
398
399
400 protected: // non-public interface for the Mesh class
401
402  friend class Mesh;
403
404  /// Fill Mesh::{vertices,elements,boundary} for the current finest level.
405  void GetMeshComponents(Mesh &mesh) const;
406
407  /** Get edge and face numbering from 'mesh' (i.e., set all Edge::index and
408  Face::index) after a new mesh was created from us. */
409  void OnMeshUpdated(Mesh *mesh);
410
411  /** Delete top-level vertex coordinates if the Mesh became curved, e.g.,
412  by calling Mesh::SetCurvature or otherwise setting the Nodes. */
414
415
416 protected: // implementation
417
418  int Dim, spaceDim; ///< dimensions of the elements and the vertex coordinates
419  int MyRank; ///< used in parallel, or when loading a parallel file in serial
420  bool Iso; ///< true if the mesh only contains isotropic refinements
421  int Geoms; ///< bit mask of element geometries present, see InitGeomFlags()
422  bool Legacy; ///< true if the mesh was loaded from the legacy v1.1 format
423
424  /** A Node can hold a vertex, an edge, or both. Elements directly point to
425  their corner nodes, but edge nodes also exist and can be accessed using
426  a hash-table given their two end-point node IDs. All nodes can be
427  accessed in this way, with the exception of top-level vertex nodes.
428  When an element is being refined, the mid-edge nodes are readily
429  available with this mechanism. The new elements "sign in" to the nodes
430  by increasing the reference counts of their vertices and edges. The
431  parent element "signs off" its nodes by decrementing the ref counts. */
432  struct Node : public Hashed2
433  {
436
437  Node() : vert_refc(0), edge_refc(0), vert_index(-1), edge_index(-1) {}
438  ~Node();
439
440  bool HasVertex() const { return vert_refc > 0; }
441  bool HasEdge() const { return edge_refc > 0; }
442
443  // decrease vertex/edge ref count, return false if Node should be deleted
444  bool UnrefVertex() { --vert_refc; return vert_refc || edge_refc; }
445  bool UnrefEdge() { --edge_refc; return vert_refc || edge_refc; }
446  };
447
448  /** Similarly to nodes, faces can be accessed by hashing their four vertex
449  node IDs. A face knows about the one or two elements that are using it.
450  A face that is not on the boundary and only has one element referencing
451  it is either a master or a slave face. */
452  struct Face : public Hashed4
453  {
454  int attribute; ///< boundary element attribute, -1 if internal face
455  int index; ///< face number in the Mesh
456  int elem[2]; ///< up to 2 elements sharing the face
457
458  Face() : attribute(-1), index(-1) { elem[0] = elem[1] = -1; }
459
460  bool Boundary() const { return attribute >= 0; }
461  bool Unused() const { return elem[0] < 0 && elem[1] < 0; }
462
463  // add or remove an element from the 'elem[2]' array
464  void RegisterElement(int e);
465  void ForgetElement(int e);
466
467  /// Return one of elem[0] or elem[1] and make sure the other is -1.
468  int GetSingleElement() const;
469  };
470
471  /** This is an element in the refinement hierarchy. Each element has
472  either been refined and points to its children, or is a leaf and points
473  to its vertex nodes. */
474  struct Element
475  {
476  char geom; ///< Geometry::Type of the element (char for storage only)
477  char ref_type; ///< bit mask of X,Y,Z refinements (bits 0,1,2 respectively)
478  char tet_type; ///< tetrahedron split type, currently always 0
479  char flag; ///< generic flag/marker, can be used by algorithms
480  int index; ///< element number in the Mesh, -1 if refined
481  int rank; ///< processor number (ParNCMesh), -1 if undefined/unknown
483  union
484  {
485  int node[8]; ///< element corners (if ref_type == 0)
486  int child[8]; ///< 2-8 children (if ref_type != 0)
487  };
488  int parent; ///< parent element, -1 if this is a root element, -2 if free'd
489
490  Element(Geometry::Type geom, int attr);
491
492  Geometry::Type Geom() const { return Geometry::Type(geom); }
493  bool IsLeaf() const { return !ref_type && (parent != -2); }
494  };
495
496
497  // primary data
498
499  HashTable<Node> nodes; // associative container holding all Nodes
500  HashTable<Face> faces; // associative container holding all Faces
501
502  BlockArray<Element> elements; // storage for all Elements
503  Array<int> free_element_ids; // unused element ids - indices into 'elements'
504
505  /** Initial traversal state (~ element orientation) for each root element
506  NOTE: M = root_state.Size() is the number of root elements.
507  NOTE: the first M items of 'elements' is the coarse mesh. */
509
510  /** Coordinates of top-level vertices (organized as triples). If empty,
511  the Mesh is curved (Nodes != NULL) and NCMesh is topology-only. */
513
514
515  // secondary data
516
517  /** Apart from the primary data structure, which is the element/node/face
518  hierarchy, there is secondary data that is derived from the primary
519  data and needs to be updated when the primary data changes. Update()
520  takes care of that and needs to be called after each refinement and
521  derefinement. */
522  virtual void Update();
523
524  // set by UpdateLeafElements, UpdateVertices and OnMeshUpdated
526
527  // NOTE: the serial code understands the bare minimum about ghost elements and
528  // other ghost entities in order to be able to load parallel partial meshes
530
531  Array<int> leaf_elements; ///< finest elements, in Mesh ordering (+ ghosts)
532  Array<int> leaf_sfc_index; ///< natural tree ordering of leaf elements
533  Array<int> vertex_nodeId; ///< vertex-index to node-id map, see UpdateVertices
534
535  NCList face_list; ///< lazy-initialized list of faces, see GetFaceList
536  NCList edge_list; ///< lazy-initialized list of edges, see GetEdgeList
537  NCList vertex_list; ///< lazy-initialized list of vertices, see GetVertexList
538
539  Array<int> boundary_faces; ///< subset of all faces, set by BuildFaceList
540  Array<char> face_geom; ///< face geometry by face index, set by OnMeshUpdated
541
542  Table element_vertex; ///< leaf-element to vertex table, see FindSetNeighbors
543
544
545  /// Update the leaf elements indices in leaf_elements
546  void UpdateLeafElements();
547
548  /** @brief This method assigns indices to vertices (Node::vert_index) that
549  will be seen by the Mesh class and the rest of MFEM.
550
551  We must be careful to:
552  1. Stay compatible with the conforming code, which expects top-level
553  (original) vertices to be indexed first, otherwise GridFunctions
554  defined on a conforming mesh would no longer be valid when the
555  mesh is converted to an NC mesh.
556
557  2. Make sure serial NCMesh is compatible with the parallel ParNCMesh,
558  so it is possible to read parallel partial solutions in serial code
559  (e.g., serial GLVis). This means handling ghost elements, if present.
560
561  3. Assign vertices in a globally consistent order for parallel meshes:
562  if two vertices i,j are shared by two ranks r1,r2, and i<j on r1,
563  then i<j on r2 as well. This is true for top-level vertices but also
564  for the remaining shared vertices thanks to the globally consistent
565  SFC ordering of the leaf elements. This property reduces communication
566  and simplifies ParNCMesh. */
567  void UpdateVertices(); ///< update Vertex::index and vertex_nodeId
568
569  /** Collect the leaf elements in leaf_elements, and the ghost elements in
570  ghosts. Compute and set the element indices of @a elements. On quad and
571  hex refined elements tries to order leaf elements along a space-filling
572  curve according to the given @a state variable. */
573  void CollectLeafElements(int elem, int state, Array<int> &ghosts,
574  int &counter);
575
576  /** Try to find a space-filling curve friendly orientation of the root
577  elements: set 'root_state' based on the ordering of coarse elements.
578  Note that the coarse mesh itself must be ordered as an SFC by e.g.
579  Mesh::GetGeckoElementOrdering. */
580  void InitRootState(int root_count);
581
582  /** Compute the Geometry::Type present in the root elements (coarse elements)
583  and set @a Geoms bitmask accordingly. */
584  void InitGeomFlags();
585
586  /// Return true if the mesh contains prism elements.
587  bool HavePrisms() const { return Geoms & (1 << Geometry::PRISM); }
588
589  /// Return true if the mesh contains tetrahedral elements.
590  bool HaveTets() const { return Geoms & (1 << Geometry::TETRAHEDRON); }
591
592  /// Return true if the Element @a el is a ghost element.
593  bool IsGhost(const Element &el) const { return el.rank != MyRank; }
594
595
596  // refinement/derefinement
597
598  Array<Refinement> ref_stack; ///< stack of scheduled refinements (temporary)
599  HashTable<Node> shadow; ///< temporary storage for reparented nodes
600  Array<Triple<int, int, int> > reparents; ///< scheduled node reparents (tmp)
601
602  Table derefinements; ///< possible derefinements, see GetDerefinementTable
603
604  /** Refine the element @a elem with the refinement @a ref_type
605  (c.f. Refinement::enum) */
606  void RefineElement(int elem, char ref_type);
607
608  /// Derefine the element @a elem, does nothing on leaf elements.
609  void DerefineElement(int elem);
610
611  // Add an Element @a el to the NCMesh, optimized to reuse freed elements.
613  {
614  if (free_element_ids.Size())
615  {
616  int idx = free_element_ids.Last();
618  elements[idx] = el;
619  return idx;
620  }
621  return elements.Append(el);
622  }
623
624  // Free the element with index @a id.
625  void FreeElement(int id)
626  {
628  elements[id].ref_type = 0;
629  elements[id].parent = -2; // mark the element as free
630  }
631
632  int NewHexahedron(int n0, int n1, int n2, int n3,
633  int n4, int n5, int n6, int n7, int attr,
634  int fattr0, int fattr1, int fattr2,
635  int fattr3, int fattr4, int fattr5);
636
637  int NewWedge(int n0, int n1, int n2,
638  int n3, int n4, int n5, int attr,
639  int fattr0, int fattr1,
640  int fattr2, int fattr3, int fattr4);
641
642  int NewTetrahedron(int n0, int n1, int n2, int n3, int attr,
643  int fattr0, int fattr1, int fattr2, int fattr3);
644
645  int NewQuadrilateral(int n0, int n1, int n2, int n3, int attr,
646  int eattr0, int eattr1, int eattr2, int eattr3);
647
648  int NewTriangle(int n0, int n1, int n2,
649  int attr, int eattr0, int eattr1, int eattr2);
650
651  int NewSegment(int n0, int n1, int attr, int vattr1, int vattr2);
652
653  mfem::Element* NewMeshElement(int geom) const;
654
655  int QuadFaceSplitType(int v1, int v2, int v3, int v4, int mid[5]
656  = NULL /*optional output of mid-edge nodes*/) const;
657
658  bool TriFaceSplit(int v1, int v2, int v3, int mid[3] = NULL) const;
659
660  void ForceRefinement(int vn1, int vn2, int vn3, int vn4);
661
662  void FindEdgeElements(int vn1, int vn2, int vn3, int vn4,
663  Array<MeshId> &prisms) const;
664
665  void CheckAnisoPrism(int vn1, int vn2, int vn3, int vn4,
666  const Refinement *refs, int nref);
667
668  void CheckAnisoFace(int vn1, int vn2, int vn3, int vn4,
669  int mid12, int mid34, int level = 0);
670
671  void CheckIsoFace(int vn1, int vn2, int vn3, int vn4,
672  int en1, int en2, int en3, int en4, int midf);
673
674  void ReparentNode(int node, int new_p1, int new_p2);
675
676  int FindMidEdgeNode(int node1, int node2) const;
677  int GetMidEdgeNode(int node1, int node2);
678
679  int GetMidFaceNode(int en1, int en2, int en3, int en4);
680
681  void ReferenceElement(int elem);
682  void UnreferenceElement(int elem, Array<int> &elemFaces);
683
684  Face* GetFace(Element &elem, int face_no);
685  void RegisterFaces(int elem, int *fattr = NULL);
686  void DeleteUnusedFaces(const Array<int> &elemFaces);
687
688  void CollectDerefinements(int elem, Array<Connection> &list);
689
690  /// Return el.node[index] correctly, even if the element is refined.
691  int RetrieveNode(const Element &el, int index);
692
693  /// Extended version of find_node: works if 'el' is refined.
694  int FindNodeExt(const Element &el, int node, bool abort = true);
695
696
697  // face/edge lists
698
699  static int find_node(const Element &el, int node);
700  static int find_element_edge(const Element &el, int vn0, int vn1,
701  bool abort = true);
702  static int find_local_face(int geom, int a, int b, int c);
703
704  struct Point;
705  struct PointMatrix;
706
707  int ReorderFacePointMat(int v0, int v1, int v2, int v3,
708  int elem, const PointMatrix &pm,
709  PointMatrix &reordered) const;
710
711  void TraverseQuadFace(int vn0, int vn1, int vn2, int vn3,
712  const PointMatrix& pm, int level, Face* eface[4],
713  MatrixMap &matrix_map);
714  bool TraverseTriFace(int vn0, int vn1, int vn2,
715  const PointMatrix& pm, int level,
716  MatrixMap &matrix_map);
717  void TraverseTetEdge(int vn0, int vn1, const Point &p0, const Point &p1,
718  MatrixMap &matrix_map);
719  void TraverseEdge(int vn0, int vn1, double t0, double t1, int flags,
720  int level, MatrixMap &matrix_map);
721
722  virtual void BuildFaceList();
723  virtual void BuildEdgeList();
724  virtual void BuildVertexList();
725
726  virtual void ElementSharesFace(int elem, int local, int face) {} // ParNCMesh
727  virtual void ElementSharesEdge(int elem, int local, int enode) {} // ParNCMesh
728  virtual void ElementSharesVertex(int elem, int local, int vnode) {} // ParNCMesh
729
730
731  // neighbors / element_vertex table
732
733  /** Return all vertex-, edge- and face-neighbors of a set of elements.
734  The neighbors are returned as a list (neighbors != NULL), as a set
735  (neighbor_set != NULL), or both. The sizes of the set arrays must match
736  that of leaf_elements. The function is intended to be used for large
737  sets of elements and its complexity is linear in the number of leaf
738  elements in the mesh. */
739  void FindSetNeighbors(const Array<char> &elem_set,
740  Array<int> *neighbors, /* append */
741  Array<char> *neighbor_set = NULL);
742
743  /** Return all vertex-, edge- and face-neighbors of a single element.
744  You can limit the number of elements being checked using 'search_set'.
745  The complexity of the function is linear in the size of the search set.*/
746  void FindNeighbors(int elem,
747  Array<int> &neighbors, /* append */
748  const Array<int> *search_set = NULL);
749
750  /** Expand a set of elements by all vertex-, edge- and face-neighbors.
751  The output array 'expanded' will contain all items from 'elems'
752  (provided they are in 'search_set') plus their neighbors. The neighbor
753  search can be limited to the optional search set. The complexity is
754  linear in the sum of the sizes of 'elems' and 'search_set'. */
755  void NeighborExpand(const Array<int> &elems,
756  Array<int> &expanded,
757  const Array<int> *search_set = NULL);
758
759
760  void CollectEdgeVertices(int v0, int v1, Array<int> &indices);
761  void CollectTriFaceVertices(int v0, int v1, int v2, Array<int> &indices);
762  void CollectQuadFaceVertices(int v0, int v1, int v2, int v3,
763  Array<int> &indices);
765
767  {
769  }
770
771  int GetVertexRootCoord(int elem, RefCoord coord[3]) const;
772  void CollectIncidentElements(int elem, const RefCoord coord[3],
773  Array<int> &list) const;
774
775  /** Return elements neighboring to a local vertex of element 'elem'. Only
776  elements from within the same refinement tree ('cousins') are returned.
777  Complexity is proportional to the depth of elem's refinement tree. */
778  void FindVertexCousins(int elem, int local, Array<int> &cousins) const;
779
780
781  // coarse/fine transformations
782
783  struct Point
784  {
785  int dim;
786  double coord[3];
787
788  Point() { dim = 0; }
789
790  Point(const Point &) = default;
791
792  Point(double x)
793  { dim = 1; coord[0] = x; }
794
795  Point(double x, double y)
796  { dim = 2; coord[0] = x; coord[1] = y; }
797
798  Point(double x, double y, double z)
799  { dim = 3; coord[0] = x; coord[1] = y; coord[2] = z; }
800
801  Point(const Point& p0, const Point& p1)
802  {
803  dim = p0.dim;
804  for (int i = 0; i < dim; i++)
805  {
806  coord[i] = (p0.coord[i] + p1.coord[i]) * 0.5;
807  }
808  }
809
810  Point(const Point& p0, const Point& p1, const Point& p2, const Point& p3)
811  {
812  dim = p0.dim;
813  MFEM_ASSERT(p1.dim == dim && p2.dim == dim && p3.dim == dim, "");
814  for (int i = 0; i < dim; i++)
815  {
816  coord[i] = (p0.coord[i] + p1.coord[i] + p2.coord[i] + p3.coord[i])
817  * 0.25;
818  }
819  }
820
821  Point& operator=(const Point& src)
822  {
823  dim = src.dim;
824  for (int i = 0; i < dim; i++) { coord[i] = src.coord[i]; }
825  return *this;
826  }
827  };
828
829  /** @brief The PointMatrix stores the coordinates of the slave face using the
830  master face coordinate as reference.
831
832  In 2D, the point matrix has the orientation of the parent
833  edge, so its columns need to be flipped when applying it, see
834  ApplyLocalSlaveTransformation.
835
836  In 3D, the orientation part of Elem2Inf is encoded in the point
837  matrix.
838
839  The following transformation gives the relation between the
840  reference quad face coordinates (xi, eta) in [0,1]^2, and the fine quad
841  face coordinates (x, y):
842  x = a0*(1-xi)*(1-eta) + a1*xi*(1-eta) + a2*xi*eta + a3*(1-xi)*eta
843  y = b0*(1-xi)*(1-eta) + b1*xi*(1-eta) + b2*xi*eta + b3*(1-xi)*eta
844  */
845  struct PointMatrix
846  {
847  int np;
849
850  PointMatrix() : np(0) {}
851
852  PointMatrix(const Point& p0, const Point& p1)
853  { np = 2; points[0] = p0; points[1] = p1; }
854
855  PointMatrix(const Point& p0, const Point& p1, const Point& p2)
856  { np = 3; points[0] = p0; points[1] = p1; points[2] = p2; }
857
858  PointMatrix(const Point& p0, const Point& p1, const Point& p2, const Point& p3)
859  { np = 4; points[0] = p0; points[1] = p1; points[2] = p2; points[3] = p3; }
860
861  PointMatrix(const Point& p0, const Point& p1, const Point& p2,
862  const Point& p3, const Point& p4, const Point& p5)
863  {
864  np = 6;
865  points[0] = p0; points[1] = p1; points[2] = p2;
866  points[3] = p3; points[4] = p4; points[5] = p5;
867  }
868  PointMatrix(const Point& p0, const Point& p1, const Point& p2,
869  const Point& p3, const Point& p4, const Point& p5,
870  const Point& p6, const Point& p7)
871  {
872  np = 8;
873  points[0] = p0; points[1] = p1; points[2] = p2; points[3] = p3;
874  points[4] = p4; points[5] = p5; points[6] = p6; points[7] = p7;
875  }
876
877  Point& operator()(int i) { return points[i]; }
878  const Point& operator()(int i) const { return points[i]; }
879
880  bool operator==(const PointMatrix &pm) const;
881
882  void GetMatrix(DenseMatrix& point_matrix) const;
883  };
884
891
892  static const PointMatrix& GetGeomIdentity(Geometry::Type geom);
893
894  void GetPointMatrix(Geometry::Type geom, const char* ref_path,
895  DenseMatrix& matrix);
896
897  typedef std::map<std::string, int> RefPathMap;
898
899  void TraverseRefinements(int elem, int coarse_index,
900  std::string &ref_path, RefPathMap &map);
901
902  /// storage for data returned by Get[De]RefinementTransforms()
904
905  /// state of leaf_elements before Refine(), set by MarkCoarseLevel()
907
908  void InitDerefTransforms();
909  void SetDerefMatrixCodes(int parent, Array<int> &fine_coarse);
910
911
912  // vertex temporary data, used by GetMeshComponents
913
914  struct TmpVertex
915  {
916  bool valid, visited;
917  double pos[3];
918  TmpVertex() : valid(false), visited(false) {}
919  };
920
922
923  const double *CalcVertexPos(int node) const;
924
925
926  // utility
927
928  int GetEdgeMaster(int node) const;
929
930  void FindFaceNodes(int face, int node[4]);
931
932  int EdgeSplitLevel(int vn1, int vn2) const;
933  int TriFaceSplitLevel(int vn1, int vn2, int vn3) const;
934  void QuadFaceSplitLevel(int vn1, int vn2, int vn3, int vn4,
935  int& h_level, int& v_level) const;
936
937  void CountSplits(int elem, int splits[3]) const;
938  void GetLimitRefinements(Array<Refinement> &refinements, int max_level);
939
940
941  // I/O
942
943  /// Print the "vertex_parents" section of the mesh file.
944  int PrintVertexParents(std::ostream *out) const;
945  /// Load the vertex parent hierarchy from a mesh file.
947
948  /** Print the "boundary" section of the mesh file.
949  If out == NULL, only return the number of boundary elements. */
950  int PrintBoundary(std::ostream *out) const;
951  /// Load the "boundary" section of the mesh file.
953
954  /// Print the "coordinates" section of the mesh file.
955  void PrintCoordinates(std::ostream &out) const;
956  /// Load the "coordinates" section of the mesh file.
958
959  /// Count root elements and initialize root_state.
960  void InitRootElements();
961  /// Return the index of the last top-level node plus one.
962  int CountTopLevelNodes() const;
963  /// Return true if all root_states are zero.
964  bool ZeroRootStates() const;
965
966  /// Load the element refinement hierarchy from a legacy mesh file.
968  void CopyElements(int elem, const BlockArray<Element> &tmp_elements);
969  /// Load the deprecated MFEM mesh v1.1 format for backward compatibility.
970  void LoadLegacyFormat(std::istream &input, int &curved, int &is_nc);
971
972
973  // geometry
974
975  /// This holds in one place the constants about the geometries we support
976  struct GeomInfo
977  {
978  int nv, ne, nf; // number of: vertices, edges, faces
979  int edges[12][2]; // edge vertices (up to 12 edges)
980  int faces[6][4]; // face vertices (up to 6 faces)
981  int nfv[6]; // number of face vertices
982
984  GeomInfo() : initialized(false) {}
985  void InitGeom(Geometry::Type geom);
986  };
987
989
990 #ifdef MFEM_DEBUG
991 public:
992  void DebugLeafOrder(std::ostream &out) const;
993  void DebugDump(std::ostream &out) const;
994 #endif
995
996  friend class ParNCMesh; // for ParNCMesh::ElementSet
997  friend struct MatrixMap;
998  friend struct PointMatrixHash;
999 };
1000
1001 }
1002
1003 #endif
NCList face_list
lazy-initialized list of faces, see GetFaceList
Definition: ncmesh.hpp:535
NCList edge_list
lazy-initialized list of edges, see GetEdgeList
Definition: ncmesh.hpp:536
void LegacyToNewVertexOrdering(Array< int > &order) const
I/O: Return a map from old (v1.1) vertex indices to new vertex indices.
Definition: ncmesh.cpp:5950
The PointMatrix stores the coordinates of the slave face using the master face coordinate as referenc...
Definition: ncmesh.hpp:845
void LoadLegacyFormat(std::istream &input, int &curved, int &is_nc)
Load the deprecated MFEM mesh v1.1 format for backward compatibility.
Definition: ncmesh.cpp:5792
int Size() const
Return the logical size of the array.
Definition: array.hpp:138
static void GridSfcOrdering3D(int width, int height, int depth, Array< int > &coords)
Definition: ncmesh.cpp:4753
void CheckAnisoPrism(int vn1, int vn2, int vn3, int vn4, const Refinement *refs, int nref)
Definition: ncmesh.cpp:750
CoarseFineTransformations transforms
storage for data returned by Get[De]RefinementTransforms()
Definition: ncmesh.hpp:903
static void GridSfcOrdering2D(int width, int height, Array< int > &coords)
Definition: ncmesh.cpp:4738
int NewQuadrilateral(int n0, int n1, int n2, int n3, int attr, int eattr0, int eattr1, int eattr2, int eattr3)
Definition: ncmesh.cpp:553
static PointMatrix pm_seg_identity
Definition: ncmesh.hpp:885
int elem[2]
up to 2 elements sharing the face
Definition: ncmesh.hpp:456
char ref_type
refinement XYZ bit mask (7 = full isotropic)
Definition: ncmesh.hpp:39
int GetFaceVerticesEdges(const MeshId &face_id, int vert_index[4], int edge_index[4], int edge_orientation[4]) const
Definition: ncmesh.cpp:4816
TmpVertex * tmp_vertex
Definition: ncmesh.hpp:921
bool TriFaceSplit(int v1, int v2, int v3, int mid[3]=NULL) const
Definition: ncmesh.cpp:2589
void SetDerefMatrixCodes(int parent, Array< int > &fine_coarse)
Definition: ncmesh.cpp:1906
const CoarseFineTransformations & GetDerefinementTransforms()
Definition: ncmesh.cpp:4401
char flag
generic flag/marker, can be used by algorithms
Definition: ncmesh.hpp:479
bool HasEdge() const
Definition: ncmesh.hpp:441
Refinement(int index, int type=Refinement::XYZ)
Definition: ncmesh.hpp:43
PointMatrix(const Point &p0, const Point &p1, const Point &p2)
Definition: ncmesh.hpp:855
This holds in one place the constants about the geometries we support.
Definition: ncmesh.hpp:976
Array< Triple< int, int, int > > reparents
scheduled node reparents (tmp)
Definition: ncmesh.hpp:600
Point(const Point &p0, const Point &p1)
Definition: ncmesh.hpp:801
static const int NumGeom
Definition: geom.hpp:42
Array< Slave > slaves
Definition: ncmesh.hpp:231
void CollectTriFaceVertices(int v0, int v1, int v2, Array< int > &indices)
Definition: ncmesh.cpp:3348
char tet_type
tetrahedron split type, currently always 0
Definition: ncmesh.hpp:478
int NewSegment(int n0, int n1, int attr, int vattr1, int vattr2)
Definition: ncmesh.cpp:605
virtual void LimitNCLevel(int max_nc_level)
Definition: ncmesh.cpp:5203
virtual void Trim()
Save memory by releasing all non-essential and cached data.
Definition: ncmesh.cpp:5974
int index
element number in the Mesh, -1 if refined
Definition: ncmesh.hpp:480
PointMatrix(const Point &p0, const Point &p1, const Point &p2, const Point &p3)
Definition: ncmesh.hpp:858
std::int64_t RefCoord
Definition: ncmesh.hpp:397
Embedding()=default
void ForceRefinement(int vn1, int vn2, int vn3, int vn4)
Definition: ncmesh.cpp:645
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:868
Lists all edges/faces in the nonconforming mesh.
Definition: ncmesh.hpp:227
bool Legacy
true if the mesh was loaded from the legacy v1.1 format
Definition: ncmesh.hpp:422
unsigned matrix
index into NCList::point_matrices[geom]
Definition: ncmesh.hpp:217
int NVertices
Definition: ncmesh.hpp:525
int GetNVertices() const
Return the number of vertices in the NCMesh.
Definition: ncmesh.hpp:149
void GetMeshComponents(Mesh &mesh) const
Fill Mesh::{vertices,elements,boundary} for the current finest level.
Definition: ncmesh.cpp:2303
void ClearTransforms()
Free all internal data created by the above three functions.
Definition: ncmesh.cpp:4481
Table derefinements
possible derefinements, see GetDerefinementTable
Definition: ncmesh.hpp:602
Data type dense matrix using column-major storage.
Definition: densemat.hpp:23
Geometry::Type Geom() const
Definition: ncmesh.hpp:194
NCList vertex_list
lazy-initialized list of vertices, see GetVertexList
Definition: ncmesh.hpp:537
void InitDerefTransforms()
Definition: ncmesh.cpp:1887
static PointMatrix pm_prism_identity
Definition: ncmesh.hpp:889
void Print(std::ostream &out) const
I/O: Print the mesh in &quot;MFEM NC mesh v1.0&quot; format.
Definition: ncmesh.cpp:5400
char geom
Geometry::Type of the element (char for storage only)
Definition: ncmesh.hpp:476
void InitRootState(int root_count)
Definition: ncmesh.cpp:2201
long TotalSize() const
Definition: ncmesh.cpp:3266
int GetEdgeNCOrientation(const MeshId &edge_id) const
Definition: ncmesh.cpp:4804
int NewTetrahedron(int n0, int n1, int n2, int n3, int attr, int fattr0, int fattr1, int fattr2, int fattr3)
Definition: ncmesh.cpp:527
void CheckAnisoFace(int vn1, int vn2, int vn3, int vn4, int mid12, int mid34, int level=0)
Definition: ncmesh.cpp:775
bool ZeroRootStates() const
Return true if all root_states are zero.
Definition: ncmesh.cpp:5391
static PointMatrix pm_tri_identity
Definition: ncmesh.hpp:886
void FreeElement(int id)
Definition: ncmesh.hpp:625
void CountSplits(int elem, int splits[3]) const
Definition: ncmesh.cpp:5090
Geometry::Type Geom() const
Definition: ncmesh.hpp:492
void CollectDerefinements(int elem, Array< Connection > &list)
Definition: ncmesh.cpp:1774
const Point & operator()(int i) const
Definition: ncmesh.hpp:878
Point & operator()(int i)
Definition: ncmesh.hpp:877
void GetLimitRefinements(Array< Refinement > &refinements, int max_level)
Definition: ncmesh.cpp:5173
int PrintMemoryDetail() const
Definition: ncmesh.cpp:6040
void TraverseEdge(int vn0, int vn1, double t0, double t1, int flags, int level, MatrixMap &matrix_map)
Definition: ncmesh.cpp:3060
double coord[3]
Definition: ncmesh.hpp:786
bool UnrefVertex()
Definition: ncmesh.hpp:444
int spaceDim
dimensions of the elements and the vertex coordinates
Definition: ncmesh.hpp:418
bool HavePrisms() const
Return true if the mesh contains prism elements.
Definition: ncmesh.hpp:587
Array< int > vertex_nodeId
vertex-index to node-id map, see UpdateVertices
Definition: ncmesh.hpp:533
int attribute
boundary element attribute, -1 if internal face
Definition: ncmesh.hpp:454
void DebugDump(std::ostream &out) const
Definition: ncmesh.cpp:6093
void FindFaceNodes(int face, int node[4])
Definition: ncmesh.cpp:4942
Array< int > root_state
Definition: ncmesh.hpp:508
static const PointMatrix & GetGeomIdentity(Geometry::Type geom)
Definition: ncmesh.cpp:3866
void DeleteAll()
Delete the whole array.
Definition: array.hpp:846
static int find_element_edge(const Element &el, int vn0, int vn1, bool abort=true)
Definition: ncmesh.cpp:2626
int index
Mesh element number.
Definition: ncmesh.hpp:38
int master
master number (in Mesh numbering)
Definition: ncmesh.hpp:216
const NCList & GetFaceList()
Return the current list of conforming and nonconforming faces.
Definition: ncmesh.hpp:253
const MeshId & LookUp(int index, int *type=NULL) const
Definition: ncmesh.cpp:3271
void OnMeshUpdated(Mesh *mesh)
Definition: ncmesh.cpp:2398
void DebugLeafOrder(std::ostream &out) const
Definition: ncmesh.cpp:6068
A parallel extension of the NCMesh class.
Definition: pncmesh.hpp:64
int NewWedge(int n0, int n1, int n2, int n3, int n4, int n5, int attr, int fattr0, int fattr1, int fattr2, int fattr3, int fattr4)
Definition: ncmesh.cpp:495
void CollectEdgeVertices(int v0, int v1, Array< int > &indices)
Definition: ncmesh.cpp:3336
void CollectLeafElements(int elem, int state, Array< int > &ghosts, int &counter)
Definition: ncmesh.cpp:1925
static int find_local_face(int geom, int a, int b, int c)
Definition: ncmesh.cpp:2644
Array< Refinement > ref_stack
stack of scheduled refinements (temporary)
Definition: ncmesh.hpp:598
bool Empty() const
Definition: ncmesh.hpp:241
Point(const Point &p0, const Point &p1, const Point &p2, const Point &p3)
Definition: ncmesh.hpp:810
void CollectIncidentElements(int elem, const RefCoord coord[3], Array< int > &list) const
Definition: ncmesh.cpp:3779
void ReferenceElement(int elem)
Definition: ncmesh.cpp:315
void GetPointMatrix(Geometry::Type geom, const char *ref_path, DenseMatrix &matrix)
Definition: ncmesh.cpp:3882
void CheckIsoFace(int vn1, int vn2, int vn3, int vn4, int en1, int en2, int en3, int en4, int midf)
Definition: ncmesh.cpp:870
void InitGeomFlags()
Definition: ncmesh.cpp:222
Face * GetFace(Element &elem, int face_no)
Definition: ncmesh.cpp:428
void TraverseRefinements(int elem, int coarse_index, std::string &ref_path, RefPathMap &map)
Definition: ncmesh.cpp:4316
int PrintBoundary(std::ostream *out) const
Definition: ncmesh.cpp:5273
int GetMidEdgeNode(int node1, int node2)
Definition: ncmesh.cpp:300
Element(Geometry::Type geom, int attr)
Definition: ncmesh.cpp:453
int index
face number in the Mesh
Definition: ncmesh.hpp:455
const Table & GetDerefinementTable()
Definition: ncmesh.cpp:1807
Table element_vertex
leaf-element to vertex table, see FindSetNeighbors
Definition: ncmesh.hpp:542
DenseTensor point_matrices[Geometry::NumGeom]
Definition: ncmesh.hpp:77
unsigned matrix
Definition: ncmesh.hpp:58
int Append(const T &el)
Append element &#39;el&#39; to array, resize if necessary.
Definition: array.hpp:751
int CountTopLevelNodes() const
Return the index of the last top-level node plus one.
Definition: ncmesh.cpp:5519
bool operator==(const PointMatrix &pm) const
Definition: ncmesh.cpp:3819
void GetMatrix(DenseMatrix &point_matrix) const
Definition: ncmesh.cpp:3833
Definition: ncmesh.hpp:612
virtual void Derefine(const Array< int > &derefs)
Definition: ncmesh.cpp:1851
double b
Definition: lissajous.cpp:42
void QuadFaceSplitLevel(int vn1, int vn2, int vn3, int vn4, int &h_level, int &v_level) const
Definition: ncmesh.cpp:5063
void FindNeighbors(int elem, Array< int > &neighbors, const Array< int > *search_set=NULL)
Definition: ncmesh.cpp:3589
Geometry::Type GetElementGeometry(int index) const
Return element geometry type. index is the Mesh element number.
Definition: ncmesh.hpp:358
void InitGeom(Geometry::Type geom)
Definition: ncmesh.cpp:27
friend struct MatrixMap
Definition: ncmesh.hpp:997
Array< int > coarse_elements
state of leaf_elements before Refine(), set by MarkCoarseLevel()
Definition: ncmesh.hpp:906
void UpdateVertices()
This method assigns indices to vertices (Node::vert_index) that will be seen by the Mesh class and th...
Definition: ncmesh.cpp:2021
int NGhostVertices
Definition: ncmesh.hpp:529
int ReorderFacePointMat(int v0, int v1, int v2, int v3, int elem, const PointMatrix &pm, PointMatrix &reordered) const
Definition: ncmesh.cpp:2722
Master(int index, int element, int local, int geom, int sb, int se)
Definition: ncmesh.hpp:208
Array< DenseMatrix * > point_matrices[Geometry::NumGeom]
List of unique point matrices for each slave geometry.
Definition: ncmesh.hpp:234
void RegisterFaces(int elem, int *fattr=NULL)
Definition: ncmesh.cpp:389
virtual int GetNGhostElements() const
Definition: ncmesh.hpp:154
Array< Embedding > embeddings
Fine element positions in their parents.
Definition: ncmesh.hpp:73
virtual void BuildEdgeList()
Definition: ncmesh.cpp:3088
const CoarseFineTransformations & GetRefinementTransforms()
Definition: ncmesh.cpp:4350
Load the element refinement hierarchy from a legacy mesh file.
Definition: ncmesh.cpp:5721
Identifies a vertex/edge/face in both Mesh and NCMesh.
Definition: ncmesh.hpp:187
int FindMidEdgeNode(int node1, int node2) const
Definition: ncmesh.cpp:284
int parent
parent element, -1 if this is a root element, -2 if free&#39;d
Definition: ncmesh.hpp:488
void MarkCoarseLevel()
Definition: ncmesh.cpp:4302
signed char local
local number within &#39;element&#39;
Definition: ncmesh.hpp:191
virtual void ElementSharesFace(int elem, int local, int face)
Definition: ncmesh.hpp:726
int GetNumRootElements()
Return the number of root elements.
Definition: ncmesh.hpp:366
Load the &quot;coordinates&quot; section of the mesh file.
Definition: ncmesh.cpp:5370
virtual void ElementSharesVertex(int elem, int local, int vnode)
Definition: ncmesh.hpp:728
int MyRank
Definition: ncmesh.hpp:419
int Size() const
Returns the number of TYPE I elements.
Definition: table.hpp:92
A class for non-conforming AMR. The class is not used directly by the user, rather it is an extension...
Definition: ncmesh.hpp:121
int GetElementSizeReduction(int i) const
Definition: ncmesh.cpp:4907
unsigned geom
Definition: ncmesh.hpp:57
virtual ~NCMesh()
Definition: ncmesh.cpp:243
friend struct PointMatrixHash
Definition: ncmesh.hpp:998
int GetNFaces() const
Return the number of (2D) faces in the NCMesh.
Definition: ncmesh.hpp:153
virtual void GetBoundaryClosure(const Array< int > &bdr_attr_is_ess, Array< int > &bdr_vertices, Array< int > &bdr_edges)
Definition: ncmesh.cpp:4966
int element
NCMesh::Element containing this vertex/edge/face.
Definition: ncmesh.hpp:190
Geometry::Type GetFaceGeometry(int index) const
Return face geometry type. index is the Mesh face number.
Definition: ncmesh.hpp:362
static GeomInfo GI[Geometry::NumGeom]
Definition: ncmesh.hpp:988
int slaves_end
slave faces
Definition: ncmesh.hpp:205
void MakeTopologyOnly()
Definition: ncmesh.hpp:413
void ReparentNode(int node, int new_p1, int new_p2)
Definition: ncmesh.cpp:268
int NewTriangle(int n0, int n1, int n2, int attr, int eattr0, int eattr1, int eattr2)
Definition: ncmesh.cpp:579
void DeleteUnusedFaces(const Array< int > &elemFaces)
Definition: ncmesh.cpp:403
bool Iso
true if the mesh only contains isotropic refinements
Definition: ncmesh.hpp:420
I/O: Return true if the mesh was loaded from the legacy v1.1 format.
Definition: ncmesh.hpp:384
Point(double x, double y, double z)
Definition: ncmesh.hpp:798
bool HasVertex() const
Definition: ncmesh.hpp:440
void Swap(Array< T > &, Array< T > &)
Definition: array.hpp:630
std::map< std::string, int > RefPathMap
Definition: ncmesh.hpp:897
unsigned ghost
For internal use: 0 if regular fine element, 1 if parallel ghost element.
Definition: ncmesh.hpp:61
int SpaceDimension() const
Return the space dimension of the NCMesh.
Definition: ncmesh.hpp:146
virtual void BuildFaceList()
Definition: ncmesh.cpp:2968
Nonconforming edge/face within a bigger edge/face.
Definition: ncmesh.hpp:214
void DerefineElement(int elem)
Derefine the element elem, does nothing on leaf elements.
Definition: ncmesh.cpp:1608
void GetElementFacesAttributes(int i, Array< int > &faces, Array< int > &fattr) const
Return the faces and face attributes of leaf element &#39;i&#39;.
Definition: ncmesh.cpp:4921
const NCList & GetVertexList()
Definition: ncmesh.hpp:268
bool Boundary() const
Definition: ncmesh.hpp:460
bool IsLeaf() const
Definition: ncmesh.hpp:493
Point(double x)
Definition: ncmesh.hpp:792
void RegisterElement(int e)
Definition: ncmesh.cpp:414
NCMesh & operator=(NCMesh &)=delete
Copy assignment not supported.
Embedding(int elem, Geometry::Type geom, int matrix=0, bool ghost=false)
Definition: ncmesh.hpp:64
mfem::Element * NewMeshElement(int geom) const
Definition: ncmesh.cpp:2264
Array< int > leaf_sfc_index
natural tree ordering of leaf elements
Definition: ncmesh.hpp:532
PointMatrix(const Point &p0, const Point &p1, const Point &p2, const Point &p3, const Point &p4, const Point &p5)
Definition: ncmesh.hpp:861
void DeleteLast()
Delete the last entry of the array.
Definition: array.hpp:193
std::size_t MemoryUsage() const
Definition: ncmesh.cpp:6007
void UpdateLeafElements()
Update the leaf elements indices in leaf_elements.
Definition: ncmesh.cpp:1993
int PrintVertexParents(std::ostream *out) const
Print the &quot;vertex_parents&quot; section of the mesh file.
Definition: ncmesh.cpp:5221
int TriFaceSplitLevel(int vn1, int vn2, int vn3) const
Definition: ncmesh.cpp:5046
int GetNEdges() const
Return the number of edges in the NCMesh.
Definition: ncmesh.hpp:151
int RetrieveNode(const Element &el, int index)
Return el.node[index] correctly, even if the element is refined.
Definition: ncmesh.cpp:1572
int Geoms
bit mask of element geometries present, see InitGeomFlags()
Definition: ncmesh.hpp:421
PointMatrix(const Point &p0, const Point &p1)
Definition: ncmesh.hpp:852
void MakeCoarseToFineTable(Table &coarse_to_fine, bool want_ghosts=false) const
Definition: ncmesh.cpp:4459
int NGhostElements
Definition: ncmesh.hpp:529
void BuildElementToVertexTable()
Definition: ncmesh.cpp:3406
HashTable< Node > nodes
Definition: ncmesh.hpp:499
double a
Definition: lissajous.cpp:41
std::size_t MemoryUsage() const
Definition: ncmesh.cpp:5989
void ForgetElement(int e)
Definition: ncmesh.cpp:421
static PointMatrix pm_tet_identity
Definition: ncmesh.hpp:888
int GetMidFaceNode(int en1, int en2, int en3, int en4)
Definition: ncmesh.cpp:307
void RefineElement(int elem, char ref_type)
Definition: ncmesh.cpp:887
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:465
void TraverseTetEdge(int vn0, int vn1, const Point &p0, const Point &p1, MatrixMap &matrix_map)
Definition: ncmesh.cpp:2872
Array< int > boundary_faces
subset of all faces, set by BuildFaceList
Definition: ncmesh.hpp:539
int child[8]
2-8 children (if ref_type != 0)
Definition: ncmesh.hpp:486
int NGhostFaces
Definition: ncmesh.hpp:529
Array< double > coordinates
Definition: ncmesh.hpp:512
const NCList & GetNCList(int entity)
Return vertex/edge/face list (entity = 0/1/2, respectively).
Definition: ncmesh.hpp:275
Array< int > leaf_elements
finest elements, in Mesh ordering (+ ghosts)
Definition: ncmesh.hpp:531
Definition: ncmesh.hpp:887
Array< Master > masters
Definition: ncmesh.hpp:230
MFEM_DEPRECATED void GetCoarseToFineMap(const Mesh &fine_mesh, Table &coarse_to_fine) const
Definition: ncmesh.hpp:90
int EdgeSplitLevel(int vn1, int vn2) const
Definition: ncmesh.cpp:5039
Array< MeshId > conforming
Definition: ncmesh.hpp:229
std::size_t MemoryUsage() const
Definition: ncmesh.cpp:6017
unsigned edge_flags
orientation flags, see OrientedPointMatrix
Definition: ncmesh.hpp:218
void FindVertexCousins(int elem, int local, Array< int > &cousins) const
Definition: ncmesh.cpp:3802
signed char geom
Geometry::Type (faces only) (char to save RAM)
Definition: ncmesh.hpp:192
int QuadFaceSplitType(int v1, int v2, int v3, int v4, int mid[5]=NULL) const
Definition: ncmesh.cpp:2542
void OrientedPointMatrix(const Slave &slave, DenseMatrix &oriented_matrix) const
Return the point matrix oriented according to the master and slave edges.
Definition: ncmesh.cpp:3226
Array< int > free_element_ids
Definition: ncmesh.hpp:503
void TraverseQuadFace(int vn0, int vn1, int vn2, int vn3, const PointMatrix &pm, int level, Face *eface[4], MatrixMap &matrix_map)
Definition: ncmesh.cpp:2753
int index(int i, int j, int nx, int ny)
Definition: life.cpp:235
int NGhostEdges
Definition: ncmesh.hpp:529
NCMesh(const Mesh *mesh)
Definition: ncmesh.cpp:104
int parent
Coarse Element index in the coarse mesh.
Definition: ncmesh.hpp:52
Point(double x, double y)
Definition: ncmesh.hpp:795
static PointMatrix pm_hex_identity
Definition: ncmesh.hpp:890
int Dimension() const
Return the dimension of the NCMesh.
Definition: ncmesh.hpp:144
void FindEdgeElements(int vn1, int vn2, int vn3, int vn4, Array< MeshId > &prisms) const
Definition: ncmesh.cpp:703
virtual void CheckDerefinementNCLevel(const Table &deref_table, Array< int > &level_ok, int max_nc_level)
Definition: ncmesh.cpp:1822
T & Last()
Return the last element in the array.
Definition: array.hpp:784
void NeighborExpand(const Array< int > &elems, Array< int > &expanded, const Array< int > *search_set=NULL)
Definition: ncmesh.cpp:3672
BlockArray< Element > elements
Definition: ncmesh.hpp:502
void FindSetNeighbors(const Array< char > &elem_set, Array< int > *neighbors, Array< char > *neighbor_set=NULL)
Definition: ncmesh.cpp:3486
void GetEdgeVertices(const MeshId &edge_id, int vert_index[2], bool oriented=true) const
Return Mesh vertex indices of an edge identified by &#39;edge_id&#39;.
Definition: ncmesh.cpp:4785
virtual void Update()
Definition: ncmesh.cpp:231
Slave(int index, int element, int local, int geom)
Definition: ncmesh.hpp:221
bool HaveTets() const
Return true if the mesh contains tetrahedral elements.
Definition: ncmesh.hpp:590
Data type point element.
Definition: point.hpp:22
void InitRootElements()
Count root elements and initialize root_state.
Definition: ncmesh.cpp:5479
temporary storage for reparented nodes
Definition: ncmesh.hpp:599
Defines the coarse-fine transformations of all fine elements.
Definition: ncmesh.hpp:70
virtual void BuildVertexList()
Definition: ncmesh.cpp:3191
const NCList & GetEdgeList()
Return the current list of conforming and nonconforming edges.
Definition: ncmesh.hpp:260
MeshId(int index, int element, int local, int geom=-1)
Definition: ncmesh.hpp:197
void UpdateElementToVertexTable()
Definition: ncmesh.hpp:766
bool IsGhost(const Element &el) const
Return true if the Element el is a ghost element.
Definition: ncmesh.hpp:593
Load the &quot;boundary&quot; section of the mesh file.
Definition: ncmesh.cpp:5312
void CopyElements(int elem, const BlockArray< Element > &tmp_elements)
Definition: ncmesh.cpp:5703
virtual void ElementSharesEdge(int elem, int local, int enode)
Definition: ncmesh.hpp:727
int GetElementDepth(int i) const
Return the distance of leaf &#39;i&#39; from the root.
Definition: ncmesh.cpp:4895
int FindNodeExt(const Element &el, int node, bool abort=true)
Extended version of find_node: works if &#39;el&#39; is refined.
Definition: ncmesh.cpp:2616
char ref_type
bit mask of X,Y,Z refinements (bits 0,1,2 respectively)
Definition: ncmesh.hpp:477
int NElements
Definition: ncmesh.hpp:525
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:66
void CollectQuadFaceVertices(int v0, int v1, int v2, int v3, Array< int > &indices)
Definition: ncmesh.cpp:3372
bool Unused() const
Definition: ncmesh.hpp:461
static int find_node(const Element &el, int node)
Definition: ncmesh.cpp:2606
void UnreferenceElement(int elem, Array< int > &elemFaces)
Definition: ncmesh.cpp:346
int index
Mesh number.
Definition: ncmesh.hpp:189
Load the vertex parent hierarchy from a mesh file.
Definition: ncmesh.cpp:5250
Rank 3 tensor (array of matrices)
Definition: densemat.hpp:953
Abstract data type element.
Definition: element.hpp:28
Point & operator=(const Point &src)
Definition: ncmesh.hpp:821
Refinement()=default
int GetSingleElement() const
Return one of elem[0] or elem[1] and make sure the other is -1.
Definition: ncmesh.cpp:436
void PrintCoordinates(std::ostream &out) const
Print the &quot;coordinates&quot; section of the mesh file.
Definition: ncmesh.cpp:5352
const double * CalcVertexPos(int node) const
Definition: ncmesh.cpp:2278
int rank
processor number (ParNCMesh), -1 if undefined/unknown
Definition: ncmesh.hpp:481
int node[8]
element corners (if ref_type == 0)
Definition: ncmesh.hpp:485
int GetVertexRootCoord(int elem, RefCoord coord[3]) const
Definition: ncmesh.cpp:3731
bool TraverseTriFace(int vn0, int vn1, int vn2, const PointMatrix &pm, int level, MatrixMap &matrix_map)
Definition: ncmesh.cpp:2909
HashTable< Face > faces
Definition: ncmesh.hpp:500
Defines the position of a fine element within a coarse element.
Definition: ncmesh.hpp:49
virtual void Refine(const Array< Refinement > &refinements)
Definition: ncmesh.cpp:1524
Array< char > face_geom
face geometry by face index, set by OnMeshUpdated
Definition: ncmesh.hpp:540
int GetEdgeMaster(int v1, int v2) const
Definition: ncmesh.cpp:4886