1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "mergePolyMesh.H"
28 #include "polyTopoChanger.H"
29 #include "mapPolyMesh.H"
30 #include "polyAddPoint.H"
31 #include "polyAddCell.H"
32 #include "polyAddFace.H"
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 defineTypeNameAndDebug(Foam::mergePolyMesh, 1);
39 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
41 Foam::label Foam::mergePolyMesh::patchIndex(const polyPatch& p)
43 // Find the patch name on the list. If the patch is already there
44 // and patch types match, return index
45 const word& pType = p.type();
46 const word& pName = p.name();
48 bool nameFound = false;
50 forAll(patchNames_, patchI)
52 if (patchNames_[patchI] == pName)
54 if (patchTypes_[patchI] == pType)
56 // Found name and types match
61 // Found the name, but type is different
67 // Patch not found. Append to the list
68 patchTypes_.append(pType);
72 // Duplicate name is not allowed. Create a composite name from the
73 // patch name and case name
74 const word& caseName = p.boundaryMesh().mesh().time().caseName();
76 patchNames_.append(pName + "_" + caseName);
78 Info<< "label patchIndex(const polyPatch& p) : "
79 << "Patch " << p.index() << " named "
80 << pName << " in mesh " << caseName
81 << " already exists, but patch types "
82 << " do not match.\nCreating a composite name as "
83 << patchNames_.last() << endl;
87 patchNames_.append(pName);
90 return patchNames_.size() - 1;
94 Foam::label Foam::mergePolyMesh::zoneIndex
96 DynamicList<word>& names,
102 if (names[zoneI] == curName)
108 // Not found. Add new name to the list
109 names.append(curName);
111 return names.size() - 1;
115 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
117 Foam::mergePolyMesh::mergePolyMesh(const IOobject& io)
121 patchTypes_(2*boundaryMesh().size()),
122 patchNames_(2*boundaryMesh().size()),
127 // Insert the original patches into the list
128 wordList curPatchTypes = boundaryMesh().types();
129 wordList curPatchNames = boundaryMesh().names();
131 forAll(curPatchTypes, patchI)
133 patchTypes_.append(curPatchTypes[patchI]);
134 patchNames_.append(curPatchNames[patchI]);
137 // Insert point, face and cell zones into the list
140 wordList curPointZoneNames = pointZones().names();
141 if (curPointZoneNames.size())
143 pointZoneNames_.setCapacity(2*curPointZoneNames.size());
146 forAll(curPointZoneNames, zoneI)
148 pointZoneNames_.append(curPointZoneNames[zoneI]);
152 wordList curFaceZoneNames = faceZones().names();
154 if (curFaceZoneNames.size())
156 faceZoneNames_.setCapacity(2*curFaceZoneNames.size());
158 forAll(curFaceZoneNames, zoneI)
160 faceZoneNames_.append(curFaceZoneNames[zoneI]);
164 wordList curCellZoneNames = cellZones().names();
166 if (curCellZoneNames.size())
168 cellZoneNames_.setCapacity(2*curCellZoneNames.size());
170 forAll(curCellZoneNames, zoneI)
172 cellZoneNames_.append(curCellZoneNames[zoneI]);
177 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
180 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
182 void Foam::mergePolyMesh::addMesh(const polyMesh& m)
184 // Add all the points, faces and cells of the new mesh
190 const pointField& p = m.points();
191 labelList renumberPoints(p.size());
193 const pointZoneMesh& pz = m.pointZones();
194 labelList pointZoneIndices(pz.size());
198 pointZoneIndices[zoneI] = zoneIndex(pointZoneNames_, pz[zoneI].name());
203 // Grab zone ID. If a point is not in a zone, it will return -1
204 zoneID = pz.whichZone(pointI);
208 // Translate zone ID into the new index
209 zoneID = pointZoneIndices[zoneID];
212 renumberPoints[pointI] =
217 p[pointI], // Point to add
218 -1, // Master point (straight addition)
219 zoneID, // Zone for point
220 pointI < m.nPoints() // Is in cell?
227 const cellList& c = m.cells();
228 labelList renumberCells(c.size());
230 const cellZoneMesh& cz = m.cellZones();
231 labelList cellZoneIndices(cz.size());
235 cellZoneIndices[zoneI] = zoneIndex(cellZoneNames_, cz[zoneI].name());
240 // Grab zone ID. If a cell is not in a zone, it will return -1
241 zoneID = cz.whichZone(cellI);
245 // Translate zone ID into the new index
246 zoneID = cellZoneIndices[zoneID];
249 renumberCells[cellI] =
258 zoneID // Zone for cell
264 const polyBoundaryMesh& bm = m.boundaryMesh();
266 // Gather the patch indices
267 labelList patchIndices(bm.size());
269 forAll(patchIndices, patchI)
271 patchIndices[patchI] = patchIndex(bm[patchI]);
274 // Temporary: update number of allowable patches. This should be
275 // determined at the top - before adding anything.
276 meshMod_.setNumPatches(patchNames_.size());
280 const faceZoneMesh& fz = m.faceZones();
281 labelList faceZoneIndices(fz.size());
285 faceZoneIndices[zoneI] = zoneIndex(faceZoneNames_, fz[zoneI].name());
288 const faceList& f = m.faces();
289 labelList renumberFaces(f.size());
291 const labelList& own = m.faceOwner();
292 const labelList& nei = m.faceNeighbour();
294 label newOwn, newNei, newPatch, newZone;
299 const face& curFace = f[faceI];
301 face newFace(curFace.size());
303 forAll(curFace, pointI)
305 newFace[pointI] = renumberPoints[curFace[pointI]];
310 // Check that the face is valid
311 if (min(newFace) < 0)
313 FatalErrorIn("void mergePolyMesh::addMesh(const polyMesh&)")
314 << "Error in point mapping for face " << faceI
315 << ". Old face: " << curFace << " New face: " << newFace
316 << abort(FatalError);
320 if (faceI < m.nInternalFaces() || faceI >= m.nFaces())
326 newPatch = patchIndices[bm.whichPatch(faceI)];
330 if (newOwn > -1) newOwn = renumberCells[newOwn];
339 newNei = renumberCells[newNei];
343 newZone = fz.whichZone(faceI);
348 newZoneFlip = fz[newZone].flipMap()[fz[newZone].whichFace(faceI)];
351 newZone = faceZoneIndices[newZone];
354 renumberFaces[faceI] =
376 void Foam::mergePolyMesh::merge()
378 Info<< "patch names: " << patchNames_ << nl
379 << "patch types: " << patchTypes_ << nl
380 << "point zone names: " << pointZoneNames_ << nl
381 << "face zone names: " << faceZoneNames_ << nl
382 << "cell zone names: " << cellZoneNames_ << endl;
384 // Add the patches if necessary
385 if (patchNames_.size() != boundaryMesh().size())
387 Info<< "Copying old patches" << endl;
389 List<polyPatch*> newPatches(patchNames_.size());
391 const polyBoundaryMesh& oldPatches = boundaryMesh();
393 // Note. Re-using counter in two for loops
396 for (patchI = 0; patchI < oldPatches.size(); patchI++)
398 newPatches[patchI] = oldPatches[patchI].clone(oldPatches).ptr();
401 Info<< "Adding new patches. " << endl;
403 label endOfLastPatch =
404 oldPatches[patchI - 1].start() + oldPatches[patchI - 1].size();
406 for (; patchI < patchNames_.size(); patchI++)
424 addPatches(newPatches);
427 // Add the zones if necessary
430 pointZoneNames_.size() != pointZones().size()
431 || faceZoneNames_.size() != faceZones().size()
432 || cellZoneNames_.size() != cellZones().size()
438 // Change mesh. No inflation
439 meshMod_.changeMesh(*this, false);
441 // Clear topo change for the next operation
446 // ************************************************************************* //