mergePolyMesh.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 | Copyright (C) 2011-2015 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 "mergePolyMesh.H"
27 #include "Time.H"
28 #include "polyTopoChanger.H"
29 #include "mapPolyMesh.H"
30 #include "polyAddPoint.H"
31 #include "polyAddCell.H"
32 #include "polyAddFace.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 defineTypeNameAndDebug(mergePolyMesh, 1);
39 }
40 
41 
42 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 
45 {
46  // Find the patch name on the list. If the patch is already there
47  // and patch types match, return index
48  const word& pType = p.type();
49  const word& pName = p.name();
50 
51  bool nameFound = false;
52 
53  forAll(patchNames_, patchI)
54  {
55  if (patchNames_[patchI] == pName)
56  {
57  if (word(patchDicts_[patchI]["type"]) == pType)
58  {
59  // Found name and types match
60  return patchI;
61  }
62  else
63  {
64  // Found the name, but type is different
65  nameFound = true;
66  }
67  }
68  }
69 
70  // Patch not found. Append to the list
71  {
72  OStringStream os;
73  p.write(os);
74  patchDicts_.append(dictionary(IStringStream(os.str())()));
75  }
76 
77  if (nameFound)
78  {
79  // Duplicate name is not allowed. Create a composite name from the
80  // patch name and case name
81  const word& caseName = p.boundaryMesh().mesh().time().caseName();
82 
83  patchNames_.append(pName + "_" + caseName);
84 
85  Info<< "label patchIndex(const polyPatch& p) : "
86  << "Patch " << p.index() << " named "
87  << pName << " in mesh " << caseName
88  << " already exists, but patch types "
89  << " do not match.\nCreating a composite name as "
90  << patchNames_.last() << endl;
91  }
92  else
93  {
94  patchNames_.append(pName);
95  }
96 
97  return patchNames_.size() - 1;
98 }
99 
100 
102 (
103  DynamicList<word>& names,
104  const word& curName
105 )
106 {
107  forAll(names, zoneI)
108  {
109  if (names[zoneI] == curName)
110  {
111  return zoneI;
112  }
113  }
114 
115  // Not found. Add new name to the list
116  names.append(curName);
117 
118  return names.size() - 1;
119 }
120 
121 
122 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
123 
124 Foam::mergePolyMesh::mergePolyMesh(const IOobject& io)
125 :
126  polyMesh(io),
127  meshMod_(*this),
128  patchNames_(2*boundaryMesh().size()),
129  patchDicts_(2*boundaryMesh().size()),
130  pointZoneNames_(),
131  faceZoneNames_(),
132  cellZoneNames_()
133 {
134  // Insert the original patches into the list
135  wordList curPatchNames = boundaryMesh().names();
136 
137  forAll(boundaryMesh(), patchI)
138  {
139  patchNames_.append(boundaryMesh()[patchI].name());
140 
141  OStringStream os;
142  boundaryMesh()[patchI].write(os);
143  patchDicts_.append(dictionary(IStringStream(os.str())()));
144  }
145 
146  // Insert point, face and cell zones into the list
147 
148  // Point zones
149  wordList curPointZoneNames = pointZones().names();
150  if (curPointZoneNames.size())
151  {
152  pointZoneNames_.setCapacity(2*curPointZoneNames.size());
153  }
154 
155  forAll(curPointZoneNames, zoneI)
156  {
157  pointZoneNames_.append(curPointZoneNames[zoneI]);
158  }
159 
160  // Face zones
161  wordList curFaceZoneNames = faceZones().names();
162 
163  if (curFaceZoneNames.size())
164  {
165  faceZoneNames_.setCapacity(2*curFaceZoneNames.size());
166  }
167  forAll(curFaceZoneNames, zoneI)
168  {
169  faceZoneNames_.append(curFaceZoneNames[zoneI]);
170  }
171 
172  // Cell zones
173  wordList curCellZoneNames = cellZones().names();
174 
175  if (curCellZoneNames.size())
176  {
177  cellZoneNames_.setCapacity(2*curCellZoneNames.size());
178  }
179  forAll(curCellZoneNames, zoneI)
180  {
181  cellZoneNames_.append(curCellZoneNames[zoneI]);
182  }
183 }
184 
185 
186 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
187 
188 
189 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
190 
191 void Foam::mergePolyMesh::addMesh(const polyMesh& m)
192 {
193  // Add all the points, faces and cells of the new mesh
194 
195  // Add points
196 
197  label zoneID = -1;
198 
199  const pointField& p = m.points();
200  labelList renumberPoints(p.size());
201 
202  const pointZoneMesh& pz = m.pointZones();
203  labelList pointZoneIndices(pz.size());
204 
205  forAll(pz, zoneI)
206  {
207  pointZoneIndices[zoneI] = zoneIndex(pointZoneNames_, pz[zoneI].name());
208  }
209 
210  forAll(p, pointI)
211  {
212  // Grab zone ID. If a point is not in a zone, it will return -1
213  zoneID = pz.whichZone(pointI);
214 
215  if (zoneID >= 0)
216  {
217  // Translate zone ID into the new index
218  zoneID = pointZoneIndices[zoneID];
219  }
220 
221  renumberPoints[pointI] =
223  (
224  polyAddPoint
225  (
226  p[pointI], // Point to add
227  -1, // Master point (straight addition)
228  zoneID, // Zone for point
229  pointI < m.nPoints() // Is in cell?
230  )
231  );
232  }
233 
234  // Add cells
235 
236  const cellList& c = m.cells();
237  labelList renumberCells(c.size());
238 
239  const cellZoneMesh& cz = m.cellZones();
240  labelList cellZoneIndices(cz.size());
241 
242  forAll(cz, zoneI)
243  {
244  cellZoneIndices[zoneI] = zoneIndex(cellZoneNames_, cz[zoneI].name());
245  }
246 
247  forAll(c, cellI)
248  {
249  // Grab zone ID. If a cell is not in a zone, it will return -1
250  zoneID = cz.whichZone(cellI);
251 
252  if (zoneID >= 0)
253  {
254  // Translate zone ID into the new index
255  zoneID = cellZoneIndices[zoneID];
256  }
257 
258  renumberCells[cellI] =
260  (
261  polyAddCell
262  (
263  -1, // Master point
264  -1, // Master edge
265  -1, // Master face
266  -1, // Master cell
267  zoneID // Zone for cell
268  )
269  );
270  }
271 
272  // Add faces
273  const polyBoundaryMesh& bm = m.boundaryMesh();
274 
275  // Gather the patch indices
276  labelList patchIndices(bm.size());
277 
278  forAll(patchIndices, patchI)
279  {
280  patchIndices[patchI] = patchIndex(bm[patchI]);
281  }
282 
283  // Temporary: update number of allowable patches. This should be
284  // determined at the top - before adding anything.
286 
287 
288 
289  const faceZoneMesh& fz = m.faceZones();
290  labelList faceZoneIndices(fz.size());
291 
292  forAll(fz, zoneI)
293  {
294  faceZoneIndices[zoneI] = zoneIndex(faceZoneNames_, fz[zoneI].name());
295  }
296 
297  const faceList& f = m.faces();
298  labelList renumberFaces(f.size());
299 
300  const labelList& own = m.faceOwner();
301  const labelList& nei = m.faceNeighbour();
302 
303  label newOwn, newNei, newPatch, newZone;
304  bool newZoneFlip;
305 
306  forAll(f, faceI)
307  {
308  const face& curFace = f[faceI];
309 
310  face newFace(curFace.size());
311 
312  forAll(curFace, pointI)
313  {
314  newFace[pointI] = renumberPoints[curFace[pointI]];
315  }
316 
317  if (debug)
318  {
319  // Check that the face is valid
320  if (min(newFace) < 0)
321  {
323  << "Error in point mapping for face " << faceI
324  << ". Old face: " << curFace << " New face: " << newFace
325  << abort(FatalError);
326  }
327  }
328 
329  if (faceI < m.nInternalFaces() || faceI >= m.nFaces())
330  {
331  newPatch = -1;
332  }
333  else
334  {
335  newPatch = patchIndices[bm.whichPatch(faceI)];
336  }
337 
338  newOwn = own[faceI];
339  if (newOwn > -1) newOwn = renumberCells[newOwn];
340 
341  if (newPatch > -1)
342  {
343  newNei = -1;
344  }
345  else
346  {
347  newNei = nei[faceI];
348  newNei = renumberCells[newNei];
349  }
350 
351 
352  newZone = fz.whichZone(faceI);
353  newZoneFlip = false;
354 
355  if (newZone >= 0)
356  {
357  newZoneFlip = fz[newZone].flipMap()[fz[newZone].whichFace(faceI)];
358 
359  // Grab the new zone
360  newZone = faceZoneIndices[newZone];
361  }
362 
363  renumberFaces[faceI] =
365  (
366  polyAddFace
367  (
368  newFace,
369  newOwn,
370  newNei,
371  -1,
372  -1,
373  -1,
374  false,
375  newPatch,
376  newZone,
377  newZoneFlip
378  )
379  );
380  }
381 
382 }
383 
384 
386 {
387  Info<< "patch names: " << patchNames_ << nl
388  << "patch dicts: " << patchDicts_ << nl
389  << "point zone names: " << pointZoneNames_ << nl
390  << "face zone names: " << faceZoneNames_ << nl
391  << "cell zone names: " << cellZoneNames_ << endl;
392 
393  // Add the patches if necessary
394  if (patchNames_.size() != boundaryMesh().size())
395  {
396  Info<< "Copying old patches" << endl;
397 
398  List<polyPatch*> newPatches(patchNames_.size());
399 
400  const polyBoundaryMesh& oldPatches = boundaryMesh();
401 
402  // Note. Re-using counter in two for loops
403  label patchI = 0;
404 
405  for (patchI = 0; patchI < oldPatches.size(); patchI++)
406  {
407  newPatches[patchI] = oldPatches[patchI].clone(oldPatches).ptr();
408  }
409 
410  Info<< "Adding new patches. " << endl;
411 
412  label endOfLastPatch =
413  oldPatches[patchI - 1].start() + oldPatches[patchI - 1].size();
414 
415  for (; patchI < patchNames_.size(); patchI++)
416  {
417  // Add a patch
418  dictionary dict(patchDicts_[patchI]);
419  dict.set("nFaces", 0);
420  dict.set("startFace", endOfLastPatch);
421 
422  newPatches[patchI] =
423  (
425  (
426  patchNames_[patchI],
427  dict,
428  patchI,
429  oldPatches
430  ).ptr()
431  );
432  }
433 
434  removeBoundary();
435  addPatches(newPatches);
436  }
437 
438  // Add the zones if necessary
439  if (pointZoneNames_.size() > pointZones().size())
440  {
441  Info<< "Adding new pointZones. " << endl;
442  label nZones = pointZones().size();
443 
444  pointZones().setSize(pointZoneNames_.size());
445 
446  for (label zoneI = nZones; zoneI < pointZoneNames_.size(); zoneI++)
447  {
448  pointZones().set
449  (
450  zoneI,
451  new pointZone
452  (
453  pointZoneNames_[zoneI],
454  labelList(),
455  zoneI,
456  pointZones()
457  )
458  );
459  }
460  }
461  if (cellZoneNames_.size() > cellZones().size())
462  {
463  Info<< "Adding new cellZones. " << endl;
464 
465  label nZones = cellZones().size();
466 
467  cellZones().setSize(cellZoneNames_.size());
468 
469  for (label zoneI = nZones; zoneI < cellZoneNames_.size(); zoneI++)
470  {
471  cellZones().set
472  (
473  zoneI,
474  new cellZone
475  (
476  cellZoneNames_[zoneI],
477  labelList(),
478  zoneI,
479  cellZones()
480  )
481  );
482  }
483  }
484  if (faceZoneNames_.size() > faceZones().size())
485  {
486  Info<< "Adding new faceZones. " << endl;
487 
488  label nZones = faceZones().size();
489 
490  faceZones().setSize(faceZoneNames_.size());
491 
492  for (label zoneI = nZones; zoneI < faceZoneNames_.size(); zoneI++)
493  {
494  faceZones().set
495  (
496  zoneI,
497  new faceZone
498  (
499  faceZoneNames_[zoneI],
500  labelList(),
501  boolList(),
502  zoneI,
503  faceZones()
504  )
505  );
506  }
507  }
508 
509  // Change mesh. No inflation
510  meshMod_.changeMesh(*this, false);
511 
512  // Clear topo change for the next operation
513  meshMod_.clear();
514 }
515 
516 
517 // ************************************************************************* //
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
Foam::mergePolyMesh::patchDicts_
DynamicList< dictionary > patchDicts_
Patch dictionaries.
Definition: mergePolyMesh.H:64
Foam::mergePolyMesh::mergePolyMesh
mergePolyMesh(const mergePolyMesh &)
Disallow default bitwise copy construct.
p
p
Definition: pEqn.H:62
Foam::labelList
List< label > labelList
A List of labels.
Definition: labelList.H:56
mergePolyMesh.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::mergePolyMesh::meshMod_
polyTopoChange meshMod_
Topological change to accumulated all mesh changes.
Definition: mergePolyMesh.H:58
polyAddFace.H
mapPolyMesh.H
polyTopoChanger.H
Foam::mergePolyMesh::addMesh
void addMesh(const polyMesh &m)
Add a mesh.
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::cellZoneMesh
ZoneMesh< cellZone, polyMesh > cellZoneMesh
A ZoneMesh with the type cellZone.
Definition: cellZoneMeshFwd.H:41
Foam::pointZoneMesh
ZoneMesh< pointZone, polyMesh > pointZoneMesh
A ZoneMesh with the type pointZone.
Definition: pointZoneMeshFwd.H:41
Foam::mergePolyMesh::patchIndex
label patchIndex(const polyPatch &)
Return patch index given a name and type.
Foam::wordList
List< word > wordList
A List of words.
Definition: fileName.H:54
Foam::faceZoneMesh
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with the type faceZone.
Definition: faceZoneMeshFwd.H:41
Foam::label
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
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
Foam::IOobject::caseName
const fileName & caseName() const
Definition: IOobject.C:251
Foam::cellList
List< cell > cellList
list of cells
Definition: cellList.H:42
Foam::mergePolyMesh::faceZoneNames_
DynamicList< word > faceZoneNames_
Face zone names.
Definition: mergePolyMesh.H:70
Foam::IOobject::name
const word & name() const
Return name.
Definition: IOobject.H:273
polyAddPoint.H
Foam::mergePolyMesh::merge
void merge()
Merge meshes.
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::polyPatch::New
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
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::boolList
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
Foam::DynamicList::append
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
polyAddCell.H
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::polyTopoChange::setAction
label setAction(const topoAction &action)
For compatibility with polyTopoChange: set topological action.
Definition: polyTopoChange.C:2530
Foam::mergePolyMesh::cellZoneNames_
DynamicList< word > cellZoneNames_
Cell zone names.
Definition: mergePolyMesh.H:73
f
labelList f(nPoints)
Foam::faceList
List< face > faceList
Definition: faceListFwd.H:43
Foam::polyTopoChange::setNumPatches
void setNumPatches(const label nPatches)
Explicitly set the number of patches if construct-without-mesh.
Definition: polyTopoChangeI.H:53
Foam::mergePolyMesh::zoneIndex
label zoneIndex(DynamicList< word > &, const word &)
Return zone index given a list of active zones and a name.
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
List
Definition: Test.C:19
Foam::mergePolyMesh::patchNames_
DynamicList< word > patchNames_
Patch names.
Definition: mergePolyMesh.H:61
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::min
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::name
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
Foam::mergePolyMesh::pointZoneNames_
DynamicList< word > pointZoneNames_
Point zone names.
Definition: mergePolyMesh.H:67
Foam::dictionary::set
void set(entry *)
Assign a new entry, overwrite any existing entry.
Definition: dictionary.C:856