1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
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
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "mergePolyMesh.H"
29 #include "directTopoChange.H"
30 #include "mapPolyMesh.H"
31 #include "polyAddPoint.H"
32 #include "polyAddCell.H"
33 #include "polyAddFace.H"
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 defineTypeNameAndDebug(Foam::mergePolyMesh, 1);
40 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
42 Foam::label Foam::mergePolyMesh::patchIndex(const polyPatch& p)
44 // Find the patch name on the list. If the patch is already there
45 // and patch types match, return index
46 const word& pType = p.type();
47 const word& pName = p.name();
49 bool nameFound = false;
51 forAll (patchNames_, patchI)
53 if (patchNames_[patchI] == pName)
55 if (patchTypes_[patchI] == pType)
57 // Found name and types match
62 // Found the name, but type is different
68 // Patch not found. Append to the list
69 patchTypes_.append(pType);
73 // Duplicate name is not allowed. Create a composite name from the
74 // patch name and case name
75 const word& caseName = p.boundaryMesh().mesh().time().caseName();
77 patchNames_.append(pName + "_" + caseName);
79 Info<< "label patchIndex(const polyPatch& p) : "
80 << "Patch " << p.index() << " named "
81 << pName << " in mesh " << caseName
82 << " already exists, but patch types "
83 << " do not match.\nCreating a composite name as "
84 << patchNames_[patchNames_.size() - 1] << endl;
88 patchNames_.append(pName);
91 return patchNames_.size() - 1;
95 Foam::label Foam::mergePolyMesh::zoneIndex
97 DynamicList<word>& names,
101 forAll (names, zoneI)
103 if (names[zoneI] == curName)
109 // Not found. Add new name to the list
110 names.append(curName);
112 return names.size() - 1;
116 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
118 Foam::mergePolyMesh::mergePolyMesh(const IOobject& io)
122 patchTypes_(2*boundaryMesh().size()),
123 patchNames_(2*boundaryMesh().size()),
132 // Insert the original patches into the list
133 wordList curPatchTypes = boundaryMesh().types();
134 wordList curPatchNames = boundaryMesh().names();
136 forAll (curPatchTypes, patchI)
138 patchTypes_.append(curPatchTypes[patchI]);
139 patchNames_.append(curPatchNames[patchI]);
142 // Insert point, face and cell zones into the list
145 wordList curPointZoneNames = pointZones().names();
146 if (curPointZoneNames.size())
148 pointZoneNames_.setCapacity(2*curPointZoneNames.size());
151 forAll (curPointZoneNames, zoneI)
153 pointZoneNames_.append(curPointZoneNames[zoneI]);
155 const pointField& p = points();
156 const pointZoneMesh& pz = pointZones();
159 pointZones_.append(pz.whichZone(pointI));
163 wordList curFaceZoneNames = faceZones().names();
165 if (curFaceZoneNames.size())
167 faceZoneNames_.setCapacity(2*curFaceZoneNames.size());
169 forAll (curFaceZoneNames, zoneI)
171 faceZoneNames_.append(curFaceZoneNames[zoneI]);
173 const faceList& f = faces();
174 const faceZoneMesh& fz = faceZones();
177 label zoneID = fz.whichZone(faceI);
178 faceZones_.append(zoneID);
181 faceZoneFlips_.append(fz[zoneID].flipMap()[faceI]);
183 faceZoneFlips_.append(false);
186 faceZoneFlips_.shrink();
189 wordList curCellZoneNames = cellZones().names();
191 if (curCellZoneNames.size())
193 cellZoneNames_.setCapacity(2*curCellZoneNames.size());
195 forAll (curCellZoneNames, zoneI)
197 cellZoneNames_.append(curCellZoneNames[zoneI]);
199 const cellList& c = cells();
200 const cellZoneMesh& cz = cellZones();
203 cellZones_.append(cz.whichZone(cellI));
209 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
212 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
214 void Foam::mergePolyMesh::addMesh(const polyMesh& m)
216 // Add all the points, faces and cells of the new mesh
222 const pointField& p = m.points();
223 labelList renumberPoints(p.size());
225 const pointZoneMesh& pz = m.pointZones();
226 labelList pointZoneIndices(pz.size());
230 pointZoneIndices[zoneI] = zoneIndex(pointZoneNames_, pz[zoneI].name());
235 // Grab zone ID. If a point is not in a zone, it will return -1
236 zoneID = pz.whichZone(pointI);
240 // Translate zone ID into the new index
241 zoneID = pointZoneIndices[zoneID];
244 renumberPoints[pointI] =
249 p[pointI], // Point to add
250 -1, // Master point (straight addition)
251 zoneID, // Zone for point
252 pointI < m.nPoints() // Is in cell?
256 pointZones_.append(zoneID);
262 const cellList& c = m.cells();
263 labelList renumberCells(c.size());
265 const cellZoneMesh& cz = m.cellZones();
266 labelList cellZoneIndices(cz.size());
270 cellZoneIndices[zoneI] = zoneIndex(cellZoneNames_, cz[zoneI].name());
275 // Grab zone ID. If a cell is not in a zone, it will return -1
276 zoneID = cz.whichZone(cellI);
280 // Translate zone ID into the new index
281 zoneID = cellZoneIndices[zoneID];
284 renumberCells[cellI] =
293 zoneID // Zone for cell
297 cellZones_.append(zoneID);
301 const polyBoundaryMesh& bm = m.boundaryMesh();
303 // Gather the patch indices
304 labelList patchIndices(bm.size());
306 forAll (patchIndices, patchI)
308 patchIndices[patchI] = patchIndex(bm[patchI]);
311 // Temporary: update number of allowable patches. This should be
312 // determined at the top - before adding anything.
313 meshMod_.setNumPatches(patchNames_.size());
317 const faceZoneMesh& fz = m.faceZones();
318 labelList faceZoneIndices(fz.size());
322 faceZoneIndices[zoneI] = zoneIndex(faceZoneNames_, fz[zoneI].name());
325 const faceList& f = m.faces();
326 labelList renumberFaces(f.size());
328 const labelList& own = m.faceOwner();
329 const labelList& nei = m.faceNeighbour();
331 label newOwn, newNei, newPatch, newZone;
336 const face& curFace = f[faceI];
338 face newFace(curFace.size());
340 forAll (curFace, pointI)
342 newFace[pointI] = renumberPoints[curFace[pointI]];
347 // Check that the face is valid
348 if (min(newFace) < 0)
350 FatalErrorIn("void mergePolyMesh::addMesh(const polyMesh&)")
351 << "Error in point mapping for face " << faceI
352 << ". Old face: " << curFace << " New face: " << newFace
353 << abort(FatalError);
357 if (faceI < m.nInternalFaces() || faceI >= m.nFaces())
363 newPatch = patchIndices[bm.whichPatch(faceI)];
367 if (newOwn > -1) newOwn = renumberCells[newOwn];
376 newNei = renumberCells[newNei];
380 newZone = fz.whichZone(faceI);
385 newZoneFlip = fz[newZone].flipMap()[fz[newZone].whichFace(faceI)];
388 newZone = faceZoneIndices[newZone];
391 renumberFaces[faceI] =
408 faceZones_.append(newZone);
409 faceZoneFlips_.append(newZoneFlip);
413 faceZoneFlips_.shrink();
417 void Foam::mergePolyMesh::merge()
419 Info<< "patch names: " << patchNames_ << nl
420 << "patch types: " << patchTypes_ << nl
421 << "point zone names: " << pointZoneNames_ << nl
422 << "face zone names: " << faceZoneNames_ << nl
423 << "cell zone names: " << cellZoneNames_ << endl;
425 // Add the patches if necessary
426 if (patchNames_.size() != boundaryMesh().size())
428 Info << "Copying old patches" << endl;
430 List<polyPatch*> newPatches(patchNames_.size());
432 const polyBoundaryMesh& oldPatches = boundaryMesh();
434 // Note. Re-using counter in two for loops
437 for (patchI = 0; patchI < oldPatches.size(); patchI++)
439 newPatches[patchI] = oldPatches[patchI].clone(oldPatches).ptr();
442 Info << "Adding new patches. " << endl;
444 label endOfLastPatch =
445 oldPatches[patchI - 1].start() + oldPatches[patchI - 1].size();
447 for (; patchI < patchNames_.size(); patchI++)
465 addPatches(newPatches);
468 // Add the zones if necessary
471 pointZoneNames_.size() != pointZones().size()
472 || faceZoneNames_.size() != faceZones().size()
473 || cellZoneNames_.size() != cellZones().size()
477 List<pointZone*> pZones(pointZoneNames_.size());
478 List<faceZone*> fZones(faceZoneNames_.size());
479 List<cellZone*> cZones(cellZoneNames_.size());
481 if(pointZoneNames_.size() > 0)
483 Info << "Updating point zones" << endl;
485 List<DynamicList<label> > pzPoints(pointZoneNames_.size());
486 forAll(pointZones_, pointI)
488 label zoneID = pointZones_[pointI];
491 pzPoints[zoneID].append(pointI);
496 pZones[i] = new pointZone
506 if(faceZoneNames_.size() > 0)
508 Info << "Updating face zones" << endl;
510 List<DynamicList<label> > fzFaces(faceZoneNames_.size());
511 List<DynamicList<bool> > fzFlips(faceZoneNames_.size());
513 forAll(faceZones_, faceI)
515 label zoneID = faceZones_[faceI];
519 fzFaces[zoneID].append(faceI);
520 fzFlips[zoneID].append(faceZoneFlips_[faceI]);
529 fZones[i] = new faceZone
540 if(cellZoneNames_.size() > 0)
542 Info << "Updating cell zones" << endl;
544 List<DynamicList<label> > czCells(cellZoneNames_.size());
545 forAll(cellZones_, cellI)
547 label zoneID = cellZones_[cellI];
550 czCells[zoneID].append(cellI);
557 cZones[i] = new cellZone
568 addZones(pZones, fZones, cZones);
572 // Change mesh. No inflation
573 meshMod_.changeMesh(*this, false);
575 // Clear topo change for the next operation
580 // ************************************************************************* //