Loading...
Searching...
No Matches
advancingFrontAMIParallelOps.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2017 OpenFOAM Foundation
9 Copyright (C) 2018-2024 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "advancingFrontAMI.H"
30#include "mergePoints.H"
31#include "mapDistribute.H"
32#include "AABBTree.H"
33
34// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35
36Foam::label Foam::advancingFrontAMI::calcOverlappingProcs
37(
38 const List<treeBoundBoxList>& procBb,
39 const treeBoundBox& bb,
40 boolList& overlaps
41) const
42{
43 overlaps.setSize(procBb.size());
44 overlaps = false;
45
46 label nOverlaps = 0;
47
48 forAll(procBb, proci)
49 {
50 const treeBoundBoxList& bbp = procBb[proci];
51
52 for (const treeBoundBox& tbb: bbp)
53 {
54 if (tbb.overlaps(bb))
55 {
56 overlaps[proci] = true;
57 ++nOverlaps;
58 break;
59 }
60 }
61 }
62
63 return nOverlaps;
64}
65
66
67void Foam::advancingFrontAMI::distributePatches
68(
69 const mapDistribute& map,
70 const primitivePatch& pp,
71 const globalIndex& gi,
72 List<faceList>& faces,
74 List<labelList>& faceIDs
75) const
76{
77 faces.setSize(Pstream::nProcs(comm()));
79 faceIDs.setSize(Pstream::nProcs(comm()));
80
81 PstreamBuffers pBufs(comm());
82
83 for (const int domain : Pstream::allProcs(comm()))
84 {
85 const labelList& sendElems = map.subMap()[domain];
86
87 if (sendElems.empty())
88 {
89 // Safety
90 faces[domain].clear();
91 points[domain].clear();
92 faceIDs[domain].clear();
93 }
94 else
95 {
96 faceList subFaces(UIndirectList<face>(pp, sendElems));
97 primitivePatch subPatch(SubList<face>(subFaces), pp.points());
98
99 if (debug & 2)
100 {
101 Pout<< "distributePatches: to processor " << domain
102 << " sending faces " << subPatch.faceCentres() << endl;
103 }
104
105
106 if (domain == Pstream::myProcNo(comm()))
107 {
108 // Do send/receive for myself
109 faces[domain] = subPatch.localFaces();
110 points[domain] = subPatch.localPoints();
111 faceIDs[domain] =
112 gi.toGlobal(Pstream::myProcNo(comm()), sendElems);
113 }
114 else
115 {
116 // Normal send
117 UOPstream str(domain, pBufs);
118 str
119 << subPatch.localFaces()
120 << subPatch.localPoints()
121 << gi.toGlobal(Pstream::myProcNo(comm()), sendElems);
122 }
123 }
124 }
125
126 pBufs.finishedSends();
127
128
129 // Consume
130 for (const int domain : Pstream::allProcs(comm()))
131 {
132 const labelList& recvElems = map.constructMap()[domain];
133
134 if (domain != Pstream::myProcNo(comm()) && recvElems.size())
135 {
136 UIPstream is(domain, pBufs);
137
138 is >> faces[domain]
139 >> points[domain]
140 >> faceIDs[domain];
141 }
142 }
143}
144
145
146void Foam::advancingFrontAMI::distributeAndMergePatches
147(
148 const mapDistribute& map,
149 const primitivePatch& tgtPatch,
150 const globalIndex& gi,
151 faceList& tgtFaces,
152 pointField& tgtPoints,
153 labelList& tgtFaceIDs
154) const
155{
156 // Exchange per-processor data
157 List<faceList> allFaces;
159 List<labelList> allTgtFaceIDs;
160 distributePatches(map, tgtPatch, gi, allFaces, allPoints, allTgtFaceIDs);
161
162 // Renumber and flatten
163 label nFaces = 0;
164 label nPoints = 0;
165 forAll(allFaces, proci)
166 {
167 nFaces += allFaces[proci].size();
168 nPoints += allPoints[proci].size();
169 }
170
171 tgtFaces.setSize(nFaces);
172 tgtPoints.setSize(nPoints);
173 tgtFaceIDs.setSize(nFaces);
174
175 nFaces = 0;
176 nPoints = 0;
177
178 // My own data first
179 {
180 const labelList& faceIDs = allTgtFaceIDs[Pstream::myProcNo(comm())];
181 SubList<label>(tgtFaceIDs, faceIDs.size()) = faceIDs;
182
183 const faceList& fcs = allFaces[Pstream::myProcNo(comm())];
184 for (const face& f : fcs)
185 {
186 face& newF = tgtFaces[nFaces++];
187 newF.setSize(f.size());
188 forAll(f, fp)
189 {
190 newF[fp] = f[fp] + nPoints;
191 }
192 }
193
194 const pointField& pts = allPoints[Pstream::myProcNo(comm())];
195 for (const point& pt: pts)
196 {
197 tgtPoints[nPoints++] = pt;
198 }
199 }
200
201
202 // Other proc data follows
203 forAll(allFaces, proci)
204 {
205 if (proci != Pstream::myProcNo(comm()))
206 {
207 const labelList& faceIDs = allTgtFaceIDs[proci];
208 SubList<label>(tgtFaceIDs, faceIDs.size(), nFaces) = faceIDs;
209
210 const faceList& fcs = allFaces[proci];
211 for (const face& f : fcs)
212 {
213 face& newF = tgtFaces[nFaces++];
214 newF.setSize(f.size());
215 forAll(f, fp)
216 {
217 newF[fp] = f[fp] + nPoints;
218 }
219 }
220
221 const pointField& pts = allPoints[proci];
222 for (const point& pt: pts)
223 {
224 tgtPoints[nPoints++] = pt;
225 }
226 }
227 }
228
229 // Merge
230 labelList oldToNew;
231 bool nChanged = Foam::inplaceMergePoints
232 (
233 tgtPoints,
234 SMALL,
235 false,
236 oldToNew
237 );
238
239 if (nChanged)
240 {
241 if (debug)
242 {
243 Pout<< "Merged from " << oldToNew.size()
244 << " down to " << tgtPoints.size() << " points" << endl;
245 }
246
247 for (face& f : tgtFaces)
248 {
249 inplaceRenumber(oldToNew, f);
250 }
251 }
252}
253
254
255Foam::autoPtr<Foam::mapDistribute> Foam::advancingFrontAMI::calcProcMap
256(
257 const primitivePatch& srcPatch,
258 const primitivePatch& tgtPatch
259) const
260{
261 if (comm() == -1)
262 {
264 << "Processor " << UPstream::myProcNo(UPstream::worldComm)
265 << " not in communicator " << comm() << exit(FatalError);
266 }
267
268 // Get decomposition of patch
270
271 if (srcPatch.size())
272 {
273 procBb[Pstream::myProcNo(comm())] =
275 (
276 srcPatch.localFaces(),
277 srcPatch.localPoints(),
278 false
279 ).boundBoxes();
280 }
281 else
282 {
283 procBb[Pstream::myProcNo(comm())] = treeBoundBoxList();
284 }
285
286 Pstream::allGatherList(procBb, UPstream::msgType(), comm());
287
288 if (debug)
289 {
290 Info<< "Determining extent of srcPatch per processor:" << nl
291 << "\tproc\tbb" << endl;
292 forAll(procBb, proci)
293 {
294 Info<< '\t' << proci << '\t' << procBb[proci] << endl;
295 }
296 }
297
298 // Determine which faces of tgtPatch overlaps srcPatch per proc
299 const faceList& faces = tgtPatch.localFaces();
300 const pointField& points = tgtPatch.localPoints();
301
302 labelListList sendMap;
303
304 {
305 // Per processor indices into all segments to send
306 List<DynamicList<label>> dynSendMap(Pstream::nProcs(comm()));
307
308 // Work array - whether processor bb overlaps the face bounds
309 boolList procBbOverlaps(Pstream::nProcs(comm()));
310
311 forAll(faces, facei)
312 {
313 if (faces[facei].size())
314 {
315 treeBoundBox faceBb(points, faces[facei]);
316
317 // Find the processor this face overlaps
318 calcOverlappingProcs(procBb, faceBb, procBbOverlaps);
319
320 forAll(procBbOverlaps, proci)
321 {
322 if (procBbOverlaps[proci])
323 {
324 dynSendMap[proci].append(facei);
325 }
326 }
327 }
328 }
329
330 // Convert dynamicList to labelList
331 sendMap.setSize(Pstream::nProcs(comm()));
332 forAll(sendMap, proci)
333 {
334 sendMap[proci].transfer(dynSendMap[proci]);
335 }
336 }
337
338 // Debug printing
339 if (debug)
340 {
341 Pout<< "Of my " << faces.size() << " I need to send to:" << nl
342 << "\tproc\tfaces" << endl;
343 forAll(sendMap, proci)
344 {
345 Pout<< '\t' << proci << '\t' << sendMap[proci].size() << endl;
346 }
347 }
348
350 (
351 std::move(sendMap),
352 false, //subHasFlip
353 false, //constructHasFlip
354 comm()
355 );
356}
357
358
359// ************************************************************************* //
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
Templated tree of axis-aligned bounding boxes (AABB).
Definition AABBTree.H:116
const List< treeBoundBox > & boundBoxes() const noexcept
Return the bounding boxes making up the tree.
Definition AABBTree.H:209
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
void setSize(label n)
Alias for resize().
Definition List.H:536
void clear()
Clear the list, i.e. set size to zero.
Definition ListI.H:133
const Field< point_type > & points() const noexcept
Return reference to global points.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
static void allGatherList(UList< T > &values, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Gather data, but keep individual values separate. Uses MPI_Allgather or manual communication.
A non-owning sub-view of a List (allocated or unallocated storage).
Definition SubList.H:61
Input inter-processor communications stream using MPI send/recv etc. - operating on external buffer.
Definition UIPstream.H:313
A List with indirect addressing. Like IndirectList but does not store addressing.
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
Output inter-processor communications stream using MPI send/recv etc. - operating on external buffer.
Definition UOPstream.H:408
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
Definition UPstream.H:1706
static int & msgType() noexcept
Message tag of standard messages.
Definition UPstream.H:1926
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run.
Definition UPstream.H:1697
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Definition UPstream.H:1069
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
Definition UPstream.H:1857
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
Definition autoPtr.H:178
A face is a list of labels corresponding to mesh vertices.
Definition face.H:71
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
Definition globalIndex.H:77
Class containing processor-to-processor mapping information.
Standard boundBox with extra functionality for use in octree.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
const pointField & points
label nPoints
Geometric merging of points. See below.
tmp< pointField > allPoints(const Triangulation &t)
Extract all points in vertex-index order.
Namespace for handling debugging switches.
Definition debug.C:45
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values within a list.
List< labelList > labelListList
List of labelList.
Definition labelList.H:38
List< label > labelList
A List of labels.
Definition List.H:62
List< treeBoundBox > treeBoundBoxList
A List of treeBoundBox.
messageStream Info
Information stream (stdout output on master, null elsewhere).
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field.
List< face > faceList
List of faces.
Definition faceListFwd.H:41
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
vector point
Point is a vector.
Definition point.H:37
List< bool > boolList
A List of bools.
Definition List.H:60
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
label inplaceMergePoints(PointList &points, const scalar mergeTol, const bool verbose, labelList &pointToUnique)
Inplace merge points, preserving the original point order. All points closer/equal mergeTol are to be...
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
vectorField pointField
pointField is a vectorField.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
labelList f(nPoints)
const pointField & pts
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299