1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "cellDistFuncs.H"
28 #include "wallPolyPatch.H"
29 #include "polyBoundaryMesh.H"
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 defineTypeNameAndDebug(cellDistFuncs, 0);
41 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 // Find val in first nElems elements of elems.
44 Foam::label Foam::cellDistFuncs::findIndex
47 const labelList& elems,
51 for (label i = 0; i < nElems; i++)
62 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
64 // Construct from mesh
65 Foam::cellDistFuncs::cellDistFuncs(const polyMesh& mesh)
71 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
73 // Get patch ids of named patches
74 Foam::labelHashSet Foam::cellDistFuncs::getPatchIDs
76 const wordList& patchNames
79 const polyBoundaryMesh& bMesh = mesh().boundaryMesh();
81 // Construct Set of patchNames for easy checking if included
82 HashSet<word> patchNamesHash(patchNames.size());
84 forAll(patchNames, patchI)
86 patchNamesHash.insert(patchNames[patchI]);
89 // Loop over all patches and check if patch name in hashset
91 labelHashSet patchIDs(bMesh.size());
95 const polyPatch& patch = bMesh[patchI];
97 if (patchNamesHash.found(patch.name()))
99 patchIDs.insert(patchI);
106 // Return smallest true distance from p to any of wallFaces.
107 // Note that even if normal hits face we still check other faces.
108 // Note that wallFaces is untruncated and we explicitly pass in size.
109 Foam::scalar Foam::cellDistFuncs::smallestDist
112 const polyPatch& patch,
113 const label nWallFaces,
114 const labelList& wallFaces,
118 const pointField& points = patch.points();
120 scalar minDist = GREAT;
123 for(label wallFaceI = 0; wallFaceI < nWallFaces; wallFaceI++)
125 label patchFaceI = wallFaces[wallFaceI];
127 pointHit curHit = patch[patchFaceI].nearestPoint(p, points);
129 if (curHit.distance() < minDist)
131 minDist = curHit.distance();
132 minFaceI = patch.start() + patchFaceI;
140 // Get point neighbours of faceI (including faceI). Returns number of faces.
141 // Note: does not allocate storage but does use linear search to determine
142 // uniqueness. For polygonal faces this might be quite inefficient.
143 Foam::label Foam::cellDistFuncs::getPointNeighbours
145 const primitivePatch& patch,
146 const label patchFaceI,
147 labelList& neighbours
150 label nNeighbours = 0;
153 neighbours[nNeighbours++] = patchFaceI;
155 // Add all face neighbours
156 const labelList& faceNeighbours = patch.faceFaces()[patchFaceI];
158 forAll(faceNeighbours, faceNeighbourI)
160 neighbours[nNeighbours++] = faceNeighbours[faceNeighbourI];
163 // Remember part of neighbours that contains edge-connected faces.
164 label nEdgeNbs = nNeighbours;
167 // Add all point-only neighbours by linear searching in edge neighbours.
168 // Assumes that point-only neighbours are not using multiple points on
171 const face& f = patch.localFaces()[patchFaceI];
175 label pointI = f[fp];
177 const labelList& pointNbs = patch.pointFaces()[pointI];
179 forAll(pointNbs, nbI)
181 label faceI = pointNbs[nbI];
183 // Check for faceI in edge-neighbours part of neighbours
184 if (findIndex(nEdgeNbs, neighbours, faceI) == -1)
186 neighbours[nNeighbours++] = faceI;
194 // Check for duplicates
196 // Use hashSet to determine nbs.
197 labelHashSet nbs(4*f.size());
201 const labelList& pointNbs = patch.pointFaces()[f[fp]];
205 nbs.insert(pointNbs[i]);
210 for (label i = 0; i < nNeighbours; i++)
212 label nb = neighbours[i];
216 SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
217 << "getPointNeighbours : patchFaceI:" << patchFaceI
218 << " verts:" << f << endl;
222 SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
223 << "point:" << f[fp] << " pointFaces:"
224 << patch.pointFaces()[f[fp]] << endl;
227 for (label i = 0; i < nNeighbours; i++)
229 SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
230 << "fast nbr:" << neighbours[i]
234 FatalErrorIn("getPointNeighbours")
235 << "Problem: fast pointNeighbours routine included " << nb
236 << " which is not in proper neigbour list " << nbs.toc()
237 << abort(FatalError);
244 FatalErrorIn("getPointNeighbours")
245 << "Problem: fast pointNeighbours routine did not find "
246 << nbs.toc() << abort(FatalError);
254 // size of largest patch (out of supplied subset of patches)
255 Foam::label Foam::cellDistFuncs::maxPatchSize(const labelHashSet& patchIDs)
260 forAll(mesh().boundaryMesh(), patchI)
262 if (patchIDs.found(patchI))
264 const polyPatch& patch = mesh().boundaryMesh()[patchI];
266 maxSize = Foam::max(maxSize, patch.size());
273 // sum of patch sizes (out of supplied subset of patches)
274 Foam::label Foam::cellDistFuncs::sumPatchSize(const labelHashSet& patchIDs)
279 forAll(mesh().boundaryMesh(), patchI)
281 if (patchIDs.found(patchI))
283 const polyPatch& patch = mesh().boundaryMesh()[patchI];
292 // Gets nearest wall for cells next to wall
293 void Foam::cellDistFuncs::correctBoundaryFaceCells
295 const labelHashSet& patchIDs,
296 scalarField& wallDistCorrected,
297 Map<label>& nearestFace
300 // Size neighbours array for maximum possible (= size of largest patch)
301 label maxPointNeighbours = maxPatchSize(patchIDs);
303 labelList neighbours(maxPointNeighbours);
306 // Correct all cells with face on wall
307 const vectorField& cellCentres = mesh().cellCentres();
308 const labelList& faceOwner = mesh().faceOwner();
310 forAll(mesh().boundaryMesh(), patchI)
312 if (patchIDs.found(patchI))
314 const polyPatch& patch = mesh().boundaryMesh()[patchI];
316 // Check cells with face on wall
317 forAll(patch, patchFaceI)
319 label nNeighbours = getPointNeighbours
326 label cellI = faceOwner[patch.start() + patchFaceI];
330 wallDistCorrected[cellI] = smallestDist
339 // Store wallCell and its nearest neighbour
340 nearestFace.insert(cellI, minFaceI);
348 // Correct all cells connected to wall (via point) and not in nearestFace
349 void Foam::cellDistFuncs::correctBoundaryPointCells
351 const labelHashSet& patchIDs,
352 scalarField& wallDistCorrected,
353 Map<label>& nearestFace
356 // Correct all (non-visited) cells with point on wall
358 const labelListList& pointCells = mesh().pointCells();
359 const vectorField& cellCentres = mesh().cellCentres();
361 forAll(mesh().boundaryMesh(), patchI)
363 if (patchIDs.found(patchI))
365 const polyPatch& patch = mesh().boundaryMesh()[patchI];
367 const labelList& meshPoints = patch.meshPoints();
368 const labelListList& pointFaces = patch.pointFaces();
370 forAll(meshPoints, meshPointI)
372 label vertI = meshPoints[meshPointI];
374 const labelList& neighbours = pointCells[vertI];
376 forAll(neighbours, neighbourI)
378 label cellI = neighbours[neighbourI];
380 if (!nearestFace.found(cellI))
382 const labelList& wallFaces = pointFaces[meshPointI];
386 wallDistCorrected[cellI] = smallestDist
395 // Store wallCell and its nearest neighbour
396 nearestFace.insert(cellI, minFaceI);
405 // ************************************************************************* //