MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
pncmesh.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_PNCMESH
13#define MFEM_PNCMESH
14
15#include "../config/config.hpp"
16
17#ifdef MFEM_USE_MPI
18
19#include <map>
20#include <set>
21
22#include "ncmesh.hpp"
25#include "../fem/fespace.hpp"
26
27namespace mfem
28{
29
30/** \brief A parallel extension of the NCMesh class.
31 *
32 * The basic idea (and assumption) is that all processors share the coarsest
33 * layer ("root elements"). This has the advantage that refinements can easily
34 * be exchanged between processors when rebalancing since individual elements
35 * can be uniquely identified by the index of the root element and a path in
36 * the refinement tree.
37 *
38 * Each leaf element is owned by one of the processors (NCMesh::Element::rank).
39 * The underlying NCMesh stores not only elements for the current ('MyRank')
40 * processor, but also a minimal layer of adjacent "ghost" elements owned by
41 * other processors. The ghost layer is synchronized after refinement.
42 *
43 * The ghost layer contains all vertex-, edge- and face-neighbors of the
44 * current processor's region. It is used to determine constraining relations
45 * and ownership of DOFs on the processor boundary. Ghost elements are never
46 * seen by the rest of MFEM as they are skipped when a Mesh is created from
47 * the NCMesh.
48 *
49 * The processor that owns a vertex, edge or a face (and in turn its DOFs) is
50 * currently defined to be the one with the lowest rank in the group of
51 * processors that share the entity.
52 *
53 * Vertices, edges and faces that are not owned by this ('MyRank') processor
54 * are ghosts, and are numbered after all real vertices/edges/faces, i.e.,
55 * they have indices greater than NVertices, NEdges, NFaces, respectively.
56 *
57 * A shared vertex/edge/face is identified in an interprocessor message by a
58 * pair of numbers. The first number specifies an element in an ElementSet
59 * (typically sent at the beginning of the message) that contains the v/e/f.
60 * The second number is the local index of the v/e/f in that element.
61 */
62class ParNCMesh : public NCMesh
63{
64protected:
65 ParNCMesh() = default;
66public:
67 /// Construct by partitioning a serial NCMesh.
68 /** SFC partitioning is used by default. A user-specified partition can be
69 passed in 'part', where part[i] is the desired MPI rank for element i. */
70 ParNCMesh(MPI_Comm comm, const NCMesh& ncmesh,
71 const int *partitioning = nullptr);
72
73 /** Load from a stream, parallel version. See the serial NCMesh::NCMesh
74 counterpart for a description of the parameters. */
75 ParNCMesh(MPI_Comm comm, std::istream &input,
76 int version, int &curved, int &is_nc);
77
78 /// Deep copy of another instance.
79 ParNCMesh(const ParNCMesh &other);
80
81 virtual ~ParNCMesh();
82
83 /** An override of NCMesh::Refine, which is called eventually, after making
84 sure that refinements that occur on the processor boundary are sent to
85 the neighbor processors so they can keep their ghost layers up to
86 date. */
87 void Refine(const Array<Refinement> &refinements) override;
88
89 /** See Mesh::AnisotropicConflict. The return value is globally MPI-reduced,
90 whereas @a conflicts contains local indices of conflicting entries of
91 @a refinements. */
92 bool AnisotropicConflict(const Array<Refinement> &refinements,
93 std::set<int> &conflicts);
94
95 /// Parallel version of NCMesh::LimitNCLevel.
96 void LimitNCLevel(int max_nc_level) override;
97
98 /** Parallel version of NCMesh::CheckDerefinementNCLevel. */
99 void CheckDerefinementNCLevel(const Table &deref_table,
100 Array<int> &level_ok, int max_nc_level) override;
101
102 /** Parallel reimplementation of NCMesh::Derefine, keeps ghost layers
103 in sync. The interface is identical. */
104 void Derefine(const Array<int> &derefs) override;
105
106 /** Gets partitioning for the coarse mesh if the current fine mesh were to
107 be derefined. */
108 void GetFineToCoarsePartitioning(const Array<int> &derefs,
109 Array<int> &new_ranks) const;
110
111 /** Migrate leaf elements of the global refinement hierarchy (including ghost
112 elements) so that each processor owns the same number of leaves (+-1).
113 The default partitioning strategy is based on equal splitting of the
114 space-filling sequence of leaf elements (custom_partition == NULL).
115 Alternatively, a used-defined element-rank assignment array can be
116 passed. */
117 void Rebalance(const Array<int> *custom_partition = NULL);
118
119 // Interface for ParFiniteElementSpace
120 int GetNElements() const { return NElements; }
121
122 int GetNGhostVertices() const { return NGhostVertices; }
123 int GetNGhostEdges() const { return NGhostEdges; }
124 int GetNGhostFaces() const { return NGhostFaces; }
125 int GetNGhostElements() const override { return NGhostElements; }
126
127 // Return a list of vertices/edges/faces shared by this processor and at
128 // least one other processor. These are subsets of NCMesh::<entity>_list. */
132
133 /* Gets the array of global serial indices in NCMesh::elements of all ghost
134 elements for this processor. */
135 void GetGhostElements(Array<int> & gelem);
136
137 /// Helper to get shared vertices/edges/faces ('entity' == 0/1/2 resp.).
138 const NCList& GetSharedList(int entity)
139 {
140 switch (entity)
141 {
142 case 0: return GetSharedVertices();
143 case 1: return GetSharedEdges();
144 default: return GetSharedFaces();
145 }
146 }
147
148 /// Return (shared) face orientation relative to its owner element.
150 {
151 return (index < NFaces) ? face_orient[index] : 0;
152 }
153
154 using GroupId = short;
155 using CommGroup = std::vector<int>;
156
157 /// Return vertex/edge/face ('entity' == 0/1/2, resp.) owner.
159 {
160 MFEM_ASSERT(entity >= 0 && entity < 3, "");
161 MFEM_ASSERT(index >= 0, "");
162 if (!entity_owner[entity].Size())
163 {
164 GetSharedList(entity);
165 }
166 return entity_owner[entity][index];
167 }
168
169 /** Return the P matrix communication group ID for a vertex/edge/face.
170 The groups are calculated specifically to match the P matrix
171 construction algorithm and its communication pattern. */
173 {
174 MFEM_ASSERT(entity >= 0 && entity < 3, "");
175 MFEM_ASSERT(index >= 0, "");
176 if (!entity_pmat_group[entity].Size())
177 {
179 }
180 return entity_pmat_group[entity][index];
181 }
182
183 /// Return a list of ranks contained in the group of the given ID.
184 const CommGroup& GetGroup(GroupId id) const
185 {
186 MFEM_ASSERT(id >= 0, "");
187 return groups[id];
188 }
189
190 /// Return true if group 'id' contains the given rank.
191 bool GroupContains(GroupId id, int rank) const;
192
193 /// Return true if the specified vertex/edge/face is a ghost.
194 bool IsGhost(int entity, int index) const
195 {
196 if (index < 0) // special case prism edge-face constraint
197 {
198 MFEM_ASSERT(entity == 2, "");
199 entity = 1;
200 index = -1 - index;
201 }
202 switch (entity)
203 {
204 case 0: return index >= NVertices;
205 case 1: return index >= NEdges;
206 default: return index >= NFaces;
207 }
208 }
209
210 /** Returns owner processor for element 'index'. This is normally MyRank but
211 for index >= NElements (i.e., for ghosts) it may be something else. */
212 int ElementRank(int index) const
213 {
214 return elements[leaf_elements[index]].rank;
215 }
216
217
218 // utility
219
220 /// Return the MPI rank for this process.
221 int GetMyRank() const { return MyRank; }
222
223 /// Return true if using more than one MPI process.
224 bool IsParallel() const override { return NRanks > 1; }
225
226 /// Use the communication pattern from last Rebalance() to send element DOFs.
227 void SendRebalanceDofs(int old_ndofs, const Table &old_element_dofs,
228 long old_global_offset, FiniteElementSpace* space);
229
230 /// Receive element DOFs sent by SendRebalanceDofs().
232
233 /** Get previous indices (pre-Rebalance) of current elements. Index of -1
234 indicates that an element didn't exist in the mesh before. */
236
237 /** Get previous (pre-Derefine) fine element ranks. This complements the
238 CoarseFineTransformations::embeddings array in parallel. */
240
241 /** Exchange element data for derefinements that straddle processor
242 boundaries. 'elem_data' is enlarged and filled with ghost values. */
243 template<typename Type>
245 const Table &deref_table);
246
247 /** Extension of NCMesh::GetBoundaryClosure. Filters out ghost vertices and
248 ghost edges from 'bdr_vertices' and 'bdr_edges', and uncovers hidden
249 internal boundary faces. */
250 void GetBoundaryClosure(const Array<int> &bdr_attr_is_ess,
251 Array<int> &bdr_vertices,
252 Array<int> &bdr_edges, Array<int> &bdr_faces) override;
253
254 /// Save memory by releasing all non-essential and cached data.
255 void Trim() override;
256
257 /// Return total number of bytes allocated.
258 std::size_t MemoryUsage(bool with_base = true) const;
259
260 int PrintMemoryDetail(bool with_base = true) const;
261
262 /** Extract a debugging Mesh containing all leaf elements, including ghosts.
263 The debug mesh will have element attributes set to element rank + 1. */
264 void GetDebugMesh(Mesh &debug_mesh) const;
265
266 // Ghost element indices and their orders, for parallel p-refinement.
268 {
269 unsigned int element; // Element index
270 char order; // Element order
271 };
272
274 const Array<VarOrderElemInfo> & sendData,
275 Array<VarOrderElemInfo> & recvData);
276
277 /** For a ghost element with index @a elem, the edge indices are returned in
278 @a edges. */
279 void FindEdgesOfGhostElement(int elem, Array<int> & edges);
280
281 /** For a ghost element with index @a elem, the face indices are returned in
282 @a faces. */
283 void FindFacesOfGhostElement(int elem, Array<int> & faces);
284
285 /** For a ghost face with index @a face, the edge indices are returned in
286 @a edges. */
287 void FindEdgesOfGhostFace(int face, Array<int> & edges);
288
289protected: // interface for ParMesh
290
291 friend class ParMesh;
292 friend class ParSubMesh;
293
294 /** For compatibility with conforming code in ParMesh and ParFESpace.
295 Initializes shared structures in ParMesh: gtopo, shared_*, group_s*,
296 s*_l*. The ParMesh then acts as a parallel mesh cut along the NC
297 interfaces. */
298 void GetConformingSharedStructures(class ParMesh &pmesh);
299
300 /** Populate face neighbor members of ParMesh from the ghost layer, without
301 communication. */
302 void GetFaceNeighbors(class ParMesh &pmesh);
303protected: // implementation
304
305 MPI_Comm MyComm;
307
308 using GroupList = std::vector<CommGroup>;
309 using GroupMap = std::map<CommGroup, GroupId>;
310
311 GroupList groups; // comm group list; NOTE: groups[0] = { MyRank }
312 GroupMap group_id; // search index over groups
313
314 // owner rank for each vertex, edge and face (encoded as singleton group)
316 // P matrix comm pattern groups for each vertex/edge/face (0/1/2)
318
319 // ParMesh-compatible (conforming) groups for each vertex/edge/face (0/1/2)
321 // ParMesh compatibility helper arrays to order groups, also temporary
323
324 // lists of vertices/edges/faces shared by us and at least one more processor
326
327 Array<char> face_orient; // see CalcFaceOrientations
328
329 /** Type of each leaf element:
330 1 - our element (rank == MyRank),
331 3 - our element, and neighbor to the ghost layer,
332 2 - ghost layer element (existing element, but rank != MyRank),
333 0 - element beyond the ghost layer, may not be a real element.
334 Note: indexed by Element::index. See also UpdateLayers(). */
336
337 Array<int> ghost_layer; ///< list of elements whose 'element_type' == 2.
338 Array<int> boundary_layer; ///< list of type 3 elements
339
340 void Update() override;
341
342 /// Return the processor number for a global element number.
343 int Partition(long index, long total_elements) const
344 { return index * NRanks / total_elements; }
345
346 /// Helper to get the partitioning when the serial mesh gets split initially
347 int InitialPartition(int index) const
348 { return Partition(index, leaf_elements.Size()); }
349
350 /// Return the global index of the first element owned by processor 'rank'.
351 long PartitionFirstIndex(int rank, long total_elements) const
352 { return (rank * total_elements + NRanks-1) / NRanks; }
353
354 void BuildFaceList() override;
355 void BuildEdgeList() override;
356 void BuildVertexList() override;
357
358 void ElementSharesFace(int elem, int local, int face) override;
359 void ElementSharesEdge(int elem, int local, int enode) override;
360 void ElementSharesVertex(int elem, int local, int vnode) override;
361
362 GroupId GetGroupId(const CommGroup &group);
363 GroupId GetSingletonGroup(int rank);
364
365 Array<int> tmp_owner; // temporary
368
369 void InitOwners(int num, Array<GroupId> &entity_owner);
370 void MakeSharedList(const NCList &list, NCList &shared);
371
372 void AddConnections(int entity, int index, const Array<int> &ranks);
374 void CreateGroups(int nentities, Array<Connection> &index_rank,
375 Array<GroupId> &entity_group);
376
377 static int get_face_orientation(const Face &face, const Element &e1,
378 const Element &e2,
379 int local[2] = NULL /* optional output */);
381
382 void UpdateLayers();
383
384 void MakeSharedTable(int ngroups, int ent, Array<int> &shared_local,
385 Table &group_shared, Array<char> *entity_geom = NULL,
386 char geom = 0);
387
388 /** Uniquely encodes a set of leaf elements in the refinement hierarchy of
389 an NCMesh. Can be dumped to a stream, sent to another processor, loaded,
390 and decoded to identify the same set of elements (refinements) in a
391 different but compatible NCMesh. The encoding can optionally include
392 the refinement types needed to reach the leaves, so the element set can
393 be decoded (recreated) even if the receiver has an incomplete tree. */
395 {
396 public:
399 ElementSet(const ElementSet &other);
400
401 void Encode(const Array<int> &elements);
402 void Dump(std::ostream &os) const;
403
404 void Load(std::istream &is);
405 void Decode(Array<int> &elements) const;
406
407 void SetNCMesh(NCMesh *ncmesh_) { this->ncmesh = ncmesh_; }
408 const NCMesh* GetNCMesh() const { return ncmesh; }
409
410 protected:
411 Array<unsigned char> data; ///< encoded refinement (sub-)trees
414
415 void EncodeTree(int elem);
416 void DecodeTree(int elem, int &pos, Array<int> &elements) const;
417
418 void WriteInt(int value);
419 int GetInt(int pos) const;
420 void FlagElements(const Array<int> &elements, char flag);
421
422#ifdef MFEM_DEBUG
424 std::string RefPath() const;
425#endif
426 };
427
428 /** Adjust some of the MeshIds before encoding for recipient 'rank', so that
429 they only reference elements that exist in the recipient's ref. tree. */
430 void AdjustMeshIds(Array<MeshId> ids[], int rank);
431
432 void ChangeVertexMeshIdElement(NCMesh::MeshId &id, int elem);
433 void ChangeEdgeMeshIdElement(NCMesh::MeshId &id, int elem);
434 void ChangeRemainingMeshIds(Array<MeshId> &ids, int pos,
435 const Array<Pair<int, int> > &find);
436
437 // Write/read a processor-independent encoding of vertex/edge/face IDs.
438 void EncodeMeshIds(std::ostream &os, Array<MeshId> ids[]);
439 void DecodeMeshIds(std::istream &is, Array<MeshId> ids[]);
440
441 // Write/read comm groups and a list of their IDs.
442 void EncodeGroups(std::ostream &os, const Array<GroupId> &ids);
443 void DecodeGroups(std::istream &is, Array<GroupId> &ids);
444
445 bool CheckElementType(int elem, int type);
446
447 Array<int> tmp_neighbors; // temporary, used by ElementNeighborProcessors
448
449 /** Return a list of processors that own elements in the immediate
450 neighborhood of 'elem' (i.e., vertex, edge and face neighbors),
451 and are not 'MyRank'. */
452 void ElementNeighborProcessors(int elem, Array<int> &ranks);
453
454 /** Get a list of ranks that own elements in the neighborhood of our region.
455 NOTE: MyRank is not included. */
456 void NeighborProcessors(Array<int> &neighbors);
457
458 /** Traverse the (local) refinement tree and determine which subtrees are
459 no longer needed, i.e., their leaves are not owned by us nor are they our
460 ghosts. These subtrees are then derefined. */
461 void Prune();
462
463 /// Internal. Recursive part of Prune().
464 bool PruneTree(int elem);
465
466
467 /** A base for internal messages used by Refine(), Derefine() and Rebalance().
468 * Allows sending values associated with elements in a set.
469 * If RefType == true, the element set is recreated on the receiving end.
470 */
471 template<class ValueType, bool RefTypes, int Tag>
472 class ElementValueMessage : public VarMessage<Tag>
473 {
474 public:
475 using VarMessage<Tag>::data;
476 std::vector<int> elements;
477 std::vector<ValueType> values;
478
479 int Size() const { return static_cast<int>(elements.size()); }
480 void Reserve(int size) { elements.reserve(size); values.reserve(size); }
481
482 void Add(int elem, ValueType val)
483 { elements.push_back(elem); values.push_back(val); }
484
485 /// Set pointer to ParNCMesh (needed to encode the message).
486 void SetNCMesh(ParNCMesh* pncmesh_) { this->pncmesh = pncmesh_; }
487
489
490 protected:
492
493 void Encode(int) override;
494 void Decode(int) override;
495 };
496
497 /** Used by ParNCMesh::Refine() to inform neighbors about refinements at
498 * the processor boundary. This keeps their ghost layers synchronized.
499 */
501 VarMessageTag::NEIGHBOR_REFINEMENT_VM>
502 {
503 public:
504 void AddRefinement(int elem, char ref_type) { Add(elem, ref_type); }
505 typedef std::map<int, NeighborRefinementMessage> Map;
506 };
507
508 /** Used by ParNCMesh::Derefine() to keep the ghost layers synchronized.
509 */
511 VarMessageTag::NEIGHBOR_DEREFINEMENT_VM>
512 {
513 public:
514 void AddDerefinement(int elem, int rank) { Add(elem, rank); }
515 typedef std::map<int, NeighborDerefinementMessage> Map;
516 };
517
518 /** Used in Step 2 of Rebalance() to synchronize new rank assignments in
519 * the ghost layer.
520 */
522 VarMessageTag::NEIGHBOR_ELEMENT_RANK_VM>
523 {
524 public:
525 void AddElementRank(int elem, int rank) { Add(elem, rank); }
526 typedef std::map<int, NeighborElementRankMessage> Map;
527 };
528
529 /** Used by Rebalance() to send elements and their ranks. Note that
530 * RefTypes == true which means the refinement hierarchy will be recreated
531 * on the receiving side.
532 */
533 class RebalanceMessage : public ElementValueMessage<int, true,
534 VarMessageTag::REBALANCE_VM>
535 {
536 public:
537 void AddElementRank(int elem, int rank) { Add(elem, rank); }
538 typedef std::map<int, RebalanceMessage> Map;
539 };
540
541 /** Allows migrating element data (DOFs) after Rebalance().
542 * Used by SendRebalanceDofs and RecvRebalanceDofs.
543 */
544 class RebalanceDofMessage : public VarMessage<VarMessageTag::REBALANCE_DOF_VM>
545 {
546 public:
547 std::vector<int> elem_ids, dofs;
549
550 void SetElements(const Array<int> &elems, NCMesh *ncmesh);
551 void SetNCMesh(NCMesh* ncmesh) { eset.SetNCMesh(ncmesh); }
552 std::size_t MemoryUsage() const;
553
554 typedef std::map<int, RebalanceDofMessage> Map;
555
556 protected:
558
559 void Encode(int) override;
560 void Decode(int) override;
561 };
562
563 /** Used by CommunicateGhostData to send p-refined element indices and
564 their order. */
566 VarMessageTag::NEIGHBOR_PREFINEMENT_VM>
567 {
568 public:
569 void AddRefinement(int elem, int order) { Add(elem, order); }
570 typedef std::map<int, NeighborPRefinementMessage> Map;
571 };
572
573 /** Assign new Element::rank to leaf elements and send them to their new
574 owners, keeping the ghost layer up to date. Used by Rebalance() and
575 Derefine(). 'target_elements' is the number of elements this rank
576 is supposed to own after the exchange. If this number is not known
577 a priori, the parameter can be set to -1, but more expensive
578 communication (synchronous sends and a barrier) will be used in that
579 case. */
580 void RedistributeElements(Array<int> &new_ranks, int target_elements,
581 bool record_comm);
582
583 /** Recorded communication pattern from last Rebalance. Used by
584 Send/RecvRebalanceDofs to ship element DOFs. */
587
588 /** After Rebalance, this array holds the old element indices, or -1 if an
589 element didn't exist in the mesh previously. After Derefine, it holds
590 the ranks of the old (potentially non-existent) fine elements. */
592
593 /// Stores modified point matrices created by GetFaceNeighbors
595 void ClearAuxPM();
596
597 std::size_t GroupsMemoryUsage() const;
598
599 // The following functions help with checking for anisotropic refinements in
600 // different directions on a face shared by two hexahedral elements.
601
602 /** For the face with ordered vertices vn* and neighboring element @a elem,
603 check whether the other neighboring element (if it exists) is marked for
604 a horizontal refinement conflicting with a vertical split. */
605 void CheckRefAnisoFace(int elem, int vn1, int vn2, int vn3, int vn4,
606 const Array<Refinement> &refinements,
607 const std::map<int, int> &elemToRef,
608 std::set<int> &conflicts);
609
610 /** For the face with ordered vertices vn*, edge midpoints en*, and
611 neighboring element @a elem, check whether the other neighboring element
612 (if it exists) is marked for a refinement conflicting with an isotropic
613 refinement of the face. */
614 void CheckRefIsoFace(int elem, int vn1, int vn2, int vn3, int vn4,
615 int en1, int en2, int en3, int en4,
616 const Array<Refinement> &refinements,
617 const std::map<int, int> &elemToRef,
618 std::set<int> &conflicts);
619
620 /// Check whether any master face is marked for a conflicting refinement.
621 void CheckRefinementMaster(const Array<Refinement> &refinements,
622 const std::map<int, int> &elemToRef,
623 std::set<int> &conflicts);
624
625 /** Check whether the refinement of the element with index @a elem and type
626 @a ref_type would cause a conflict. */
627 void CheckRefinement(int elem, char ref_type,
628 const Array<Refinement> &refinements,
629 const std::map<int, int> &elemToRef,
630 std::set<int> &conflicts);
631
632 /** For a vertical split of the master face with ordered vertices
633 (vn1, vn2, vn3, vn4), check whether there is a horizontal split among the
634 slave faces. */
635 bool CheckRefAnisoFaceSplits(int vn1, int vn2, int vn3, int vn4,
636 int level = 0);
637 friend class NeighborRowMessage;
638 friend class NeighborOrderMessage;
639};
640
641
642// comparison operator so that MeshId can be used as key in std::map
643inline bool operator< (const NCMesh::MeshId &a, const NCMesh::MeshId &b)
644{
645 return a.index < b.index;
646}
647
648// equality of MeshId is based on 'index' (element/local are not unique)
649inline bool operator== (const NCMesh::MeshId &a, const NCMesh::MeshId &b)
650{
651 return a.index == b.index;
652}
653
654} // namespace mfem
655
656#endif // MFEM_USE_MPI
657
658#endif // MFEM_PNCMESH
int Size() const
Return the logical size of the array.
Definition array.hpp:166
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:208
Mesh data type.
Definition mesh.hpp:65
A class for non-conforming AMR. The class is not used directly by the user, rather it is an extension...
Definition ncmesh.hpp:190
int NGhostElements
Definition ncmesh.hpp:785
int PrintMemoryDetail() const
Definition ncmesh.cpp:7030
HashTable< Face > faces
Definition ncmesh.hpp:684
BlockArray< Element > elements
Definition ncmesh.hpp:688
Array< int > leaf_elements
finest elements, in Mesh ordering (+ ghosts)
Definition ncmesh.hpp:787
int NGhostVertices
Definition ncmesh.hpp:785
const NCList & GetVertexList()
Definition ncmesh.hpp:384
const NCList & GetFaceList()
Return the current list of conforming and nonconforming faces.
Definition ncmesh.hpp:369
const NCList & GetEdgeList()
Return the current list of conforming and nonconforming edges.
Definition ncmesh.hpp:376
int MyRank
used in parallel, or when loading a parallel file in serial
Definition ncmesh.hpp:589
int NGhostEdges
Definition ncmesh.hpp:785
long MemoryUsage() const
Return total number of bytes allocated.
Definition ncmesh.cpp:7007
int NGhostFaces
Definition ncmesh.hpp:785
A pair of objects.
Class for parallel meshes.
Definition pmesh.hpp:34
void DecodeTree(int elem, int &pos, Array< int > &elements) const
Definition pncmesh.cpp:2973
Array< unsigned char > data
encoded refinement (sub-)trees
Definition pncmesh.hpp:411
const NCMesh * GetNCMesh() const
Definition pncmesh.hpp:408
void Encode(const Array< int > &elements)
Definition pncmesh.cpp:2934
ElementSet(NCMesh *ncmesh=NULL, bool include_ref_types=false)
Definition pncmesh.hpp:397
int GetInt(int pos) const
Definition pncmesh.cpp:2873
void Decode(Array< int > &elements) const
Definition pncmesh.cpp:3015
void FlagElements(const Array< int > &elements, char flag)
Definition pncmesh.cpp:2882
std::string RefPath() const
Definition pncmesh.cpp:2955
void Load(std::istream &is)
Definition pncmesh.cpp:3031
void Dump(std::ostream &os) const
Definition pncmesh.cpp:3025
void SetNCMesh(NCMesh *ncmesh_)
Definition pncmesh.hpp:407
std::vector< ValueType > values
Definition pncmesh.hpp:477
void Add(int elem, ValueType val)
Definition pncmesh.hpp:482
void SetNCMesh(ParNCMesh *pncmesh_)
Set pointer to ParNCMesh (needed to encode the message).
Definition pncmesh.hpp:486
std::map< int, NeighborDerefinementMessage > Map
Definition pncmesh.hpp:515
void AddDerefinement(int elem, int rank)
Definition pncmesh.hpp:514
void AddElementRank(int elem, int rank)
Definition pncmesh.hpp:525
std::map< int, NeighborElementRankMessage > Map
Definition pncmesh.hpp:526
void AddRefinement(int elem, int order)
Definition pncmesh.hpp:569
std::map< int, NeighborPRefinementMessage > Map
Definition pncmesh.hpp:570
void AddRefinement(int elem, char ref_type)
Definition pncmesh.hpp:504
std::map< int, NeighborRefinementMessage > Map
Definition pncmesh.hpp:505
void SetElements(const Array< int > &elems, NCMesh *ncmesh)
Definition pncmesh.cpp:3420
std::map< int, RebalanceDofMessage > Map
Definition pncmesh.hpp:554
std::map< int, RebalanceMessage > Map
Definition pncmesh.hpp:538
void AddElementRank(int elem, int rank)
Definition pncmesh.hpp:537
A parallel extension of the NCMesh class.
Definition pncmesh.hpp:63
bool AnisotropicConflict(const Array< Refinement > &refinements, std::set< int > &conflicts)
Definition pncmesh.cpp:1507
Array< int > entity_elem_local[3]
Definition pncmesh.hpp:322
void SendRebalanceDofs(int old_ndofs, const Table &old_element_dofs, long old_global_offset, FiniteElementSpace *space)
Use the communication pattern from last Rebalance() to send element DOFs.
Definition pncmesh.cpp:2786
void MakeSharedTable(int ngroups, int ent, Array< int > &shared_local, Table &group_shared, Array< char > *entity_geom=NULL, char geom=0)
Definition pncmesh.cpp:832
Array< int > tmp_neighbors
Definition pncmesh.hpp:447
bool IsGhost(int entity, int index) const
Return true if the specified vertex/edge/face is a ghost.
Definition pncmesh.hpp:194
NCList shared_edges
Definition pncmesh.hpp:325
int GetFaceOrientation(int index) const
Return (shared) face orientation relative to its owner element.
Definition pncmesh.hpp:149
Array< Connection > entity_index_rank[3]
Definition pncmesh.hpp:367
GroupMap group_id
Definition pncmesh.hpp:312
std::map< CommGroup, GroupId > GroupMap
Definition pncmesh.hpp:309
GroupId GetEntityGroupId(int entity, int index)
Definition pncmesh.hpp:172
int GetNGhostEdges() const
Definition pncmesh.hpp:123
RebalanceDofMessage::Map send_rebalance_dofs
Definition pncmesh.hpp:585
void CalcFaceOrientations()
Definition pncmesh.cpp:637
const Array< int > & GetDerefineOldRanks() const
Definition pncmesh.hpp:239
void DecodeGroups(std::istream &is, Array< GroupId > &ids)
Definition pncmesh.cpp:3320
bool PruneTree(int elem)
Internal. Recursive part of Prune().
Definition pncmesh.cpp:1437
bool CheckElementType(int elem, int type)
Definition pncmesh.cpp:766
void CheckRefinement(int elem, char ref_type, const Array< Refinement > &refinements, const std::map< int, int > &elemToRef, std::set< int > &conflicts)
Definition pncmesh.cpp:1849
bool IsParallel() const override
Return true if using more than one MPI process.
Definition pncmesh.hpp:224
const CommGroup & GetGroup(GroupId id) const
Return a list of ranks contained in the group of the given ID.
Definition pncmesh.hpp:184
void GetGhostElements(Array< int > &gelem)
Definition pncmesh.cpp:3620
void Trim() override
Save memory by releasing all non-essential and cached data.
Definition pncmesh.cpp:3501
void BuildVertexList() override
Definition pncmesh.cpp:339
void FindEdgesOfGhostElement(int elem, Array< int > &edges)
Definition pncmesh.cpp:277
void FindFacesOfGhostElement(int elem, Array< int > &faces)
Definition pncmesh.cpp:303
Array< int > ghost_layer
list of elements whose 'element_type' == 2.
Definition pncmesh.hpp:337
void BuildFaceList() override
Definition pncmesh.cpp:151
void GetFaceNeighbors(class ParMesh &pmesh)
Definition pncmesh.cpp:993
int GetNGhostFaces() const
Definition pncmesh.hpp:124
void LimitNCLevel(int max_nc_level) override
Parallel version of NCMesh::LimitNCLevel.
Definition pncmesh.cpp:2087
RebalanceDofMessage::Map recv_rebalance_dofs
Definition pncmesh.hpp:586
void ChangeVertexMeshIdElement(NCMesh::MeshId &id, int elem)
Definition pncmesh.cpp:3122
void UpdateLayers()
Definition pncmesh.cpp:728
void EncodeGroups(std::ostream &os, const Array< GroupId > &ids)
Definition pncmesh.cpp:3278
virtual ~ParNCMesh()
Definition pncmesh.cpp:93
void Refine(const Array< Refinement > &refinements) override
Definition pncmesh.cpp:2009
int ElementRank(int index) const
Definition pncmesh.hpp:212
void FindEdgesOfGhostFace(int face, Array< int > &edges)
Definition pncmesh.cpp:256
Array< GroupId > entity_conf_group[3]
Definition pncmesh.hpp:320
Array< int > boundary_layer
list of type 3 elements
Definition pncmesh.hpp:338
int Partition(long index, long total_elements) const
Return the processor number for a global element number.
Definition pncmesh.hpp:343
void AdjustMeshIds(Array< MeshId > ids[], int rank)
Definition pncmesh.cpp:3040
NCList shared_vertices
Definition pncmesh.hpp:325
std::size_t GroupsMemoryUsage() const
Definition pncmesh.cpp:3542
const NCList & GetSharedVertices()
Definition pncmesh.hpp:129
void ChangeEdgeMeshIdElement(NCMesh::MeshId &id, int elem)
Definition pncmesh.cpp:3140
void GetConformingSharedStructures(class ParMesh &pmesh)
Definition pncmesh.cpp:892
bool CheckRefAnisoFaceSplits(int vn1, int vn2, int vn3, int vn4, int level=0)
Definition pncmesh.cpp:1638
void Derefine(const Array< int > &derefs) override
Definition pncmesh.cpp:2136
void Rebalance(const Array< int > *custom_partition=NULL)
Definition pncmesh.cpp:2448
int GetNGhostElements() const override
Definition pncmesh.hpp:125
void ElementNeighborProcessors(int elem, Array< int > &ranks)
Definition pncmesh.cpp:783
void RecvRebalanceDofs(Array< int > &elements, Array< long > &dofs)
Receive element DOFs sent by SendRebalanceDofs().
Definition pncmesh.cpp:2819
static int get_face_orientation(const Face &face, const Element &e1, const Element &e2, int local[2]=NULL)
Definition pncmesh.cpp:607
void GetFineToCoarsePartitioning(const Array< int > &derefs, Array< int > &new_ranks) const
Definition pncmesh.cpp:2105
void ElementSharesFace(int elem, int local, int face) override
Definition pncmesh.cpp:128
void BuildEdgeList() override
Definition pncmesh.cpp:218
Array< char > tmp_shared_flag
Definition pncmesh.hpp:366
NCList shared_faces
Definition pncmesh.hpp:325
Array< int > old_index_or_rank
Definition pncmesh.hpp:591
MPI_Comm MyComm
Definition pncmesh.hpp:305
void CheckRefIsoFace(int elem, int vn1, int vn2, int vn3, int vn4, int en1, int en2, int en3, int en4, const Array< Refinement > &refinements, const std::map< int, int > &elemToRef, std::set< int > &conflicts)
Definition pncmesh.cpp:1837
std::vector< int > CommGroup
Definition pncmesh.hpp:155
void DecodeMeshIds(std::istream &is, Array< MeshId > ids[])
Definition pncmesh.cpp:3221
void GetBoundaryClosure(const Array< int > &bdr_attr_is_ess, Array< int > &bdr_vertices, Array< int > &bdr_edges, Array< int > &bdr_faces) override
Definition pncmesh.cpp:663
void EncodeMeshIds(std::ostream &os, Array< MeshId > ids[])
Definition pncmesh.cpp:3178
void CheckRefinementMaster(const Array< Refinement > &refinements, const std::map< int, int > &elemToRef, std::set< int > &conflicts)
Check whether any master face is marked for a conflicting refinement.
Definition pncmesh.cpp:1665
Array< DenseMatrix * > aux_pm_store
Stores modified point matrices created by GetFaceNeighbors.
Definition pncmesh.hpp:594
void CheckDerefinementNCLevel(const Table &deref_table, Array< int > &level_ok, int max_nc_level) override
Definition pncmesh.cpp:2390
void RedistributeElements(Array< int > &new_ranks, int target_elements, bool record_comm)
Definition pncmesh.cpp:2509
const NCList & GetSharedList(int entity)
Helper to get shared vertices/edges/faces ('entity' == 0/1/2 resp.).
Definition pncmesh.hpp:138
Array< int > tmp_owner
Definition pncmesh.hpp:365
int GetMyRank() const
Return the MPI rank for this process.
Definition pncmesh.hpp:221
int GetNElements() const
Definition pncmesh.hpp:120
GroupId GetSingletonGroup(int rank)
Definition pncmesh.cpp:477
void ChangeRemainingMeshIds(Array< MeshId > &ids, int pos, const Array< Pair< int, int > > &find)
Definition pncmesh.cpp:3166
Array< char > face_orient
Definition pncmesh.hpp:327
GroupId GetEntityOwnerId(int entity, int index)
Return vertex/edge/face ('entity' == 0/1/2, resp.) owner.
Definition pncmesh.hpp:158
Array< char > element_type
Definition pncmesh.hpp:335
void InitOwners(int num, Array< GroupId > &entity_owner)
Definition pncmesh.cpp:371
int GetNGhostVertices() const
Definition pncmesh.hpp:122
void CheckRefAnisoFace(int elem, int vn1, int vn2, int vn3, int vn4, const Array< Refinement > &refinements, const std::map< int, int > &elemToRef, std::set< int > &conflicts)
Definition pncmesh.cpp:1776
GroupList groups
Definition pncmesh.hpp:311
Array< GroupId > entity_owner[3]
Definition pncmesh.hpp:315
void CalculatePMatrixGroups()
Definition pncmesh.cpp:535
void ElementSharesEdge(int elem, int local, int enode) override
Definition pncmesh.cpp:193
ParNCMesh()=default
const NCList & GetSharedEdges()
Definition pncmesh.hpp:130
void GetDebugMesh(Mesh &debug_mesh) const
Definition pncmesh.cpp:3484
void Update() override
Definition pncmesh.cpp:98
std::vector< CommGroup > GroupList
Definition pncmesh.hpp:308
bool GroupContains(GroupId id, int rank) const
Return true if group 'id' contains the given rank.
Definition pncmesh.cpp:486
const NCList & GetSharedFaces()
Definition pncmesh.hpp:131
const Array< int > & GetRebalanceOldIndex() const
Definition pncmesh.hpp:235
Array< GroupId > entity_pmat_group[3]
Definition pncmesh.hpp:317
void MakeSharedList(const NCList &list, NCList &shared)
Definition pncmesh.cpp:381
void AddConnections(int entity, int index, const Array< int > &ranks)
Definition pncmesh.cpp:527
int InitialPartition(int index) const
Helper to get the partitioning when the serial mesh gets split initially.
Definition pncmesh.hpp:347
void NeighborProcessors(Array< int > &neighbors)
Definition pncmesh.cpp:815
void CreateGroups(int nentities, Array< Connection > &index_rank, Array< GroupId > &entity_group)
Definition pncmesh.cpp:497
void SynchronizeDerefinementData(Array< Type > &elem_data, const Table &deref_table)
Definition pncmesh.cpp:2308
GroupId GetGroupId(const CommGroup &group)
Definition pncmesh.cpp:461
void CommunicateGhostData(const Array< VarOrderElemInfo > &sendData, Array< VarOrderElemInfo > &recvData)
Definition pncmesh.cpp:3633
long PartitionFirstIndex(int rank, long total_elements) const
Return the global index of the first element owned by processor 'rank'.
Definition pncmesh.hpp:351
void ElementSharesVertex(int elem, int local, int vnode) override
Definition pncmesh.cpp:316
Subdomain representation of a topological parent in another ParMesh.
Definition psubmesh.hpp:54
Table stores the connectivity of elements of TYPE I to elements of TYPE II. For example,...
Definition table.hpp:43
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
string space
bool operator==(const Array< T > &LHS, const Array< T > &RHS)
Definition array.hpp:406
bool operator<(const Pair< A, B > &p, const Pair< A, B > &q)
Comparison operator for class Pair, based on the first element only.
Identifies a vertex/edge/face in both Mesh and NCMesh.
Definition ncmesh.hpp:260
Lists all edges/faces in the nonconforming mesh.
Definition ncmesh.hpp:301
Variable-length MPI message containing unspecific binary data.