Loading...
Searching...
No Matches
extrudePatchMesh.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2020-2024 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "extrudePatchMesh.H"
30
31#include "createShellMesh.H"
32#include "polyTopoChange.H"
33#include "wallPolyPatch.H"
34#include "emptyPolyPatch.H"
36#include "unitConversion.H"
37
38// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39
40namespace Foam
41{
43}
44
45
46// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
47
48Foam::extrudePatchMesh::extrudePatchMesh
49(
50 const word& regionName,
51 const fvMesh& mesh,
52 const fvPatch& p,
53 const dictionary& dict
54)
55:
56 fvMesh
57 (
58 IOobject
59 (
61 mesh.facesInstance(),
62 mesh,
63 IOobject::READ_IF_PRESENT,
64 IOobject::NO_WRITE,
65 IOobject::REGISTER
66 ),
67 Zero,
68 false
69 ),
70 extrudedPatch_(p.patch()),
71 dict_(dict)
72{}
73
74
75Foam::extrudePatchMesh::extrudePatchMesh
76(
77 const fvMesh& mesh,
78 const fvPatch& p,
79 const dictionary& dict,
80 const word& regionName,
81 const polyPatchList& regionPatches
82)
84 extrudePatchMesh(regionName, mesh, p, dict)
85{
86 extrudeMesh(regionPatches);
87}
88
89
90Foam::extrudePatchMesh::extrudePatchMesh
91(
92 const fvMesh& mesh,
93 const fvPatch& p,
94 const dictionary& dict,
95 const word& regionName,
96 const List<polyPatch*>& regionPatches
97)
98:
100{
101 // Acquire ownership of the pointers
102 polyPatchList plist(const_cast<List<polyPatch*>&>(regionPatches));
103
104 extrudeMesh(plist);
105}
106
107
108Foam::extrudePatchMesh::extrudePatchMesh
109(
110 const fvMesh& mesh,
111 const fvPatch& p,
112 const dictionary& dict,
113 const word& regionName
114)
115:
117{
118 polyPatchList regionPatches(3);
119 List<dictionary> dicts(regionPatches.size());
120 List<word> patchNames(regionPatches.size());
121 List<word> patchTypes(regionPatches.size());
122
123 dicts[bottomPatchID] = dict_.subDict("bottomCoeffs");
124 dicts[sidePatchID] = dict_.subDict("sideCoeffs");
125 dicts[topPatchID] = dict_.subDict("topCoeffs");
126
127 forAll(dicts, patchi)
128 {
129 dicts[patchi].readEntry("name", patchNames[patchi]);
130 dicts[patchi].readEntry("type", patchTypes[patchi]);
131 }
132
133 forAll(regionPatches, patchi)
134 {
135 dictionary& patchDict = dicts[patchi];
136 patchDict.set("nFaces", 0);
137 patchDict.set("startFace", 0);
138
139 regionPatches.set
140 (
141 patchi,
143 (
144 patchNames[patchi],
145 patchDict,
146 patchi,
147 mesh.boundaryMesh()
148 )
149 );
150 }
151
152 extrudeMesh(regionPatches);
153}
154
155
156void Foam::extrudePatchMesh::extrudeMesh(const polyPatchList& regionPatches)
157{
158 if (this->boundaryMesh().empty())
159 {
160 const bool columnCells = dict_.get<bool>("columnCells");
161 scalar featAngleCos = -GREAT;
162 scalar featAngle = -1;
163 if (dict_.readIfPresent("featureAngle", featAngle))
164 {
165 featAngleCos = Foam::cos(degToRad(featAngle));
166 }
167
168 bitSet nonManifoldEdge(extrudedPatch_.nEdges());
169 for (label edgeI = 0; edgeI < extrudedPatch_.nInternalEdges(); edgeI++)
170 {
171 if (columnCells)
172 {
173 nonManifoldEdge.set(edgeI);
174 }
175 else
176 {
177 const auto& fcs = extrudedPatch_.edgeFaces()[edgeI];
178 if (fcs.size() > 2)
179 {
180 // TBD: issue #2780 : non-manifold edges get seen as
181 // internal.
182 // This bit of code can be removed once #2780 is solved.
183 nonManifoldEdge.set(edgeI);
184 }
185 else if (fcs.size() == 2 && featAngleCos >= -1)
186 {
187 const auto& n = extrudedPatch_.faceNormals();
188 if ((n[fcs[0]] & n[fcs[1]]) < featAngleCos)
189 {
190 nonManifoldEdge.set(edgeI);
191 }
192 }
193 }
194 }
195
197
198 faceList pointGlobalRegions;
199 faceList pointLocalRegions;
200 labelList localToGlobalRegion;
201
203 (
204 extrudedPatch_, extrudedPatch_.points()
205 );
206
208 (
209 this->globalData(),
210 pp,
211 nonManifoldEdge,
212 false,
213
214 pointGlobalRegions,
215 pointLocalRegions,
216 localToGlobalRegion
217 );
218
219
220 // Per local region an originating point
221 labelList localRegionPoints(localToGlobalRegion.size());
222 forAll(pointLocalRegions, facei)
223 {
224 const face& f = extrudedPatch_.localFaces()[facei];
225 const face& pRegions = pointLocalRegions[facei];
226 forAll(pRegions, fp)
227 {
228 localRegionPoints[pRegions[fp]] = f[fp];
229 }
230 }
231
232 // Calculate region normals by reducing local region normals
233 pointField localRegionNormals(localToGlobalRegion.size());
234 {
235 pointField localSum(localToGlobalRegion.size(), Zero);
236
237 forAll(pointLocalRegions, facei)
238 {
239 const face& pRegions = pointLocalRegions[facei];
240 forAll(pRegions, fp)
241 {
242 label localRegionI = pRegions[fp];
243 localSum[localRegionI] +=
244 extrudedPatch_.faceNormals()[facei];
245 }
246 }
247
248 Map<point> globalSum(2*localToGlobalRegion.size());
249
250 forAll(localSum, localRegionI)
251 {
252 label globalRegionI = localToGlobalRegion[localRegionI];
253 globalSum.insert(globalRegionI, localSum[localRegionI]);
254 }
255
256 // Reduce
258
259 forAll(localToGlobalRegion, localRegionI)
260 {
261 label globalRegionI = localToGlobalRegion[localRegionI];
262 localRegionNormals[localRegionI] = globalSum[globalRegionI];
263 }
264 localRegionNormals /= mag(localRegionNormals);
265 }
266
267
268 // Per local region an extrusion direction
269 vectorField firstDisp(localToGlobalRegion.size());
270 forAll(firstDisp, regionI)
271 {
272 //const point& regionPt = regionCentres[regionI];
273 const point& regionPt = extrudedPatch_.points()
274 [
275 extrudedPatch_.meshPoints()
276 [
277 localRegionPoints[regionI]
278 ]
279 ];
280 const vector& n = localRegionNormals[regionI];
281 firstDisp[regionI] = model_()(regionPt, n, 1) - regionPt;
282 }
283
284 const label nNewPatches = regionPatches.size();
285
286 // Extrude engine
287 createShellMesh extruder
288 (
289 pp,
290 pointLocalRegions,
291 localRegionPoints
292 );
293 this->clearOut();
294 this->removeFvBoundary();
295 // Make sure the patches index the new mesh
296 polyPatchList newRegionPatches(regionPatches.size());
297 forAll(regionPatches, patchi)
298 {
299 newRegionPatches.set
300 (
301 patchi,
302 regionPatches[patchi].clone(this->boundaryMesh())
303 );
304 }
305 this->addFvPatches(newRegionPatches, true);
306
307
308 // At this point we have a valid mesh with 3 patches and zero cells.
309 // Determine:
310 // - per face the top and bottom patch (topPatchID, bottomPatchID)
311 // - per edge, per face on edge the side patch (edgePatches)
312 labelListList edgePatches(extrudedPatch_.nEdges());
313 forAll(edgePatches, edgeI)
314 {
315 const labelList& eFaces = extrudedPatch_.edgeFaces()[edgeI];
316
317 if (eFaces.size() != 2 || nonManifoldEdge.test(edgeI))
318 {
319 edgePatches[edgeI].setSize(eFaces.size(), sidePatchID);
320 }
321 }
322
323 polyTopoChange meshMod(nNewPatches);
324
325 extruder.setRefinement
326 (
327 firstDisp, // first displacement
328 model_().expansionRatio(),
329 model_().nLayers(), // nLayers
330 labelList(extrudedPatch_.size(), topPatchID),
331 labelList(extrudedPatch_.size(), bottomPatchID),
332 edgePatches,
333 meshMod
334 );
335
336 autoPtr<mapPolyMesh> map = meshMod.changeMesh
337 (
338 *this, // mesh to change
339 false // inflate
340 );
341
342 // Update numbering on extruder.
343 extruder.updateMesh(map());
344
345 this->setInstance(this->thisDb().time().constant());
346 this->write();
347 }
348}
349
350
351// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
label n
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
bool set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
Definition List.H:469
A HashTable to objects of type <T> with a label key.
Definition Map.H:54
static void mapCombineReduce(Container &values, CombineOp cop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Forwards to Pstream::mapReduce with an in-place cop.
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
Definition PtrList.H:171
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
label size() const noexcept
The number of entries in the list.
Definition UPtrListI.H:106
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition bitSet.H:61
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Creates mesh by extruding a patch.
static void calcPointRegions(const globalMeshData &globalData, const primitiveFacePatch &patch, const bitSet &nonManifoldEdge, const bool syncNonCollocated, faceList &pointGlobalRegions, faceList &pointLocalRegions, labelList &localToGlobalRegion)
Helper: calculate point regions. The point region is the.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition dictionary.C:441
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, IOobjectOption::readOption readOpt=IOobjectOption::MUST_READ) const
Find entry and assign to T val. FatalIOError if it is found and the number of tokens is incorrect,...
dictionary()
Default construct, a top-level empty dictionary.
Definition dictionary.C:68
entry * set(entry *entryPtr)
Assign a new entry, overwriting any existing entry.
Definition dictionary.C:765
static autoPtr< extrudeModel > New(const dictionary &dict)
Select null constructed.
Mesh at a patch created on the fly. The following entry should be used on the field boundary dictiona...
A face is a list of labels corresponding to mesh vertices.
Definition face.H:71
Mesh data needed to do the Finite Volume discretisation.
Definition fvMesh.H:85
fvMesh(const fvMesh &)=delete
No copy construct.
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition fvPatch.H:71
static const word & regionName(const word &region)
The mesh region name or word::null if polyMesh::defaultRegion.
Definition polyMesh.C:796
static autoPtr< polyPatch > New(const word &patchType, const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm)
Return pointer to a new patch created on freestore from components.
Direct mesh changes based on v1.3 polyTopoChange syntax.
A class for handling words, derived from Foam::string.
Definition word.H:66
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
volScalarField & p
dynamicFvMesh & mesh
Foam::word regionName(args.getOrDefault< word >("region", Foam::polyMesh::defaultRegion))
Different types of constants.
Namespace for OpenFOAM.
PtrList< polyPatch > polyPatchList
Store lists of polyPatch as a PtrList.
Definition polyPatch.H:61
List< labelList > labelListList
List of labelList.
Definition labelList.H:38
List< label > labelList
A List of labels.
Definition List.H:62
List< face > faceList
List of faces.
Definition faceListFwd.H:41
constexpr scalar degToRad() noexcept
Multiplication factor for degrees to radians conversion.
PrimitivePatch< List< face >, const pointField & > primitiveFacePatch
A PrimitivePatch with List storage for the faces, const reference for the point field.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Field< vector > vectorField
Specialisation of Field<T> for vector.
vector point
Point is a vector.
Definition point.H:37
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
vectorField pointField
pointField is a vectorField.
Vector< scalar > vector
Definition vector.H:57
dimensionedScalar cos(const dimensionedScalar &ds)
runTime write()
wordList patchTypes(nPatches)
wordList patchNames(nPatches)
labelList f(nPoints)
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
Unit conversion functions.