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

fvPatchMapper.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 "fvPatchMapper.H"
00027 #include <finiteVolume/fvPatch.H>
00028 #include <finiteVolume/fvBoundaryMesh.H>
00029 #include <finiteVolume/fvMesh.H>
00030 #include <OpenFOAM/mapPolyMesh.H>
00031 #include <OpenFOAM/faceMapper.H>
00032 
00033 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00034 
00035 void Foam::fvPatchMapper::calcAddressing() const
00036 {
00037     if
00038     (
00039         directAddrPtr_
00040      || interpolationAddrPtr_
00041      || weightsPtr_
00042     )
00043     {
00044         FatalErrorIn
00045         (
00046             "void fvPatchMapper::calcAddressing() const)"
00047         )   << "Addressing already calculated"
00048             << abort(FatalError);
00049     }
00050 
00051     // Mapping
00052     const label oldPatchStart =
00053         faceMap_.oldPatchStarts()[patch_.index()];
00054 
00055     const label oldPatchEnd =
00056         oldPatchStart + faceMap_.oldPatchSizes()[patch_.index()];
00057 
00058     // Assemble the maps: slice to patch
00059     if (direct())
00060     {
00061         // Direct mapping - slice to size
00062         directAddrPtr_ = new labelList
00063         (
00064             patch_.patchSlice
00065             (
00066                 static_cast<const labelList&>(faceMap_.directAddressing())
00067             )
00068         );
00069         labelList& addr = *directAddrPtr_;
00070 
00071         // Adjust mapping to manage hits into other patches and into
00072         // internal
00073         forAll (addr, faceI)
00074         {
00075             if
00076             (
00077                 addr[faceI] >= oldPatchStart
00078              && addr[faceI] < oldPatchEnd
00079             )
00080             {
00081                 addr[faceI] -= oldPatchStart;
00082             }
00083             else
00084             {
00085                 addr[faceI] = 0;
00086             }
00087         }
00088 
00089         if (fvMesh::debug)
00090         {
00091             if (min(addr) < 0)
00092             {
00093                 FatalErrorIn
00094                 (
00095                     "void fvPatchMapper::calcAddressing() const"
00096                 )   << "Error in patch mapping for patch "
00097                     << patch_.index() << " named " << patch_.name()
00098                     << abort(FatalError);
00099             }
00100         }
00101     }
00102     else
00103     {
00104         // Interpolative mapping
00105         interpolationAddrPtr_ =
00106             new labelListList
00107             (
00108                 patch_.patchSlice(faceMap_.addressing())
00109             );
00110         labelListList& addr = *interpolationAddrPtr_;
00111 
00112         weightsPtr_ =
00113             new scalarListList
00114             (
00115                 patch_.patchSlice(faceMap_.weights())
00116             );
00117         scalarListList& w = *weightsPtr_;
00118 
00119         // Adjust mapping to manage hits into other patches and into
00120         // internal
00121         forAll (addr, faceI)
00122         {
00123             labelList& curAddr = addr[faceI];
00124             scalarList& curW = w[faceI];
00125 
00126             if
00127             (
00128                 min(curAddr) >= oldPatchStart
00129              && max(curAddr) < oldPatchEnd
00130             )
00131             {
00132                 // No adjustment of weights, just subtract patch start
00133                 forAll (curAddr, i)
00134                 {
00135                     curAddr[i] -= oldPatchStart;
00136                 }
00137             }
00138             else
00139             {
00140                 // Need to recalculate weights to exclude hits into internal
00141                 labelList newAddr(curAddr.size(), false);
00142                 scalarField newWeights(curAddr.size());
00143                 label nActive = 0;
00144 
00145                 forAll (curAddr, lfI)
00146                 {
00147                     if
00148                     (
00149                         curAddr[lfI] >= oldPatchStart
00150                      && curAddr[lfI] < oldPatchEnd
00151                     )
00152                     {
00153                         newAddr[nActive] = curAddr[lfI] - oldPatchStart;
00154                         newWeights[nActive] = curW[lfI];
00155                         nActive++;
00156                     }
00157                 }
00158 
00159                 // Cater for bad mapping
00160                 if (nActive == 0)
00161                 {
00162                     newAddr[nActive] = 0;
00163                     newWeights[nActive] = 1;
00164                     nActive++;
00165                 }
00166 
00167                 newAddr.setSize(nActive);
00168                 newWeights.setSize(nActive);
00169 
00170                 // Re-scale the weights
00171                 newWeights /= sum(newWeights);
00172 
00173                 // Reset addressing and weights
00174                 curAddr = newAddr;
00175                 curW = newWeights;
00176             }
00177         }
00178 
00179         if (fvMesh::debug)
00180         {
00181             forAll (addr, i)
00182             {
00183                 if (min(addr[i]) < 0)
00184                 {
00185                     FatalErrorIn
00186                     (
00187                         "void fvPatchMapper::calcAddressing() const"
00188                     )   << "Error in patch mapping for patch "
00189                         << patch_.index() << " named " << patch_.name()
00190                         << abort(FatalError);
00191                 }
00192             }
00193         }
00194     }
00195 }
00196 
00197 
00198 void Foam::fvPatchMapper::clearOut()
00199 {
00200     deleteDemandDrivenData(directAddrPtr_);
00201     deleteDemandDrivenData(interpolationAddrPtr_);
00202     deleteDemandDrivenData(weightsPtr_);
00203 }
00204 
00205 
00206 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00207 
00208 // Construct from components
00209 Foam::fvPatchMapper::fvPatchMapper
00210 (
00211     const fvPatch& patch,
00212     const faceMapper& faceMap
00213 )
00214 :
00215     patch_(patch),
00216     faceMap_(faceMap),
00217     sizeBeforeMapping_(faceMap.oldPatchSizes()[patch_.index()]),
00218     directAddrPtr_(NULL),
00219     interpolationAddrPtr_(NULL),
00220     weightsPtr_(NULL)
00221 {}
00222 
00223 
00224 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00225 
00226 Foam::fvPatchMapper::~fvPatchMapper()
00227 {
00228     clearOut();
00229 }
00230 
00231 
00232 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00233 
00234 const Foam::unallocLabelList& Foam::fvPatchMapper::directAddressing() const
00235 {
00236     if (!direct())
00237     {
00238         FatalErrorIn
00239         (
00240             "const unallocLabelList& fvPatchMapper::directAddressing() const"
00241         )   << "Requested direct addressing for an interpolative mapper."
00242             << abort(FatalError);
00243     }
00244 
00245     if (!directAddrPtr_)
00246     {
00247         calcAddressing();
00248     }
00249 
00250     return *directAddrPtr_;
00251 }
00252 
00253 
00254 const Foam::labelListList& Foam::fvPatchMapper::addressing() const
00255 {
00256     if (direct())
00257     {
00258         FatalErrorIn
00259         (
00260             "const labelListList& fvPatchMapper::addressing() const"
00261         )   << "Requested interpolative addressing for a direct mapper."
00262             << abort(FatalError);
00263     }
00264 
00265     if (!interpolationAddrPtr_)
00266     {
00267         calcAddressing();
00268     }
00269 
00270     return *interpolationAddrPtr_;
00271 }
00272 
00273 
00274 const Foam::scalarListList& Foam::fvPatchMapper::weights() const
00275 {
00276     if (direct())
00277     {
00278         FatalErrorIn
00279         (
00280             "const scalarListList& fvPatchMapper::weights() const"
00281         )   << "Requested interpolative weights for a direct mapper."
00282             << abort(FatalError);
00283     }
00284 
00285     if (!weightsPtr_)
00286     {
00287         calcAddressing();
00288     }
00289 
00290     return *weightsPtr_;
00291 }
00292 
00293 
00294 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00295 
00296 
00297 // * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
00298 
00299 
00300 // * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
00301 
00302 
00303 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines