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

cellMapper.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 "cellMapper.H"
00027 #include <OpenFOAM/demandDrivenData.H>
00028 #include <OpenFOAM/polyMesh.H>
00029 #include <OpenFOAM/mapPolyMesh.H>
00030 
00031 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00032 
00033 
00034 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00035 
00036 void Foam::cellMapper::calcAddressing() const
00037 {
00038     if
00039     (
00040         directAddrPtr_
00041      || interpolationAddrPtr_
00042      || weightsPtr_
00043      || insertedCellLabelsPtr_
00044     )
00045     {
00046         FatalErrorIn("void cellMapper::calcAddressing() const")
00047             << "Addressing already calculated."
00048             << abort(FatalError);
00049     }
00050 
00051     if (direct())
00052     {
00053         // Direct addressing, no weights
00054 
00055         directAddrPtr_ = new labelList(mpm_.cellMap());
00056         labelList& directAddr = *directAddrPtr_;
00057 
00058         // Not necessary to resize the list as there are no retired cells
00059         // directAddr.setSize(mesh_.nCells());
00060 
00061         insertedCellLabelsPtr_ = new labelList(mesh_.nCells());
00062         labelList& insertedCells = *insertedCellLabelsPtr_;
00063 
00064         label nInsertedCells = 0;
00065 
00066         forAll (directAddr, cellI)
00067         {
00068             if (directAddr[cellI] < 0)
00069             {
00070                 // Found inserted cell
00071                 directAddr[cellI] = 0;
00072                 insertedCells[nInsertedCells] = cellI;
00073                 nInsertedCells++;
00074             }
00075         }
00076 
00077         insertedCells.setSize(nInsertedCells);
00078     }
00079     else
00080     {
00081         // Interpolative addressing
00082 
00083         interpolationAddrPtr_ = new labelListList(mesh_.nCells());
00084         labelListList& addr = *interpolationAddrPtr_;
00085 
00086         weightsPtr_ = new scalarListList(mesh_.nCells());
00087         scalarListList& w = *weightsPtr_;
00088 
00089         const List<objectMap>& cfp = mpm_.cellsFromPointsMap();
00090 
00091         forAll (cfp, cfpI)
00092         {
00093             // Get addressing
00094             const labelList& mo = cfp[cfpI].masterObjects();
00095 
00096             label cellI = cfp[cfpI].index();
00097 
00098             if (addr[cellI].size())
00099             {
00100                 FatalErrorIn("void cellMapper::calcAddressing() const")
00101                     << "Master cell " << cellI
00102                     << " mapped from point cells " << mo
00103                     << " already destination of mapping." << abort(FatalError);
00104             }
00105 
00106             // Map from masters, uniform weights
00107             addr[cellI] = mo;
00108             w[cellI] = scalarList(mo.size(), 1.0/mo.size());
00109         }
00110 
00111         const List<objectMap>& cfe = mpm_.cellsFromEdgesMap();
00112 
00113         forAll (cfe, cfeI)
00114         {
00115             // Get addressing
00116             const labelList& mo = cfe[cfeI].masterObjects();
00117 
00118             label cellI = cfe[cfeI].index();
00119 
00120             if (addr[cellI].size())
00121             {
00122                 FatalErrorIn("void cellMapper::calcAddressing() const")
00123                     << "Master cell " << cellI
00124                     << " mapped from edge cells " << mo
00125                     << " already destination of mapping." << abort(FatalError);
00126             }
00127 
00128             // Map from masters, uniform weights
00129             addr[cellI] = mo;
00130             w[cellI] = scalarList(mo.size(), 1.0/mo.size());
00131         }
00132 
00133         const List<objectMap>& cff = mpm_.cellsFromFacesMap();
00134 
00135         forAll (cff, cffI)
00136         {
00137             // Get addressing
00138             const labelList& mo = cff[cffI].masterObjects();
00139 
00140             label cellI = cff[cffI].index();
00141 
00142             if (addr[cellI].size())
00143             {
00144                 FatalErrorIn("void cellMapper::calcAddressing() const")
00145                     << "Master cell " << cellI
00146                     << " mapped from face cells " << mo
00147                     << " already destination of mapping." << abort(FatalError);
00148             }
00149 
00150             // Map from masters, uniform weights
00151             addr[cellI] = mo;
00152             w[cellI] = scalarList(mo.size(), 1.0/mo.size());
00153         }
00154 
00155         const List<objectMap>& cfc = mpm_.cellsFromCellsMap();
00156 
00157         forAll (cfc, cfcI)
00158         {
00159             // Get addressing
00160             const labelList& mo = cfc[cfcI].masterObjects();
00161 
00162             label cellI = cfc[cfcI].index();
00163 
00164             if (addr[cellI].size())
00165             {
00166                 FatalErrorIn("void cellMapper::calcAddressing() const")
00167                     << "Master cell " << cellI
00168                     << " mapped from cell cells " << mo
00169                     << " already destination of mapping." << abort(FatalError);
00170             }
00171 
00172             // Map from masters, uniform weights
00173             addr[cellI] = mo;
00174             w[cellI] = scalarList(mo.size(), 1.0/mo.size());
00175         }
00176 
00177 
00178         // Do mapped faces. Note that can already be set from cellsFromCells
00179         // so check if addressing size still zero.
00180 
00181         const labelList& cm = mpm_.cellMap();
00182 
00183         forAll (cm, cellI)
00184         {
00185             if (cm[cellI] > -1 && addr[cellI].empty())
00186             {
00187                 // Mapped from a single cell
00188                 addr[cellI] = labelList(1, cm[cellI]);
00189                 w[cellI] = scalarList(1, 1.0);
00190             }
00191         }
00192 
00193         // Grab inserted points (for them the size of addressing is still zero)
00194 
00195         insertedCellLabelsPtr_ = new labelList(mesh_.nCells());
00196         labelList& insertedCells = *insertedCellLabelsPtr_;
00197 
00198         label nInsertedCells = 0;
00199 
00200         forAll (addr, cellI)
00201         {
00202             if (addr[cellI].empty())
00203             {
00204                 // Mapped from a dummy cell
00205                 addr[cellI] = labelList(1, 0);
00206                 w[cellI] = scalarList(1, 1.0);
00207 
00208                 insertedCells[nInsertedCells] = cellI;
00209                 nInsertedCells++;
00210             }
00211         }
00212 
00213         insertedCells.setSize(nInsertedCells);
00214     }
00215 }
00216 
00217 
00218 void Foam::cellMapper::clearOut()
00219 {
00220     deleteDemandDrivenData(directAddrPtr_);
00221     deleteDemandDrivenData(interpolationAddrPtr_);
00222     deleteDemandDrivenData(weightsPtr_);
00223     deleteDemandDrivenData(insertedCellLabelsPtr_);
00224 }
00225 
00226 
00227 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00228 
00229 // Construct from components
00230 Foam::cellMapper::cellMapper(const mapPolyMesh& mpm)
00231 :
00232     mesh_(mpm.mesh()),
00233     mpm_(mpm),
00234     insertedCells_(true),
00235     direct_(false),
00236     directAddrPtr_(NULL),
00237     interpolationAddrPtr_(NULL),
00238     weightsPtr_(NULL),
00239     insertedCellLabelsPtr_(NULL)
00240 {
00241     // Check for possibility of direct mapping
00242     if
00243     (
00244         mpm_.cellsFromPointsMap().empty()
00245      && mpm_.cellsFromEdgesMap().empty()
00246      && mpm_.cellsFromFacesMap().empty()
00247      && mpm_.cellsFromCellsMap().empty()
00248     )
00249     {
00250         direct_ = true;
00251     }
00252     else
00253     {
00254         direct_ = false;
00255     }
00256 
00257     // Check for inserted cells
00258     if (direct_ && (mpm_.cellMap().empty() || min(mpm_.cellMap()) > -1))
00259     {
00260         insertedCells_ = false;
00261     }
00262     else
00263     {
00264         // Need to check all 3 lists to see if there are inserted cells
00265         // with no owner
00266 
00267         // Make a copy of the cell map, add the entried for cells from points,
00268         // cells from edges and cells from faces and check for left-overs
00269         labelList cm(mesh_.nCells(), -1);
00270 
00271         const List<objectMap>& cfp = mpm_.cellsFromPointsMap();
00272 
00273         forAll (cfp, cfpI)
00274         {
00275             cm[cfp[cfpI].index()] = 0;
00276         }
00277 
00278         const List<objectMap>& cfe = mpm_.cellsFromEdgesMap();
00279 
00280         forAll (cfe, cfeI)
00281         {
00282             cm[cfe[cfeI].index()] = 0;
00283         }
00284 
00285         const List<objectMap>& cff = mpm_.cellsFromFacesMap();
00286 
00287         forAll (cff, cffI)
00288         {
00289             cm[cff[cffI].index()] = 0;
00290         }
00291 
00292         const List<objectMap>& cfc = mpm_.cellsFromCellsMap();
00293 
00294         forAll (cfc, cfcI)
00295         {
00296             cm[cfc[cfcI].index()] = 0;
00297         }
00298 
00299         if (min(cm) < 0)
00300         {
00301             insertedCells_ = true;
00302         }
00303     }
00304 }
00305 
00306 
00307 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00308 
00309 Foam::cellMapper::~cellMapper()
00310 {
00311     clearOut();
00312 }
00313 
00314 
00315 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00316 
00317 Foam::label Foam::cellMapper::size() const
00318 {
00319     return mpm_.cellMap().size();
00320 }
00321 
00322 
00323 Foam::label Foam::cellMapper::sizeBeforeMapping() const
00324 {
00325     return mpm_.nOldCells();
00326 }
00327 
00328 
00329 const Foam::unallocLabelList& Foam::cellMapper::directAddressing() const
00330 {
00331     if (!direct())
00332     {
00333         FatalErrorIn
00334         (
00335             "const unallocLabelList& cellMapper::directAddressing() const"
00336         )   << "Requested direct addressing for an interpolative mapper."
00337             << abort(FatalError);
00338     }
00339 
00340     if (!insertedObjects())
00341     {
00342         // No inserted cells.  Re-use cellMap
00343         return mpm_.cellMap();
00344     }
00345     else
00346     {
00347         if (!directAddrPtr_)
00348         {
00349             calcAddressing();
00350         }
00351 
00352         return *directAddrPtr_;
00353     }
00354 }
00355 
00356 
00357 const Foam::labelListList& Foam::cellMapper::addressing() const
00358 {
00359     if (direct())
00360     {
00361         FatalErrorIn
00362         (
00363             "const labelListList& cellMapper::addressing() const"
00364         )   << "Requested interpolative addressing for a direct mapper."
00365             << abort(FatalError);
00366     }
00367 
00368     if (!interpolationAddrPtr_)
00369     {
00370         calcAddressing();
00371     }
00372 
00373     return *interpolationAddrPtr_;
00374 }
00375 
00376 
00377 const Foam::scalarListList& Foam::cellMapper::weights() const
00378 {
00379     if (direct())
00380     {
00381         FatalErrorIn
00382         (
00383             "const scalarListList& cellMapper::weights() const"
00384         )   << "Requested interpolative weights for a direct mapper."
00385             << abort(FatalError);
00386     }
00387 
00388     if (!weightsPtr_)
00389     {
00390         calcAddressing();
00391     }
00392 
00393     return *weightsPtr_;
00394 }
00395 
00396 
00397 const Foam::labelList& Foam::cellMapper::insertedObjectLabels() const
00398 {
00399     if (!insertedCellLabelsPtr_)
00400     {
00401         if (!insertedObjects())
00402         {
00403             // There are no inserted cells
00404             insertedCellLabelsPtr_ = new labelList(0);
00405         }
00406         else
00407         {
00408             calcAddressing();
00409         }
00410     }
00411 
00412     return *insertedCellLabelsPtr_;
00413 }
00414 
00415 
00416 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00417 
00418 
00419 // * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
00420 
00421 
00422 // * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
00423 
00424 
00425 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines