MFEM  v4.6.0
Finite element discretization library
psubmesh.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, 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_PSUBMESH
13 #define MFEM_PSUBMESH
14 
15 #include "../../config/config.hpp"
16 
17 #ifdef MFEM_USE_MPI
18 
19 #include "ptransfermap.hpp"
20 #include "../pmesh.hpp"
21 #include "../../fem/pgridfunc.hpp"
22 #include "submesh.hpp"
23 
24 namespace mfem
25 {
26 
27 /**
28  * @brief Subdomain representation of a topological parent in another ParMesh.
29  *
30  * ParSubMesh is a subdomain representation of a ParMesh defined on its parents
31  * attributes. The current implementation creates either a domain or surface
32  * subset of the parent Mesh and reuses the parallel distribution.
33  *
34  * The attributes are taken from the parent. That means if a volume is extracted
35  * from a volume, it has the same domain attribute as the parent. Its boundary
36  * attributes are generated (there will be one boundary attribute 1 for all of
37  * the boundaries).
38  *
39  * If a surface is extracted from a volume, the boundary attribute from the
40  * parent is assigned to be the new domain attribute. Its boundary attributes
41  * are generated (there will be one boundary attribute 1 for all of the
42  * boundaries).
43  *
44  * For more customized boundary attributes, the resulting ParSubMesh has to be
45  * postprocessed.
46  *
47  * ParSubMesh maintains the parallel distribution of the elements on
48  * corresponding processors.
49  */
50 
51 class ParSubMesh : public ParMesh
52 {
53 public:
54  ParSubMesh() = delete;
55 
56  /**
57  * @brief Create a domain ParSubMesh from it's parent.
58  *
59  * The ParSubMesh object expects the parent ParMesh object to be valid for
60  * the entire object lifetime. The @a domain_attributes have to mark exactly
61  * one connected subset of the parent Mesh.
62  *
63  * @param[in] parent Parent ParMesh
64  * @param[in] domain_attributes Domain attributes to extract
65  */
66  static ParSubMesh CreateFromDomain(const ParMesh &parent,
67  Array<int> &domain_attributes);
68 
69  /**
70  * @brief Create a surface ParSubMesh from it's parent.
71  *
72  * The ParSubMesh object expects the parent ParMesh object to be valid for the
73  * entire object lifetime. The @a boundary_attributes have to mark exactly one
74  * connected subset of the parent Mesh.
75  *
76  * @param[in] parent Parent ParMesh
77  * @param[in] boundary_attributes Boundary attributes to extract
78  */
79  static ParSubMesh CreateFromBoundary(const ParMesh &parent,
80  Array<int> &boundary_attributes);
81 
82  /**
83  * @brief Get the parent ParMesh object
84  */
85  const ParMesh* GetParent() const
86  {
87  return &parent_;
88  }
89 
90  /**
91  * @brief Get the From indicator.
92  *
93  * Indicates whether the ParSubMesh has been created from a domain or
94  * surface.
95  */
97  {
98  return from_;
99  }
100 
101  /**
102  * @brief Get the parent element id map.
103  *
104  * ParSubMesh element id (array index) to parent ParMesh element id.
105  */
107  {
108  return parent_element_ids_;
109  }
110 
111  /**
112  * @brief Get the parent vertex id map.
113  *
114  * ParSubMesh vertex id (array index) to parent ParMesh vertex id.
115  */
117  {
118  return parent_vertex_ids_;
119  }
120 
121  /**
122  * @brief Get the parent face id map.
123  *
124  * ParSubMesh face id (array index) to parent ParMesh face id.
125  */
127  {
128  return parent_face_ids_;
129  }
130 
131  /**
132  * @brief Get the relative face orientations
133  *
134  * ParSubMesh element id (array index) to parent ParMesh face orientation.
135  */
137  {
138  return parent_face_ori_;
139  }
140 
141  /**
142  * @brief Get the ParSubMesh face id map.
143  *
144  * ParMesh face id (array index) to ParSubMesh face id.
145  */
147  {
148  return parent_to_submesh_face_ids_;
149  }
150 
151  /**
152  * @brief Transfer the dofs of a ParGridFunction.
153  *
154  * The @a src ParGridFunction can either be defined on a ParMesh or a
155  * ParSubMesh and is transferred appropriately.
156  *
157  * @note Either @a src or @a dst has to be defined on a ParSubMesh.
158  *
159  * @param[in] src
160  * @param[out] dst
161  */
162  static void Transfer(const ParGridFunction &src, ParGridFunction &dst);
163 
164  /**
165  * @brief Create a Transfer Map object.
166  *
167  * The @a src ParGridFunction can either be defined on a ParMesh or a
168  * ParSubMesh and is transferred appropriately.
169  *
170  * @note Either @a src or @a dst has to be defined on a ParSubMesh.
171  */
173  const ParGridFunction &dst);
174 
175  /**
176  * @brief Check if ParMesh @a m is a ParSubMesh.
177  *
178  * @param m The input ParMesh
179  */
180  static bool IsParSubMesh(const ParMesh *m)
181  {
182  return dynamic_cast<const ParSubMesh *>(m) != nullptr;
183  }
184 
185 private:
186  ParSubMesh(const ParMesh &parent, SubMesh::From from, Array<int> &attributes);
187 
188  /**
189  * @brief Find shared vertices on the ParSubMesh.
190  *
191  * Uses the parent GroupCommunicator to determine shared vertices.
192  * Collective. Limited to 32 ranks.
193  *
194  * Array of integer bitfields to indicate if rank X (bit location) has shared
195  * vtx Y (array index).
196  *
197  * Example with 4 ranks and X shared vertices.
198  * * R0-R3 indicate ranks 0 to 3
199  * * v0-v3 indicate vertices 0 to 3
200  * The array is used as follows (only relevant bits shown):
201  *
202  * rhvtx[0] = [0...0 1 0 1] Rank 0 and 2 have shared vertex 0
203  * rhvtx[1] = [0...0 1 1 1] Rank 0, 1 and 2 have shared vertex 1
204  * rhvtx[2] = [0...0 0 1 1] Rank 0 and 1 have shared vertex 2
205  * rhvtx[3] = [0...1 0 1 0] Rank 1 and 3 have shared vertex 3. Corner case
206  * which shows that a rank can contribute the shared vertex, but the adjacent
207  * element or edge might not be included in the relevant SubMesh.
208  *
209  * +--------------+--------------+...
210  * | |v0 |
211  * | R0 | R2 | R3
212  * | | |
213  * +--------------+--------------+...
214  * | |v1 |
215  * | R0 | R1 | R3
216  * | |v2 |v3
217  * +--------------+--------------+...
218  *
219  * @param[out] rhvtx Encoding of which rank contains which vertex.
220  */
221  void FindSharedVerticesRanks(Array<int> &rhvtx);
222 
223  /**
224  * @brief Find shared edges on the ParSubMesh.
225  *
226  * Uses the parent GroupCommunicator to determine shared edges.
227  * Collective. Limited to 32 ranks.
228  *
229  * See FindSharedVerticesRanks for the encoding for @a rhe.
230  *
231  * @param[out] rhe Encoding of which rank contains which edge.
232  */
233  void FindSharedEdgesRanks(Array<int> &rhe);
234 
235  /**
236  * @brief Find shared faces on the ParSubMesh.
237  *
238  * Uses the parent GroupCommunicator to determine shared faces. Collective.
239  *
240  * The encoded output arrays @a rhq and @a rht contain either 0, 1 or 2 for
241  * each shared face.
242  *
243  * 0: Face might have been a shared face in the parent ParMesh, but is
244  * not contained in the ParSubMesh.
245  * 1: Face is contained in the ParSubMesh but only on one rank.
246  * 2: Face is contained in the ParSubMesh and shared by two ranks. This
247  * is the only feasible entity of a shared face in a ParSubMesh.
248  *
249  * @param[out] rhq Encoding of which rank contains which face quadrilateral.
250  */
251  void FindSharedFacesRanks(Array<int>& rht, Array<int> &rhq);
252 
253  /**
254  * @brief Append shared vertices encoded in @a rhvtx to @a groups.
255  *
256  * @param[in,out] groups
257  * @param[in,out] rhvtx Encoding of which rank contains which vertex. The
258  * output is reused s.t. the array index i (the vertex id) is the associated
259  * group.
260  */
261  void AppendSharedVerticesGroups(ListOfIntegerSets &groups, Array<int> &rhvtx);
262 
263  /**
264  * @brief Append shared edges encoded in @a rhe to @a groups.
265  *
266  * @param[in,out] groups
267  * @param[in,out] rhe Encoding of which rank contains which edge. The output
268  * is reused s.t. the array index i (the edge id) is the associated group.
269  */
270  void AppendSharedEdgesGroups(ListOfIntegerSets &groups, Array<int> &rhe);
271 
272  /**
273  * @brief Append shared faces encoded in @a rhq and @a rht to @a groups.
274  *
275  * @param[in,out] groups
276  * @param[in,out] rht Encoding of which rank contains which face triangle.
277  * The output is reused s.t. the array index i (the face triangle id) is the
278  * associated group.
279  * @param[in,out] rhq Encoding of which rank contains which face
280  * quadrilateral. The output is reused s.t. the array index i (the face
281  * quadrilateral id) is the associated group.
282  */
283  void AppendSharedFacesGroups(ListOfIntegerSets &groups, Array<int>& rht,
284  Array<int> &rhq);
285 
286  /**
287  * @brief Build vertex group.
288  *
289  * @param[in] ngroups Number of groups.
290  * @param[in] rhvtx Encoding of which rank contains which vertex.
291  * @param[in] nsverts Number of shared vertices.
292  */
293  void BuildVertexGroup(int ngroups, const Array<int>& rhvtx, int& nsverts);
294 
295  /**
296  * @brief Build edge group.
297  *
298  * @param[in] ngroups Number of groups.
299  * @param[in] rhe Encoding of which rank contains which edge.
300  * @param[in] nsedges Number of shared edges.
301  */
302  void BuildEdgeGroup(int ngroups, const Array<int>& rhe, int& nsedges);
303 
304  /**
305  * @brief Build face group.
306  *
307  * @param[in] ngroups Number of groups.
308  * @param[in] rht Encoding of which rank contains which face triangle.
309  * @param[in] nstrias Number of shared face triangles.
310  * @param[in] rhq Encoding of which rank contains which face quadrilateral.
311  * @param[in] nsquads Number of shared face quadrilaterals.
312  */
313  void BuildFaceGroup(int ngroups, const Array<int>& rht, int& nstrias,
314  const Array<int>& rhq, int& nsquads);
315 
316  /**
317  * @brief Build the shared vertex to local vertex mapping.
318  *
319  * @param nsverts Number of shared vertices.
320  * @param rhvtx Encoding of which rank contains which vertex.
321  */
322  void BuildSharedVerticesMapping(const int nsverts, const Array<int>& rhvtx);
323 
324  /**
325  * @brief Build the shared edge to local edge mapping.
326  *
327  * @param[in] nsedges Number of shared edges.
328  * @param[in] rhe Encoding of which rank contains which edge.
329  */
330  void BuildSharedEdgesMapping(const int nsedges, const Array<int>& rhe);
331 
332  /**
333  * @brief Build the shared faces to local faces mapping.
334  *
335  * Shared faces are divided into triangles and quadrilaterals.
336  *
337  * @param[in] nstrias Number of shared face triangles.
338  * @param[in] rht Encoding of which rank contains which face triangle.
339  * @param[in] nsquads Number of shared face quadrilaterals.
340  * @param[in] rhq Encoding of which rank contains which face quadrilateral.
341  */
342  void BuildSharedFacesMapping(const int nstrias, const Array<int>& rht,
343  const int nsquads, const Array<int>& rhq);
344 
345  /// The parent Mesh
346  const ParMesh &parent_;
347 
348  /// Indicator from which part of the parent ParMesh the ParSubMesh is going to
349  /// be created.
350  SubMesh::From from_;
351 
352  /// Attributes on the parent ParMesh on which the ParSubMesh is created. Could
353  /// either be domain or boundary attributes (determined by from_).
354  Array<int> attributes_;
355 
356  /// Mapping from ParSubMesh element ids (index of the array), to the parent
357  /// ParMesh element ids.
358  Array<int> parent_element_ids_;
359 
360  /// Mapping from ParSubMesh vertex ids (index of the array), to the parent
361  /// ParMesh vertex ids.
362  Array<int> parent_vertex_ids_;
363 
364  /// Mapping from ParSubMesh edge ids (index of the array), to the parent
365  /// ParMesh edge ids.
366  Array<int> parent_edge_ids_;
367 
368  /// Mapping from ParSubMesh face ids (index of the array), to the parent
369  /// ParMesh face ids.
370  Array<int> parent_face_ids_;
371 
372  /// Mapping from SubMesh face ids (index of the array), to the orientation
373  /// of the face relative to the parent face.
374  Array<int> parent_face_ori_;
375 
376  /// Mapping from parent ParMesh vertex ids (index of the array), to the
377  /// ParSubMesh vertex ids. Inverse map of parent_vertex_ids_.
378  Array<int> parent_to_submesh_vertex_ids_;
379 
380  /// Mapping from parent ParMesh edge ids (index of the array), to the
381  /// ParSubMesh edge ids. Inverse map of parent_edge_ids_.
382  Array<int> parent_to_submesh_edge_ids_;
383 
384  /// Mapping from parent ParMesh face ids (index of the array), to the
385  /// ParSubMesh face ids. Inverse map of parent_face_ids_.
386  Array<int> parent_to_submesh_face_ids_;
387 };
388 
389 } // namespace mfem
390 
391 #endif // MFEM_USE_MPI
392 
393 #endif
static ParSubMesh CreateFromBoundary(const ParMesh &parent, Array< int > &boundary_attributes)
Create a surface ParSubMesh from it&#39;s parent.
Definition: psubmesh.cpp:32
const Array< int > & GetParentElementIDMap() const
Get the parent element id map.
Definition: psubmesh.hpp:106
const ParMesh * GetParent() const
Get the parent ParMesh object.
Definition: psubmesh.hpp:85
const Array< int > & GetParentFaceIDMap() const
Get the parent face id map.
Definition: psubmesh.hpp:126
Subdomain representation of a topological parent in another ParMesh.
Definition: psubmesh.hpp:51
static ParSubMesh CreateFromDomain(const ParMesh &parent, Array< int > &domain_attributes)
Create a domain ParSubMesh from it&#39;s parent.
Definition: psubmesh.cpp:26
static bool IsParSubMesh(const ParMesh *m)
Check if ParMesh m is a ParSubMesh.
Definition: psubmesh.hpp:180
ParTransferMap represents a mapping of degrees of freedom from a source ParGridFunction to a destinat...
From
Indicator from which part of the parent Mesh the SubMesh is created.
Definition: submesh.hpp:46
static ParTransferMap CreateTransferMap(const ParGridFunction &src, const ParGridFunction &dst)
Create a Transfer Map object.
Definition: psubmesh.cpp:938
ParSubMesh()=delete
const Array< int > & GetParentToSubMeshFaceIDMap() const
Get the ParSubMesh face id map.
Definition: psubmesh.hpp:146
const Array< int > & GetParentFaceOrientations() const
Get the relative face orientations.
Definition: psubmesh.hpp:136
Class for parallel grid function.
Definition: pgridfunc.hpp:32
static void Transfer(const ParGridFunction &src, ParGridFunction &dst)
Transfer the dofs of a ParGridFunction.
Definition: psubmesh.cpp:932
const Array< int > & GetParentVertexIDMap() const
Get the parent vertex id map.
Definition: psubmesh.hpp:116
List of integer sets.
Definition: sets.hpp:62
Class for parallel meshes.
Definition: pmesh.hpp:32
SubMesh::From GetFrom() const
Get the From indicator.
Definition: psubmesh.hpp:96
Array< int > attributes
A list of all unique element attributes used by the Mesh.
Definition: mesh.hpp:273