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-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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"
35 #include "wedgePolyPatch.H"
36 
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41  defineTypeNameAndDebug(extrudePatchMesh, 0);
42 }
43 
44 
45 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
46 
47 Foam::extrudePatchMesh::extrudePatchMesh
48 (
49  const word& regionName,
50  const fvMesh& mesh,
51  const fvPatch& p,
52  const dictionary& dict
53 )
54 :
55  fvMesh
56  (
57  IOobject
58  (
59  regionName,
60  mesh.facesInstance(),
61  mesh,
62  IOobject::READ_IF_PRESENT,
63  IOobject::NO_WRITE,
64  IOobject::REGISTER
65  ),
66  Zero,
67  false
68  ),
69  extrudedPatch_(p.patch()),
70  dict_(dict)
71 {}
72 
73 
74 Foam::extrudePatchMesh::extrudePatchMesh
75 (
76  const fvMesh& mesh,
77  const fvPatch& p,
78  const dictionary& dict,
79  const word& regionName,
80  polyPatchList& regionPatches
81 )
82 :
84 {
85  extrudeMesh(regionPatches);
86 }
87 
88 
89 Foam::extrudePatchMesh::extrudePatchMesh
90 (
91  const fvMesh& mesh,
92  const fvPatch& p,
93  const dictionary& dict,
94  const word& regionName,
95  const List<polyPatch*>& regionPatches
96 )
97 :
99 {
100  // Acquire ownership of the pointers
101  polyPatchList plist(const_cast<List<polyPatch*>&>(regionPatches));
102 
103  extrudeMesh(plist);
104 }
105 
106 
107 Foam::extrudePatchMesh::extrudePatchMesh
108 (
109  const fvMesh& mesh,
110  const fvPatch& p,
111  const dictionary& dict,
112  const word& regionName
113 )
114 :
116 {
117  polyPatchList regionPatches(3);
118  List<dictionary> dicts(regionPatches.size());
119  List<word> patchNames(regionPatches.size());
120  List<word> patchTypes(regionPatches.size());
121 
122  dicts[bottomPatchID] = dict_.subDict("bottomCoeffs");
123  dicts[sidePatchID] = dict_.subDict("sideCoeffs");
124  dicts[topPatchID] = dict_.subDict("topCoeffs");
125 
126  forAll(dicts, patchi)
127  {
128  dicts[patchi].readEntry("name", patchNames[patchi]);
129  dicts[patchi].readEntry("type", patchTypes[patchi]);
130  }
131 
132  forAll(regionPatches, patchi)
133  {
134  dictionary& patchDict = dicts[patchi];
135  patchDict.set("nFaces", 0);
136  patchDict.set("startFace", 0);
137 
138  regionPatches.set
139  (
140  patchi,
142  (
143  patchNames[patchi],
144  patchDict,
145  patchi,
146  mesh.boundaryMesh()
147  )
148  );
149  }
150 
151  extrudeMesh(regionPatches);
152 }
153 
154 
155 void Foam::extrudePatchMesh::extrudeMesh(polyPatchList& regionPatches)
156 {
157  if (this->boundaryMesh().empty())
158  {
159  const bool columnCells = dict_.get<bool>("columnCells");
160 
161  bitSet nonManifoldEdge(extrudedPatch_.nEdges());
162  for (label edgeI = 0; edgeI < extrudedPatch_.nInternalEdges(); edgeI++)
163  {
164  if (columnCells)
165  {
166  nonManifoldEdge.set(edgeI);
167  }
168  else if (extrudedPatch_.edgeFaces()[edgeI].size() > 2)
169  {
170  // TBD: issue #2780 : non-manifold edges get seen as internal
171  // This bit of code can be removed once #2780 is solved.
172  nonManifoldEdge.set(edgeI);
173  }
174  }
175 
176  autoPtr<extrudeModel> model_(extrudeModel::New(dict_));
177 
178  faceList pointGlobalRegions;
179  faceList pointLocalRegions;
180  labelList localToGlobalRegion;
181 
182  const primitiveFacePatch pp
183  (
184  extrudedPatch_, extrudedPatch_.points()
185  );
186 
188  (
189  this->globalData(),
190  pp,
191  nonManifoldEdge,
192  false,
193 
194  pointGlobalRegions,
195  pointLocalRegions,
196  localToGlobalRegion
197  );
198 
199 
200  // Per local region an originating point
201  labelList localRegionPoints(localToGlobalRegion.size());
202  forAll(pointLocalRegions, facei)
203  {
204  const face& f = extrudedPatch_.localFaces()[facei];
205  const face& pRegions = pointLocalRegions[facei];
206  forAll(pRegions, fp)
207  {
208  localRegionPoints[pRegions[fp]] = f[fp];
209  }
210  }
211 
212  // Calculate region normals by reducing local region normals
213  pointField localRegionNormals(localToGlobalRegion.size());
214  {
215  pointField localSum(localToGlobalRegion.size(), Zero);
216 
217  forAll(pointLocalRegions, facei)
218  {
219  const face& pRegions = pointLocalRegions[facei];
220  forAll(pRegions, fp)
221  {
222  label localRegionI = pRegions[fp];
223  localSum[localRegionI] +=
224  extrudedPatch_.faceNormals()[facei];
225  }
226  }
227 
228  Map<point> globalSum(2*localToGlobalRegion.size());
229 
230  forAll(localSum, localRegionI)
231  {
232  label globalRegionI = localToGlobalRegion[localRegionI];
233  globalSum.insert(globalRegionI, localSum[localRegionI]);
234  }
235 
236  // Reduce
237  Pstream::mapCombineReduce(globalSum, plusEqOp<point>());
238 
239  forAll(localToGlobalRegion, localRegionI)
240  {
241  label globalRegionI = localToGlobalRegion[localRegionI];
242  localRegionNormals[localRegionI] = globalSum[globalRegionI];
243  }
244  localRegionNormals /= mag(localRegionNormals);
245  }
246 
247 
248  // Per local region an extrusion direction
249  vectorField firstDisp(localToGlobalRegion.size());
250  forAll(firstDisp, regionI)
251  {
252  //const point& regionPt = regionCentres[regionI];
253  const point& regionPt = extrudedPatch_.points()
254  [
255  extrudedPatch_.meshPoints()
256  [
257  localRegionPoints[regionI]
258  ]
259  ];
260  const vector& n = localRegionNormals[regionI];
261  firstDisp[regionI] = model_()(regionPt, n, 1) - regionPt;
262  }
263 
264  const label nNewPatches = regionPatches.size();
265 
266  // Extrude engine
267  createShellMesh extruder
268  (
269  pp,
270  pointLocalRegions,
271  localRegionPoints
272  );
273  this->clearOut();
274  this->removeFvBoundary();
275  this->addFvPatches(regionPatches, true);
276 
277 
278  // At this point we have a valid mesh with 3 patches and zero cells.
279  // Determine:
280  // - per face the top and bottom patch (topPatchID, bottomPatchID)
281  // - per edge, per face on edge the side patch (edgePatches)
282  labelListList edgePatches(extrudedPatch_.nEdges());
283  forAll(edgePatches, edgeI)
284  {
285  const labelList& eFaces = extrudedPatch_.edgeFaces()[edgeI];
286 
287  if (eFaces.size() != 2 || nonManifoldEdge.test(edgeI))
288  {
289  edgePatches[edgeI].setSize(eFaces.size(), sidePatchID);
290  }
291  }
292 
293  polyTopoChange meshMod(nNewPatches);
294 
295  extruder.setRefinement
296  (
297  firstDisp, // first displacement
298  model_().expansionRatio(),
299  model_().nLayers(), // nLayers
300  labelList(extrudedPatch_.size(), topPatchID),
301  labelList(extrudedPatch_.size(), bottomPatchID),
302  edgePatches,
303  meshMod
304  );
305 
306  autoPtr<mapPolyMesh> map = meshMod.changeMesh
307  (
308  *this, // mesh to change
309  false // inflate
310  );
311 
312  // Update numbering on extruder.
313  extruder.updateMesh(map());
314 
315  this->setInstance(this->thisDb().time().constant());
316  this->write();
317  }
318 }
319 
320 
321 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dictionary dict
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
Definition: List.H:489
wordList patchTypes(nPatches)
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:70
Mesh at a patch created on the fly. The following entry should be used on the field boundary dictiona...
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:441
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
dictionary()
Default construct, a top-level empty dictionary.
Definition: dictionary.C:68
List< face > faceList
List of faces.
Definition: faceListFwd.H:39
PtrList< polyPatch > polyPatchList
Store lists of polyPatch as a PtrList.
Definition: polyPatch.H:56
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
void setSize(const label n)
Alias for resize()
Definition: List.H:316
dynamicFvMesh & mesh
A class for handling words, derived from Foam::string.
Definition: word.H:63
wordList patchNames(nPatches)
Vector< scalar > vector
Definition: vector.H:57
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.
defineTypeNameAndDebug(combustionModel, 0)
labelList f(nPoints)
static autoPtr< extrudeModel > New(const dictionary &dict)
Select null constructed.
PrimitivePatch< List< face >, const pointField & > primitiveFacePatch
A PrimitivePatch with List storage for the faces, const reference for the point field.
vector point
Point is a vector.
Definition: point.H:37
Foam::word regionName(args.getOrDefault< word >("region", Foam::polyMesh::defaultRegion))
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
const std::string patch
OpenFOAM patch number as a std::string.
label n
Field< vector > vectorField
Specialisation of Field<T> for vector.
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.
Definition: polyPatchNew.C:28
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
static void mapCombineReduce(Container &values, const CombineOp &cop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) applying cop to inplace combine map values from different processo...
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
Namespace for OpenFOAM.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127