twoPhaseEulerFoam:frictionalStressModel/Schaeffer: Correct mut on processor boundaries
[OpenFOAM-1.7.x.git] / src / meshTools / cellDist / cellDistFuncs.C
blob1dbcdc8ce7d2cf985204e1175618ba4540fe022e
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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"
27 #include "polyMesh.H"
28 #include "wallPolyPatch.H"
29 #include "polyBoundaryMesh.H"
31 namespace Foam
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 defineTypeNameAndDebug(cellDistFuncs, 0);
41 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
43 // Find val in first nElems elements of elems.
44 Foam::label Foam::cellDistFuncs::findIndex
46     const label nElems,
47     const labelList& elems,
48     const label val
51     for (label i = 0; i < nElems; i++)
52     {
53         if (elems[i] == val)
54         {
55             return i;
56         }
57     }
58     return -1;
62 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
64 // Construct from mesh
65 Foam::cellDistFuncs::cellDistFuncs(const polyMesh& mesh)
67     mesh_(mesh)
71 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
73 // Get patch ids of named patches
74 Foam::labelHashSet Foam::cellDistFuncs::getPatchIDs
76     const wordList& patchNames
77 ) const
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)
85     {
86         patchNamesHash.insert(patchNames[patchI]);
87     }
89     // Loop over all patches and check if patch name in hashset
91     labelHashSet patchIDs(bMesh.size());
93     forAll(bMesh, patchI)
94     {
95         const polyPatch& patch = bMesh[patchI];
97         if (patchNamesHash.found(patch.name()))
98         {
99             patchIDs.insert(patchI);
100         }
101     }
102     return patchIDs;
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
111     const point& p,
112     const polyPatch& patch,
113     const label nWallFaces,
114     const labelList& wallFaces,
115     label& minFaceI
116 ) const
118     const pointField& points = patch.points();
120     scalar minDist = GREAT;
121     minFaceI = -1;
123     for(label wallFaceI = 0; wallFaceI < nWallFaces; wallFaceI++)
124     {
125         label patchFaceI = wallFaces[wallFaceI];
127         pointHit curHit = patch[patchFaceI].nearestPoint(p, points);
129         if (curHit.distance() < minDist)
130         {
131             minDist = curHit.distance();
132             minFaceI = patch.start() + patchFaceI;
133         }
134     }
136     return minDist;
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
148 ) const
150     label nNeighbours = 0;
152     // Add myself
153     neighbours[nNeighbours++] = patchFaceI;
155     // Add all face neighbours
156     const labelList& faceNeighbours = patch.faceFaces()[patchFaceI];
158     forAll(faceNeighbours, faceNeighbourI)
159     {
160         neighbours[nNeighbours++] = faceNeighbours[faceNeighbourI];
161     }
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
169     // face.
171     const face& f = patch.localFaces()[patchFaceI];
173     forAll(f, fp)
174     {
175         label pointI = f[fp];
177         const labelList& pointNbs = patch.pointFaces()[pointI];
179         forAll(pointNbs, nbI)
180         {
181             label faceI = pointNbs[nbI];
183             // Check for faceI in edge-neighbours part of neighbours
184             if (findIndex(nEdgeNbs, neighbours, faceI) == -1)
185             {
186                 neighbours[nNeighbours++] = faceI;
187             }
188         }
189     }
192     if (debug)
193     {
194         // Check for duplicates
196         // Use hashSet to determine nbs.
197         labelHashSet nbs(4*f.size());
199         forAll(f, fp)
200         {
201             const labelList& pointNbs = patch.pointFaces()[f[fp]];
203             forAll(pointNbs, i)
204             {
205                 nbs.insert(pointNbs[i]);
206             }
207         }
209         // Subtract ours.
210         for (label i = 0; i < nNeighbours; i++)
211         {
212             label nb = neighbours[i];
214             if (!nbs.found(nb))
215             {
216                 SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
217                     << "getPointNeighbours : patchFaceI:" << patchFaceI
218                     << " verts:" << f << endl;
220                 forAll(f, fp)
221                 {
222                     SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
223                         << "point:" << f[fp] << " pointFaces:"
224                         << patch.pointFaces()[f[fp]] << endl;
225                 }
227                 for (label i = 0; i < nNeighbours; i++)
228                 {
229                     SeriousErrorIn("Foam::cellDistFuncs::getPointNeighbours")
230                         << "fast nbr:" << neighbours[i]
231                         << endl;
232                 }
234                 FatalErrorIn("getPointNeighbours")
235                     << "Problem: fast pointNeighbours routine included " << nb
236                     << " which is not in proper neigbour list " << nbs.toc()
237                     << abort(FatalError);
238             }
239             nbs.erase(nb);
240         }
242         if (nbs.size())
243         {
244             FatalErrorIn("getPointNeighbours")
245                 << "Problem: fast pointNeighbours routine did not find "
246                 << nbs.toc() << abort(FatalError);
247         }
248     }
250     return nNeighbours;
254 // size of largest patch (out of supplied subset of patches)
255 Foam::label Foam::cellDistFuncs::maxPatchSize(const labelHashSet& patchIDs)
256  const
258     label maxSize = 0;
260     forAll(mesh().boundaryMesh(), patchI)
261     {
262         if (patchIDs.found(patchI))
263         {
264             const polyPatch& patch = mesh().boundaryMesh()[patchI];
266             maxSize = Foam::max(maxSize, patch.size());
267         }
268     }
269     return maxSize;
273 // sum of patch sizes (out of supplied subset of patches)
274 Foam::label Foam::cellDistFuncs::sumPatchSize(const labelHashSet& patchIDs)
275  const
277     label sum = 0;
279     forAll(mesh().boundaryMesh(), patchI)
280     {
281         if (patchIDs.found(patchI))
282         {
283             const polyPatch& patch = mesh().boundaryMesh()[patchI];
285             sum += patch.size();
286         }
287     }
288     return sum;
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
298 ) const
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)
311     {
312         if (patchIDs.found(patchI))
313         {
314             const polyPatch& patch = mesh().boundaryMesh()[patchI];
316             // Check cells with face on wall
317             forAll(patch, patchFaceI)
318             {
319                 label nNeighbours = getPointNeighbours
320                 (
321                     patch,
322                     patchFaceI,
323                     neighbours
324                 );
326                 label cellI = faceOwner[patch.start() + patchFaceI];
328                 label minFaceI = -1;
330                 wallDistCorrected[cellI] = smallestDist
331                 (
332                     cellCentres[cellI],
333                     patch,
334                     nNeighbours,
335                     neighbours,
336                     minFaceI
337                 );
339                 // Store wallCell and its nearest neighbour
340                 nearestFace.insert(cellI, minFaceI);
341             }
342         }
343     }
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
354 ) const
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)
362     {
363         if (patchIDs.found(patchI))
364         {
365             const polyPatch& patch = mesh().boundaryMesh()[patchI];
367             const labelList& meshPoints = patch.meshPoints();
368             const labelListList& pointFaces = patch.pointFaces();
370             forAll(meshPoints, meshPointI)
371             {
372                 label vertI = meshPoints[meshPointI];
374                 const labelList& neighbours = pointCells[vertI];
376                 forAll(neighbours, neighbourI)
377                 {
378                     label cellI = neighbours[neighbourI];
380                     if (!nearestFace.found(cellI))
381                     {
382                         const labelList& wallFaces = pointFaces[meshPointI];
384                         label minFaceI = -1;
386                         wallDistCorrected[cellI] = smallestDist
387                         (
388                             cellCentres[cellI],
389                             patch,
390                             wallFaces.size(),
391                             wallFaces,
392                             minFaceI
393                         );
395                         // Store wallCell and its nearest neighbour
396                         nearestFace.insert(cellI, minFaceI);
397                     }
398                 }
399             }
400         }
401     }
405 // ************************************************************************* //