Merge remote-tracking branch 'origin/nr/multiSolverFix' into nextRelease
[foam-extend-3.2.git] / src / dynamicMesh / dynamicFvMesh / dynamicTopoFvMesh / lengthScaleEstimator / lengthScaleEstimatorI.H
blob8b0ef6ef4f378c2a9a00d11286ea12928300080c
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright held by original author
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 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
19     for more details.
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 namespace Foam
30 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
33 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
35 inline scalar lengthScaleEstimator::ratioMin() const
37     return ratioMin_;
41 inline scalar lengthScaleEstimator::ratioMax() const
43     return ratioMax_;
47 inline scalar lengthScaleEstimator::growthFactor() const
49     return growthFactor_;
53 //- Limit length scale for surface-edges
54 inline void lengthScaleEstimator::limitScale(scalar& scale) const
56     // Need to account for multiplication by ratioMin / ratioMax as well
57     scale = Foam::max(scale, minLengthScale_ / ratioMin_);
58     scale = Foam::min(scale, maxLengthScale_ / ratioMax_);
62 //- Check if a particular patch is free-floating
63 //  (i.e., gets its length-scale from the interior)
64 inline bool lengthScaleEstimator::isFreePatch
66     const label pIndex
67 ) const
69     const polyBoundaryMesh& boundary = mesh_.boundaryMesh();
71     if (freePatches_.found(boundary[pIndex].name()))
72     {
73         return true;
74     }
76     // Certain boundary types are also considered floating
77     const word& pType = boundary[pIndex].type();
79     if
80     (
81         (pType == "processor") ||
82         (pType == "cyclic") ||
83         (pType == "wedge") ||
84         (pType == "empty") ||
85         (pType == "symmetryPlane")
86     )
87     {
88         return true;
89     }
91     return false;
95 //- Check if a particular patch is flagged
96 //  for proximity-based refinement
97 inline bool lengthScaleEstimator::isProximityPatch
99     const label pIndex
100 ) const
102     if (proximityPatches_.found(mesh_.boundaryMesh()[pIndex].name()))
103     {
104         return true;
105     }
107     return false;
111 //- Check if a particular patch is flagged
112 //  for curvature-based refinement
113 inline bool lengthScaleEstimator::isCurvaturePatch
115     const label pIndex
116 ) const
118     if (curvaturePatches_.found(mesh_.boundaryMesh()[pIndex].name()))
119     {
120         return true;
121     }
123     return false;
127 //- Check whether a particular point is too close
128 //  to a previous mesh slice location
129 inline bool lengthScaleEstimator::checkOldSlices
131     const vector& gCentre
132 ) const
134     forAll(sliceBoxes_, boxI)
135     {
136         if (sliceBoxes_[boxI].contains(gCentre))
137         {
138             // Too close to another slice-point. Bail out.
139             return true;
140         }
141     }
143     return false;
147 //- Add a boundBox to the existing set of sliceBoxes
148 inline void lengthScaleEstimator::appendBox
150     const boundBox& bBox
153     label currentSize = sliceBoxes_.size();
154     sliceBoxes_.setSize(currentSize + 1);
155     sliceBoxes_[currentSize] = bBox;
159 //- Clear the list of sliceBoxes
160 inline void lengthScaleEstimator::clearBoxes()
162     sliceBoxes_.clear();
166 //- Check whether a particular patch permits refinement
167 //  - Return true if not permitted
168 inline bool lengthScaleEstimator::checkRefinementPatch
170     const label pIndex
171 ) const
173     if (pIndex < 0)
174     {
175         return false;
176     }
178     if (findIndex(noModPatchIDs_, pIndex) > -1)
179     {
180         return true;
181     }
183     // Refinement is allowed
184     return false;
188 // Return the fixed length-scale value for a boundary face
189 inline scalar lengthScaleEstimator::fixedLengthScale
191     const label fIndex,
192     const label pIndex,
193     bool usePolyMesh
194 ) const
196     scalar scale = 0.0;
198     const polyBoundaryMesh& boundary = mesh_.boundaryMesh();
200     // Check fixed length-scale patches
201     // If the value is negative, average face length-scales.
202     if (fixedPatches_.found(boundary[pIndex].name()))
203     {
204         scalar dictValue =
205         (
206             fixedPatches_[boundary[pIndex].name()][0].scalarToken()
207         );
209         if (dictValue > 0.0)
210         {
211             return dictValue;
212         }
213     }
215     // Approximate a length-scale from face area
216     if (usePolyMesh)
217     {
218         scale = Foam::sqrt(2.0 * mag(mesh_.faceAreas()[fIndex]));
219     }
221     return scale;
225 // Test an edge / face for proximity with other faces on proximity patches
226 // and return the scalar distance to an oppositely-oriented face.
227 inline bool lengthScaleEstimator::testProximity
229     const vector& gCentre,
230     const vector& gNormal,
231     const scalar testStep,
232     label& proxFace,
233     scalar& proxDistance
234 ) const
236     // Reset input
237     proxDistance = GREAT;
239     DynamicList<label> posIndices(20);
240     scalar minDeviation = -0.9;
241     label nD = spatialRes_, binSize = proximityBins_.size();
243     // Obtain min/max extents
244     const point& bMin = proxBoundBox_.min();
245     const point& bMax = proxBoundBox_.max();
247     // Extend bounding-box dimensions a bit to avoid edge-effects.
248     scalar ext = 0.02*(mag(bMax - bMin));
250     // Define an inverse grid-cell size.
251     scalar xL = nD/(bMax.x() - bMin.x() + ext);
252     scalar yL = nD/(bMax.y() - bMin.y() + ext);
253     scalar zL = nD/(bMax.z() - bMin.z() + ext);
255     // Reset the proximity face
256     proxFace = -1;
258     // Now take multiple steps in both normal directions,
259     // and add to the list of boxes to be checked.
260     for (scalar dir = -1.0; dir < 2.0; dir += 2.0)
261     {
262         for (scalar step = 0.0; step < 5.0*testStep; step += testStep)
263         {
264             // Hash the point-location
265             point p = (gCentre + (dir*step*gNormal)) - bMin;
267             label i = label(mag(::floor(p.x()*xL)));
268             label j = label(mag(::floor(p.y()*yL)));
269             label k = label(mag(::floor(p.z()*zL)));
271             label pos = mag(((k*nD*nD)+(j*nD)+i) % binSize);
273             if (findIndex(posIndices, pos) == -1)
274             {
275                 posIndices.append(pos);
276             }
277         }
278     }
280     // Obtain old-mesh face geometry for reference.
281     const vectorField& faceAreas = mesh_.faceAreas();
282     const vectorField& faceCentres = mesh_.faceCentres();
284     forAll(posIndices, indexI)
285     {
286         const labelList& posBin = proximityBins_[posIndices[indexI]];
288         forAll(posBin, faceI)
289         {
290             // Step 1: Measure the distance to the face.
291             vector rFace = (faceCentres[posBin[faceI]] - gCentre);
293             scalar distance = mag(rFace);
295             // Step 2: Check if this face is oriented away from face / edge.
296             const vector& fNormal = faceAreas[posBin[faceI]];
298             scalar deviation = (gNormal & (fNormal/(mag(fNormal) + VSMALL)));
300             if
301             (
302                 (deviation < minDeviation) &&
303                 (distance < proxDistance)
304             )
305             {
306                 // Update statistics
307                 proxFace = posBin[faceI];
308                 proxDistance = distance;
309                 // minDeviation = deviation;
310             }
311         }
312     }
314     // Check for fall below threshold
315     if ((proxFace != -1) && (proxDistance < sliceThreshold_))
316     {
317         return true;
318     }
320     // Does not fall below threshold
321     return false;
325 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
327 } // End namespace Foam
329 // ************************************************************************* //