Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / mesh / cfMesh / utilities / boundaryLayers / refineBoundaryLayers / refineBoundaryLayers.C
blob0e757a73fd7594687f5cba10a77af1f93bafbf04
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | cfMesh: A library for mesh generation
4    \\    /   O peration     |
5     \\  /    A nd           | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6      \\/     M anipulation  | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
8 License
9     This file is part of cfMesh.
11     cfMesh 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 3 of the License, or (at your
14     option) any later version.
16     cfMesh 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 cfMesh.  If not, see <http://www.gnu.org/licenses/>.
24 Description
26 \*---------------------------------------------------------------------------*/
28 #include "refineBoundaryLayers.H"
29 #include "meshSurfaceEngine.H"
30 #include "demandDrivenData.H"
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 namespace Foam
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 const meshSurfaceEngine& refineBoundaryLayers::surfaceEngine() const
41     if( !msePtr_ )
42         msePtr_ = new meshSurfaceEngine(mesh_);
44     return *msePtr_;
47 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
49 refineBoundaryLayers::refineBoundaryLayers(polyMeshGen& mesh)
51     mesh_(mesh),
52     msePtr_(NULL),
53     globalNumLayers_(1),
54     globalThicknessRatio_(1.0),
55     globalMaxThicknessFirstLayer_(VGREAT),
56     numLayersForPatch_(),
57     thicknessRatioForPatch_(),
58     maxThicknessForPatch_(),
59     discontinuousLayersForPatch_(),
60     cellSubsetName_(),
61     done_(false),
62     is2DMesh_(false),
63     specialMode_(false),
64     nLayersAtBndFace_(),
65     splitEdges_(),
66     splitEdgesAtPoint_(),
67     newVerticesForSplitEdge_(),
68     facesFromFace_(),
69     newFaces_()
72 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
74 refineBoundaryLayers::~refineBoundaryLayers()
76     deleteDemandDrivenData(msePtr_);
79 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
81 void refineBoundaryLayers::avoidRefinement()
83     if( done_ )
84     {
85         FatalErrorIn
86         (
87             "void refineBoundaryLayers::avoidRefinement()"
88         ) << "refineLayers is already executed" << exit(FatalError);
89     }
91     globalNumLayers_ = 1;
92     numLayersForPatch_.clear();
95 void refineBoundaryLayers::activate2DMode()
97     if( done_ )
98     {
99         FatalErrorIn
100         (
101             "void refineBoundaryLayers::activate2DMode()"
102         ) << "refineLayers is already executed" << exit(FatalError);
103     }
105     is2DMesh_ = true;
108 void refineBoundaryLayers::setGlobalNumberOfLayers(const label nLayers)
110     if( done_ )
111     {
112         FatalErrorIn
113         (
114             "void refineBoundaryLayers::setGlobalNumberOfLayers(const label)"
115         ) << "refineLayers is already executed" << exit(FatalError);
116     }
118     if( nLayers < 2 )
119     {
120         WarningIn
121         (
122             "void refineBoundaryLayers::setGlobalNumberOfLayers(const label)"
123         ) << "The specified global number of boundary layers is less than 2"
124           << endl;
126         return;
127     }
129     globalNumLayers_ = nLayers;
132 void refineBoundaryLayers::setGlobalThicknessRatio(const scalar thicknessRatio)
134     if( done_ )
135     {
136         FatalErrorIn
137         (
138             "void refineBoundaryLayers::setGlobalThicknessRatio(const scalar)"
139         ) << "refineLayers is already executed" << exit(FatalError);
140     }
142     if( thicknessRatio < 1.0 )
143     {
144         WarningIn
145         (
146             "void refineBoundaryLayers::setGlobalThicknessRatio(const scalar)"
147         ) << "The specified global thickness ratio is less than 1.0" << endl;
149         return;
150     }
152     globalThicknessRatio_ = thicknessRatio;
155 void refineBoundaryLayers::setGlobalMaxThicknessOfFirstLayer
157     const scalar maxThickness
160     if( done_ )
161     {
162         FatalErrorIn
163         (
164             "void refineBoundaryLayers::setGlobalMaxThicknessOfFirstLayer"
165             "(const scalar)"
166         ) << "refineLayers is already executed" << exit(FatalError);
167     }
169     if( maxThickness <= 0.0 )
170     {
171         WarningIn
172         (
173             "void refineBoundaryLayers::setGlobalMaxThicknessOfFirstLayer"
174             "(const scalar)"
175         ) << "The specified global maximum thickness of the first"
176           << " boundary layer is negative!!" << endl;
178         return;
179     }
181     globalMaxThicknessFirstLayer_ = maxThickness;
184 void refineBoundaryLayers::setNumberOfLayersForPatch
186     const word& patchName,
187     const label nLayers
190     if( done_ )
191     {
192         FatalErrorIn
193         (
194             "void refineBoundaryLayers::setNumberOfLayersForPatch"
195             "(const word&, const label)"
196         ) << "refineLayers is already executed" << exit(FatalError);
197     }
199     if( nLayers < 2 )
200     {
201         WarningIn
202         (
203             "void refineBoundaryLayers::setNumberOfLayersForPatch"
204             "(const word&, const label)"
205         ) << "The specified number of boundary layers for patch " << patchName
206           << " is less than 2... boundary layers disabled for this patch!" << endl;
207     }
209     const labelList matchedIDs = mesh_.findPatches(patchName);
211     forAll(matchedIDs, matchI)
212     {
213         numLayersForPatch_[mesh_.getPatchName(matchedIDs[matchI])] = nLayers;
214     }
217 void refineBoundaryLayers::setThicknessRatioForPatch
219     const word& patchName,
220     const scalar thicknessRatio
223     if( done_ )
224     {
225         FatalErrorIn
226         (
227             "void refineBoundaryLayers::setThicknessRatioForPatch"
228             "(const word&, const scalar)"
229         ) << "refineLayers is already executed" << exit(FatalError);
230     }
232     if( thicknessRatio < 1.0 )
233     {
234         WarningIn
235         (
236             "void refineBoundaryLayers::setThicknessRatioForPatch"
237             "(const word&, const scalar)"
238         ) << "The specified thickness ratio for patch " << patchName
239           << " is less than 1.0" << endl;
241         return;
242     }
244     const labelList matchedIDs = mesh_.findPatches(patchName);
246     forAll(matchedIDs, matchI)
247     {
248         const word pName = mesh_.getPatchName(matchedIDs[matchI]);
249         thicknessRatioForPatch_[pName] = thicknessRatio;
250     }
253 void refineBoundaryLayers::setMaxThicknessOfFirstLayerForPatch
255     const word& patchName,
256     const scalar maxThickness
259     if( done_ )
260     {
261         FatalErrorIn
262         (
263             "void refineBoundaryLayers::setMaxThicknessOfFirstLayerForPatch"
264             "(const word&, const scalar)"
265         ) << "refineLayers is already executed" << exit(FatalError);
266     }
268     if( maxThickness <= 0.0 )
269     {
270         WarningIn
271         (
272             "void refineBoundaryLayers::setGlobalMaxThicknessOfFirstLayer"
273             "(const word&, const scalar)"
274         ) << "The specified maximum thickness of the first boundary layer "
275           << "for patch " << patchName << " is negative!!" << endl;
277         return;
278     }
280     const labelList matchedIDs = mesh_.findPatches(patchName);
282     forAll(matchedIDs, matchI)
283     {
284         const word pName = mesh_.getPatchName(matchedIDs[matchI]);
285         maxThicknessForPatch_[pName] = maxThickness;
286     }
289 void refineBoundaryLayers::setInteruptForPatch(const word& patchName)
291     if( done_ )
292     {
293         FatalErrorIn
294         (
295             "void refineBoundaryLayers::setInteruptForPatch(const word&)"
296         ) << "refineLayers is already executed" << exit(FatalError);
297     }
299     const labelList matchedIDs = mesh_.findPatches(patchName);
301     forAll(matchedIDs, matchI)
302     {
303         const word pName = mesh_.getPatchName(matchedIDs[matchI]);
304         discontinuousLayersForPatch_.insert(pName);
305     }
308 void refineBoundaryLayers::setCellSubset(const word subsetName)
310     if( done_ )
311     {
312         FatalErrorIn
313         (
314             "void refineBoundaryLayers::setCellSubset(const word)"
315         ) << "refineLayers is already executed" << exit(FatalError);
316     }
318     cellSubsetName_ = subsetName;
321 void refineBoundaryLayers::activateSpecialMode()
323     specialMode_ = true;
326 void refineBoundaryLayers::refineLayers()
328     bool refinePatch(false);
329     for
330     (
331         std::map<word, label>::const_iterator it=numLayersForPatch_.begin();
332         it!=numLayersForPatch_.end();
333         ++it
334     )
335         if( it->second > 1 )
336             refinePatch = true;
338     if( (globalNumLayers_ < 2) && !refinePatch )
339         return;
341     Info << "Starting refining boundary layers" << endl;
343     if( done_ )
344     {
345         WarningIn
346         (
347             "void refineBoundaryLayers::refineLayers()"
348         ) << "Boundary layers are already refined! "
349           << "Stopping refinement" << endl;
351         return;
352     }
354     if( !analyseLayers() )
355     {
356         WarningIn
357         (
358             "void refineBoundaryLayers::refineLayers()"
359         ) << "Boundary layers do not exist in the mesh! Cannot refine" << endl;
361         return;
362     }
364     generateNewVertices();
366     generateNewFaces();
368     generateNewCells();
370     done_ = true;
372     Info << "Finished refining boundary layers" << endl;
375 void refineBoundaryLayers::pointsInBndLayer(labelLongList& layerPoints)
377     layerPoints.clear();
379     boolList pointInLayer(mesh_.points().size(), false);
381     forAll(newVerticesForSplitEdge_, seI)
382     {
383         forAllRow(newVerticesForSplitEdge_, seI, i)
384             pointInLayer[newVerticesForSplitEdge_(seI, i)] = true;
385     }
387     forAll(pointInLayer, pointI)
388         if( pointInLayer[pointI] )
389             layerPoints.append(pointI);
392 void refineBoundaryLayers::pointsInBndLayer(const word subsetName)
394     label sId = mesh_.pointSubsetIndex(subsetName);
395     if( sId < 0 )
396         sId = mesh_.addPointSubset(subsetName);
398     forAll(newVerticesForSplitEdge_, seI)
399     {
400         forAllRow(newVerticesForSplitEdge_, seI, i)
401             mesh_.addPointToSubset(sId, newVerticesForSplitEdge_(seI, i));
402     }
405 void refineBoundaryLayers::readSettings
407     const dictionary& meshDict,
408     refineBoundaryLayers& refLayers
411     if( meshDict.isDict("boundaryLayers") )
412     {
413         const dictionary& bndLayers = meshDict.subDict("boundaryLayers");
415         //- read global properties
416         if( bndLayers.found("nLayers") )
417         {
418             const label nLayers = readLabel(bndLayers.lookup("nLayers"));
419             refLayers.setGlobalNumberOfLayers(nLayers);
420         }
421         if( bndLayers.found("thicknessRatio") )
422         {
423             const scalar ratio =
424                 readScalar(bndLayers.lookup("thicknessRatio"));
425             refLayers.setGlobalThicknessRatio(ratio);
426         }
427         if( bndLayers.found("maxFirstLayerThickness") )
428         {
429             const scalar maxFirstThickness =
430                 readScalar(bndLayers.lookup("maxFirstLayerThickness"));
431             refLayers.setGlobalMaxThicknessOfFirstLayer(maxFirstThickness);
432         }
434         //- consider specified patches for exclusion from boundary layer creation
435         //- implemented by setting the number of layers to 1
436         if( bndLayers.found("excludedPatches") )
437         {
438             const wordList patchNames(bndLayers.lookup("excludedPatches"));
440             forAll(patchNames, patchI)
441             {
442                 const word pName = patchNames[patchI];
444                 refLayers.setNumberOfLayersForPatch(pName, 1);
445             }
446         }
448         //- patch-based properties
449         if( bndLayers.isDict("patchBoundaryLayers") )
450         {
451             const dictionary& patchBndLayers =
452                 bndLayers.subDict("patchBoundaryLayers");
453             const wordList patchNames = patchBndLayers.toc();
455             forAll(patchNames, patchI)
456             {
457                 const word pName = patchNames[patchI];
459                 if( patchBndLayers.isDict(pName) )
460                 {
461                     const dictionary& patchDict =
462                         patchBndLayers.subDict(pName);
464                     if( patchDict.found("nLayers") )
465                     {
466                         const label nLayers =
467                             readLabel(patchDict.lookup("nLayers"));
469                         refLayers.setNumberOfLayersForPatch(pName, nLayers);
470                     }
471                     if( patchDict.found("thicknessRatio") )
472                     {
473                         const scalar ratio =
474                             readScalar(patchDict.lookup("thicknessRatio"));
475                         refLayers.setThicknessRatioForPatch(pName, ratio);
476                     }
477                     if( patchDict.found("maxFirstLayerThickness") )
478                     {
479                         const scalar maxFirstThickness =
480                             readScalar
481                             (
482                                 patchDict.lookup("maxFirstLayerThickness")
483                             );
484                         refLayers.setMaxThicknessOfFirstLayerForPatch
485                         (
486                             pName,
487                             maxFirstThickness
488                         );
489                     }
490                     if( patchDict.found("allowDiscontinuity") )
491                     {
492                         const bool allowDiscontinuity =
493                             readBool(patchDict.lookup("allowDiscontinuity"));
495                         if( allowDiscontinuity )
496                             refLayers.setInteruptForPatch(pName);
497                     }
498                 }
499                 else
500                 {
501                     Warning << "Cannot refine layer for patch "
502                         << patchNames[patchI] << endl;
503                 }
504             }
505         }
506     }
507     else
508     {
509         //- the layer will not be refined
510         refLayers.avoidRefinement();
511     }
514 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
516 } // End namespace Foam
518 // ************************************************************************* //