1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 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, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "cellDistFuncs.H"
29 #include "wallPolyPatch.H"
30 #include "polyBoundaryMesh.H"
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37 defineTypeNameAndDebug(cellDistFuncs, 0);
42 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
44 // Find val in first nElems elements of elems.
45 Foam::label Foam::cellDistFuncs::findIndex
48 const labelList& elems,
52 for (label i = 0; i < nElems; i++)
63 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
65 // Construct from mesh
66 Foam::cellDistFuncs::cellDistFuncs(const polyMesh& mesh)
72 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
74 // Get patch ids of named patches
75 Foam::labelHashSet Foam::cellDistFuncs::getPatchIDs
77 const wordList& patchNames
80 const polyBoundaryMesh& bMesh = mesh().boundaryMesh();
82 // Construct Set of patchNames for easy checking if included
83 HashSet<word> patchNamesHash(patchNames.size());
85 forAll(patchNames, patchI)
87 patchNamesHash.insert(patchNames[patchI]);
90 // Loop over all patches and check if patch name in hashset
92 labelHashSet patchIDs(bMesh.size());
96 const polyPatch& patch = bMesh[patchI];
98 if (patchNamesHash.found(patch.name()))
100 patchIDs.insert(patchI);
107 // Return smallest true distance from p to any of wallFaces.
108 // Note that even if normal hits face we still check other faces.
109 // Note that wallFaces is untruncated and we explicitly pass in size.
110 Foam::scalar Foam::cellDistFuncs::smallestDist
113 const polyPatch& patch,
114 const label nWallFaces,
115 const labelList& wallFaces,
119 const pointField& points = patch.points();
121 scalar minDist = GREAT;
124 for(label wallFaceI = 0; wallFaceI < nWallFaces; wallFaceI++)
126 label patchFaceI = wallFaces[wallFaceI];
128 pointHit curHit = patch[patchFaceI].nearestPoint(p, points);
130 if (curHit.distance() < minDist)
132 minDist = curHit.distance();
133 minFaceI = patch.start() + patchFaceI;
141 // Get point neighbours of faceI (including faceI). Returns number of faces.
142 // Note: does not allocate storage but does use linear search to determine
143 // uniqueness. For polygonal faces this might be quite inefficient.
144 Foam::label Foam::cellDistFuncs::getPointNeighbours
146 const primitivePatch& patch,
147 const label patchFaceI,
148 labelList& neighbours
151 label nNeighbours = 0;
154 neighbours[nNeighbours++] = patchFaceI;
156 // Add all face neighbours
157 const labelList& faceNeighbours = patch.faceFaces()[patchFaceI];
159 forAll(faceNeighbours, faceNeighbourI)
161 neighbours[nNeighbours++] = faceNeighbours[faceNeighbourI];
164 // Remember part of neighbours that contains edge-connected faces.
165 label nEdgeNbs = nNeighbours;
168 // Add all point-only neighbours by linear searching in edge neighbours.
169 // Assumes that point-only neighbours are not using multiple points on
172 const face& f = patch.localFaces()[patchFaceI];
176 label pointI = f[fp];
178 const labelList& pointNbs = patch.pointFaces()[pointI];
180 forAll(pointNbs, nbI)
182 label faceI = pointNbs[nbI];
184 // Check for faceI in edge-neighbours part of neighbours
185 if (findIndex(nEdgeNbs, neighbours, faceI) == -1)
187 neighbours[nNeighbours++] = faceI;
195 // Check for duplicates
197 // Use hashSet to determine nbs.
198 labelHashSet nbs(4*f.size());
202 const labelList& pointNbs = patch.pointFaces()[f[fp]];
206 nbs.insert(pointNbs[i]);
211 for (label i = 0; i < nNeighbours; i++)
213 label nb = neighbours[i];
217 SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
218 << "getPointNeighbours : patchFaceI:" << patchFaceI
219 << " verts:" << f << endl;
223 SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
224 << "point:" << f[fp] << " pointFaces:"
225 << patch.pointFaces()[f[fp]] << endl;
228 for (label i = 0; i < nNeighbours; i++)
230 SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
231 << "fast nbr:" << neighbours[i]
235 FatalErrorIn("getPointNeighbours")
236 << "Problem: fast pointNeighbours routine included " << nb
237 << " which is not in proper neigbour list " << nbs.toc()
238 << abort(FatalError);
245 FatalErrorIn("getPointNeighbours")
246 << "Problem: fast pointNeighbours routine did not find "
247 << nbs.toc() << abort(FatalError);
255 // size of largest patch (out of supplied subset of patches)
256 Foam::label Foam::cellDistFuncs::maxPatchSize(const labelHashSet& patchIDs)
261 forAll(mesh().boundaryMesh(), patchI)
263 if (patchIDs.found(patchI))
265 const polyPatch& patch = mesh().boundaryMesh()[patchI];
267 maxSize = Foam::max(maxSize, patch.size());
274 // sum of patch sizes (out of supplied subset of patches)
275 Foam::label Foam::cellDistFuncs::sumPatchSize(const labelHashSet& patchIDs)
280 forAll(mesh().boundaryMesh(), patchI)
282 if (patchIDs.found(patchI))
284 const polyPatch& patch = mesh().boundaryMesh()[patchI];
293 // Gets nearest wall for cells next to wall
294 void Foam::cellDistFuncs::correctBoundaryFaceCells
296 const labelHashSet& patchIDs,
297 scalarField& wallDistCorrected,
298 Map<label>& nearestFace
301 // Size neighbours array for maximum possible (= size of largest patch)
302 label maxPointNeighbours = maxPatchSize(patchIDs);
304 labelList neighbours(maxPointNeighbours);
307 // Correct all cells with face on wall
308 const vectorField& cellCentres = mesh().cellCentres();
309 const labelList& faceOwner = mesh().faceOwner();
311 forAll(mesh().boundaryMesh(), patchI)
313 if (patchIDs.found(patchI))
315 const polyPatch& patch = mesh().boundaryMesh()[patchI];
317 // Check cells with face on wall
318 forAll(patch, patchFaceI)
320 label nNeighbours = getPointNeighbours
327 label cellI = faceOwner[patch.start() + patchFaceI];
331 wallDistCorrected[cellI] = smallestDist
340 // Store wallCell and its nearest neighbour
341 nearestFace.insert(cellI, minFaceI);
349 // Correct all cells connected to wall (via point) and not in nearestFace
350 void Foam::cellDistFuncs::correctBoundaryPointCells
352 const labelHashSet& patchIDs,
353 scalarField& wallDistCorrected,
354 Map<label>& nearestFace
357 // Correct all (non-visited) cells with point on wall
359 const labelListList& pointCells = mesh().pointCells();
360 const vectorField& cellCentres = mesh().cellCentres();
362 forAll(mesh().boundaryMesh(), patchI)
364 if (patchIDs.found(patchI))
366 const polyPatch& patch = mesh().boundaryMesh()[patchI];
368 const labelList& meshPoints = patch.meshPoints();
369 const labelListList& pointFaces = patch.pointFaces();
371 forAll(meshPoints, meshPointI)
373 label vertI = meshPoints[meshPointI];
375 const labelList& neighbours = pointCells[vertI];
377 forAll(neighbours, neighbourI)
379 label cellI = neighbours[neighbourI];
381 if (!nearestFace.found(cellI))
383 const labelList& wallFaces = pointFaces[meshPointI];
387 wallDistCorrected[cellI] = smallestDist
396 // Store wallCell and its nearest neighbour
397 nearestFace.insert(cellI, minFaceI);
406 // ************************************************************************* //