FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

mergePolyMesh.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "mergePolyMesh.H"
00027 #include <OpenFOAM/Time.H>
00028 #include <dynamicMesh/polyTopoChanger.H>
00029 #include <OpenFOAM/mapPolyMesh.H>
00030 #include <dynamicMesh/polyAddPoint.H>
00031 #include <dynamicMesh/polyAddCell.H>
00032 #include <dynamicMesh/polyAddFace.H>
00033 
00034 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00035 
00036 defineTypeNameAndDebug(Foam::mergePolyMesh, 1);
00037 
00038 
00039 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00040 
00041 Foam::label Foam::mergePolyMesh::patchIndex(const polyPatch& p)
00042 {
00043     // Find the patch name on the list.  If the patch is already there
00044     // and patch types match, return index
00045     const word& pType = p.type();
00046     const word& pName = p.name();
00047 
00048     bool nameFound = false;
00049 
00050     forAll (patchNames_, patchI)
00051     {
00052         if (patchNames_[patchI] == pName)
00053         {
00054             if (patchTypes_[patchI] == pType)
00055             {
00056                 // Found name and types match
00057                 return patchI;
00058             }
00059             else
00060             {
00061                 // Found the name, but type is different
00062                 nameFound = true;
00063             }
00064         }
00065     }
00066 
00067     // Patch not found.  Append to the list
00068     patchTypes_.append(pType);
00069 
00070     if (nameFound)
00071     {
00072         // Duplicate name is not allowed.  Create a composite name from the
00073         // patch name and case name
00074         const word& caseName = p.boundaryMesh().mesh().time().caseName();
00075 
00076         patchNames_.append(pName + "_" + caseName);
00077 
00078         Info<< "label patchIndex(const polyPatch& p) : "
00079             << "Patch " << p.index() << " named "
00080             << pName << " in mesh " << caseName
00081             << " already exists, but patch types "
00082             << " do not match.\nCreating a composite name as "
00083             << patchNames_[patchNames_.size() - 1] << endl;
00084     }
00085     else
00086     {
00087         patchNames_.append(pName);
00088     }
00089 
00090     return patchNames_.size() - 1;
00091 }
00092 
00093 
00094 Foam::label Foam::mergePolyMesh::zoneIndex
00095 (
00096     DynamicList<word>& names,
00097     const word& curName
00098 )
00099 {
00100     forAll (names, zoneI)
00101     {
00102         if (names[zoneI] == curName)
00103         {
00104             return zoneI;
00105         }
00106     }
00107 
00108     // Not found.  Add new name to the list
00109     names.append(curName);
00110 
00111     return names.size() - 1;
00112 }
00113 
00114 
00115 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00116 
00117 Foam::mergePolyMesh::mergePolyMesh(const IOobject& io)
00118 :
00119     polyMesh(io),
00120     meshMod_(*this),
00121     patchTypes_(2*boundaryMesh().size()),
00122     patchNames_(2*boundaryMesh().size()),
00123     pointZoneNames_(),
00124     faceZoneNames_(),
00125     cellZoneNames_()
00126 {
00127     // Insert the original patches into the list
00128     wordList curPatchTypes = boundaryMesh().types();
00129     wordList curPatchNames = boundaryMesh().names();
00130 
00131     forAll (curPatchTypes, patchI)
00132     {
00133         patchTypes_.append(curPatchTypes[patchI]);
00134         patchNames_.append(curPatchNames[patchI]);
00135     }
00136 
00137     // Insert point, face and cell zones into the list
00138 
00139     // Point zones
00140     wordList curPointZoneNames = pointZones().names();
00141     if (curPointZoneNames.size())
00142     {
00143         pointZoneNames_.setCapacity(2*curPointZoneNames.size());
00144     }
00145 
00146     forAll (curPointZoneNames, zoneI)
00147     {
00148         pointZoneNames_.append(curPointZoneNames[zoneI]);
00149     }
00150 
00151     // Face zones
00152     wordList curFaceZoneNames = faceZones().names();
00153 
00154     if (curFaceZoneNames.size())
00155     {
00156         faceZoneNames_.setCapacity(2*curFaceZoneNames.size());
00157     }
00158     forAll (curFaceZoneNames, zoneI)
00159     {
00160         faceZoneNames_.append(curFaceZoneNames[zoneI]);
00161     }
00162 
00163     // Cell zones
00164     wordList curCellZoneNames = cellZones().names();
00165 
00166     if (curCellZoneNames.size())
00167     {
00168         cellZoneNames_.setCapacity(2*curCellZoneNames.size());
00169     }
00170     forAll (curCellZoneNames, zoneI)
00171     {
00172         cellZoneNames_.append(curCellZoneNames[zoneI]);
00173     }
00174 }
00175 
00176 
00177 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00178 
00179 
00180 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00181 
00182 void Foam::mergePolyMesh::addMesh(const polyMesh& m)
00183 {
00184     // Add all the points, faces and cells of the new mesh
00185 
00186     // Add points
00187 
00188     label zoneID = -1;
00189 
00190     const pointField& p = m.points();
00191     labelList renumberPoints(p.size());
00192 
00193     const pointZoneMesh& pz = m.pointZones();
00194     labelList pointZoneIndices(pz.size());
00195 
00196     forAll (pz, zoneI)
00197     {
00198         pointZoneIndices[zoneI] = zoneIndex(pointZoneNames_, pz[zoneI].name());
00199     }
00200 
00201     forAll (p, pointI)
00202     {
00203         // Grab zone ID.  If a point is not in a zone, it will return -1
00204         zoneID = pz.whichZone(pointI);
00205 
00206         if (zoneID > 0)
00207         {
00208             // Translate zone ID into the new index
00209             zoneID = pointZoneIndices[zoneID];
00210         }
00211 
00212         renumberPoints[pointI] =
00213             meshMod_.setAction
00214             (
00215                 polyAddPoint
00216                 (
00217                     p[pointI],            // Point to add
00218                     -1,                   // Master point (straight addition)
00219                     zoneID,               // Zone for point
00220                     pointI < m.nPoints()  // Is in cell?
00221                 )
00222             );
00223     }
00224 
00225     // Add cells
00226 
00227     const cellList& c = m.cells();
00228     labelList renumberCells(c.size());
00229 
00230     const cellZoneMesh& cz = m.cellZones();
00231     labelList cellZoneIndices(cz.size());
00232 
00233     forAll (cz, zoneI)
00234     {
00235         cellZoneIndices[zoneI] = zoneIndex(cellZoneNames_, cz[zoneI].name());
00236     }
00237 
00238     forAll (c, cellI)
00239     {
00240         // Grab zone ID.  If a cell is not in a zone, it will return -1
00241         zoneID = cz.whichZone(cellI);
00242 
00243         if (zoneID > 0)
00244         {
00245             // Translate zone ID into the new index
00246             zoneID = cellZoneIndices[zoneID];
00247         }
00248 
00249         renumberCells[cellI] =
00250             meshMod_.setAction
00251             (
00252                 polyAddCell
00253                 (
00254                     -1,                   // Master point
00255                     -1,                   // Master edge
00256                     -1,                   // Master face
00257                     -1,                   // Master cell
00258                     zoneID                // Zone for cell
00259                 )
00260             );
00261     }
00262 
00263     // Add faces
00264     const polyBoundaryMesh& bm = m.boundaryMesh();
00265 
00266     // Gather the patch indices
00267     labelList patchIndices(bm.size());
00268 
00269     forAll (patchIndices, patchI)
00270     {
00271         patchIndices[patchI] = patchIndex(bm[patchI]);
00272     }
00273 
00274     // Temporary: update number of allowable patches. This should be
00275     // determined at the top - before adding anything.
00276     meshMod_.setNumPatches(patchNames_.size());
00277 
00278 
00279 
00280     const faceZoneMesh& fz = m.faceZones();
00281     labelList faceZoneIndices(fz.size());
00282 
00283     forAll (fz, zoneI)
00284     {
00285         faceZoneIndices[zoneI] = zoneIndex(faceZoneNames_, fz[zoneI].name());
00286     }
00287 
00288     const faceList& f = m.faces();
00289     labelList renumberFaces(f.size());
00290 
00291     const labelList& own = m.faceOwner();
00292     const labelList& nei = m.faceNeighbour();
00293 
00294     label newOwn, newNei, newPatch, newZone;
00295     bool newZoneFlip;
00296 
00297     forAll (f, faceI)
00298     {
00299         const face& curFace = f[faceI];
00300 
00301         face newFace(curFace.size());
00302 
00303         forAll (curFace, pointI)
00304         {
00305             newFace[pointI] = renumberPoints[curFace[pointI]];
00306         }
00307 
00308         if (debug)
00309         {
00310             // Check that the face is valid
00311             if (min(newFace) < 0)
00312             {
00313                 FatalErrorIn("void mergePolyMesh::addMesh(const polyMesh&)")
00314                     << "Error in point mapping for face " << faceI
00315                     << ".  Old face: " << curFace << " New face: " << newFace
00316                     << abort(FatalError);
00317             }
00318         }
00319 
00320         if (faceI < m.nInternalFaces() || faceI >= m.nFaces())
00321         {
00322             newPatch = -1;
00323         }
00324         else
00325         {
00326             newPatch = patchIndices[bm.whichPatch(faceI)];
00327         }
00328 
00329         newOwn = own[faceI];
00330         if (newOwn > -1) newOwn = renumberCells[newOwn];
00331 
00332         if (newPatch > -1)
00333         {
00334             newNei = -1;
00335         }
00336         else
00337         {
00338             newNei = nei[faceI];
00339             newNei = renumberCells[newNei];
00340         }
00341 
00342 
00343         newZone = fz.whichZone(faceI);
00344         newZoneFlip = false;
00345 
00346         if (newZone > -1)
00347         {
00348             newZoneFlip = fz[newZone].flipMap()[fz[newZone].whichFace(faceI)];
00349 
00350             // Grab the new zone
00351             newZone = faceZoneIndices[newZone];
00352         }
00353 
00354         renumberFaces[faceI] =
00355             meshMod_.setAction
00356             (
00357                 polyAddFace
00358                 (
00359                     newFace,
00360                     newOwn,
00361                     newNei,
00362                     -1,
00363                     -1,
00364                     -1,
00365                     false,
00366                     newPatch,
00367                     newZone,
00368                     newZoneFlip
00369                 )
00370             );
00371     }
00372 
00373 }
00374 
00375 
00376 void Foam::mergePolyMesh::merge()
00377 {
00378     Info<< "patch names: " << patchNames_ << nl
00379         << "patch types: " << patchTypes_ << nl
00380         << "point zone names: " << pointZoneNames_ << nl
00381         << "face zone names: " << faceZoneNames_ << nl
00382         << "cell zone names: " << cellZoneNames_ << endl;
00383 
00384     // Add the patches if necessary
00385     if (patchNames_.size() != boundaryMesh().size())
00386     {
00387         Info << "Copying old patches" << endl;
00388 
00389         List<polyPatch*> newPatches(patchNames_.size());
00390 
00391         const polyBoundaryMesh& oldPatches = boundaryMesh();
00392 
00393         // Note.  Re-using counter in two for loops
00394         label patchI = 0;
00395 
00396         for (patchI = 0; patchI < oldPatches.size(); patchI++)
00397         {
00398             newPatches[patchI] = oldPatches[patchI].clone(oldPatches).ptr();
00399         }
00400 
00401         Info << "Adding new patches. " << endl;
00402 
00403         label endOfLastPatch =
00404             oldPatches[patchI - 1].start() + oldPatches[patchI - 1].size();
00405 
00406         for (; patchI < patchNames_.size(); patchI++)
00407         {
00408             // Add a patch
00409             newPatches[patchI] =
00410             (
00411                 polyPatch::New
00412                 (
00413                     patchTypes_[patchI],
00414                     patchNames_[patchI],
00415                     0,
00416                     endOfLastPatch,
00417                     patchI,
00418                     oldPatches
00419                 ).ptr()
00420             );
00421         }
00422 
00423         removeBoundary();
00424         addPatches(newPatches);
00425     }
00426 
00427     // Add the zones if necessary
00428     if
00429     (
00430         pointZoneNames_.size() != pointZones().size()
00431      || faceZoneNames_.size() != faceZones().size()
00432      || cellZoneNames_.size() != cellZones().size()
00433     )
00434     {
00435 
00436     }
00437 
00438     // Change mesh. No inflation
00439     meshMod_.changeMesh(*this, false);
00440 
00441     // Clear topo change for the next operation
00442     meshMod_.clear();
00443 }
00444 
00445 
00446 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines