MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
psubmesh.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, 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
16
17#ifdef MFEM_USE_MPI
18
19#include "ptransfermap.hpp"
20#include "../pmesh.hpp"
22#include "submesh.hpp"
23
24namespace 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
51class ParSubMesh : public ParMesh
52{
53public:
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
185private:
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
List of integer sets.
Definition sets.hpp:63
Array< int > attributes
A list of all unique element attributes used by the Mesh.
Definition mesh.hpp:280
Class for parallel grid function.
Definition pgridfunc.hpp:33
Class for parallel meshes.
Definition pmesh.hpp:34
Subdomain representation of a topological parent in another ParMesh.
Definition psubmesh.hpp:52
static bool IsParSubMesh(const ParMesh *m)
Check if ParMesh m is a ParSubMesh.
Definition psubmesh.hpp:180
const Array< int > & GetParentElementIDMap() const
Get the parent element id map.
Definition psubmesh.hpp:106
const Array< int > & GetParentToSubMeshFaceIDMap() const
Get the ParSubMesh face id map.
Definition psubmesh.hpp:146
static ParTransferMap CreateTransferMap(const ParGridFunction &src, const ParGridFunction &dst)
Create a Transfer Map object.
static ParSubMesh CreateFromBoundary(const ParMesh &parent, Array< int > &boundary_attributes)
Create a surface ParSubMesh from it's parent.
Definition psubmesh.cpp:32
const Array< int > & GetParentVertexIDMap() const
Get the parent vertex id map.
Definition psubmesh.hpp:116
const Array< int > & GetParentFaceOrientations() const
Get the relative face orientations.
Definition psubmesh.hpp:136
const ParMesh * GetParent() const
Get the parent ParMesh object.
Definition psubmesh.hpp:85
ParSubMesh()=delete
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's parent.
Definition psubmesh.cpp:26
static void Transfer(const ParGridFunction &src, ParGridFunction &dst)
Transfer the dofs of a ParGridFunction.
SubMesh::From GetFrom() const
Get the From indicator.
Definition psubmesh.hpp:96
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:47