extrude2DMesh.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "extrude2DMesh.H"
27 #include "polyMesh.H"
28 #include "polyTopoChange.H"
29 
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 
32 namespace Foam
33 {
34  defineTypeNameAndDebug(extrude2DMesh, 0);
35 }
36 
37 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 
39 void Foam::extrude2DMesh::check2D() const
40 {
41  const faceList& faces = mesh_.faces();
42  forAll(faces, facei)
43  {
44  if (faces[facei].size() != 2)
45  {
47  << "Face " << facei << " size " << faces[facei].size()
48  << " is not of size 2: mesh is not a valid two-dimensional "
49  << "mesh" << exit(FatalError);
50  }
51  }
52 }
53 
54 
55 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
56 
58 (
59  polyMesh& mesh,
60  const dictionary& dict,
61  const extrudeModel& model
62 )
63 :
64  mesh_(mesh),
65  dict_(dict),
66  model_(model),
67  modelType_(dict.lookup("extrudeModel")),
68  patchType_(dict.lookup("patchType")),
69  frontPatchi_(-1),
70  backPatchi_(-1),
71  cellZonesAddedCells_(mesh.cellZones().size())
72 {
73  check2D();
74 }
75 
76 
77 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
78 
80 {}
81 
82 
83 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
84 
86 {
87  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
88 
89  frontPatchi_ = patches.findIndex("front");
90  backPatchi_ = patches.findIndex("back");
91 
92  // Add patch.
93  List<polyPatch*> newPatches(patches.size() + 2);
94 
96  {
97  const polyPatch& pp = patches[patchi];
98 
99  newPatches[patchi] =
100  pp.clone
101  (
102  patches,
103  newPatches.size(),
104  pp.size(),
105  pp.start()
106  ).ptr();
107  }
108 
109  if (frontPatchi_ == -1)
110  {
111  frontPatchi_ = patches.size();
112 
113  newPatches[frontPatchi_] =
115  (
116  patchType_,
117  "front",
118  0,
119  mesh_.nFaces(),
120  frontPatchi_,
121  patches
122  ).ptr();
123 
124  Info<< "Adding patch " << newPatches[frontPatchi_]->name()
125  << " at index " << frontPatchi_
126  << " for front faces." << nl << endl;
127  }
128 
129  if (backPatchi_ == -1)
130  {
131  backPatchi_ = patches.size() + 1;
132 
133  newPatches[backPatchi_] =
135  (
136  patchType_,
137  "back",
138  0,
139  mesh_.nFaces(),
140  backPatchi_,
141  patches
142  ).ptr();
143 
144  Info<< "Adding patch " << newPatches[backPatchi_]->name()
145  << " at index " << backPatchi_
146  << " for back faces." << nl << endl;
147  }
148 
149  mesh_.removeBoundary();
150  mesh_.addPatches(newPatches);
151 }
152 
153 
155 (
156  polyTopoChange& meshMod
157 )
158 {
159  const label nLayers = model_.nLayers();
160  const pointField& points = mesh_.points();
161  label nFaces = 0;
162 
163  for (label layer = 0; layer < nLayers; ++layer)
164  {
165  const label offset = layer*mesh_.nCells();
166 
167  forAll(mesh_.cells(), celli)
168  {
169  const label newCelli = meshMod.addCell
170  (
171  celli + offset // masterCellID
172  );
173 
174  const labelList zones(mesh_.cellZones().whichZones(celli));
175  forAll(zones, zonei)
176  {
177  cellZonesAddedCells_[zonei].insert(newCelli);
178  }
179  }
180  }
181 
182 
183  // Generate points
184  // ~~~~~~~~~~~~~~~
185 
186  for (label layer = 0; layer <= nLayers; ++layer)
187  {
188  label offset = layer * points.size();
189 
190  forAll(points, pointi)
191  {
192  // Don't need the surface normal for either linearDirection or
193  // wedge. Will need to add to be able to use others.
194  point newPoint = model_
195  (
196  points[pointi],
197  vector(),
198  layer
199  );
200 
201  meshMod.addPoint
202  (
203  newPoint,
204  pointi + offset,
205  true // inCell
206  );
207  }
208 
209  Pout<< "Added " << points.size() << " points to layer "
210  << layer << endl;
211  }
212 
213 
214  // Generate faces
215  // ~~~~~~~~~~~~~~
216 
217  const faceList& faces = mesh_.faces();
218  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
219 
220  for (label layer = 0; layer < nLayers; ++layer)
221  {
222  label currentLayerOffset = layer * mesh_.nPoints();
223  label nextLayerOffset = currentLayerOffset + mesh_.nPoints();
224 
225  for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
226  {
227  face newFace(4);
228  const face& f = faces[facei];
229  newFace[0] = f[0] + currentLayerOffset;
230  newFace[1] = f[1] + currentLayerOffset;
231  newFace[2] = f[1] + nextLayerOffset;
232  newFace[3] = f[0] + nextLayerOffset;
233 
234  label offset = layer * mesh_.nCells();
235 
236  meshMod.addFace
237  (
238  newFace,
239  mesh_.faceOwner()[facei] + offset, // own
240  mesh_.faceNeighbour()[facei] + offset, // nei
241  nFaces++, // masterFaceID
242  false, // flipFaceFlux
243  -1 // patchID
244  );
245 
246  if (debug)
247  {
248  Info<< newFace << " "
249  << mesh_.faceOwner()[facei] + offset << " "
250  << mesh_.faceNeighbour()[facei] + offset << " "
251  << nFaces - 1
252  << endl;
253  }
254  }
255  }
256 
258  {
259  for (label layer=0; layer < nLayers; layer++)
260  {
261  label currentLayerOffset = layer*mesh_.nPoints();
262  label nextLayerOffset = currentLayerOffset + mesh_.nPoints();
263 
264  label startFacei = patches[patchi].start();
265  label endFacei = startFacei + patches[patchi].size();
266 
267  for (label facei = startFacei; facei < endFacei; facei++)
268  {
269  face newFace(4);
270  const face& f = faces[facei];
271  newFace[0] = f[0] + currentLayerOffset;
272  newFace[1] = f[1] + currentLayerOffset;
273  newFace[2] = f[1] + nextLayerOffset;
274  newFace[3] = f[0] + nextLayerOffset;
275 
276  label offset = layer * mesh_.nCells();
277 
278  meshMod.addFace
279  (
280  newFace,
281  mesh_.faceOwner()[facei] + offset, // own
282  -1, // nei
283  nFaces++, // masterFaceID
284  false, // flipFaceFlux
285  patchi // patchID
286  );
287 
288  if (debug)
289  {
290  Info<< newFace << " "
291  << mesh_.faceOwner()[facei] + offset << " "
292  << nFaces - 1
293  << endl;
294  }
295  }
296  }
297  }
298 
299  // Add extra internal faces that need special treatment for owners and
300  // neighbours.
301  forAll(mesh_.cells(), celli)
302  {
303  const cell& cFaces = mesh_.cells()[celli];
304 
305  face frontFace(cFaces.size());
306 
307  // Make a loop out of faces.
308  label nextFacei = cFaces[0];
309 
310  const face& f = faces[nextFacei];
311 
312  label nextPointi;
313  if (mesh_.faceOwner()[nextFacei] == celli)
314  {
315  frontFace[0] = f[0];
316  nextPointi = f[1];
317  }
318  else
319  {
320  frontFace[0] = f[1];
321  nextPointi = f[0];
322  }
323 
324 
325  for (label i = 1; i < frontFace.size(); i++)
326  {
327  frontFace[i] = nextPointi;
328 
329  // Find face containing pointi
330  forAll(cFaces, cFacei)
331  {
332  label facei = cFaces[cFacei];
333  if (facei != nextFacei)
334  {
335  const face& f = faces[facei];
336 
337  if (f[0] == nextPointi)
338  {
339  nextPointi = f[1];
340  nextFacei = facei;
341  break;
342  }
343  else if (f[1] == nextPointi)
344  {
345  nextPointi = f[0];
346  nextFacei = facei;
347  break;
348  }
349  }
350  }
351  }
352 
353  for (label layer = 0; layer < nLayers - 1; ++layer)
354  {
355  // Offset to create front face.
356  forAll(frontFace, fp)
357  {
358  frontFace[fp] += mesh_.nPoints();
359  }
360 
361  label offset = layer * mesh_.nCells();
362 
363  label nei = -1;
364  if (layer != nLayers - 1)
365  {
366  nei = celli + offset + mesh_.nCells();
367  }
368 
369  meshMod.addFace
370  (
371  frontFace,
372  celli + offset, // own
373  nei, // nei
374  nFaces++, // masterFaceID
375  false, // flipFaceFlux
376  -1 // patchID
377  );
378 
379  if (debug)
380  {
381  Info<< frontFace << " "
382  << celli + offset << " "
383  << nei << " "
384  << nFaces - 1
385  << endl;
386  }
387  }
388  }
389 
390  // Generate front and back faces
391  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
392 
393  forAll(mesh_.cells(), celli)
394  {
395  const cell& cFaces = mesh_.cells()[celli];
396 
397  face frontFace(cFaces.size());
398 
399  // Make a loop out of faces.
400  label nextFacei = cFaces[0];
401 
402  const face& f = faces[nextFacei];
403 
404  label nextPointi;
405  if (mesh_.faceOwner()[nextFacei] == celli)
406  {
407  frontFace[0] = f[0];
408  nextPointi = f[1];
409  }
410  else
411  {
412  frontFace[0] = f[1];
413  nextPointi = f[0];
414  }
415 
416 
417  for (label i = 1; i < frontFace.size(); i++)
418  {
419  frontFace[i] = nextPointi;
420 
421  // Find face containing pointi
422  forAll(cFaces, cFacei)
423  {
424  label facei = cFaces[cFacei];
425  if (facei != nextFacei)
426  {
427  const face& f = faces[facei];
428 
429  if (f[0] == nextPointi)
430  {
431  nextPointi = f[1];
432  nextFacei = facei;
433  break;
434  }
435  else if (f[1] == nextPointi)
436  {
437  nextPointi = f[0];
438  nextFacei = facei;
439  break;
440  }
441  }
442  }
443  }
444 
445  // Add back face.
446  meshMod.addFace
447  (
448  frontFace.reverseFace(),
449  celli, // own
450  -1, // nei
451  nFaces++, // masterFaceID
452  false, // flipFaceFlux
453  backPatchi_ // patchID
454  );
455 
456  if (debug)
457  {
458  Info<< nl<<frontFace.reverseFace() << " "
459  << celli << " "
460  << nFaces - 1
461  << endl;
462  }
463 
464  // Offset to create front face.
465  forAll(frontFace, fp)
466  {
467  frontFace[fp] += mesh_.nPoints()* (nLayers);
468  }
469 
470  label offset = (nLayers - 1) * mesh_.nCells();
471 
472  meshMod.addFace
473  (
474  frontFace,
475  celli + offset, // own
476  -1, // nei
477  nFaces++, // masterFaceID
478  false, // flipFaceFlux
479  frontPatchi_ // patchID
480  );
481 
482  if (debug)
483  {
484  Info<< frontFace << " "
485  << celli + offset << " "
486  << nFaces - 1
487  << endl;
488  }
489  }
490 }
491 
492 
494 {
495  // Add the cellZones to the merged mesh
496  mesh_.cellZones().insert(cellZonesAddedCells_);
497 }
498 
499 
500 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
extrude2DMesh(polyMesh &, const dictionary &dict, const extrudeModel &model)
void updateZones()
Update the mesh zones.
~extrude2DMesh()
Destructor.
void setRefinement(polyTopoChange &)
Play commands into polyTopoChange to extrude mesh.
void addFrontBackPatches()
Add front and back patches.
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1326
static autoPtr< polyPatch > New(const word &patchType, const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm)
Return a pointer to a new patch created on freestore from.
Definition: polyPatchNew.C:32
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
label patchi
const pointField & points
const fvPatchList & patches
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:257
messageStream Info
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
vector point
Point is a vector.
Definition: point.H:41
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
defineTypeNameAndDebug(combustionModel, 0)
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
error FatalError
void offset(label &lst, const label o)
List< face > faceList
Definition: faceListFwd.H:41
static const char nl
Definition: Ostream.H:266
labelList f(nPoints)
dictionary dict