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

lduAddressing.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 "lduAddressing.H"
00027 #include <OpenFOAM/demandDrivenData.H>
00028 
00029 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00030 
00031 void Foam::lduAddressing::calcLosort() const
00032 {
00033     if (losortPtr_)
00034     {
00035         FatalErrorIn("lduAddressing::calcLosort() const")
00036             << "losort already calculated"
00037             << abort(FatalError);
00038     }
00039 
00040     // Scan the neighbour list to find out how many times the cell
00041     // appears as a neighbour of the face. Done this way to avoid guessing
00042     // and resizing list
00043     labelList nNbrOfFace(size(), 0);
00044 
00045     const unallocLabelList& nbr = upperAddr();
00046 
00047     forAll (nbr, nbrI)
00048     {
00049         nNbrOfFace[nbr[nbrI]]++;
00050     }
00051 
00052     // Create temporary neighbour addressing
00053     labelListList cellNbrFaces(size());
00054 
00055     forAll (cellNbrFaces, cellI)
00056     {
00057         cellNbrFaces[cellI].setSize(nNbrOfFace[cellI]);
00058     }
00059 
00060     // Reset the list of number of neighbours to zero
00061     nNbrOfFace = 0;
00062 
00063     // Scatter the neighbour faces
00064     forAll (nbr, nbrI)
00065     {
00066         cellNbrFaces[nbr[nbrI]][nNbrOfFace[nbr[nbrI]]] = nbrI;
00067 
00068         nNbrOfFace[nbr[nbrI]]++;
00069     }
00070 
00071     // Gather the neighbours into the losort array
00072     losortPtr_ = new labelList(nbr.size(), -1);
00073 
00074     labelList& lst = *losortPtr_;
00075 
00076     // Set counter for losort
00077     label lstI = 0;
00078 
00079     forAll (cellNbrFaces, cellI)
00080     {
00081         const labelList& curNbr = cellNbrFaces[cellI];
00082 
00083         forAll (curNbr, curNbrI)
00084         {
00085             lst[lstI] = curNbr[curNbrI];
00086             lstI++;
00087         }
00088     }
00089 }
00090 
00091 
00092 void Foam::lduAddressing::calcOwnerStart() const
00093 {
00094     if (ownerStartPtr_)
00095     {
00096         FatalErrorIn("lduAddressing::calcOwnerStart() const")
00097             << "owner start already calculated"
00098             << abort(FatalError);
00099     }
00100 
00101     const labelList& own = lowerAddr();
00102 
00103     ownerStartPtr_ = new labelList(size() + 1, own.size());
00104 
00105     labelList& ownStart = *ownerStartPtr_;
00106 
00107     // Set up first lookup by hand
00108     ownStart[0] = 0;
00109     label nOwnStart = 0;
00110     label i = 1;
00111 
00112     forAll (own, faceI)
00113     {
00114         label curOwn = own[faceI];
00115 
00116         if (curOwn > nOwnStart)
00117         {
00118             while (i <= curOwn)
00119             {
00120                 ownStart[i++] = faceI;
00121             }
00122 
00123             nOwnStart = curOwn;
00124         }
00125     }
00126 }
00127 
00128 
00129 void Foam::lduAddressing::calcLosortStart() const
00130 {
00131     if (losortStartPtr_)
00132     {
00133         FatalErrorIn("lduAddressing::calcLosortStart() const")
00134             << "losort start already calculated"
00135             << abort(FatalError);
00136     }
00137 
00138     losortStartPtr_ = new labelList(size() + 1, 0);
00139 
00140     labelList& lsrtStart = *losortStartPtr_;
00141 
00142     const labelList& nbr = upperAddr();
00143 
00144     const labelList& lsrt = losortAddr();
00145 
00146     // Set up first lookup by hand
00147     lsrtStart[0] = 0;
00148     label nLsrtStart = 0;
00149     label i = 0;
00150 
00151     forAll (lsrt, faceI)
00152     {
00153         // Get neighbour
00154         const label curNbr = nbr[lsrt[faceI]];
00155 
00156         if (curNbr > nLsrtStart)
00157         {
00158             while (i <= curNbr)
00159             {
00160                 lsrtStart[i++] = faceI;
00161             }
00162 
00163             nLsrtStart = curNbr;
00164         }
00165     }
00166 
00167     // Set up last lookup by hand
00168     lsrtStart[size()] = nbr.size();
00169 }
00170 
00171 
00172 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00173 
00174 Foam::lduAddressing::~lduAddressing()
00175 {
00176     deleteDemandDrivenData(losortPtr_);
00177     deleteDemandDrivenData(ownerStartPtr_);
00178     deleteDemandDrivenData(losortStartPtr_);
00179 }
00180 
00181 
00182 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00183 
00184 const Foam::unallocLabelList& Foam::lduAddressing::losortAddr() const
00185 {
00186     if (!losortPtr_)
00187     {
00188         calcLosort();
00189     }
00190 
00191     return *losortPtr_;
00192 }
00193 
00194 
00195 const Foam::unallocLabelList& Foam::lduAddressing::ownerStartAddr() const
00196 {
00197     if (!ownerStartPtr_)
00198     {
00199         calcOwnerStart();
00200     }
00201 
00202     return *ownerStartPtr_;
00203 }
00204 
00205 
00206 const Foam::unallocLabelList& Foam::lduAddressing::losortStartAddr() const
00207 {
00208     if (!losortStartPtr_)
00209     {
00210         calcLosortStart();
00211     }
00212 
00213     return *losortStartPtr_;
00214 }
00215 
00216 
00217 // Return edge index given owner and neighbour label
00218 Foam::label Foam::lduAddressing::triIndex(const label a, const label b) const
00219 {
00220     label own = min(a, b);
00221 
00222     label nbr = max(a, b);
00223 
00224     label startLabel = ownerStartAddr()[own];
00225 
00226     label endLabel = ownerStartAddr()[own + 1];
00227 
00228     const unallocLabelList& neighbour = upperAddr();
00229 
00230     for (label i = startLabel; i < endLabel; i++)
00231     {
00232         if (neighbour[i] == nbr)
00233         {
00234             return i;
00235         }
00236     }
00237 
00238     // If neighbour has not been found, something has gone seriously
00239     // wrong with the addressing mechanism
00240     FatalErrorIn
00241     (
00242         "lduAddressing::triIndex(const label owner, const label nbr) const"
00243     )   << "neighbour " << nbr << " not found for owner " << own << ". "
00244         << "Problem with addressing"
00245         << abort(FatalError);
00246 
00247     return -1;
00248 }
00249 
00250 
00251 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines