1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2004-2011 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"
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 defineTypeNameAndDebug(Foam::cellDistFuncs, 0);
36 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 // Find val in first nElems elements of elems.
39 Foam::label Foam::cellDistFuncs::findIndex
42 const labelList& elems,
46 for (label i = 0; i < nElems; i++)
57 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
59 Foam::cellDistFuncs::cellDistFuncs(const polyMesh& mesh)
65 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
67 Foam::labelHashSet Foam::cellDistFuncs::getPatchIDs
69 const wordReList& patchNames
72 return mesh().boundaryMesh().patchSet(patchNames, false);
76 // Return smallest true distance from p to any of wallFaces.
77 // Note that even if normal hits face we still check other faces.
78 // Note that wallFaces is untruncated and we explicitly pass in size.
79 Foam::scalar Foam::cellDistFuncs::smallestDist
82 const polyPatch& patch,
83 const label nWallFaces,
84 const labelList& wallFaces,
88 const pointField& points = patch.points();
90 scalar minDist = GREAT;
93 for (label wallFaceI = 0; wallFaceI < nWallFaces; wallFaceI++)
95 label patchFaceI = wallFaces[wallFaceI];
97 pointHit curHit = patch[patchFaceI].nearestPoint(p, points);
99 if (curHit.distance() < minDist)
101 minDist = curHit.distance();
102 minFaceI = patch.start() + patchFaceI;
110 // Get point neighbours of faceI (including faceI). Returns number of faces.
111 // Note: does not allocate storage but does use linear search to determine
112 // uniqueness. For polygonal faces this might be quite inefficient.
113 Foam::label Foam::cellDistFuncs::getPointNeighbours
115 const primitivePatch& patch,
116 const label patchFaceI,
117 labelList& neighbours
120 label nNeighbours = 0;
123 neighbours[nNeighbours++] = patchFaceI;
125 // Add all face neighbours
126 const labelList& faceNeighbours = patch.faceFaces()[patchFaceI];
128 forAll(faceNeighbours, faceNeighbourI)
130 neighbours[nNeighbours++] = faceNeighbours[faceNeighbourI];
133 // Remember part of neighbours that contains edge-connected faces.
134 label nEdgeNbs = nNeighbours;
137 // Add all point-only neighbours by linear searching in edge neighbours.
138 // Assumes that point-only neighbours are not using multiple points on
141 const face& f = patch.localFaces()[patchFaceI];
145 label pointI = f[fp];
147 const labelList& pointNbs = patch.pointFaces()[pointI];
149 forAll(pointNbs, nbI)
151 label faceI = pointNbs[nbI];
153 // Check for faceI in edge-neighbours part of neighbours
154 if (findIndex(nEdgeNbs, neighbours, faceI) == -1)
156 neighbours[nNeighbours++] = faceI;
164 // Check for duplicates
166 // Use hashSet to determine nbs.
167 labelHashSet nbs(4*f.size());
171 const labelList& pointNbs = patch.pointFaces()[f[fp]];
175 nbs.insert(pointNbs[i]);
180 for (label i = 0; i < nNeighbours; i++)
182 label nb = neighbours[i];
186 SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
187 << "getPointNeighbours : patchFaceI:" << patchFaceI
188 << " verts:" << f << endl;
192 SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
193 << "point:" << f[fp] << " pointFaces:"
194 << patch.pointFaces()[f[fp]] << endl;
197 for (label i = 0; i < nNeighbours; i++)
199 SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
200 << "fast nbr:" << neighbours[i]
204 FatalErrorIn("getPointNeighbours")
205 << "Problem: fast pointNeighbours routine included " << nb
206 << " which is not in proper neigbour list " << nbs.toc()
207 << abort(FatalError);
214 FatalErrorIn("getPointNeighbours")
215 << "Problem: fast pointNeighbours routine did not find "
216 << nbs.toc() << abort(FatalError);
224 // size of largest patch (out of supplied subset of patches)
225 Foam::label Foam::cellDistFuncs::maxPatchSize
227 const labelHashSet& patchIDs
232 forAll(mesh().boundaryMesh(), patchI)
234 if (patchIDs.found(patchI))
236 const polyPatch& patch = mesh().boundaryMesh()[patchI];
238 maxSize = Foam::max(maxSize, patch.size());
245 // sum of patch sizes (out of supplied subset of patches)
246 Foam::label Foam::cellDistFuncs::sumPatchSize
248 const labelHashSet& patchIDs
254 forAll(mesh().boundaryMesh(), patchI)
256 if (patchIDs.found(patchI))
258 const polyPatch& patch = mesh().boundaryMesh()[patchI];
267 // Gets nearest wall for cells next to wall
268 void Foam::cellDistFuncs::correctBoundaryFaceCells
270 const labelHashSet& patchIDs,
271 scalarField& wallDistCorrected,
272 Map<label>& nearestFace
275 // Size neighbours array for maximum possible (= size of largest patch)
276 label maxPointNeighbours = maxPatchSize(patchIDs);
278 labelList neighbours(maxPointNeighbours);
281 // Correct all cells with face on wall
282 const vectorField& cellCentres = mesh().cellCentres();
283 const labelList& faceOwner = mesh().faceOwner();
285 forAll(mesh().boundaryMesh(), patchI)
287 if (patchIDs.found(patchI))
289 const polyPatch& patch = mesh().boundaryMesh()[patchI];
291 // Check cells with face on wall
292 forAll(patch, patchFaceI)
294 label nNeighbours = getPointNeighbours
301 label cellI = faceOwner[patch.start() + patchFaceI];
305 wallDistCorrected[cellI] = smallestDist
314 // Store wallCell and its nearest neighbour
315 nearestFace.insert(cellI, minFaceI);
323 // Correct all cells connected to wall (via point) and not in nearestFace
324 void Foam::cellDistFuncs::correctBoundaryPointCells
326 const labelHashSet& patchIDs,
327 scalarField& wallDistCorrected,
328 Map<label>& nearestFace
331 // Correct all (non-visited) cells with point on wall
333 const labelListList& pointCells = mesh().pointCells();
334 const vectorField& cellCentres = mesh().cellCentres();
336 forAll(mesh().boundaryMesh(), patchI)
338 if (patchIDs.found(patchI))
340 const polyPatch& patch = mesh().boundaryMesh()[patchI];
342 const labelList& meshPoints = patch.meshPoints();
343 const labelListList& pointFaces = patch.pointFaces();
345 forAll(meshPoints, meshPointI)
347 label vertI = meshPoints[meshPointI];
349 const labelList& neighbours = pointCells[vertI];
351 forAll(neighbours, neighbourI)
353 label cellI = neighbours[neighbourI];
355 if (!nearestFace.found(cellI))
357 const labelList& wallFaces = pointFaces[meshPointI];
361 wallDistCorrected[cellI] = smallestDist
370 // Store wallCell and its nearest neighbour
371 nearestFace.insert(cellI, minFaceI);
380 // ************************************************************************* //