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

distributeCells.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 "domainDecomposition.H"
00027 #include <decompositionMethods/decompositionMethod.H>
00028 #include <OSspecific/cpuTime.H>
00029 #include <OpenFOAM/cyclicPolyPatch.H>
00030 #include <meshTools/cellSet.H>
00031 #include <meshTools/regionSplit.H>
00032 
00033 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00034 
00035 void domainDecomposition::distributeCells()
00036 {
00037     Info<< "\nCalculating distribution of cells" << endl;
00038 
00039     cpuTime decompositionTime;
00040 
00041 
00042     // See if any faces need to have owner and neighbour on same processor
00043     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00044 
00045     labelHashSet sameProcFaces;
00046 
00047     if (decompositionDict_.found("preservePatches"))
00048     {
00049         wordList pNames(decompositionDict_.lookup("preservePatches"));
00050 
00051         Info<< "Keeping owner of faces in patches " << pNames
00052             << " on same processor. This only makes sense for cyclics." << endl;
00053 
00054         const polyBoundaryMesh& patches = boundaryMesh();
00055 
00056         forAll(pNames, i)
00057         {
00058             label patchI = patches.findPatchID(pNames[i]);
00059 
00060             if (patchI == -1)
00061             {
00062                 FatalErrorIn("domainDecomposition::distributeCells()")
00063                     << "Unknown preservePatch " << pNames[i]
00064                     << endl << "Valid patches are " << patches.names()
00065                     << exit(FatalError);
00066             }
00067 
00068             const polyPatch& pp = patches[patchI];
00069 
00070             forAll(pp, i)
00071             {
00072                 sameProcFaces.insert(pp.start() + i);
00073             }
00074         }
00075     }
00076     if (decompositionDict_.found("preserveFaceZones"))
00077     {
00078         wordList zNames(decompositionDict_.lookup("preserveFaceZones"));
00079 
00080         Info<< "Keeping owner and neighbour of faces in zones " << zNames
00081             << " on same processor" << endl;
00082 
00083         const faceZoneMesh& fZones = faceZones();
00084 
00085         forAll(zNames, i)
00086         {
00087             label zoneI = fZones.findZoneID(zNames[i]);
00088 
00089             if (zoneI == -1)
00090             {
00091                 FatalErrorIn("domainDecomposition::distributeCells()")
00092                     << "Unknown preserveFaceZone " << zNames[i]
00093                     << endl << "Valid faceZones are " << fZones.names()
00094                     << exit(FatalError);
00095             }
00096 
00097             const faceZone& fz = fZones[zoneI];
00098 
00099             forAll(fz, i)
00100             {
00101                 sameProcFaces.insert(fz[i]);
00102             }
00103         }
00104     }
00105 
00106 
00107     // Construct decomposition method and either do decomposition on
00108     // cell centres or on agglomeration
00109 
00110 
00111     autoPtr<decompositionMethod> decomposePtr = decompositionMethod::New
00112     (
00113         decompositionDict_,
00114         *this
00115     );
00116 
00117     if (sameProcFaces.empty())
00118     {
00119         if (decompositionDict_.found("weightField"))
00120         {
00121             word weightName = decompositionDict_.lookup("weightField");
00122 
00123             volScalarField weights
00124             (
00125                 IOobject
00126                 (
00127                     weightName,
00128                     time().timeName(),
00129                     *this,
00130                     IOobject::MUST_READ,
00131                     IOobject::NO_WRITE
00132                 ),
00133                 *this
00134             );
00135 
00136             cellToProc_ = decomposePtr().decompose
00137             (
00138                 cellCentres(),
00139                 weights.internalField()
00140             );
00141         }
00142         else
00143         {
00144             cellToProc_ = decomposePtr().decompose(cellCentres());
00145         }
00146     }
00147     else
00148     {
00149         Info<< "Selected " << sameProcFaces.size()
00150             << " faces whose owner and neighbour cell should be kept on the"
00151             << " same processor" << endl;
00152 
00153         if (decompositionDict_.found("weightField"))
00154         {
00155             WarningIn("void domainDecomposition::distributeCells()")
00156                 << "weightField not supported when agglomerated "
00157                 << "decomposition required" << endl;
00158         }
00159 
00160         // Faces where owner and neighbour are not 'connected' (= all except
00161         // sameProcFaces)
00162         boolList blockedFace(nFaces(), true);
00163 
00164         forAllConstIter(labelHashSet, sameProcFaces, iter)
00165         {
00166             blockedFace[iter.key()] = false;
00167         }
00168 
00169         // Connect coupled boundary faces
00170         const polyBoundaryMesh& patches =  boundaryMesh();
00171 
00172         forAll(patches, patchI)
00173         {
00174             const polyPatch& pp = patches[patchI];
00175 
00176             if (pp.coupled())
00177             {
00178                 forAll(pp, i)
00179                 {
00180                     blockedFace[pp.start()+i] = false;
00181                 }
00182             }
00183         }
00184 
00185         // Determine global regions, separated by blockedFaces
00186         regionSplit globalRegion(*this, blockedFace);
00187 
00188 
00189         // Determine region cell centres
00190         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00191 
00192         // This just takes the first cell in the region. Otherwise the problem
00193         // is with cyclics - if we'd average the region centre might be
00194         // somewhere in the middle of the domain which might not be anywhere
00195         // near any of the cells.
00196 
00197         const point greatPoint(GREAT, GREAT, GREAT);
00198 
00199         pointField regionCentres(globalRegion.nRegions(), greatPoint);
00200 
00201         forAll(globalRegion, cellI)
00202         {
00203             label regionI = globalRegion[cellI];
00204 
00205             if (regionCentres[regionI] == greatPoint)
00206             {
00207                 regionCentres[regionI] = cellCentres()[cellI];
00208             }
00209         }
00210 
00211         // Do decomposition on agglomeration
00212         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00213         cellToProc_ = decomposePtr().decompose(globalRegion, regionCentres);
00214     }
00215 
00216     Info<< "\nFinished decomposition in "
00217         << decompositionTime.elapsedCpuTime()
00218         << " s" << endl;
00219 }
00220 
00221 
00222 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines