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

processorGAMGInterface.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 "processorGAMGInterface.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028 
00029 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00030 
00031 namespace Foam
00032 {
00033     defineTypeNameAndDebug(processorGAMGInterface, 0);
00034     addToRunTimeSelectionTable
00035     (
00036         GAMGInterface,
00037         processorGAMGInterface,
00038         lduInterface
00039     );
00040 }
00041 
00042 
00043 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00044 
00045 Foam::processorGAMGInterface::processorGAMGInterface
00046 (
00047     const lduInterface& fineInterface,
00048     const labelField& localRestrictAddressing,
00049     const labelField& neighbourRestrictAddressing
00050 )
00051 :
00052     GAMGInterface
00053     (
00054         fineInterface,
00055         localRestrictAddressing,
00056         neighbourRestrictAddressing
00057     ),
00058     fineProcInterface_(refCast<const processorLduInterface>(fineInterface))
00059 {
00060     // Make a lookup table of entries for owner/neighbour
00061     HashTable<SLList<label>, label, Hash<label> > neighboursTable
00062     (
00063         localRestrictAddressing.size()
00064     );
00065 
00066     // Table of face-sets to be agglomerated
00067     HashTable<SLList<SLList<label> >, label, Hash<label> > faceFaceTable
00068     (
00069         localRestrictAddressing.size()
00070     );
00071 
00072     label nCoarseFaces = 0;
00073 
00074     forAll (localRestrictAddressing, ffi)
00075     {
00076         label curMaster = -1;
00077         label curSlave = -1;
00078 
00079         // Do switching on master/slave indexes based on the owner/neighbour of
00080         // the processor index such that both sides get the same answer.
00081         if (myProcNo() < neighbProcNo())
00082         {
00083             // Master side
00084             curMaster = localRestrictAddressing[ffi];
00085             curSlave = neighbourRestrictAddressing[ffi];
00086         }
00087         else
00088         {
00089             // Slave side
00090             curMaster = neighbourRestrictAddressing[ffi];
00091             curSlave = localRestrictAddressing[ffi];
00092         }
00093 
00094         // Look for the master cell.  If it has already got a face,
00095         // add the coefficient to the face.  If not, create a new face.
00096         if (neighboursTable.found(curMaster))
00097         {
00098             // Check all current neighbours to see if the current slave already
00099             // exists and if so, add the fine face to the agglomeration.
00100 
00101             SLList<label>& curNbrs = neighboursTable.find(curMaster)();
00102 
00103             SLList<SLList<label> >& curFaceFaces =
00104                 faceFaceTable.find(curMaster)();
00105 
00106             bool nbrFound = false;
00107 
00108             SLList<label>::iterator nbrsIter = curNbrs.begin();
00109 
00110             SLList<SLList<label> >::iterator faceFacesIter =
00111                 curFaceFaces.begin();
00112 
00113             for
00114             (
00115                 ;
00116                 nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
00117                 ++nbrsIter, ++faceFacesIter
00118             )
00119             {
00120                 if (nbrsIter() == curSlave)
00121                 {
00122                     nbrFound = true;
00123                     faceFacesIter().append(ffi);
00124                     break;
00125                 }
00126             }
00127 
00128             if (!nbrFound)
00129             {
00130                 curNbrs.append(curSlave);
00131                 curFaceFaces.append(ffi);
00132 
00133                 // New coarse face created
00134                 nCoarseFaces++;
00135             }
00136         }
00137         else
00138         {
00139             // This master has got no neighbours yet.  Add a neighbour
00140             // and a coefficient, thus creating a new face
00141             neighboursTable.insert(curMaster, SLList<label>(curSlave));
00142             faceFaceTable.insert(curMaster, SLList<SLList<label> >(ffi));
00143 
00144             // New coarse face created
00145             nCoarseFaces++;
00146         }
00147     } // end for all fine faces
00148 
00149 
00150 
00151     faceCells_.setSize(nCoarseFaces, -1);
00152     faceRestrictAddressing_.setSize(localRestrictAddressing.size());
00153 
00154     labelList contents = neighboursTable.toc();
00155 
00156     // Reset face counter for re-use
00157     nCoarseFaces = 0;
00158 
00159     if (myProcNo() < neighbProcNo())
00160     {
00161         // On master side, the owner addressing is stored in table of contents
00162         forAll (contents, masterI)
00163         {
00164             SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
00165 
00166             SLList<SLList<label> >& curFaceFaces =
00167                 faceFaceTable.find(contents[masterI])();
00168 
00169             SLList<label>::iterator nbrsIter = curNbrs.begin();
00170 
00171             SLList<SLList<label> >::iterator faceFacesIter =
00172                 curFaceFaces.begin();
00173 
00174             for
00175             (
00176                 ;
00177                 nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
00178                 ++nbrsIter, ++faceFacesIter
00179             )
00180             {
00181                 faceCells_[nCoarseFaces] = contents[masterI];
00182 
00183                 for
00184                 (
00185                     SLList<label>::iterator facesIter = faceFacesIter().begin();
00186                     facesIter != faceFacesIter().end();
00187                     ++facesIter
00188                 )
00189                 {
00190                     faceRestrictAddressing_[facesIter()] = nCoarseFaces;
00191                 }
00192 
00193                 nCoarseFaces++;
00194             }
00195         }
00196     }
00197     else
00198     {
00199         // On slave side, the owner addressing is stored in linked lists
00200         forAll (contents, masterI)
00201         {
00202             SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
00203 
00204             SLList<SLList<label> >& curFaceFaces =
00205                 faceFaceTable.find(contents[masterI])();
00206 
00207             SLList<label>::iterator nbrsIter = curNbrs.begin();
00208 
00209             SLList<SLList<label> >::iterator faceFacesIter =
00210                 curFaceFaces.begin();
00211 
00212             for
00213             (
00214                 ;
00215                 nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
00216                 ++nbrsIter, ++faceFacesIter
00217             )
00218             {
00219                 faceCells_[nCoarseFaces] = nbrsIter();
00220 
00221                 for
00222                 (
00223                     SLList<label>::iterator facesIter = faceFacesIter().begin();
00224                     facesIter != faceFacesIter().end();
00225                     ++facesIter
00226                 )
00227                 {
00228                     faceRestrictAddressing_[facesIter()] = nCoarseFaces;
00229                 }
00230 
00231                 nCoarseFaces++;
00232             }
00233         }
00234     }
00235 }
00236 
00237 
00238 // * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
00239 
00240 Foam::processorGAMGInterface::~processorGAMGInterface()
00241 {}
00242 
00243 
00244 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00245 
00246 void Foam::processorGAMGInterface::initTransfer
00247 (
00248     const Pstream::commsTypes commsType,
00249     const unallocLabelList& interfaceData
00250 ) const
00251 {
00252     send(commsType, interfaceData);
00253 }
00254 
00255 
00256 Foam::tmp<Foam::labelField> Foam::processorGAMGInterface::transfer
00257 (
00258     const Pstream::commsTypes commsType,
00259     const unallocLabelList& interfaceData
00260 ) const
00261 {
00262     return receive<label>(commsType, this->size());
00263 }
00264 
00265 
00266 void Foam::processorGAMGInterface::initInternalFieldTransfer
00267 (
00268     const Pstream::commsTypes commsType,
00269     const unallocLabelList& iF
00270 ) const
00271 {
00272     send(commsType, interfaceInternalField(iF)());
00273 }
00274 
00275 
00276 Foam::tmp<Foam::labelField> Foam::processorGAMGInterface::internalFieldTransfer
00277 (
00278     const Pstream::commsTypes commsType,
00279     const unallocLabelList& iF
00280 ) const
00281 {
00282     return receive<label>(commsType, this->size());
00283 }
00284 
00285 
00286 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines