MFEM  v4.5.1
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
psubmesh.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, 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 ParSubMesh face id map.
133  *
134  * ParMesh face id (array index) to ParSubMesh face id.
135  */
137  {
138  return parent_to_submesh_face_ids_;
139  }
140 
141  /**
142  * @brief Transfer the dofs of a ParGridFunction.
143  *
144  * The @a src ParGridFunction can either be defined on a ParMesh or a
145  * ParSubMesh and is transferred appropriately.
146  *
147  * @note Either @a src or @a dst has to be defined on a ParSubMesh.
148  *
149  * @param[in] src
150  * @param[out] dst
151  */
152  static void Transfer(const ParGridFunction &src, ParGridFunction &dst);
153 
154  /**
155  * @brief Create a Transfer Map object.
156  *
157  * The @a src ParGridFunction can either be defined on a ParMesh or a
158  * ParSubMesh and is transferred appropriately.
159  *
160  * @note Either @a src or @a dst has to be defined on a ParSubMesh.
161  */
163  const ParGridFunction &dst);
164 
165  /**
166  * @brief Check if ParMesh @a m is a ParSubMesh.
167  *
168  * @param m The input ParMesh
169  */
170  static bool IsParSubMesh(const ParMesh *m)
171  {
172  return dynamic_cast<const ParSubMesh *>(m) != nullptr;
173  }
174 
175 private:
176  ParSubMesh(const ParMesh &parent, SubMesh::From from, Array<int> &attributes);
177 
178  /**
179  * @brief Find shared vertices on the ParSubMesh.
180  *
181  * Uses the parent GroupCommunicator to determine shared vertices.
182  * Collective. Limited to 32 ranks.
183  *
184  * Array of integer bitfields to indicate if rank X (bit location) has shared
185  * vtx Y (array index).
186  *
187  * Example with 4 ranks and X shared vertices.
188  * * R0-R3 indicate ranks 0 to 3
189  * * v0-v3 indicate vertices 0 to 3
190  * The array is used as follows (only relevant bits shown):
191  *
192  * rhvtx[0] = [0...0 1 0 1] Rank 0 and 2 have shared vertex 0
193  * rhvtx[1] = [0...0 1 1 1] Rank 0, 1 and 2 have shared vertex 1
194  * rhvtx[2] = [0...0 0 1 1] Rank 0 and 1 have shared vertex 2
195  * rhvtx[3] = [0...1 0 1 0] Rank 1 and 3 have shared vertex 3. Corner case
196  * which shows that a rank can contribute the shared vertex, but the adjacent
197  * element or edge might not be included in the relevant SubMesh.
198  *
199  * +--------------+--------------+...
200  * | |v0 |
201  * | R0 | R2 | R3
202  * | | |
203  * +--------------+--------------+...
204  * | |v1 |
205  * | R0 | R1 | R3
206  * | |v2 |v3
207  * +--------------+--------------+...
208  *
209  * @param[out] rhvtx Encoding of which rank contains which vertex.
210  */
211  void FindSharedVerticesRanks(Array<int> &rhvtx);
212 
213  /**
214  * @brief Find shared edges on the ParSubMesh.
215  *
216  * Uses the parent GroupCommunicator to determine shared edges.
217  * Collective. Limited to 32 ranks.
218  *
219  * See FindSharedVerticesRanks for the encoding for @a rhe.
220  *
221  * @param[out] rhe Encoding of which rank contains which edge.
222  */
223  void FindSharedEdgesRanks(Array<int> &rhe);
224 
225  /**
226  * @brief Find shared faces on the ParSubMesh.
227  *
228  * Uses the parent GroupCommunicator to determine shared faces. Collective.
229  *
230  * The encoded output arrays @a rhq and @a rht contain either 0, 1 or 2 for
231  * each shared face.
232  *
233  * 0: Face might have been a shared face in the parent ParMesh, but is
234  * not contained in the ParSubMesh.
235  * 1: Face is contained in the ParSubMesh but only on one rank.
236  * 2: Face is contained in the ParSubMesh and shared by two ranks. This
237  * is the only feasible entity of a shared face in a ParSubMesh.
238  *
239  * @param[out] rhq Encoding of which rank contains which face quadrilateral.
240  */
241  void FindSharedFacesRanks(Array<int>& rht, Array<int> &rhq);
242 
243  /**
244  * @brief Append shared vertices encoded in @a rhvtx to @a groups.
245  *
246  * @param[in,out] groups
247  * @param[in,out] rhvtx Encoding of which rank contains which vertex. The
248  * output is reused s.t. the array index i (the vertex id) is the associated
249  * group.
250  */
251  void AppendSharedVerticesGroups(ListOfIntegerSets &groups, Array<int> &rhvtx);
252 
253  /**
254  * @brief Append shared edges encoded in @a rhe to @a groups.
255  *
256  * @param[in,out] groups
257  * @param[in,out] rhe Encoding of which rank contains which edge. The output
258  * is reused s.t. the array index i (the edge id) is the associated group.
259  */
260  void AppendSharedEdgesGroups(ListOfIntegerSets &groups, Array<int> &rhe);
261 
262  /**
263  * @brief Append shared faces encoded in @a rhq and @a rht to @a groups.
264  *
265  * @param[in,out] groups
266  * @param[in,out] rht Encoding of which rank contains which face triangle.
267  * The output is reused s.t. the array index i (the face triangle id) is the
268  * associated group.
269  * @param[in,out] rhq Encoding of which rank contains which face
270  * quadrilateral. The output is reused s.t. the array index i (the face
271  * quadrilateral id) is the associated group.
272  */
273  void AppendSharedFacesGroups(ListOfIntegerSets &groups, Array<int>& rht,
274  Array<int> &rhq);
275 
276  /**
277  * @brief Build vertex group.
278  *
279  * @param[in] ngroups Number of groups.
280  * @param[in] rhvtx Encoding of which rank contains which vertex.
281  * @param[in] nsverts Number of shared vertices.
282  */
283  void BuildVertexGroup(int ngroups, const Array<int>& rhvtx, int& nsverts);
284 
285  /**
286  * @brief Build edge group.
287  *
288  * @param[in] ngroups Number of groups.
289  * @param[in] rhe Encoding of which rank contains which edge.
290  * @param[in] nsedges Number of shared edges.
291  */
292  void BuildEdgeGroup(int ngroups, const Array<int>& rhe, int& nsedges);
293 
294  /**
295  * @brief Build face group.
296  *
297  * @param[in] ngroups Number of groups.
298  * @param[in] rht Encoding of which rank contains which face triangle.
299  * @param[in] nstrias Number of shared face triangles.
300  * @param[in] rhq Encoding of which rank contains which face quadrilateral.
301  * @param[in] nsquads Number of shared face quadrilaterals.
302  */
303  void BuildFaceGroup(int ngroups, const Array<int>& rht, int& nstrias,
304  const Array<int>& rhq, int& nsquads);
305 
306  /**
307  * @brief Build the shared vertex to local vertex mapping.
308  *
309  * @param nsverts Number of shared vertices.
310  * @param rhvtx Encoding of which rank contains which vertex.
311  */
312  void BuildSharedVerticesMapping(const int nsverts, const Array<int>& rhvtx);
313 
314  /**
315  * @brief Build the shared edge to local edge mapping.
316  *
317  * @param[in] nsedges Number of shared edges.
318  * @param[in] rhe Encoding of which rank contains which edge.
319  */
320  void BuildSharedEdgesMapping(const int nsedges, const Array<int>& rhe);
321 
322  /**
323  * @brief Build the shared faces to local faces mapping.
324  *
325  * Shared faces are divided into triangles and quadrilaterals.
326  *
327  * @param[in] nstrias Number of shared face triangles.
328  * @param[in] rht Encoding of which rank contains which face triangle.
329  * @param[in] nsquads Number of shared face quadrilaterals.
330  * @param[in] rhq Encoding of which rank contains which face quadrilateral.
331  */
332  void BuildSharedFacesMapping(const int nstrias, const Array<int>& rht,
333  const int nsquads, const Array<int>& rhq);
334 
335  /// The parent Mesh
336  const ParMesh &parent_;
337 
338  /// Indicator from which part of the parent ParMesh the ParSubMesh is going to
339  /// be created.
340  SubMesh::From from_;
341 
342  /// Attributes on the parent ParMesh on which the ParSubMesh is created. Could
343  /// either be domain or boundary attributes (determined by from_).
344  Array<int> attributes_;
345 
346  /// Mapping from ParSubMesh element ids (index of the array), to the parent
347  /// ParMesh element ids.
348  Array<int> parent_element_ids_;
349 
350  /// Mapping from ParSubMesh vertex ids (index of the array), to the parent
351  /// ParMesh vertex ids.
352  Array<int> parent_vertex_ids_;
353 
354  /// Mapping from ParSubMesh edge ids (index of the array), to the parent
355  /// ParMesh edge ids.
356  Array<int> parent_edge_ids_;
357 
358  /// Mapping from ParSubMesh face ids (index of the array), to the parent
359  /// ParMesh face ids.
360  Array<int> parent_face_ids_;
361 
362  /// Mapping from parent ParMesh vertex ids (index of the array), to the
363  /// ParSubMesh vertex ids. Inverse map of parent_vertex_ids_.
364  Array<int> parent_to_submesh_vertex_ids_;
365 
366  /// Mapping from parent ParMesh edge ids (index of the array), to the
367  /// ParSubMesh edge ids. Inverse map of parent_edge_ids_.
368  Array<int> parent_to_submesh_edge_ids_;
369 
370  /// Mapping from parent ParMesh face ids (index of the array), to the
371  /// ParSubMesh face ids. Inverse map of parent_face_ids_.
372  Array<int> parent_to_submesh_face_ids_;
373 };
374 
375 } // namespace mfem
376 
377 #endif // MFEM_USE_MPI
378 
379 #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 > & GetParentVertexIDMap() const
Get the parent vertex id map.
Definition: psubmesh.hpp:116
SubMesh::From GetFrom()
Get the From indicator.
Definition: psubmesh.hpp:96
Subdomain representation of a topological parent in another ParMesh.
Definition: psubmesh.hpp:51
const Array< int > & GetParentFaceIDMap() const
Get the parent face id map.
Definition: psubmesh.hpp:126
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:170
ParTransferMap represents a mapping of degrees of freedom from a source ParGridFunction to a destinat...
const ParMesh * GetParent() const
Get the parent ParMesh object.
Definition: psubmesh.hpp:85
From
Indicator from which part of the parent Mesh the SubMesh is created.
Definition: submesh.hpp:46
const Array< int > & GetParentToSubMeshFaceIDMap() const
Get the ParSubMesh face id map.
Definition: psubmesh.hpp:136
static ParTransferMap CreateTransferMap(const ParGridFunction &src, const ParGridFunction &dst)
Create a Transfer Map object.
Definition: psubmesh.cpp:806
ParSubMesh()=delete
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:800
List of integer sets.
Definition: sets.hpp:62
Class for parallel meshes.
Definition: pmesh.hpp:32
Array< int > attributes
A list of all unique element attributes used by the Mesh.
Definition: mesh.hpp:268
const Array< int > & GetParentElementIDMap() const
Get the parent element id map.
Definition: psubmesh.hpp:106