1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
28 Private member of domainDecomposition.
29 Decomposes the mesh into bits
31 \*---------------------------------------------------------------------------*/
33 #include "domainDecomposition.H"
34 #include "IOstreams.H"
35 #include "SLPtrList.H"
37 #include "primitiveMesh.H"
38 #include "cyclicPolyPatch.H"
40 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
42 void Foam::domainDecomposition::append(labelList& lst, const label elem)
44 label sz = lst.size();
50 void Foam::domainDecomposition::addInterProcFace
53 const label ownerProc,
56 List<Map<label> >& nbrToInterPatch,
57 List<DynamicList<DynamicList<label> > >& interPatchFaces
60 Map<label>::iterator patchIter = nbrToInterPatch[ownerProc].find(nbrProc);
62 // Introduce turning index only for internal faces (are duplicated).
63 label ownerIndex = facei+1;
64 label nbrIndex = -(facei+1);
66 if (patchIter != nbrToInterPatch[ownerProc].end())
68 // Existing interproc patch. Add to both sides.
69 label toNbrProcPatchI = patchIter();
70 interPatchFaces[ownerProc][toNbrProcPatchI].append(ownerIndex);
72 if (isInternalFace(facei))
74 label toOwnerProcPatchI = nbrToInterPatch[nbrProc][ownerProc];
75 interPatchFaces[nbrProc][toOwnerProcPatchI].append(nbrIndex);
80 // Create new interproc patches.
81 label toNbrProcPatchI = nbrToInterPatch[ownerProc].size();
82 nbrToInterPatch[ownerProc].insert(nbrProc, toNbrProcPatchI);
83 DynamicList<label> oneFace;
84 oneFace.append(ownerIndex);
85 interPatchFaces[ownerProc].append(oneFace);
87 if (isInternalFace(facei))
89 label toOwnerProcPatchI = nbrToInterPatch[nbrProc].size();
90 nbrToInterPatch[nbrProc].insert(ownerProc, toOwnerProcPatchI);
92 oneFace.append(nbrIndex);
93 interPatchFaces[nbrProc].append(oneFace);
99 void Foam::domainDecomposition::decomposeMesh()
101 // Decide which cell goes to which processor
104 // Distribute the cells according to the given processor label
106 // calculate the addressing information for the original mesh
107 Info<< "\nCalculating original mesh data" << endl;
109 // set references to the original mesh
110 const polyBoundaryMesh& patches = boundaryMesh();
111 const faceList& fcs = faces();
112 const labelList& owner = faceOwner();
113 const labelList& neighbour = faceNeighbour();
115 // loop through the list of processor labels for the cell and add the
116 // cell shape to the list of cells for the appropriate processor
118 Info<< "\nDistributing cells to processors" << endl;
120 // Cells per processor
121 procCellAddressing_ = invertOneToMany(nProcs_, cellToProc_);
123 Info<< "\nDistributing faces to processors" << endl;
125 // Loop through all internal faces and decide which processor they belong to
126 // First visit all internal faces. If cells at both sides belong to the
127 // same processor, the face is an internal face. If they are different,
128 // it belongs to both processors.
130 procFaceAddressing_.setSize(nProcs_);
133 forAll(neighbour, facei)
135 if (cellToProc_[owner[facei]] == cellToProc_[neighbour[facei]])
137 // Face internal to processor. Notice no turning index.
138 procFaceAddressing_[cellToProc_[owner[facei]]].append(facei+1);
142 // for all processors, set the size of start index and patch size
143 // lists to the number of patches in the mesh
144 forAll(procPatchSize_, procI)
146 procPatchSize_[procI].setSize(patches.size());
147 procPatchStartIndex_[procI].setSize(patches.size());
150 forAll(patches, patchi)
152 // Reset size and start index for all processors
153 forAll(procPatchSize_, procI)
155 procPatchSize_[procI][patchi] = 0;
156 procPatchStartIndex_[procI][patchi] =
157 procFaceAddressing_[procI].size();
160 const label patchStart = patches[patchi].start();
162 if (!isA<cyclicPolyPatch>(patches[patchi]))
164 // Normal patch. Add faces to processor where the cell
165 // next to the face lives
167 const labelUList& patchFaceCells =
168 patches[patchi].faceCells();
170 forAll(patchFaceCells, facei)
172 const label curProc = cellToProc_[patchFaceCells[facei]];
174 // add the face without turning index
175 procFaceAddressing_[curProc].append(patchStart+facei+1);
177 // increment the number of faces for this patch
178 procPatchSize_[curProc][patchi]++;
183 const cyclicPolyPatch& pp = refCast<const cyclicPolyPatch>
187 // cyclic: check opposite side on this processor
188 const labelUList& patchFaceCells = pp.faceCells();
190 const labelUList& nbrPatchFaceCells =
191 pp.neighbPatch().faceCells();
193 forAll(patchFaceCells, facei)
195 const label curProc = cellToProc_[patchFaceCells[facei]];
196 const label nbrProc = cellToProc_[nbrPatchFaceCells[facei]];
197 if (curProc == nbrProc)
199 // add the face without turning index
200 procFaceAddressing_[curProc].append(patchStart+facei+1);
201 // increment the number of faces for this patch
202 procPatchSize_[curProc][patchi]++;
209 // Done internal bits of the new mesh and the ordinary patches.
212 // Per processor, from neighbour processor to the interprocessorpatch that
213 // communicates with that neighbour.
214 List<Map<label> > procNbrToInterPatch(nProcs_);
215 // Per processor the faces per interprocessorpatch.
216 List<DynamicList<DynamicList<label> > > interPatchFaces(nProcs_);
218 // Processor boundaries from internal faces
219 forAll(neighbour, facei)
221 label ownerProc = cellToProc_[owner[facei]];
222 label nbrProc = cellToProc_[neighbour[facei]];
224 if (ownerProc != nbrProc)
226 // inter - processor patch face found.
239 // Add the proper processor faces to the sub information. For faces
240 // originating from internal faces this is always -1.
241 List<labelListList> subPatchIDs(nProcs_);
242 List<labelListList> subPatchStarts(nProcs_);
243 forAll(interPatchFaces, procI)
245 label nInterfaces = interPatchFaces[procI].size();
247 subPatchIDs[procI].setSize(nInterfaces, labelList(1, -1));
248 subPatchStarts[procI].setSize(nInterfaces, labelList(1, 0));
251 // Processor boundaries from split cyclics
252 forAll(patches, patchi)
254 if (isA<cyclicPolyPatch>(patches[patchi]))
256 const cyclicPolyPatch& pp = refCast<const cyclicPolyPatch>
261 // cyclic: check opposite side on this processor
262 const labelUList& patchFaceCells = pp.faceCells();
263 const labelUList& nbrPatchFaceCells =
264 pp.neighbPatch().faceCells();
266 // Store old sizes. Used to detect which inter-proc patches
267 // have been added to.
268 labelListList oldInterfaceSizes(nProcs_);
269 forAll(oldInterfaceSizes, procI)
271 labelList& curOldSizes = oldInterfaceSizes[procI];
273 curOldSizes.setSize(interPatchFaces[procI].size());
274 forAll(curOldSizes, interI)
276 curOldSizes[interI] =
277 interPatchFaces[procI][interI].size();
281 // Add faces with different owner and neighbour processors
282 forAll(patchFaceCells, facei)
284 const label ownerProc = cellToProc_[patchFaceCells[facei]];
285 const label nbrProc = cellToProc_[nbrPatchFaceCells[facei]];
286 if (ownerProc != nbrProc)
288 // inter - processor patch face found.
300 // 1. Check if any faces added to existing interfaces
301 forAll(oldInterfaceSizes, procI)
303 const labelList& curOldSizes = oldInterfaceSizes[procI];
305 forAll(curOldSizes, interI)
307 label oldSz = curOldSizes[interI];
308 if (interPatchFaces[procI][interI].size() > oldSz)
310 // Added faces to this interface. Add an entry
311 append(subPatchIDs[procI][interI], patchi);
312 append(subPatchStarts[procI][interI], oldSz);
317 // 2. Any new interfaces
318 forAll(subPatchIDs, procI)
320 label nIntfcs = interPatchFaces[procI].size();
321 subPatchIDs[procI].setSize(nIntfcs, labelList(1, patchi));
322 subPatchStarts[procI].setSize(nIntfcs, labelList(1, 0));
328 // Shrink processor patch face addressing
329 forAll(interPatchFaces, procI)
331 DynamicList<DynamicList<label> >& curInterPatchFaces =
332 interPatchFaces[procI];
334 forAll(curInterPatchFaces, i)
336 curInterPatchFaces[i].shrink();
338 curInterPatchFaces.shrink();
342 // Sort inter-proc patch by neighbour
344 forAll(procNbrToInterPatch, procI)
346 label nInterfaces = procNbrToInterPatch[procI].size();
348 procNeighbourProcessors_[procI].setSize(nInterfaces);
349 procProcessorPatchSize_[procI].setSize(nInterfaces);
350 procProcessorPatchStartIndex_[procI].setSize(nInterfaces);
351 procProcessorPatchSubPatchIDs_[procI].setSize(nInterfaces);
352 procProcessorPatchSubPatchStarts_[procI].setSize(nInterfaces);
354 //Info<< "Processor " << procI << endl;
356 // Get sorted neighbour processors
357 const Map<label>& curNbrToInterPatch = procNbrToInterPatch[procI];
358 labelList nbrs = curNbrToInterPatch.toc();
359 sortedOrder(nbrs, order);
361 DynamicList<DynamicList<label> >& curInterPatchFaces =
362 interPatchFaces[procI];
366 const label nbrProc = nbrs[i];
367 const label interPatch = curNbrToInterPatch[nbrProc];
369 procNeighbourProcessors_[procI][i] =
371 procProcessorPatchSize_[procI][i] =
372 curInterPatchFaces[interPatch].size();
373 procProcessorPatchStartIndex_[procI][i] =
374 procFaceAddressing_[procI].size();
376 // Add size as last element to substarts and transfer
379 subPatchStarts[procI][interPatch],
380 curInterPatchFaces[interPatch].size()
382 procProcessorPatchSubPatchIDs_[procI][i].transfer
384 subPatchIDs[procI][interPatch]
386 procProcessorPatchSubPatchStarts_[procI][i].transfer
388 subPatchStarts[procI][interPatch]
391 //Info<< " nbr:" << nbrProc << endl;
392 //Info<< " interpatch:" << interPatch << endl;
393 //Info<< " size:" << procProcessorPatchSize_[procI][i] << endl;
394 //Info<< " start:" << procProcessorPatchStartIndex_[procI][i]
396 //Info<< " subPatches:"
397 // << procProcessorPatchSubPatchIDs_[procI][i]
399 //Info<< " subStarts:"
400 // << procProcessorPatchSubPatchStarts_[procI][i] << endl;
402 // And add all the face labels for interPatch
403 DynamicList<label>& interPatchFaces =
404 curInterPatchFaces[interPatch];
406 forAll(interPatchFaces, j)
408 procFaceAddressing_[procI].append(interPatchFaces[j]);
410 interPatchFaces.clearStorage();
412 curInterPatchFaces.clearStorage();
413 procFaceAddressing_[procI].shrink();
419 // forAll(procPatchStartIndex_, procI)
421 // Info<< "Processor:" << procI << endl;
423 // Info<< " total faces:" << procFaceAddressing_[procI].size()
426 // const labelList& curProcPatchStartIndex = procPatchStartIndex_[procI];
428 // forAll(curProcPatchStartIndex, patchI)
430 // Info<< " patch:" << patchI
431 // << "\tstart:" << curProcPatchStartIndex[patchI]
432 // << "\tsize:" << procPatchSize_[procI][patchI]
438 // forAll(procNeighbourProcessors_, procI)
440 // Info<< "Processor " << procI << endl;
442 // forAll(procNeighbourProcessors_[procI], i)
444 // Info<< " nbr:" << procNeighbourProcessors_[procI][i] << endl;
445 // Info<< " size:" << procProcessorPatchSize_[procI][i] << endl;
446 // Info<< " start:" << procProcessorPatchStartIndex_[procI][i]
452 // forAll(procFaceAddressing_, procI)
454 // Info<< "Processor:" << procI << endl;
456 // Info<< " faces:" << procFaceAddressing_[procI] << endl;
461 Info<< "\nDistributing points to processors" << endl;
462 // For every processor, loop through the list of faces for the processor.
463 // For every face, loop through the list of points and mark the point as
464 // used for the processor. Collect the list of used points for the
467 forAll(procPointAddressing_, procI)
469 boolList pointLabels(nPoints(), false);
471 // Get reference to list of used faces
472 const labelList& procFaceLabels = procFaceAddressing_[procI];
474 forAll(procFaceLabels, facei)
476 // Because of the turning index, some labels may be negative
477 const labelList& facePoints = fcs[mag(procFaceLabels[facei]) - 1];
479 forAll(facePoints, pointi)
481 // Mark the point as used
482 pointLabels[facePoints[pointi]] = true;
486 // Collect the used points
487 labelList& procPointLabels = procPointAddressing_[procI];
489 procPointLabels.setSize(pointLabels.size());
491 label nUsedPoints = 0;
493 forAll(pointLabels, pointi)
495 if (pointLabels[pointi])
497 procPointLabels[nUsedPoints] = pointi;
503 // Reset the size of used points
504 procPointLabels.setSize(nUsedPoints);
508 // ************************************************************************* //