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/>.
27 \*---------------------------------------------------------------------------*/
29 #include "decompositionMethod.H"
30 #include "globalIndex.H"
31 #include "cyclicPolyPatch.H"
32 #include "syncTools.H"
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 defineTypeNameAndDebug(decompositionMethod, 0);
39 defineRunTimeSelectionTable(decompositionMethod, dictionary);
42 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
44 Foam::autoPtr<Foam::decompositionMethod> Foam::decompositionMethod::New
46 const dictionary& decompositionDict
49 const word methodType(decompositionDict.lookup("method"));
51 Info<< "Selecting decompositionMethod " << methodType << endl;
53 dictionaryConstructorTable::iterator cstrIter =
54 dictionaryConstructorTablePtr_->find(methodType);
56 if (cstrIter == dictionaryConstructorTablePtr_->end())
60 "decompositionMethod::New"
61 "(const dictionary& decompositionDict)"
62 ) << "Unknown decompositionMethod "
63 << methodType << nl << nl
64 << "Valid decompositionMethods are : " << endl
65 << dictionaryConstructorTablePtr_->sortedToc()
69 return autoPtr<decompositionMethod>(cstrIter()(decompositionDict));
73 Foam::labelList Foam::decompositionMethod::decompose
76 const pointField& points
79 scalarField weights(points.size(), 1.0);
81 return decompose(mesh, points, weights);
85 Foam::labelList Foam::decompositionMethod::decompose
88 const labelList& fineToCoarse,
89 const pointField& coarsePoints,
90 const scalarField& coarseWeights
93 CompactListList<label> coarseCellCells;
102 // Decompose based on agglomerated points
103 labelList coarseDistribution
113 // Rework back into decomposition for original mesh_
114 labelList fineDistribution(fineToCoarse.size());
116 forAll(fineDistribution, i)
118 fineDistribution[i] = coarseDistribution[fineToCoarse[i]];
121 return fineDistribution;
125 Foam::labelList Foam::decompositionMethod::decompose
127 const polyMesh& mesh,
128 const labelList& fineToCoarse,
129 const pointField& coarsePoints
132 scalarField cWeights(coarsePoints.size(), 1.0);
144 Foam::labelList Foam::decompositionMethod::decompose
146 const labelListList& globalCellCells,
150 scalarField cWeights(cc.size(), 1.0);
152 return decompose(globalCellCells, cc, cWeights);
156 void Foam::decompositionMethod::calcCellCells
158 const polyMesh& mesh,
159 const labelList& agglom,
161 CompactListList<label>& cellCells
164 const labelList& faceOwner = mesh.faceOwner();
165 const labelList& faceNeighbour = mesh.faceNeighbour();
166 const polyBoundaryMesh& patches = mesh.boundaryMesh();
169 // Create global cell numbers
170 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
172 globalIndex globalAgglom(nCoarse);
175 // Get agglomerate owner on other side of coupled faces
176 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
178 labelList globalNeighbour(mesh.nFaces()-mesh.nInternalFaces());
180 forAll(patches, patchI)
182 const polyPatch& pp = patches[patchI];
186 label faceI = pp.start();
187 label bFaceI = pp.start() - mesh.nInternalFaces();
191 globalNeighbour[bFaceI] = globalAgglom.toGlobal
193 agglom[faceOwner[faceI]]
202 // Get the cell on the other side of coupled patches
203 syncTools::swapBoundaryFaceList(mesh, globalNeighbour);
206 // Count number of faces (internal + coupled)
207 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
209 // Number of faces per coarse cell
210 labelList nFacesPerCell(nCoarse, 0);
212 for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
214 label own = agglom[faceOwner[faceI]];
215 label nei = agglom[faceNeighbour[faceI]];
217 nFacesPerCell[own]++;
218 nFacesPerCell[nei]++;
221 forAll(patches, patchI)
223 const polyPatch& pp = patches[patchI];
227 label faceI = pp.start();
228 label bFaceI = pp.start()-mesh.nInternalFaces();
232 label own = agglom[faceOwner[faceI]];
234 label globalNei = globalNeighbour[bFaceI];
237 !globalAgglom.isLocal(globalNei)
238 || globalAgglom.toLocal(globalNei) != own
241 nFacesPerCell[own]++;
251 // Fill in offset and data
252 // ~~~~~~~~~~~~~~~~~~~~~~~
254 cellCells.setSize(nFacesPerCell);
258 labelList& m = cellCells.m();
259 const labelList& offsets = cellCells.offsets();
261 // For internal faces is just offsetted owner and neighbour
262 for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
264 label own = agglom[faceOwner[faceI]];
265 label nei = agglom[faceNeighbour[faceI]];
267 m[offsets[own] + nFacesPerCell[own]++] = globalAgglom.toGlobal(nei);
268 m[offsets[nei] + nFacesPerCell[nei]++] = globalAgglom.toGlobal(own);
271 // For boundary faces is offsetted coupled neighbour
272 forAll(patches, patchI)
274 const polyPatch& pp = patches[patchI];
278 label faceI = pp.start();
279 label bFaceI = pp.start()-mesh.nInternalFaces();
283 label own = agglom[faceOwner[faceI]];
285 label globalNei = globalNeighbour[bFaceI];
289 !globalAgglom.isLocal(globalNei)
290 || globalAgglom.toLocal(globalNei) != own
293 m[offsets[own] + nFacesPerCell[own]++] = globalNei;
303 // Check for duplicates connections between cells
304 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
305 // Done as postprocessing step since we now have cellCells.
307 labelHashSet nbrCells;
308 forAll(cellCells, cellI)
311 nbrCells.insert(globalAgglom.toGlobal(cellI));
313 label startIndex = cellCells.offsets()[cellI];
314 label endIndex = cellCells.offsets()[cellI+1];
316 for (label i = startIndex; i < endIndex; i++)
318 if (nbrCells.insert(cellCells.m()[i]))
320 cellCells.m()[newIndex++] = cellCells.m()[i];
323 cellCells.offsets()[cellI+1] = newIndex;
326 cellCells.m().setSize(newIndex);
329 //forAll(cellCells, cellI)
331 // const labelUList cCells = cellCells[cellI];
332 // Pout<< "Compacted: Coarse cell " << cellI << endl;
335 // Pout<< " nbr:" << cCells[i] << endl;
341 // ************************************************************************* //