1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 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 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
27 \*---------------------------------------------------------------------------*/
29 #include "cellDistFuncs.H"
31 #include "wallPolyPatch.H"
32 #include "polyBoundaryMesh.H"
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 defineTypeNameAndDebug(cellDistFuncs, 0);
44 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
46 // Find val in first nElems elements of elems.
47 Foam::label Foam::cellDistFuncs::findIndex
50 const labelList& elems,
54 for (label i = 0; i < nElems; i++)
65 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
67 // Construct from mesh
68 Foam::cellDistFuncs::cellDistFuncs(const polyMesh& mesh)
74 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
76 // Get patch ids of named patches
77 Foam::labelHashSet Foam::cellDistFuncs::getPatchIDs
79 const wordList& patchNames
82 const polyBoundaryMesh& bMesh = mesh().boundaryMesh();
84 // Construct Set of patchNames for easy checking if included
85 HashSet<word> patchNamesHash(patchNames.size());
87 forAll(patchNames, patchI)
89 patchNamesHash.insert(patchNames[patchI]);
92 // Loop over all patches and check if patch name in hashset
94 labelHashSet patchIDs(bMesh.size());
98 const polyPatch& patch = bMesh[patchI];
100 if (patchNamesHash.found(patch.name()))
102 patchIDs.insert(patchI);
109 // Get patch ids of patches of certain type (e.g. 'polyProcessorPatch')
110 Foam::labelHashSet Foam::cellDistFuncs::getPatchIDs(const word& wantedType)
113 const polyBoundaryMesh& bMesh = mesh().boundaryMesh();
115 labelHashSet patchIDs(bMesh.size());
117 forAll(bMesh, patchI)
119 const polyPatch& patch = bMesh[patchI];
121 if (patch.type() == wantedType)
123 patchIDs.insert(patchI);
130 // Return smallest true distance from p to any of wallFaces.
131 // Note that even if normal hits face we still check other faces.
132 // Note that wallFaces is untruncated and we explicitly pass in size.
133 Foam::scalar Foam::cellDistFuncs::smallestDist
136 const polyPatch& patch,
137 const label nWallFaces,
138 const labelList& wallFaces,
142 const pointField& points = patch.points();
144 scalar minDist = GREAT;
147 for(label wallFaceI = 0; wallFaceI < nWallFaces; wallFaceI++)
149 label patchFaceI = wallFaces[wallFaceI];
151 pointHit curHit = patch[patchFaceI].nearestPoint(p, points);
153 if (curHit.distance() < minDist)
155 minDist = curHit.distance();
156 minFaceI = patch.start() + patchFaceI;
164 // Get point neighbours of faceI (including faceI). Returns number of faces.
165 // Note: does not allocate storage but does use linear search to determine
166 // uniqueness. For polygonal faces this might be quite inefficient.
167 Foam::label Foam::cellDistFuncs::getPointNeighbours
169 const primitivePatch& patch,
170 const label patchFaceI,
171 labelList& neighbours
174 label nNeighbours = 0;
177 neighbours[nNeighbours++] = patchFaceI;
179 // Add all face neighbours
180 const labelList& faceNeighbours = patch.faceFaces()[patchFaceI];
182 forAll(faceNeighbours, faceNeighbourI)
184 neighbours[nNeighbours++] = faceNeighbours[faceNeighbourI];
187 // Remember part of neighbours that contains edge-connected faces.
188 label nEdgeNbs = nNeighbours;
191 // Add all point-only neighbours by linear searching in edge neighbours.
192 // Assumes that point-only neighbours are not using multiple points on
195 const face& f = patch.localFaces()[patchFaceI];
199 label pointI = f[fp];
201 const labelList& pointNbs = patch.pointFaces()[pointI];
203 forAll(pointNbs, nbI)
205 label faceI = pointNbs[nbI];
207 // Check for faceI in edge-neighbours part of neighbours
208 if (findIndex(nEdgeNbs, neighbours, faceI) == -1)
210 neighbours[nNeighbours++] = faceI;
218 // Check for duplicates
220 // Use hashSet to determine nbs.
221 labelHashSet nbs(4*f.size());
225 const labelList& pointNbs = patch.pointFaces()[f[fp]];
229 nbs.insert(pointNbs[i]);
234 for (label i = 0; i < nNeighbours; i++)
236 label nb = neighbours[i];
240 SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
241 << "getPointNeighbours : patchFaceI:" << patchFaceI
242 << " verts:" << f << endl;
246 SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
247 << "point:" << f[fp] << " pointFaces:"
248 << patch.pointFaces()[f[fp]] << endl;
251 for (label i = 0; i < nNeighbours; i++)
253 SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
254 << "fast nbr:" << neighbours[i]
258 FatalErrorIn("getPointNeighbours")
259 << "Problem: fast pointNeighbours routine included " << nb
260 << " which is not in proper neigbour list " << nbs.toc()
261 << abort(FatalError);
268 FatalErrorIn("getPointNeighbours")
269 << "Problem: fast pointNeighbours routine did not find "
270 << nbs.toc() << abort(FatalError);
278 // size of largest patch (out of supplied subset of patches)
279 Foam::label Foam::cellDistFuncs::maxPatchSize(const labelHashSet& patchIDs)
284 forAll(mesh().boundaryMesh(), patchI)
286 if (patchIDs.found(patchI))
288 const polyPatch& patch = mesh().boundaryMesh()[patchI];
290 maxSize = Foam::max(maxSize, patch.size());
297 // sum of patch sizes (out of supplied subset of patches)
298 Foam::label Foam::cellDistFuncs::sumPatchSize(const labelHashSet& patchIDs)
303 forAll(mesh().boundaryMesh(), patchI)
305 if (patchIDs.found(patchI))
307 const polyPatch& patch = mesh().boundaryMesh()[patchI];
316 // Gets nearest wall for cells next to wall
317 void Foam::cellDistFuncs::correctBoundaryFaceCells
319 const labelHashSet& patchIDs,
320 scalarField& wallDistCorrected,
321 Map<label>& nearestFace
324 // Size neighbours array for maximum possible (= size of largest patch)
325 label maxPointNeighbours = maxPatchSize(patchIDs);
327 labelList neighbours(maxPointNeighbours);
330 // Correct all cells with face on wall
331 const vectorField& cellCentres = mesh().cellCentres();
332 const labelList& faceOwner = mesh().faceOwner();
334 forAll(mesh().boundaryMesh(), patchI)
336 if (patchIDs.found(patchI))
338 const polyPatch& patch = mesh().boundaryMesh()[patchI];
340 // Check cells with face on wall
341 forAll(patch, patchFaceI)
343 label nNeighbours = getPointNeighbours
350 label cellI = faceOwner[patch.start() + patchFaceI];
354 wallDistCorrected[cellI] = smallestDist
363 // Store wallCell and its nearest neighbour
364 nearestFace.insert(cellI, minFaceI);
372 // Correct all cells connected to wall (via point) and not in nearestFace
373 void Foam::cellDistFuncs::correctBoundaryPointCells
375 const labelHashSet& patchIDs,
376 scalarField& wallDistCorrected,
377 Map<label>& nearestFace
380 // Correct all (non-visited) cells with point on wall
382 const labelListList& pointCells = mesh().pointCells();
383 const vectorField& cellCentres = mesh().cellCentres();
385 forAll(mesh().boundaryMesh(), patchI)
387 if (patchIDs.found(patchI))
389 const polyPatch& patch = mesh().boundaryMesh()[patchI];
391 const labelList& meshPoints = patch.meshPoints();
392 const labelListList& pointFaces = patch.pointFaces();
394 forAll(meshPoints, meshPointI)
396 label vertI = meshPoints[meshPointI];
398 const labelList& neighbours = pointCells[vertI];
400 forAll(neighbours, neighbourI)
402 label cellI = neighbours[neighbourI];
404 if (!nearestFace.found(cellI))
406 const labelList& wallFaces = pointFaces[meshPointI];
410 wallDistCorrected[cellI] = smallestDist
419 // Store wallCell and its nearest neighbour
420 nearestFace.insert(cellI, minFaceI);
429 // ************************************************************************* //