MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
ncmesh.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
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"
20#include "element.hpp"
21#include "vertex.hpp"
22#include "../fem/geom.hpp"
23
24#include <vector>
25#include <map>
26#include <iostream>
27#include <unordered_map>
28
29namespace mfem
30{
31
32/** Represents the index of an element to refine, plus a refinement type.
33 The refinement type is needed for anisotropic refinement of quads and hexes.
34 Bits 0,1 and 2 of 'ref_type' specify whether the element should be split
35 in the X, Y and Z directions, respectively (Z is ignored for quads). The
36 refinement spacing or scale in each direction is a number in (0,1), with the
37 default 0.5 meaning bisection. This linear scale parameter defines the
38 position of the refinement between the beginning (0) and end (1) of the
39 reference element in each direction. */
41{
42 int index; ///< Mesh element number
43 enum : char { X = 1, Y = 2, Z = 4, XY = 3, XZ = 5, YZ = 6, XYZ = 7 };
44 using ScaledType = std::pair<char, real_t>;
45 real_t s[3]; /// Refinement scale in each dimension
46 Refinement() = default;
47 /// Refinement type XYZ, with scale 0.5.
48 Refinement(int index);
49 /// Default case of empty list @a refs is XYZ with scale 0.5.
50 Refinement(int index, const std::initializer_list<ScaledType> &refs);
51 /// Refine element with a single type and scale in all dimensions.
52 Refinement(int index, char type, real_t scale = 0.5);
53 /// Return the type as char.
54 char GetType() const;
55 /// Set the element, type, and scale.
56 void Set(int element, char type,
57 real_t scale = 0.5); /// Uses @a scale in all dimensions
58 /// Set the type and scale, assuming the element is already set.
59 void SetType(char type,
60 real_t scale = 0.5); /// Uses @a scale in all dimensions
61 /// Set the scale in the directions for the currently set type.
62 void SetScaleForType(const real_t *scale);
63private :
64 void SetScale(const ScaledType &ref);
65};
66
67/// Defines the position of a fine element within a coarse element.
69{
70 /// Coarse %Element index in the coarse mesh.
71 int parent;
72
73 /** The (geom, matrix) pair determines the sub-element transformation for the
74 fine element: CoarseFineTransformations::point_matrices[geom](matrix) is
75 the point matrix of the region within the coarse element reference
76 domain.*/
77 unsigned geom : 4;
78 unsigned matrix : 27;
79
80 /// For internal use: 0 if regular fine element, 1 if parallel ghost element.
81 unsigned ghost : 1;
82
83 Embedding() = default;
84 Embedding(int elem, Geometry::Type geom, int matrix = 0, bool ghost = false)
85 : parent(elem), geom(geom), matrix(matrix), ghost(ghost) {}
86};
87
88/// Defines the coarse-fine transformations of all fine elements.
90{
91 /// Fine element positions in their parents.
93
94 /** A "dictionary" of matrices for IsoparametricTransformation. Use
95 Embedding::{geom,matrix} to access a fine element point matrix. */
97
98 /** Invert the 'embeddings' array: create a Table with coarse elements as
99 rows and fine elements as columns. If 'want_ghosts' is false, parallel
100 ghost fine elements are not included in the table. */
101 void MakeCoarseToFineTable(Table &coarse_to_fine,
102 bool want_ghosts = false) const;
103
104 void Clear();
105 bool IsInitialized() const;
106 long MemoryUsage() const;
107
108 MFEM_DEPRECATED
109 void GetCoarseToFineMap(const Mesh &fine_mesh, Table &coarse_to_fine) const
110 { MakeCoarseToFineTable(coarse_to_fine, true); (void) fine_mesh; }
111};
112
113void Swap(CoarseFineTransformations &a, CoarseFineTransformations &b);
114
115struct MatrixMap; // for internal use
116
117/** \brief A class for non-conforming AMR. The class is not used directly by the
118 * user, rather it is an extension of the Mesh class.
119 *
120 * In general, the class is used by MFEM as follows:
121 *
122 * 1. NCMesh is constructed from elements of an existing Mesh. The elements are
123 * copied and become roots of the refinement hierarchy.
124 *
125 * 2. Some elements are refined with the Refine() method. Both isotropic and
126 * anisotropic refinements of quads/hexes are supported.
127 *
128 * 3. A new Mesh is created from NCMesh containing the leaf elements. This new
129 * Mesh may have non-conforming (hanging) edges and faces and is the one
130 * seen by the user.
131 *
132 * 4. FiniteElementSpace asks NCMesh for a list of conforming, master and slave
133 * edges/faces and creates the conforming interpolation matrix P.
134 *
135 * 5. A continuous/conforming solution is obtained by solving P'*A*P x = P'*b.
136 *
137 * 6. Repeat from step 2.
138 */
140{
141protected:
142 NCMesh() = default;
143public:
144 //// Initialize with elements from an existing Mesh.
145 explicit NCMesh(const Mesh *mesh);
146
147 /** Load from a stream. The id header is assumed to have been read already
148 from \param[in] input . \param[in] version is 10 for the v1.0 NC format,
149 or 1 for the legacy v1.1 format. \param[out] curved is set to 1 if the
150 curvature GridFunction follows after mesh data. \param[out] is_nc (again
151 treated as a boolean) is set to 0 if the legacy v1.1 format in fact
152 defines a conforming mesh. See Mesh::Loader for details. */
153 NCMesh(std::istream &input, int version, int &curved, int &is_nc);
154
155 /// Deep copy of another instance.
156 NCMesh(const NCMesh &other);
157
158 /// Copy assignment not supported
160
161 virtual ~NCMesh();
162
163 /// Return the dimension of the NCMesh.
164 int Dimension() const { return Dim; }
165 /// Return the space dimension of the NCMesh.
166 int SpaceDimension() const { return spaceDim; }
167
168 /// Return the number of vertices in the NCMesh.
169 int GetNVertices() const { return NVertices; }
170 /// Return the number of edges in the NCMesh.
171 int GetNEdges() const { return NEdges; }
172 /// Return the number of (2D) faces in the NCMesh.
173 int GetNFaces() const { return NFaces; }
174 virtual int GetNGhostElements() const { return 0; }
175
176 /** Perform the given batch of refinements. Please note that in the presence
177 of anisotropic splits additional refinements may be necessary to keep the
178 mesh consistent. However, the function always performs at least the
179 requested refinements. */
180 virtual void Refine(const Array<Refinement> &refinements);
181
182 /** Check the mesh and potentially refine some elements so that the maximum
183 difference of refinement levels between adjacent elements is not greater
184 than 'max_nc_level'. */
185 virtual void LimitNCLevel(int max_nc_level);
186
187 /** Return a list of derefinement opportunities. Each row of the table
188 contains Mesh indices of existing elements that can be derefined to form
189 a single new coarse element. Row numbers are then passed to Derefine.
190 This function works both in serial and parallel. */
192
193 /** Check derefinements returned by GetDerefinementTable and mark those that
194 can be done safely so that the maximum NC level condition is not
195 violated. On return, level_ok.Size() == deref_table.Size() and contains
196 0/1s. */
197 virtual void CheckDerefinementNCLevel(const Table &deref_table,
198 Array<int> &level_ok, int max_nc_level);
199
200 /** Perform a subset of the possible derefinements (see
201 GetDerefinementTable). Note that if anisotropic refinements are present
202 in the mesh, some of the derefinements may have to be skipped to preserve
203 mesh consistency. */
204 virtual void Derefine(const Array<int> &derefs);
205
206 // master/slave lists
207
208 /// Identifies a vertex/edge/face in both Mesh and NCMesh.
209 struct MeshId
210 {
211 int index; ///< Mesh number
212 int element; ///< NCMesh::Element containing this vertex/edge/face
213 signed char local; ///< local number within 'element'
214 signed char geom; ///< Geometry::Type (faces only) (char to save RAM)
215
217
218 MeshId() = default;
219 MeshId(int index, int element, int local, int geom = -1)
221 };
222
223 /** Nonconforming edge/face that has more than one neighbor. The neighbors
224 are stored in NCList::slaves[i], slaves_begin <= i < slaves_end. */
225 struct Master : public MeshId
226 {
227 int slaves_begin, slaves_end; ///< slave faces
228
229 Master() = default;
230 Master(int index, int element, int local, int geom, int sb, int se)
232 , slaves_begin(sb), slaves_end(se) {}
233 };
234
235 /// Nonconforming edge/face within a bigger edge/face.
236 struct Slave : public MeshId
237 {
238 int master; ///< master number (in Mesh numbering)
239 unsigned matrix : 24; ///< index into NCList::point_matrices[geom]
240 unsigned edge_flags : 8; ///< orientation flags, see OrientedPointMatrix
241
242 Slave() = default;
243 Slave(int index, int element, int local, int geom)
245 , master(-1), matrix(0), edge_flags(0) {}
246 };
247
248
249 /// Lists all edges/faces in the nonconforming mesh.
250 struct NCList
251 {
252 Array<MeshId> conforming; ///< All MeshIds corresponding to conformal faces
253 Array<Master> masters; ///< All MeshIds corresponding to master faces
254 Array<Slave> slaves; ///< All MeshIds corresponding to slave faces
255
256 /// List of unique point matrices for each slave geometry.
258
259 void OrientedPointMatrix(const Slave &slave,
260 DenseMatrix &oriented_matrix) const;
261
262 /// Particular MeshId type, used for allowing static casting to the
263 /// appropriate child type after searching the NCList. UNRECOGNIZED
264 /// denotes that an instance is not known within the NCList, meaning that
265 /// it does not play a part in NC mechanics. This can be because the index
266 /// did not exist in the original Mesh, or because the entry is a boundary
267 /// face, whose NC status is always conforming.
269
270 /// Helper storing a reference to a MeshId type, and the face type it can
271 /// be cast to
273 {
274 const MeshId * const id; ///< Pointer to a possible MeshId, nullptr if not found
275 /// MeshIdType corresponding to the MeshId. UNRECOGNIZED if unfound.
277 };
278 /// Return a mesh id and type for a given nc index.
280
281 /// Return a face type for a given nc index.
282 MeshIdType GetMeshIdType(int index) const;
283
284 /// Given an index, check if this is a certain face type.
285 bool CheckMeshIdType(int index, MeshIdType type) const;
286
287 /// Erase the contents of the conforming, master and slave arrays.
288 void Clear();
289 /// Whether the NCList is empty.
290 bool Empty() const
291 {
292 return conforming.Size() == 0
293 && masters.Size() == 0
294 && slaves.Size() == 0;
295 }
296 /// The total size of the component arrays in the NCList.
297 long TotalSize() const
298 {
299 return conforming.Size() + masters.Size() + slaves.Size();
300 }
301 /// The memory usage of the three public arrays. Does not account for the
302 /// inverse index.
303 long MemoryUsage() const;
304 ~NCList() { Clear(); }
305 private:
306 // Check for existence or construct the inv_index list map if necessary.
307 // const because only modifies the mutable member inv_index.
308 void BuildIndex() const;
309
310 /// A lazily constructed map from index to MeshId. Built whenever
311 /// GetMeshIdAndType, GetMeshIdType or CheckMeshIdType is called for the
312 /// first time. The MeshIdType is stored with, to enable casting to Slave
313 /// or Master elements appropriately.
314 mutable std::unordered_map<int, std::pair<MeshIdType, int>> inv_index;
315 };
316
317
318 /// Return the current list of conforming and nonconforming faces.
320 {
321 if (face_list.Empty()) { BuildFaceList(); }
322 return face_list;
323 }
324
325 /// Return the current list of conforming and nonconforming edges.
327 {
328 if (edge_list.Empty()) { BuildEdgeList(); }
329 return edge_list;
330 }
331
332 /** Return a list of vertices (in 'conforming'); this function is provided
333 for uniformity/completeness. Needed in ParNCMesh/ParFESpace. */
335 {
336 if (vertex_list.Empty()) { BuildVertexList(); }
337 return vertex_list;
338 }
339
340 /// Return vertex/edge/face list (entity = 0/1/2, respectively).
341 const NCList& GetNCList(int entity)
342 {
343 switch (entity)
344 {
345 case 0: return GetVertexList();
346 case 1: return GetEdgeList();
347 default: return GetFaceList();
348 }
349 }
350
351
352 // coarse/fine transforms
353
354 /** Remember the current layer of leaf elements before the mesh is refined.
355 Needed by GetRefinementTransforms(), must be called before Refine(). */
356 void MarkCoarseLevel();
357
358 /** After refinement, calculate the relation of each fine element to its
359 parent coarse element. Note that Refine() or LimitNCLevel() can be called
360 multiple times between MarkCoarseLevel() and this function. */
362
363 /** After derefinement, calculate the relations of previous fine elements
364 (some of which may no longer exist) to the current leaf elements. Unlike
365 for refinement, Derefine() may only be called once before this function
366 so there is no MarkFineLevel(). */
368
369 /// Free all internal data created by the above three functions.
370 void ClearTransforms();
371
372
373 // grid ordering
374
375 /** Return a space filling curve for a rectangular grid of elements.
376 Implemented is a generalized Hilbert curve for arbitrary grid dimensions.
377 If the width is odd, height should be odd too, otherwise one diagonal
378 (vertex-neighbor) step cannot be avoided in the curve. Even dimensions
379 are recommended. */
380 static void GridSfcOrdering2D(int width, int height,
381 Array<int> &coords);
382
383 /** Return a space filling curve for a 3D rectangular grid of elements. The
384 Hilbert-curve-like algorithm works well for even dimensions. For odd
385 width/height/depth it tends to produce some diagonal (edge-neighbor)
386 steps. Even dimensions are recommended. */
387 static void GridSfcOrdering3D(int width, int height, int depth,
388 Array<int> &coords);
389
390
391 // utility
392
393 /// Return Mesh vertex indices of an edge identified by 'edge_id'.
394 void GetEdgeVertices(const MeshId &edge_id, int vert_index[2],
395 bool oriented = true) const;
396
397 /** Return "NC" orientation of an edge. As opposed to standard Mesh edge
398 orientation based on vertex IDs, "NC" edge orientation follows the local
399 edge orientation within the element 'edge_id.element' and is thus
400 processor independent. TODO: this seems only partially true? */
401 int GetEdgeNCOrientation(const MeshId &edge_id) const;
402
403 /** Return Mesh vertex and edge indices of a face identified by 'face_id'.
404 The return value is the number of face vertices. */
405 int GetFaceVerticesEdges(const MeshId &face_id,
406 int vert_index[4], int edge_index[4],
407 int edge_orientation[4]) const;
408
409 /** Given an edge (by its vertex indices v1 and v2) return the first
410 (geometric) parent edge that exists in the Mesh or -1 if there is no such
411 parent. */
412 int GetEdgeMaster(int v1, int v2) const;
413
414 /** Get a list of vertices (2D/3D), edges (3D) and faces (3D) that coincide
415 with boundary elements with the specified attributes (marked in
416 'bdr_attr_is_ess'). In 3D this function also reveals "hidden" boundary
417 edges. In parallel it helps identifying boundary vertices/edges/faces
418 affected by non-local boundary elements. Hidden faces can occur for an
419 internal boundary coincident to a processor boundary.
420 */
421
422 /**
423 * @brief Get a list of vertices (2D/3D), edges (3D) and faces (3D) that
424 * coincide with boundary elements with the specified attributes (marked in
425 * 'bdr_attr_is_ess').
426 *
427 * @details In 3D this function also reveals "hidden" boundary edges. In
428 * parallel it helps identifying boundary vertices/edges/faces affected by
429 * non-local boundary elements. Hidden faces can occur for an internal
430 * boundary coincident to a processor boundary.
431 *
432 * @param bdr_attr_is_ess Indicator if a given attribute is essential.
433 * @param bdr_vertices Array of vertices that are essential.
434 * @param bdr_edges Array of edges that are essential.
435 * @param bdr_faces Array of faces that are essential.
436 */
437 virtual void GetBoundaryClosure(const Array<int> &bdr_attr_is_ess,
438 Array<int> &bdr_vertices,
439 Array<int> &bdr_edges, Array<int> &bdr_faces);
440
441 /// Return element geometry type. @a index is the Mesh element number.
444
445 /// Return face geometry type. @a index is the Mesh face number.
448
449 /// Return the number of root elements.
451
452 /// Return the distance of leaf @a i from the root.
453 int GetElementDepth(int i) const;
454
455 /** Return the size reduction compared to the root element (ignoring local
456 stretching and curvature). */
457 int GetElementSizeReduction(int i) const;
458
459 /// Return the faces and face attributes of leaf element @a i.
461 Array<int> &fattr) const;
462
463 /// Set the attribute of leaf element @a i, which is a Mesh element index.
464 void SetAttribute(int i, int attr)
465 { elements[leaf_elements[i]].attribute = attr; }
466
467 /** I/O: Print the mesh in "MFEM NC mesh v1.0" format. If @a comments is
468 non-empty, it will be printed after the first line of the file, and each
469 line should begin with '#'. */
470 void Print(std::ostream &out, const std::string &comments = "") const;
471
472 /// I/O: Return true if the mesh was loaded from the legacy v1.1 format.
473 bool IsLegacyLoaded() const { return Legacy; }
474
475 /// I/O: Return a map from old (v1.1) vertex indices to new vertex indices.
476 void LegacyToNewVertexOrdering(Array<int> &order) const;
477
478 /// Save memory by releasing all non-essential and cached data.
479 virtual void Trim();
480
481 /// Return total number of bytes allocated.
482 long MemoryUsage() const;
483
484 int PrintMemoryDetail() const;
485
486 using RefCoord = std::int64_t;
487
488 static constexpr int MaxElemNodes =
489 8; ///< Number of nodes an element can have
490 static constexpr int MaxElemEdges =
491 12; ///< Number of edges an element can have
492 static constexpr int MaxElemFaces =
493 6; ///< Number of faces an element can have
494 static constexpr int MaxElemChildren =
495 10; ///< Number of children an element can have
496 static constexpr int MaxFaceNodes =
497 4; ///< Number of faces an element can have
498
499 /**
500 * @brief Given a node index, return the vertex index associated
501 *
502 * @param node
503 * @return int
504 */
505 int GetNodeVertex(int node) { return nodes[node].vert_index; }
506
507protected: // non-public interface for the Mesh class
508
509 friend class Mesh;
510
511 /// Fill Mesh::{vertices,elements,boundary} for the current finest level.
512 void GetMeshComponents(Mesh &mesh) const;
513
514 /** Get edge and face numbering from 'mesh' (i.e., set all Edge::index and
515 Face::index) after a new mesh was created from us. */
516 void OnMeshUpdated(Mesh *mesh);
517
518 /** Delete top-level vertex coordinates if the Mesh became curved, e.g., by
519 calling Mesh::SetCurvature or otherwise setting the Nodes. */
521
522protected: // implementation
523
524 int Dim, spaceDim; ///< dimensions of the elements and the vertex coordinates
525 int MyRank; ///< used in parallel, or when loading a parallel file in serial
526 bool Iso; ///< true if the mesh only contains isotropic refinements
527 int Geoms; ///< bit mask of element geometries present, see InitGeomFlags()
528 bool Legacy; ///< true if the mesh was loaded from the legacy v1.1 format
529
530
531 /** A Node can hold a vertex, an edge, or both. Elements directly point to
532 their corner nodes, but edge nodes also exist and can be accessed using a
533 hash-table given their two end-point node IDs. All nodes can be accessed
534 in this way, with the exception of top-level vertex nodes. When an
535 element is being refined, the mid-edge nodes are readily available with
536 this mechanism. The new elements "sign in" to the nodes by increasing the
537 reference counts of their vertices and edges. The parent element "signs
538 off" its nodes by decrementing the ref counts. */
539 struct Node : public Hashed2
540 {
543
545 scale(0.5), scaleSet(false) {}
546 ~Node();
547
548 bool HasVertex() const { return vert_refc > 0; }
549 bool HasEdge() const { return edge_refc > 0; }
550
551 // decrease vertex/edge ref count, return false if Node should be deleted
552 bool UnrefVertex() { --vert_refc; return vert_refc || edge_refc; }
553 bool UnrefEdge() { --edge_refc; return vert_refc || edge_refc; }
554
555 real_t GetScale() const { return scale; }
556 void SetScale(real_t s, bool overwrite = false);
557
558 private:
559 real_t scale; ///< Scale from struct Refinement, default 0.5
560 bool scaleSet; ///< Indicates whether scale is set and cannot be changed
561#ifdef MFEM_USE_DOUBLE
562 static constexpr real_t scaleTol = 1.0e-8; ///< Scale comparison tolerance
563#else
564 static constexpr real_t scaleTol = 1.0e-5; ///< Scale comparison tolerance
565#endif
566 };
567
568 /** Similarly to nodes, faces can be accessed by hashing their four vertex
569 node IDs. A face knows about the one or two elements that are using it. A
570 face that is not on the boundary and only has one element referencing it
571 is either a master or a slave face. */
572 struct Face : public Hashed4
573 {
574 int attribute; ///< boundary element attribute, -1 if internal face
575 int index; ///< face number in the Mesh
576 int elem[2]; ///< up to 2 elements sharing the face
577
578 Face() : attribute(-1), index(-1) { elem[0] = elem[1] = -1; }
579
580 bool Boundary() const { return attribute >= 0; }
581 bool Unused() const { return elem[0] < 0 && elem[1] < 0; }
582
583 // add or remove an element from the 'elem[2]' array
584 void RegisterElement(int e);
585 void ForgetElement(int e);
586
587 /// Return one of elem[0] or elem[1] and make sure the other is -1.
588 int GetSingleElement() const;
589 int GetAttribute() const { return attribute; }
590 };
591
592 /** This is an element in the refinement hierarchy. Each element has either
593 been refined and points to its children, or is a leaf and points to its
594 vertex nodes. */
595 struct Element
596 {
597 char geom; ///< Geometry::Type of the element (char for storage only)
598 char ref_type; ///< bit mask of X,Y,Z refinements (bits 0,1,2 respectively)
599 char tet_type; ///< tetrahedron split type, currently always 0
600 char flag; ///< generic flag/marker, can be used by algorithms
601 int index; ///< element number in the Mesh, -1 if refined
602 int rank; ///< processor number (ParNCMesh), -1 if undefined/unknown
604 union
605 {
606 int node[MaxElemNodes]; ///< element corners (if ref_type == 0)
607 int child[MaxElemChildren]; ///< 2-10 children (if ref_type != 0)
608 };
609 int parent; ///< parent element, -1 if this is a root element, -2 if free'd
610 Element(Geometry::Type geom, int attr);
611
613 bool IsLeaf() const { return !ref_type && (parent != -2); }
614 int GetAttribute() const { return attribute; }
615 };
616
617
618 // primary data
619 HashTable<Node> nodes; // associative container holding all Nodes
620 HashTable<Face> faces; // associative container holding all Faces
621
622 bool using_scaling = false; // Whether Node::scale is being used
623
624 BlockArray<Element> elements; // storage for all Elements
625 Array<int> free_element_ids; // unused element ids - indices into 'elements'
626public:
627 /**
628 * @brief The number of Nodes.
629 *
630 * @return int
631 */
632 int GetNumNodes() const { return nodes.Size(); }
633 /**
634 * @brief Access a Node
635 *
636 * @param i Index of the node
637 * @return const Node&
638 */
639 const Node& GetNode(int i) const {return nodes[i]; }
640 /**
641 * @brief The number of faces
642 *
643 * @return int
644 */
645 int GetNumFaces() const { return faces.Size(); }
646 /**
647 * @brief Access a Face
648 *
649 * @param i Index of the face
650 * @return const Face&
651 */
652 const Face& GetFace(int i) const {return faces[i]; }
653 /**
654 * @brief The number of elements
655 *
656 * @return int
657 */
658 int GetNumElements() const { return elements.Size(); }
659 /**
660 * @brief Access an Element
661 *
662 * @param i Index of the element
663 * @return const Element&
664 */
665 const Element& GetElement(int i) const { return elements[i]; }
666
667 /**
668 * @brief Given a set of nodes defining a face, traverse the nodes structure
669 * to find the nodes that make up the parent face and replace the input nodes
670 * with the parent nodes. Additionally return the child index that the child
671 * face would be, relative to the discovered parent face.
672 * @details This method is concerned with the construction of an NCMesh
673 * structure for a d-1 manifold of an existing NCMesh. It forms a key element
674 * in a leaf -> root traversal of the parent ncmesh elements structure.
675 *
676 * @param[out] nodes The collection of nodes whose parent we are searching
677 * for
678 * @return int The child index corresponding to placing the face for the
679 * original nodes within the face defined by the returned parent nodes. If
680 * child index is -1, then the face is made up of root nodes, and nodes is
681 * unchanged.
682 */
683 int ParentFaceNodes(std::array<int, 4> &nodes) const;
684
685 /**
686 * @brief Method for finding the nodes associated to a @a face
687 * @return Nodes making up the face
688 */
689 std::array<int, 4> FindFaceNodes(int face) const;
690 std::array<int, 4> FindFaceNodes(const Face &fa) const;
691 /**
692 * @brief Backwards compatible method for finding the @a node associated to a
693 * @a face
694 */
695 MFEM_DEPRECATED void FindFaceNodes(int face, int node[4]) const;
696protected:
697
698 /** Initial traversal state (~ element orientation) for each root element
699 NOTE: M = root_state.Size() is the number of root elements. NOTE: the
700 first M items of 'elements' is the coarse mesh. */
702
703 /** Coordinates of top-level vertices (organized as triples). If empty, the
704 Mesh is curved (Nodes != NULL) and NCMesh is topology-only. */
706
707 // secondary data
708 /** Apart from the primary data structure, which is the element/node/face
709 hierarchy, there is secondary data that is derived from the primary data
710 and needs to be updated when the primary data changes. Update() takes
711 care of that and needs to be called after each refinement and
712 derefinement. */
713 virtual void Update();
714
715 // set by UpdateLeafElements, UpdateVertices and OnMeshUpdated
717
718 // NOTE: the serial code understands the bare minimum about ghost elements
719 // and other ghost entities in order to be able to load parallel partial
720 // meshes
722
723 Array<int> leaf_elements; ///< finest elements, in Mesh ordering (+ ghosts)
724 Array<int> leaf_sfc_index; ///< natural tree ordering of leaf elements
725 Array<int> vertex_nodeId; ///< vertex-index to node-id map, see UpdateVertices
726
727 NCList face_list; ///< lazy-initialized list of faces, see GetFaceList
728 NCList edge_list; ///< lazy-initialized list of edges, see GetEdgeList
729 NCList vertex_list; ///< lazy-initialized list of vertices, see GetVertexList
730
731 Array<int> boundary_faces; ///< subset of all faces, set by BuildFaceList
732 Array<char> face_geom; ///< face geometry by face index, set by OnMeshUpdated
733
734 Table element_vertex; ///< leaf-element to vertex table, see FindSetNeighbors
735
736 /// Update the leaf elements indices in leaf_elements
737 void UpdateLeafElements();
738
739 /** @brief This method assigns indices to vertices (Node::vert_index) that
740 will be seen by the Mesh class and the rest of MFEM.
741
742 We must be careful to:
743 1. Stay compatible with the conforming code, which expects top-level
744 (original) vertices to be indexed first, otherwise GridFunctions
745 defined on a conforming mesh would no longer be valid when the mesh is
746 converted to an NC mesh.
747
748 2. Make sure serial NCMesh is compatible with the parallel ParNCMesh, so
749 it is possible to read parallel partial solutions in serial code
750 (e.g., serial GLVis). This means handling ghost elements, if present.
751
752 3. Assign vertices in a globally consistent order for parallel meshes: if
753 two vertices i,j are shared by two ranks r1,r2, and i<j on r1, then
754 i<j on r2 as well. This is true for top-level vertices but also for
755 the remaining shared vertices thanks to the globally consistent SFC
756 ordering of the leaf elements. This property reduces communication and
757 simplifies ParNCMesh. */
758 void UpdateVertices(); ///< update Vertex::index and vertex_nodeId
759
760 /** Collect the leaf elements in leaf_elements, and the ghost elements in
761 ghosts. Compute and set the element indices of @a elements. On quad and
762 hex refined elements tries to order leaf elements along a space-filling
763 curve according to the given @a state variable. */
764 void CollectLeafElements(int elem, int state, Array<int> &ghosts,
765 int &counter);
766
767 /** Try to find a space-filling curve friendly orientation of the root
768 elements: set 'root_state' based on the ordering of coarse elements. Note
769 that the coarse mesh itself must be ordered as an SFC by e.g.
770 Mesh::GetGeckoElementOrdering. */
771 void InitRootState(int root_count);
772
773 /** Compute the Geometry::Type present in the root elements (coarse elements)
774 and set @a Geoms bitmask accordingly. */
775 void InitGeomFlags();
776
777 /// Return true if the mesh contains prism elements.
778 bool HavePrisms() const { return Geoms & (1 << Geometry::PRISM); }
779
780 /// Return true if the mesh contains pyramid elements.
781 bool HavePyramids() const { return Geoms & (1 << Geometry::PYRAMID); }
782
783 /// Return true if the mesh contains tetrahedral elements.
784 bool HaveTets() const { return Geoms & (1 << Geometry::TETRAHEDRON); }
785
786 /// Return true if the Element @a el is a ghost element.
787 bool IsGhost(const Element &el) const { return el.rank != MyRank; }
788
789 // refinement/derefinement
790
791 Array<Refinement> ref_stack; ///< stack of scheduled refinements (temporary)
792 HashTable<Node> shadow; ///< temporary storage for reparented nodes
793 Array<Triple<int, int, int> > reparents; ///< scheduled node reparents (tmp)
794 Array<real_t> reparent_scale; ///< scale associated with reparents (tmp)
795
796 Table derefinements; ///< possible derefinements, see GetDerefinementTable
797
798
799 /// Refine the element @a elem with the refinement type @a ref_type.
800 void RefineElement(int elem, char ref_type);
801
802 /// Refine one element with type and scale specified by @a ref.
803 void RefineElement(const Refinement & ref);
804
805 /// Derefine the element @a elem, does nothing on leaf elements.
806 void DerefineElement(int elem);
807
808 /// Helper function to set scale for a node with parents @a p0, @a p1.
809 void SetNodeScale(int p0, int p1, real_t scale);
810
811 /// Add an Element @a el to the NCMesh, optimized to reuse freed elements.
812 int AddElement(const Element &el)
813 {
815 {
816 int idx = free_element_ids.Last();
818 elements[idx] = el;
819 return idx;
820 }
821 return elements.Append(el);
822 }
823 int AddElement(Geometry::Type geom, int attr) { return AddElement(Element(geom,attr)); }
824
825 // Free the element with index @a id.
826 void FreeElement(int id)
827 {
829 elements[id].ref_type = 0;
830 elements[id].parent = -2; // mark the element as free
831 }
832
833 int NewHexahedron(int n0, int n1, int n2, int n3,
834 int n4, int n5, int n6, int n7, int attr,
835 int fattr0, int fattr1, int fattr2,
836 int fattr3, int fattr4, int fattr5);
837
838 int NewWedge(int n0, int n1, int n2,
839 int n3, int n4, int n5, int attr,
840 int fattr0, int fattr1,
841 int fattr2, int fattr3, int fattr4);
842
843 int NewTetrahedron(int n0, int n1, int n2, int n3, int attr,
844 int fattr0, int fattr1, int fattr2, int fattr3);
845
846 int NewPyramid(int n0, int n1, int n2, int n3, int n4, int attr,
847 int fattr0, int fattr1, int fattr2, int fattr3,
848 int fattr4);
849
850 int NewQuadrilateral(int n0, int n1, int n2, int n3, int attr,
851 int eattr0, int eattr1, int eattr2, int eattr3);
852
853 int NewTriangle(int n0, int n1, int n2,
854 int attr, int eattr0, int eattr1, int eattr2);
855
856 int NewSegment(int n0, int n1, int attr, int vattr1, int vattr2);
857
858 mfem::Element* NewMeshElement(int geom) const;
859
860 /**
861 * @brief Given a quad face defined by four vertices, establish which edges
862 * of this face have been split, and if so optionally return the mid points
863 * of those edges.
864 *
865 * @param n1 The first node defining the face
866 * @param n2 The second node defining the face
867 * @param n3 The third node defining the face
868 * @param n4 The fourth node defining the face
869 * @param s returns the scale of the split
870 * @param mid optional return of the edge mid points.
871 * @return int 0 -- no split, 1 -- "vertical" split, 2 -- "horizontal" split
872 */
873 int QuadFaceSplitType(int n1, int n2, int n3, int n4, real_t & s,
874 int mid[5] = NULL /*optional output of mid-edge nodes*/) const;
875
876 /**
877 * @brief Given a tri face defined by three vertices, establish whether the
878 * edges that make up this face have been split, and if so optionally return
879 * the midpoints.
880 * @details This is a necessary condition for this face to have been split,
881 * but is not sufficient. Consider a triangle attached to three refined
882 * triangles, in this scenario all edges can be split but this face not be
883 * split. In this case, it is necessary to check if there is a face made up
884 * of the returned midpoint nodes.
885 *
886 * @param n1 The first node defining the face
887 * @param n2 The second node defining the face
888 * @param n3 The third node defining the face
889 * @param mid optional return of the edge mid points.
890 * @return true Splits for all edges have been found
891 * @return false
892 */
893 bool TriFaceSplit(int n1, int n2, int n3, int mid[3] = NULL) const;
894
895 /**
896 * @brief Determine if a Triangle face is a master face
897 * @details This check requires looking for the edges making up the triangle
898 * being split, if nodes exist at their midpoints, and there are vertices at
899 * them, this implies the face COULD be split. To determine if it is, we then
900 * check whether these midpoints have all been connected, this is required to
901 * discriminate between an internal master face surrounded by nonconformal
902 * refinements and a conformal boundary face surrounded by refinements.
903 *
904 * @param n1 The first node defining the face
905 * @param n2 The second node defining the face
906 * @param n3 The third node defining the face
907 * @return true The face is a master
908 * @return false The face is not a master
909 */
910 inline bool TriFaceIsMaster(int n1, int n2, int n3) const
911 {
912 int mid[3];
913 return !(!TriFaceSplit(n1, n2, n3, mid) // The edges aren't split
914 // OR none of the midpoints are connected.
915 || (nodes.FindId(mid[0], mid[1]) < 0 &&
916 nodes.FindId(mid[0], mid[2]) < 0 &&
917 nodes.FindId(mid[1], mid[2]) < 0));
918 }
919
920 /**
921 * @brief Determine if a Quad face is a master face
922 *
923 * @param n1 The first node defining the face
924 * @param n2 The second node defining the face
925 * @param n3 The third node defining the face
926 * @param n4 The fourth node defining the face
927 * @return true The quad face is a master face
928 * @return false The quad face is not a master face
929 */
930 inline bool QuadFaceIsMaster(int n1, int n2, int n3, int n4) const
931 {
932 real_t s;
933 return QuadFaceSplitType(n1, n2, n3, n4, s) != 0;
934 }
935
936 void ForceRefinement(int vn1, int vn2, int vn3, int vn4);
937
938 void FindEdgeElements(int vn1, int vn2, int vn3, int vn4,
939 Array<MeshId> &prisms) const;
940
941 void CheckAnisoPrism(int vn1, int vn2, int vn3, int vn4,
942 const Refinement *refs, int nref);
943
944 void CheckAnisoFace(int vn1, int vn2, int vn3, int vn4,
945 int mid12, int mid34, int level = 0);
946
947 void CheckIsoFace(int vn1, int vn2, int vn3, int vn4,
948 int en1, int en2, int en3, int en4, int midf);
949
950 void ReparentNode(int node, int new_p1, int new_p2, real_t scale);
951
952 int FindMidEdgeNode(int node1, int node2) const;
953 int GetMidEdgeNode(int node1, int node2);
954
955 int GetMidFaceNode(int en1, int en2, int en3, int en4);
956
957 /**
958 * @brief Add references to all nodes, edges and faces of the element
959 *
960 * @param elem index into elements
961 */
962 void ReferenceElement(int elem);
963 void UnreferenceElement(int elem, Array<int> &elemFaces);
964
965 Face* GetFace(Element &elem, int face_no);
966 void RegisterFaces(int elem, int *fattr = NULL);
967 void DeleteUnusedFaces(const Array<int> &elemFaces);
968
969 void CollectDerefinements(int elem, Array<Connection> &list);
970
971 /// Return el.node[index] correctly, even if the element is refined.
972 int RetrieveNode(const Element &el, int index);
973
974 /// Extended version of find_node: works if 'el' is refined.
975 int FindNodeExt(const Element &el, int node, bool abort = true);
976
977
978 // face/edge lists
979
980 static int find_node(const Element &el, int node);
981 static int find_element_edge(const Element &el, int vn0, int vn1,
982 bool abort = true);
983 static int find_local_face(int geom, int a, int b, int c);
984
985 struct Point;
986 struct PointMatrix;
987
988 int ReorderFacePointMat(int v0, int v1, int v2, int v3,
989 int elem, const PointMatrix &pm,
990 PointMatrix &reordered) const;
991
992 void TraverseQuadFace(int vn0, int vn1, int vn2, int vn3,
993 const PointMatrix& pm, int level, Face* eface[4],
994 MatrixMap &matrix_map);
996 {
997 bool unsplit; ///< Whether this face has no further splits.
998 bool ghost_neighbor; ///< Whether the face neighbor is a ghost.
999 };
1000 TriFaceTraverseResults TraverseTriFace(int vn0, int vn1, int vn2,
1001 const PointMatrix& pm, int level,
1002 MatrixMap &matrix_map);
1003 void TraverseTetEdge(int vn0, int vn1, const Point &p0, const Point &p1,
1004 MatrixMap &matrix_map);
1005 void TraverseEdge(int vn0, int vn1, real_t t0, real_t t1, int flags,
1006 int level, MatrixMap &matrix_map);
1007
1008 virtual void BuildFaceList();
1009 virtual void BuildEdgeList();
1010 virtual void BuildVertexList();
1011
1012 virtual void ElementSharesFace(int elem, int local, int face) {} // ParNCMesh
1013 virtual void ElementSharesEdge(int elem, int local, int enode) {} // ParNCMesh
1014 virtual void ElementSharesVertex(int elem, int local, int vnode) {} // ParNCMesh
1015
1016 // neighbors / element_vertex table
1017
1018 /** Return all vertex-, edge- and face-neighbors of a set of elements. The
1019 neighbors are returned as a list (neighbors != NULL), as a set
1020 (neighbor_set != NULL), or both. The sizes of the set arrays must match
1021 that of leaf_elements. The function is intended to be used for large sets
1022 of elements and its complexity is linear in the number of leaf elements
1023 in the mesh. */
1024 void FindSetNeighbors(const Array<char> &elem_set,
1025 Array<int> *neighbors, /* append */
1026 Array<char> *neighbor_set = NULL);
1027
1028 /** Return all vertex-, edge- and face-neighbors of a single element. You can
1029 limit the number of elements being checked using 'search_set'. The
1030 complexity of the function is linear in the size of the search set.*/
1031 void FindNeighbors(int elem,
1032 Array<int> &neighbors, /* append */
1033 const Array<int> *search_set = NULL);
1034
1035 /** Expand a set of elements by all vertex-, edge- and face-neighbors. The
1036 output array 'expanded' will contain all items from 'elems' (provided
1037 they are in 'search_set') plus their neighbors. The neighbor search can
1038 be limited to the optional search set. The complexity is linear in the
1039 sum of the sizes of 'elems' and 'search_set'. */
1040 void NeighborExpand(const Array<int> &elems,
1041 Array<int> &expanded,
1042 const Array<int> *search_set = NULL);
1043
1044
1045 void CollectEdgeVertices(int v0, int v1, Array<int> &indices);
1046 void CollectTriFaceVertices(int v0, int v1, int v2, Array<int> &indices);
1047 void CollectQuadFaceVertices(int v0, int v1, int v2, int v3,
1048 Array<int> &indices);
1050
1055
1056 int GetVertexRootCoord(int elem, RefCoord coord[3]) const;
1057 void CollectIncidentElements(int elem, const RefCoord coord[3],
1058 Array<int> &list) const;
1059
1060 /** Return elements neighboring to a local vertex of element 'elem'. Only
1061 elements from within the same refinement tree ('cousins') are returned.
1062 Complexity is proportional to the depth of elem's refinement tree. */
1063 void FindVertexCousins(int elem, int local, Array<int> &cousins) const;
1064
1065
1066 // coarse/fine transformations
1067
1068 struct Point
1069 {
1070 int dim;
1072
1073 Point() { dim = 0; }
1074
1075 Point(const Point &) = default;
1076
1078 { dim = 1; coord[0] = x; }
1079
1081 { dim = 2; coord[0] = x; coord[1] = y; }
1082
1084 { dim = 3; coord[0] = x; coord[1] = y; coord[2] = z; }
1085
1086 Point(const Point& p0, const Point& p1, real_t s = 0.5)
1087 {
1088 dim = p0.dim;
1089 for (int i = 0; i < dim; i++)
1090 {
1091 coord[i] = ((1.0 - s) * p0.coord[i]) + (s * p1.coord[i]);
1092 }
1093 }
1094
1095 Point(const Point& p0, const Point& p1, const Point& p2, const Point& p3)
1096 {
1097 dim = p0.dim;
1098 MFEM_ASSERT(p1.dim == dim && p2.dim == dim && p3.dim == dim, "");
1099 for (int i = 0; i < dim; i++)
1100 {
1101 coord[i] = (p0.coord[i] + p1.coord[i] + p2.coord[i] + p3.coord[i])
1102 * 0.25;
1103 }
1104 }
1105
1106 Point& operator=(const Point& src)
1107 {
1108 dim = src.dim;
1109 for (int i = 0; i < dim; i++) { coord[i] = src.coord[i]; }
1110 return *this;
1111 }
1112 };
1113
1114 /** @brief The PointMatrix stores the coordinates of the slave face using the
1115 master face coordinate as reference.
1116
1117 In 2D, the point matrix has the orientation of the parent edge, so its
1118 columns need to be flipped when applying it, see
1119 ApplyLocalSlaveTransformation.
1120
1121 In 3D, the orientation part of Elem2Inf is encoded in the point matrix.
1122
1123 The following transformation gives the relation between the reference
1124 quad face coordinates (xi, eta) in [0,1]^2, and the fine quad face
1125 coordinates (x, y):
1126 x = a0*(1-xi)*(1-eta) + a1*xi*(1-eta) + a2*xi*eta + a3*(1-xi)*eta
1127 y = b0*(1-xi)*(1-eta) + b1*xi*(1-eta) + b2*xi*eta + b3*(1-xi)*eta
1128 */
1130 {
1131 int np;
1133
1134 PointMatrix() : np(0) {}
1135
1136 PointMatrix(const Point& p0, const Point& p1)
1137 { np = 2; points[0] = p0; points[1] = p1; }
1138
1139 PointMatrix(const Point& p0, const Point& p1, const Point& p2)
1140 { np = 3; points[0] = p0; points[1] = p1; points[2] = p2; }
1141
1142 PointMatrix(const Point& p0, const Point& p1, const Point& p2, const Point& p3)
1143 { np = 4; points[0] = p0; points[1] = p1; points[2] = p2; points[3] = p3; }
1144
1145 PointMatrix(const Point& p0, const Point& p1, const Point& p2,
1146 const Point& p3, const Point& p4)
1147 {
1148 np = 5;
1149 points[0] = p0; points[1] = p1; points[2] = p2;
1150 points[3] = p3; points[4] = p4;
1151 }
1152 PointMatrix(const Point& p0, const Point& p1, const Point& p2,
1153 const Point& p3, const Point& p4, const Point& p5)
1154 {
1155 np = 6;
1156 points[0] = p0; points[1] = p1; points[2] = p2;
1157 points[3] = p3; points[4] = p4; points[5] = p5;
1158 }
1159 PointMatrix(const Point& p0, const Point& p1, const Point& p2,
1160 const Point& p3, const Point& p4, const Point& p5,
1161 const Point& p6, const Point& p7)
1162 {
1163 np = 8;
1164 points[0] = p0; points[1] = p1; points[2] = p2; points[3] = p3;
1165 points[4] = p4; points[5] = p5; points[6] = p6; points[7] = p7;
1166 }
1167
1168 Point& operator()(int i) { return points[i]; }
1169 const Point& operator()(int i) const { return points[i]; }
1170
1171 bool operator==(const PointMatrix &pm) const;
1172
1173 void GetMatrix(DenseMatrix& point_matrix) const;
1174 };
1175
1183
1184 static const PointMatrix& GetGeomIdentity(Geometry::Type geom);
1185
1186 void GetPointMatrix(Geometry::Type geom, const char* ref_path,
1187 DenseMatrix& matrix) const;
1188
1189 using RefPathMap = std::map<std::string, int>;
1190
1191 void TraverseRefinements(int elem, int coarse_index,
1192 std::string &ref_path, RefPathMap &map) const;
1193
1194 /// storage for data returned by Get[De]RefinementTransforms()
1196
1197 /// state of leaf_elements before Refine(), set by MarkCoarseLevel()
1199
1200 void InitDerefTransforms();
1201 void SetDerefMatrixCodes(int parent, Array<int> &fine_coarse);
1202
1203 // vertex temporary data, used by GetMeshComponents
1205 {
1208 TmpVertex() : valid(false), visited(false) {}
1209 };
1210
1212
1213 const real_t *CalcVertexPos(int node) const;
1214
1215
1216 // utility
1217
1218 int GetEdgeMaster(int node) const;
1219
1220 /// Return directed scale in (0,1).
1221 inline real_t GetScale(real_t s, bool reverse) const
1222 { return reverse ? 1.0 - s : s; }
1223
1224 /**
1225 * @brief Return the number of splits of this edge that have occurred in the
1226 * NCMesh. If zero, this means the segment is not the master of any other
1227 * segments.
1228 *
1229 * @param vn1 The first vertex making up the segment
1230 * @param vn2 The second vertex making up the segment
1231 * @return int The depth of splits of this segment that are present in the
1232 * mesh.
1233 */
1234 int EdgeSplitLevel(int vn1, int vn2) const;
1235 /**
1236 * @brief Return the number of splits of this triangle that have occurred in
1237 * the NCMesh. If zero, this means the triangle is neither split, nor the
1238 * master of a split face.
1239 *
1240 * @param vn1 The first vertex making up the triangle
1241 * @param vn2 The second vertex making up the triangle
1242 * @param vn3 The third vertex making up the triangle
1243 * @return int The depth of splits of this triangle that are present in the
1244 * mesh.
1245 */
1246 int TriFaceSplitLevel(int vn1, int vn2, int vn3) const;
1247 /**
1248 * @brief Computes the number of horizontal and vertical splits of this quad
1249 * that have occurred in the NCMesh. If zero, this means the quad is not the
1250 * master of any other quad.
1251 *
1252 * @param vn1 The first vertex making up the quad
1253 * @param vn2 The second vertex making up the quad
1254 * @param vn3 The third vertex making up the quad
1255 * @param vn4 The fourth vertex making up the quad
1256 * @param h_level The number of "horizontal" splits of the quad
1257 * @param v_level The number of "vertical" splits of the quad
1258 */
1259 void QuadFaceSplitLevel(int vn1, int vn2, int vn3, int vn4,
1260 int& h_level, int& v_level) const;
1261 /**
1262 * @brief Returns the total number of splits of this quad that have occurred
1263 * in the NCMesh. If zero, this means the quad is not the master of any other
1264 * quad.
1265 * @details This is a convenience wrapper that sums the horizontal and
1266 * vertical levels from the full method.
1267 *
1268 * @param vn1 The first vertex making up the quad
1269 * @param vn2 The second vertex making up the quad
1270 * @param vn3 The third vertex making up the quad
1271 * @param vn4 The fourth vertex making up the quad
1272 * @return int The depth of splits of this triangle that are present in the
1273 * mesh. NB: An isotropic refinement has a level of 2, one horizontal split,
1274 * followed by a vertical split.
1275 */
1276 int QuadFaceSplitLevel(int vn1, int vn2, int vn3, int vn4) const;
1277
1278 void CountSplits(int elem, int splits[3]) const;
1279 void GetLimitRefinements(Array<Refinement> &refinements, int max_level);
1280
1281 // Checker helpers
1282
1284 {
1285 MFEM_VERIFY(geom == Geometry::SEGMENT ||
1286 geom == Geometry::TRIANGLE || geom == Geometry::SQUARE ||
1287 geom == Geometry::CUBE || geom == Geometry::PRISM ||
1288 geom == Geometry::PYRAMID || geom == Geometry::TETRAHEDRON,
1289 "Element type " << geom << " is not supported by NCMesh.");
1290 }
1291
1292
1293 // I/O
1294
1295 /// Print the "vertex_parents" section of the mesh file.
1296 int PrintVertexParents(std::ostream *out) const;
1297 /// Load the vertex parent hierarchy from a mesh file.
1298 void LoadVertexParents(std::istream &input);
1299
1300 /** Print the "boundary" section of the mesh file. If out == NULL, only
1301 return the number of boundary elements. */
1302 int PrintBoundary(std::ostream *out) const;
1303 /// Load the "boundary" section of the mesh file.
1304 void LoadBoundary(std::istream &input);
1305
1306 /// Print the "coordinates" section of the mesh file.
1307 void PrintCoordinates(std::ostream &out) const;
1308 /// Load the "coordinates" section of the mesh file.
1309 void LoadCoordinates(std::istream &input);
1310
1311 /// Count root elements and initialize root_state.
1312 void InitRootElements();
1313 /// Return the index of the last top-level node plus one.
1314 int CountTopLevelNodes() const;
1315 /// Return true if all root_states are zero.
1316 bool ZeroRootStates() const;
1317
1318 /// Load the element refinement hierarchy from a legacy mesh file.
1319 void LoadCoarseElements(std::istream &input);
1320 void CopyElements(int elem, const BlockArray<Element> &tmp_elements);
1321 /// Load the deprecated MFEM mesh v1.1 format for backward compatibility.
1322 void LoadLegacyFormat(std::istream &input, int &curved, int &is_nc);
1323
1324 // geometry
1325
1326 /// This holds in one place the constants about the geometries we support
1328 {
1329 int nv, ne, nf; // number of: vertices, edges, faces
1330 int edges[MaxElemEdges][2]; // edge vertices (up to 12 edges)
1331 int faces[MaxElemFaces][4]; // face vertices (up to 6 faces)
1332 int nfv[MaxElemFaces]; // number of face vertices
1333
1335 GeomInfo() : initialized(false) {}
1337 void InitGeom(Geometry::Type geom);
1338 };
1339
1341
1342#ifdef MFEM_DEBUG
1343public:
1344 void DebugLeafOrder(std::ostream &out) const;
1345 void DebugDump(std::ostream &out) const;
1346#endif
1347
1348 friend class ParNCMesh; // for ParNCMesh::ElementSet
1349 friend struct MatrixMap;
1350 friend struct PointMatrixHash;
1351 friend class NCSubMesh; // for faces, nodes
1352 friend class ParNCSubMesh; // for faces, nodes
1353};
1354
1355}
1356
1357#endif
int Size() const
Return the logical size of the array.
Definition array.hpp:147
void DeleteAll()
Delete the whole array.
Definition array.hpp:925
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Definition array.hpp:830
void DeleteLast()
Delete the last entry of the array.
Definition array.hpp:202
T & Last()
Return the last element in the array.
Definition array.hpp:863
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
Rank 3 tensor (array of matrices)
Abstract data type element.
Definition element.hpp:29
static const int NumGeom
Definition geom.hpp:46
Mesh data type.
Definition mesh.hpp:64
A class for non-conforming AMR. The class is not used directly by the user, rather it is an extension...
Definition ncmesh.hpp:140
int GetEdgeMaster(int v1, int v2) const
Definition ncmesh.cpp:5687
static constexpr int MaxElemEdges
Number of edges an element can have.
Definition ncmesh.hpp:490
static PointMatrix pm_tet_identity
Definition ncmesh.hpp:1179
void OnMeshUpdated(Mesh *mesh)
Definition ncmesh.cpp:2885
int GetNumFaces() const
The number of faces.
Definition ncmesh.hpp:645
int GetNodeVertex(int node)
Given a node index, return the vertex index associated.
Definition ncmesh.hpp:505
void GetElementFacesAttributes(int i, Array< int > &faces, Array< int > &fattr) const
Return the faces and face attributes of leaf element i.
Definition ncmesh.cpp:5722
static GeomInfo GI[Geometry::NumGeom]
Definition ncmesh.hpp:1340
virtual void Update()
Definition ncmesh.cpp:268
void FindNeighbors(int elem, Array< int > &neighbors, const Array< int > *search_set=NULL)
Definition ncmesh.cpp:4320
void FreeElement(int id)
Definition ncmesh.hpp:826
virtual void Trim()
Save memory by releasing all non-essential and cached data.
Definition ncmesh.cpp:6839
virtual void ElementSharesVertex(int elem, int local, int vnode)
Definition ncmesh.hpp:1014
HashTable< Node > shadow
temporary storage for reparented nodes
Definition ncmesh.hpp:792
void SetDerefMatrixCodes(int parent, Array< int > &fine_coarse)
Definition ncmesh.cpp:2362
void CopyElements(int elem, const BlockArray< Element > &tmp_elements)
Definition ncmesh.cpp:6567
Array< Refinement > ref_stack
stack of scheduled refinements (temporary)
Definition ncmesh.hpp:791
std::int64_t RefCoord
Definition ncmesh.hpp:486
const Face & GetFace(int i) const
Access a Face.
Definition ncmesh.hpp:652
mfem::Element * NewMeshElement(int geom) const
Definition ncmesh.cpp:2718
void SetNodeScale(int p0, int p1, real_t scale)
Helper function to set scale for a node with parents p0, p1.
Definition ncmesh.cpp:1115
int NewTriangle(int n0, int n1, int n2, int attr, int eattr0, int eattr1, int eattr2)
Definition ncmesh.cpp:758
void MakeTopologyOnly()
Definition ncmesh.hpp:520
void GetMeshComponents(Mesh &mesh) const
Fill Mesh::{vertices,elements,boundary} for the current finest level.
Definition ncmesh.cpp:2758
NCMesh()=default
int NGhostElements
Definition ncmesh.hpp:721
void LoadCoarseElements(std::istream &input)
Load the element refinement hierarchy from a legacy mesh file.
Definition ncmesh.cpp:6585
void NeighborExpand(const Array< int > &elems, Array< int > &expanded, const Array< int > *search_set=NULL)
Definition ncmesh.cpp:4403
HashTable< Node > nodes
Definition ncmesh.hpp:619
int PrintVertexParents(std::ostream *out) const
Print the "vertex_parents" section of the mesh file.
Definition ncmesh.cpp:6055
static PointMatrix pm_prism_identity
Definition ncmesh.hpp:1180
int NewSegment(int n0, int n1, int attr, int vattr1, int vattr2)
Definition ncmesh.cpp:784
static int find_node(const Element &el, int node)
Definition ncmesh.cpp:3276
void DeleteUnusedFaces(const Array< int > &elemFaces)
Definition ncmesh.cpp:455
const CoarseFineTransformations & GetRefinementTransforms() const
Definition ncmesh.cpp:5153
void BuildElementToVertexTable()
Definition ncmesh.cpp:4129
virtual int GetNGhostElements() const
Definition ncmesh.hpp:174
void TraverseEdge(int vn0, int vn1, real_t t0, real_t t1, int flags, int level, MatrixMap &matrix_map)
Definition ncmesh.cpp:3770
bool using_scaling
Definition ncmesh.hpp:622
static int find_element_edge(const Element &el, int vn0, int vn1, bool abort=true)
Definition ncmesh.cpp:3296
Array< int > free_element_ids
Definition ncmesh.hpp:625
void LoadBoundary(std::istream &input)
Load the "boundary" section of the mesh file.
Definition ncmesh.cpp:6156
int Dimension() const
Return the dimension of the NCMesh.
Definition ncmesh.hpp:164
virtual void ElementSharesFace(int elem, int local, int face)
Definition ncmesh.hpp:1012
int PrintMemoryDetail() const
Definition ncmesh.cpp:6905
Array< real_t > reparent_scale
scale associated with reparents (tmp)
Definition ncmesh.hpp:794
static constexpr int MaxElemNodes
Number of nodes an element can have.
Definition ncmesh.hpp:488
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:615
HashTable< Face > faces
Definition ncmesh.hpp:620
bool HaveTets() const
Return true if the mesh contains tetrahedral elements.
Definition ncmesh.hpp:784
int AddElement(Geometry::Type geom, int attr)
Definition ncmesh.hpp:823
void GetEdgeVertices(const MeshId &edge_id, int vert_index[2], bool oriented=true) const
Return Mesh vertex indices of an edge identified by 'edge_id'.
Definition ncmesh.cpp:5588
static PointMatrix pm_seg_identity
Definition ncmesh.hpp:1176
static constexpr int MaxFaceNodes
Number of faces an element can have.
Definition ncmesh.hpp:496
const NCList & GetNCList(int entity)
Return vertex/edge/face list (entity = 0/1/2, respectively).
Definition ncmesh.hpp:341
bool QuadFaceIsMaster(int n1, int n2, int n3, int n4) const
Determine if a Quad face is a master face.
Definition ncmesh.hpp:930
Array< int > boundary_faces
subset of all faces, set by BuildFaceList
Definition ncmesh.hpp:731
std::array< int, 4 > FindFaceNodes(int face) const
Method for finding the nodes associated to a face.
Definition ncmesh.cpp:5748
static PointMatrix pm_quad_identity
Definition ncmesh.hpp:1178
void ReferenceElement(int elem)
Add references to all nodes, edges and faces of the element.
Definition ncmesh.cpp:367
void UpdateElementToVertexTable()
Definition ncmesh.hpp:1051
BlockArray< Element > elements
Definition ncmesh.hpp:624
Array< int > coarse_elements
state of leaf_elements before Refine(), set by MarkCoarseLevel()
Definition ncmesh.hpp:1198
const CoarseFineTransformations & GetDerefinementTransforms() const
Definition ncmesh.cpp:5204
Table derefinements
possible derefinements, see GetDerefinementTable
Definition ncmesh.hpp:796
int FindNodeExt(const Element &el, int node, bool abort=true)
Extended version of find_node: works if 'el' is refined.
Definition ncmesh.cpp:3286
int ReorderFacePointMat(int v0, int v1, int v2, int v3, int elem, const PointMatrix &pm, PointMatrix &reordered) const
Definition ncmesh.cpp:3421
int FindMidEdgeNode(int node1, int node2) const
Definition ncmesh.cpp:336
Array< char > face_geom
face geometry by face index, set by OnMeshUpdated
Definition ncmesh.hpp:732
int GetEdgeNCOrientation(const MeshId &edge_id) const
Definition ncmesh.cpp:5607
Table element_vertex
leaf-element to vertex table, see FindSetNeighbors
Definition ncmesh.hpp:734
Array< Triple< int, int, int > > reparents
scheduled node reparents (tmp)
Definition ncmesh.hpp:793
virtual void BuildFaceList()
Definition ncmesh.cpp:3675
void CheckAnisoPrism(int vn1, int vn2, int vn3, int vn4, const Refinement *refs, int nref)
Definition ncmesh.cpp:953
void LoadVertexParents(std::istream &input)
Load the vertex parent hierarchy from a mesh file.
Definition ncmesh.cpp:6090
TmpVertex * tmp_vertex
Definition ncmesh.hpp:1211
static void GridSfcOrdering3D(int width, int height, int depth, Array< int > &coords)
Definition ncmesh.cpp:5556
Array< int > leaf_elements
finest elements, in Mesh ordering (+ ghosts)
Definition ncmesh.hpp:723
const real_t * CalcVertexPos(int node) const
Definition ncmesh.cpp:2733
void CollectLeafElements(int elem, int state, Array< int > &ghosts, int &counter)
Definition ncmesh.cpp:2381
const Element & GetElement(int i) const
Access an Element.
Definition ncmesh.hpp:665
int CountTopLevelNodes() const
Return the index of the last top-level node plus one.
Definition ncmesh.cpp:6378
void QuadFaceSplitLevel(int vn1, int vn2, int vn3, int vn4, int &h_level, int &v_level) const
Computes the number of horizontal and vertical splits of this quad that have occurred in the NCMesh....
Definition ncmesh.cpp:5884
int Geoms
bit mask of element geometries present, see InitGeomFlags()
Definition ncmesh.hpp:527
void InitDerefTransforms()
Definition ncmesh.cpp:2343
int GetElementSizeReduction(int i) const
Definition ncmesh.cpp:5708
virtual void LimitNCLevel(int max_nc_level)
Definition ncmesh.cpp:6039
int NGhostVertices
Definition ncmesh.hpp:721
const NCList & GetVertexList()
Definition ncmesh.hpp:334
bool ZeroRootStates() const
Return true if all root_states are zero.
Definition ncmesh.cpp:6235
Array< int > vertex_nodeId
vertex-index to node-id map, see UpdateVertices
Definition ncmesh.hpp:725
int ParentFaceNodes(std::array< int, 4 > &nodes) const
Given a set of nodes defining a face, traverse the nodes structure to find the nodes that make up the...
Definition ncmesh.cpp:3106
int GetNumRootElements()
Return the number of root elements.
Definition ncmesh.hpp:450
int RetrieveNode(const Element &el, int index)
Return el.node[index] correctly, even if the element is refined.
Definition ncmesh.cpp:1994
void FindEdgeElements(int vn1, int vn2, int vn3, int vn4, Array< MeshId > &prisms) const
Definition ncmesh.cpp:905
virtual ~NCMesh()
Definition ncmesh.cpp:280
void CollectDerefinements(int elem, Array< Connection > &list)
Definition ncmesh.cpp:2230
bool IsLegacyLoaded() const
I/O: Return true if the mesh was loaded from the legacy v1.1 format.
Definition ncmesh.hpp:473
const Node & GetNode(int i) const
Access a Node.
Definition ncmesh.hpp:639
virtual void ElementSharesEdge(int elem, int local, int enode)
Definition ncmesh.hpp:1013
int GetFaceVerticesEdges(const MeshId &face_id, int vert_index[4], int edge_index[4], int edge_orientation[4]) const
Definition ncmesh.cpp:5619
void RefineElement(int elem, char ref_type)
Refine the element elem with the refinement type ref_type.
Definition ncmesh.cpp:1121
void InitRootState(int root_count)
Definition ncmesh.cpp:2652
Geometry::Type GetElementGeometry(int index) const
Return element geometry type. index is the Mesh element number.
Definition ncmesh.hpp:442
int NewQuadrilateral(int n0, int n1, int n2, int n3, int attr, int eattr0, int eattr1, int eattr2, int eattr3)
Definition ncmesh.cpp:732
Array< int > leaf_sfc_index
natural tree ordering of leaf elements
Definition ncmesh.hpp:724
void ForceRefinement(int vn1, int vn2, int vn3, int vn4)
Definition ncmesh.cpp:824
void CollectEdgeVertices(int v0, int v1, Array< int > &indices)
Definition ncmesh.cpp:4058
NCList edge_list
lazy-initialized list of edges, see GetEdgeList
Definition ncmesh.hpp:728
static PointMatrix pm_pyramid_identity
Definition ncmesh.hpp:1181
Array< int > root_state
Definition ncmesh.hpp:701
const NCList & GetFaceList()
Return the current list of conforming and nonconforming faces.
Definition ncmesh.hpp:319
real_t GetScale(real_t s, bool reverse) const
Return directed scale in (0,1).
Definition ncmesh.hpp:1221
Geometry::Type GetFaceGeometry(int index) const
Return face geometry type. index is the Mesh face number.
Definition ncmesh.hpp:446
void CollectTriFaceVertices(int v0, int v1, int v2, Array< int > &indices)
Definition ncmesh.cpp:4070
void InitRootElements()
Count root elements and initialize root_state.
Definition ncmesh.cpp:6335
int GetMidEdgeNode(int node1, int node2)
Definition ncmesh.cpp:352
virtual void BuildEdgeList()
Definition ncmesh.cpp:3800
void DebugDump(std::ostream &out) const
Definition ncmesh.cpp:6958
void DebugLeafOrder(std::ostream &out) const
Definition ncmesh.cpp:6933
std::map< std::string, int > RefPathMap
Definition ncmesh.hpp:1189
int GetElementDepth(int i) const
Return the distance of leaf i from the root.
Definition ncmesh.cpp:5696
void TraverseRefinements(int elem, int coarse_index, std::string &ref_path, RefPathMap &map) const
Definition ncmesh.cpp:5119
void CheckIsoFace(int vn1, int vn2, int vn3, int vn4, int en1, int en2, int en3, int en4, int midf)
Definition ncmesh.cpp:1099
void GetLimitRefinements(Array< Refinement > &refinements, int max_level)
Definition ncmesh.cpp:6009
int NewPyramid(int n0, int n1, int n2, int n3, int n4, int attr, int fattr0, int fattr1, int fattr2, int fattr3, int fattr4)
Definition ncmesh.cpp:702
virtual void Derefine(const Array< int > &derefs)
Definition ncmesh.cpp:2307
bool Iso
true if the mesh only contains isotropic refinements
Definition ncmesh.hpp:526
virtual void GetBoundaryClosure(const Array< int > &bdr_attr_is_ess, Array< int > &bdr_vertices, Array< int > &bdr_edges, Array< int > &bdr_faces)
Get a list of vertices (2D/3D), edges (3D) and faces (3D) that coincide with boundary elements with t...
Definition ncmesh.cpp:5776
bool TriFaceSplit(int n1, int n2, int n3, int mid[3]=NULL) const
Given a tri face defined by three vertices, establish whether the edges that make up this face have b...
Definition ncmesh.cpp:3082
bool Legacy
true if the mesh was loaded from the legacy v1.1 format
Definition ncmesh.hpp:528
virtual void BuildVertexList()
Definition ncmesh.cpp:3912
static const PointMatrix & GetGeomIdentity(Geometry::Type geom)
Definition ncmesh.cpp:4606
int GetNVertices() const
Return the number of vertices in the NCMesh.
Definition ncmesh.hpp:169
static constexpr int MaxElemFaces
Number of faces an element can have.
Definition ncmesh.hpp:492
int GetNumElements() const
The number of elements.
Definition ncmesh.hpp:658
void CheckAnisoFace(int vn1, int vn2, int vn3, int vn4, int mid12, int mid34, int level=0)
Definition ncmesh.cpp:978
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:645
int GetVertexRootCoord(int elem, RefCoord coord[3]) const
Definition ncmesh.cpp:4462
static void CheckSupportedGeom(Geometry::Type geom)
Definition ncmesh.hpp:1283
Array< real_t > coordinates
Definition ncmesh.hpp:705
void FindVertexCousins(int elem, int local, Array< int > &cousins) const
Definition ncmesh.cpp:4538
bool IsGhost(const Element &el) const
Return true if the Element el is a ghost element.
Definition ncmesh.hpp:787
static constexpr int MaxElemChildren
Number of children an element can have.
Definition ncmesh.hpp:494
const NCList & GetEdgeList()
Return the current list of conforming and nonconforming edges.
Definition ncmesh.hpp:326
bool TriFaceIsMaster(int n1, int n2, int n3) const
Determine if a Triangle face is a master face.
Definition ncmesh.hpp:910
int MyRank
used in parallel, or when loading a parallel file in serial
Definition ncmesh.hpp:525
void Print(std::ostream &out, const std::string &comments="") const
Definition ncmesh.cpp:6244
int AddElement(const Element &el)
Add an Element el to the NCMesh, optimized to reuse freed elements.
Definition ncmesh.hpp:812
void CountSplits(int elem, int splits[3]) const
Definition ncmesh.cpp:5919
int spaceDim
dimensions of the elements and the vertex coordinates
Definition ncmesh.hpp:524
void UnreferenceElement(int elem, Array< int > &elemFaces)
Definition ncmesh.cpp:398
void LegacyToNewVertexOrdering(Array< int > &order) const
I/O: Return a map from old (v1.1) vertex indices to new vertex indices.
Definition ncmesh.cpp:6814
int NGhostEdges
Definition ncmesh.hpp:721
void CollectIncidentElements(int elem, const RefCoord coord[3], Array< int > &list) const
Definition ncmesh.cpp:4515
void TraverseTetEdge(int vn0, int vn1, const Point &p0, const Point &p1, MatrixMap &matrix_map)
Definition ncmesh.cpp:3572
int QuadFaceSplitType(int n1, int n2, int n3, int n4, real_t &s, int mid[5]=NULL) const
Given a quad face defined by four vertices, establish which edges of this face have been split,...
Definition ncmesh.cpp:3028
void RegisterFaces(int elem, int *fattr=NULL)
Definition ncmesh.cpp:441
int PrintBoundary(std::ostream *out) const
Definition ncmesh.cpp:6117
CoarseFineTransformations transforms
storage for data returned by Get[De]RefinementTransforms()
Definition ncmesh.hpp:1195
void MarkCoarseLevel()
Definition ncmesh.cpp:5105
int TriFaceSplitLevel(int vn1, int vn2, int vn3) const
Return the number of splits of this triangle that have occurred in the NCMesh. If zero,...
Definition ncmesh.cpp:5869
virtual void CheckDerefinementNCLevel(const Table &deref_table, Array< int > &level_ok, int max_nc_level)
Definition ncmesh.cpp:2278
void UpdateVertices()
This method assigns indices to vertices (Node::vert_index) that will be seen by the Mesh class and th...
Definition ncmesh.cpp:2476
int GetNFaces() const
Return the number of (2D) faces in the NCMesh.
Definition ncmesh.hpp:173
NCList vertex_list
lazy-initialized list of vertices, see GetVertexList
Definition ncmesh.hpp:729
bool HavePyramids() const
Return true if the mesh contains pyramid elements.
Definition ncmesh.hpp:781
void InitGeomFlags()
Definition ncmesh.cpp:259
int NewTetrahedron(int n0, int n1, int n2, int n3, int attr, int fattr0, int fattr1, int fattr2, int fattr3)
Definition ncmesh.cpp:677
void LoadCoordinates(std::istream &input)
Load the "coordinates" section of the mesh file.
Definition ncmesh.cpp:6214
void GetPointMatrix(Geometry::Type geom, const char *ref_path, DenseMatrix &matrix) const
Definition ncmesh.cpp:4623
void TraverseQuadFace(int vn0, int vn1, int vn2, int vn3, const PointMatrix &pm, int level, Face *eface[4], MatrixMap &matrix_map)
Definition ncmesh.cpp:3452
const Table & GetDerefinementTable()
Definition ncmesh.cpp:2263
void ClearTransforms()
Free all internal data created by the above three functions.
Definition ncmesh.cpp:5284
void SetAttribute(int i, int attr)
Set the attribute of leaf element i, which is a Mesh element index.
Definition ncmesh.hpp:464
int SpaceDimension() const
Return the space dimension of the NCMesh.
Definition ncmesh.hpp:166
void FindSetNeighbors(const Array< char > &elem_set, Array< int > *neighbors, Array< char > *neighbor_set=NULL)
Definition ncmesh.cpp:4209
int GetNumNodes() const
The number of Nodes.
Definition ncmesh.hpp:632
NCMesh & operator=(NCMesh &)=delete
Copy assignment not supported.
void CollectQuadFaceVertices(int v0, int v1, int v2, int v3, Array< int > &indices)
Definition ncmesh.cpp:4094
void PrintCoordinates(std::ostream &out) const
Print the "coordinates" section of the mesh file.
Definition ncmesh.cpp:6196
TriFaceTraverseResults TraverseTriFace(int vn0, int vn1, int vn2, const PointMatrix &pm, int level, MatrixMap &matrix_map)
Definition ncmesh.cpp:3609
int GetMidFaceNode(int en1, int en2, int en3, int en4)
Definition ncmesh.cpp:359
bool HavePrisms() const
Return true if the mesh contains prism elements.
Definition ncmesh.hpp:778
long MemoryUsage() const
Return total number of bytes allocated.
Definition ncmesh.cpp:6882
void DerefineElement(int elem)
Derefine the element elem, does nothing on leaf elements.
Definition ncmesh.cpp:2036
NCList face_list
lazy-initialized list of faces, see GetFaceList
Definition ncmesh.hpp:727
virtual void Refine(const Array< Refinement > &refinements)
Definition ncmesh.cpp:1945
void ReparentNode(int node, int new_p1, int new_p2, real_t scale)
Definition ncmesh.cpp:319
static PointMatrix pm_tri_identity
Definition ncmesh.hpp:1177
int NGhostFaces
Definition ncmesh.hpp:721
static PointMatrix pm_hex_identity
Definition ncmesh.hpp:1182
void UpdateLeafElements()
Update the leaf elements indices in leaf_elements.
Definition ncmesh.cpp:2449
void LoadLegacyFormat(std::istream &input, int &curved, int &is_nc)
Load the deprecated MFEM mesh v1.1 format for backward compatibility.
Definition ncmesh.cpp:6656
int GetNEdges() const
Return the number of edges in the NCMesh.
Definition ncmesh.hpp:171
int EdgeSplitLevel(int vn1, int vn2) const
Return the number of splits of this edge that have occurred in the NCMesh. If zero,...
Definition ncmesh.cpp:5862
static void GridSfcOrdering2D(int width, int height, Array< int > &coords)
Definition ncmesh.cpp:5541
static int find_local_face(int geom, int a, int b, int c)
Definition ncmesh.cpp:3314
Class representing a Nonconformal SubMesh. This is only used by SubMesh.
Definition ncsubmesh.hpp:28
A parallel extension of the NCMesh class.
Definition pncmesh.hpp:63
Class representing a Parallel Nonconformal SubMesh. This is only used by ParSubMesh.
Data type point element.
Definition point.hpp:23
int Size() const
Returns the number of TYPE I elements.
Definition table.hpp:100
int index(int i, int j, int nx, int ny)
Definition life.cpp:236
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
void Swap(Array< T > &, Array< T > &)
Definition array.hpp:672
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
NCMesh::RefCoord RefCoord
float real_t
Definition config.hpp:43
Defines the coarse-fine transformations of all fine elements.
Definition ncmesh.hpp:90
MFEM_DEPRECATED void GetCoarseToFineMap(const Mesh &fine_mesh, Table &coarse_to_fine) const
Definition ncmesh.hpp:109
Array< Embedding > embeddings
Fine element positions in their parents.
Definition ncmesh.hpp:92
void MakeCoarseToFineTable(Table &coarse_to_fine, bool want_ghosts=false) const
Definition ncmesh.cpp:5262
DenseTensor point_matrices[Geometry::NumGeom]
Definition ncmesh.hpp:96
Defines the position of a fine element within a coarse element.
Definition ncmesh.hpp:69
unsigned geom
Definition ncmesh.hpp:77
Embedding()=default
unsigned ghost
For internal use: 0 if regular fine element, 1 if parallel ghost element.
Definition ncmesh.hpp:81
Embedding(int elem, Geometry::Type geom, int matrix=0, bool ghost=false)
Definition ncmesh.hpp:84
int parent
Coarse Element index in the coarse mesh.
Definition ncmesh.hpp:71
unsigned matrix
Definition ncmesh.hpp:78
int rank
processor number (ParNCMesh), -1 if undefined/unknown
Definition ncmesh.hpp:602
bool IsLeaf() const
Definition ncmesh.hpp:613
int child[MaxElemChildren]
2-10 children (if ref_type != 0)
Definition ncmesh.hpp:607
char tet_type
tetrahedron split type, currently always 0
Definition ncmesh.hpp:599
Element(Geometry::Type geom, int attr)
Definition ncmesh.cpp:602
int GetAttribute() const
Definition ncmesh.hpp:614
char flag
generic flag/marker, can be used by algorithms
Definition ncmesh.hpp:600
int node[MaxElemNodes]
element corners (if ref_type == 0)
Definition ncmesh.hpp:606
char ref_type
bit mask of X,Y,Z refinements (bits 0,1,2 respectively)
Definition ncmesh.hpp:598
char geom
Geometry::Type of the element (char for storage only)
Definition ncmesh.hpp:597
int index
element number in the Mesh, -1 if refined
Definition ncmesh.hpp:601
int parent
parent element, -1 if this is a root element, -2 if free'd
Definition ncmesh.hpp:609
Geometry::Type Geom() const
Definition ncmesh.hpp:612
int GetAttribute() const
Definition ncmesh.hpp:589
void ForgetElement(int e)
Definition ncmesh.cpp:473
int elem[2]
up to 2 elements sharing the face
Definition ncmesh.hpp:576
bool Unused() const
Definition ncmesh.hpp:581
void RegisterElement(int e)
Definition ncmesh.cpp:466
bool Boundary() const
Definition ncmesh.hpp:580
int index
face number in the Mesh
Definition ncmesh.hpp:575
int GetSingleElement() const
Return one of elem[0] or elem[1] and make sure the other is -1.
Definition ncmesh.cpp:488
int attribute
boundary element attribute, -1 if internal face
Definition ncmesh.hpp:574
This holds in one place the constants about the geometries we support.
Definition ncmesh.hpp:1328
int nfv[MaxElemFaces]
Definition ncmesh.hpp:1332
int faces[MaxElemFaces][4]
Definition ncmesh.hpp:1331
int edges[MaxElemEdges][2]
Definition ncmesh.hpp:1330
void InitGeom(Geometry::Type geom)
Definition ncmesh.cpp:57
GeomInfo(Geometry::Type geom)
Definition ncmesh.hpp:1336
Master(int index, int element, int local, int geom, int sb, int se)
Definition ncmesh.hpp:230
int slaves_end
slave faces
Definition ncmesh.hpp:227
Identifies a vertex/edge/face in both Mesh and NCMesh.
Definition ncmesh.hpp:210
int element
NCMesh::Element containing this vertex/edge/face.
Definition ncmesh.hpp:212
int index
Mesh number.
Definition ncmesh.hpp:211
MeshId(int index, int element, int local, int geom=-1)
Definition ncmesh.hpp:219
Geometry::Type Geom() const
Definition ncmesh.hpp:216
signed char geom
Geometry::Type (faces only) (char to save RAM)
Definition ncmesh.hpp:214
signed char local
local number within 'element'
Definition ncmesh.hpp:213
const MeshIdType type
MeshIdType corresponding to the MeshId. UNRECOGNIZED if unfound.
Definition ncmesh.hpp:276
Lists all edges/faces in the nonconforming mesh.
Definition ncmesh.hpp:251
MeshIdType GetMeshIdType(int index) const
Return a face type for a given nc index.
Definition ncmesh.cpp:4008
Array< MeshId > conforming
All MeshIds corresponding to conformal faces.
Definition ncmesh.hpp:252
long MemoryUsage() const
Definition ncmesh.cpp:6854
Array< Slave > slaves
All MeshIds corresponding to slave faces.
Definition ncmesh.hpp:254
bool CheckMeshIdType(int index, MeshIdType type) const
Given an index, check if this is a certain face type.
Definition ncmesh.cpp:4016
bool Empty() const
Whether the NCList is empty.
Definition ncmesh.hpp:290
void Clear()
Erase the contents of the conforming, master and slave arrays.
Definition ncmesh.cpp:3969
void OrientedPointMatrix(const Slave &slave, DenseMatrix &oriented_matrix) const
Definition ncmesh.cpp:3947
Array< Master > masters
All MeshIds corresponding to master faces.
Definition ncmesh.hpp:253
long TotalSize() const
The total size of the component arrays in the NCList.
Definition ncmesh.hpp:297
Array< DenseMatrix * > point_matrices[Geometry::NumGeom]
List of unique point matrices for each slave geometry.
Definition ncmesh.hpp:257
MeshIdAndType GetMeshIdAndType(int index) const
Return a mesh id and type for a given nc index.
Definition ncmesh.cpp:3988
bool HasVertex() const
Definition ncmesh.hpp:548
bool HasEdge() const
Definition ncmesh.hpp:549
real_t GetScale() const
Definition ncmesh.hpp:555
void SetScale(real_t s, bool overwrite=false)
Definition ncmesh.cpp:298
The PointMatrix stores the coordinates of the slave face using the master face coordinate as referenc...
Definition ncmesh.hpp:1130
PointMatrix(const Point &p0, const Point &p1, const Point &p2, const Point &p3, const Point &p4)
Definition ncmesh.hpp:1145
Point & operator()(int i)
Definition ncmesh.hpp:1168
void GetMatrix(DenseMatrix &point_matrix) const
Definition ncmesh.cpp:4569
PointMatrix(const Point &p0, const Point &p1, const Point &p2)
Definition ncmesh.hpp:1139
Point points[MaxElemNodes]
Definition ncmesh.hpp:1132
PointMatrix(const Point &p0, const Point &p1, const Point &p2, const Point &p3)
Definition ncmesh.hpp:1142
PointMatrix(const Point &p0, const Point &p1, const Point &p2, const Point &p3, const Point &p4, const Point &p5)
Definition ncmesh.hpp:1152
const Point & operator()(int i) const
Definition ncmesh.hpp:1169
bool operator==(const PointMatrix &pm) const
Definition ncmesh.cpp:4555
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:1159
PointMatrix(const Point &p0, const Point &p1)
Definition ncmesh.hpp:1136
Point(const Point &p0, const Point &p1, real_t s=0.5)
Definition ncmesh.hpp:1086
Point(const Point &)=default
Point(real_t x, real_t y, real_t z)
Definition ncmesh.hpp:1083
Point(real_t x, real_t y)
Definition ncmesh.hpp:1080
Point & operator=(const Point &src)
Definition ncmesh.hpp:1106
Point(const Point &p0, const Point &p1, const Point &p2, const Point &p3)
Definition ncmesh.hpp:1095
Nonconforming edge/face within a bigger edge/face.
Definition ncmesh.hpp:237
unsigned edge_flags
orientation flags, see OrientedPointMatrix
Definition ncmesh.hpp:240
unsigned matrix
index into NCList::point_matrices[geom]
Definition ncmesh.hpp:239
int master
master number (in Mesh numbering)
Definition ncmesh.hpp:238
Slave(int index, int element, int local, int geom)
Definition ncmesh.hpp:243
bool unsplit
Whether this face has no further splits.
Definition ncmesh.hpp:997
bool ghost_neighbor
Whether the face neighbor is a ghost.
Definition ncmesh.hpp:998
Refinement()=default
Refinement scale in each dimension.
real_t s[3]
Definition ncmesh.hpp:45
void SetScaleForType(const real_t *scale)
Set the scale in the directions for the currently set type.
Definition ncmesh.cpp:540
std::pair< char, real_t > ScaledType
Definition ncmesh.hpp:44
int index
Mesh element number.
Definition ncmesh.hpp:42
void Set(int element, char type, real_t scale=0.5)
Set the element, type, and scale.
Definition ncmesh.cpp:589
char GetType() const
Return the type as char.
Definition ncmesh.cpp:580
void SetType(char type, real_t scale=0.5)
Set the type and scale, assuming the element is already set.
Definition ncmesh.cpp:596