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

GAMGAgglomerateLduAddressing.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 "GAMGAgglomeration.H"
00027 #include <OpenFOAM/GAMGInterface.H>
00028 
00029 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00030 
00031 void Foam::GAMGAgglomeration::agglomerateLduAddressing
00032 (
00033     const label fineLevelIndex
00034 )
00035 {
00036     const lduMesh& fineMesh = meshLevel(fineLevelIndex);
00037     const lduAddressing& fineMeshAddr = fineMesh.lduAddr();
00038 
00039     const unallocLabelList& upperAddr = fineMeshAddr.upperAddr();
00040     const unallocLabelList& lowerAddr = fineMeshAddr.lowerAddr();
00041 
00042     label nFineFaces = upperAddr.size();
00043 
00044     // Get restriction map for current level
00045     const labelField& restrictMap = restrictAddressing(fineLevelIndex);
00046 
00047     if (min(restrictMap) == -1)
00048     {
00049         FatalErrorIn("GAMGAgglomeration::agglomerateLduAddressing")
00050             << "min(restrictMap) == -1" << exit(FatalError);
00051     }
00052 
00053     if (restrictMap.size() != fineMeshAddr.size())
00054     {
00055         FatalErrorIn
00056         (
00057             "GAMGAgglomeration::agglomerateLduAddressing"
00058             "(const label fineLevelIndex)"
00059         )   << "restrict map does not correspond to fine level. " << endl
00060             << " Sizes: restrictMap: " << restrictMap.size()
00061             << " nEqns: " << fineMeshAddr.size()
00062             << abort(FatalError);
00063     }
00064 
00065 
00066     // Get the number of coarse cells
00067     const label nCoarseCells = nCells_[fineLevelIndex];
00068 
00069     // Storage for coarse cell neighbours and coefficients
00070 
00071     // Guess initial maximum number of neighbours in coarse cell
00072     label maxNnbrs = 10;
00073 
00074     // Number of faces for each coarse-cell
00075     labelList cCellnFaces(nCoarseCells, 0);
00076 
00077     // Setup initial packed storage for coarse-cell faces
00078     labelList cCellFaces(maxNnbrs*nCoarseCells);
00079 
00080     // Create face-restriction addressing
00081     faceRestrictAddressing_.set(fineLevelIndex, new labelList(nFineFaces));
00082     labelList& faceRestrictAddr = faceRestrictAddressing_[fineLevelIndex];
00083 
00084     // Initial neighbour array (not in upper-triangle order)
00085     labelList initCoarseNeighb(nFineFaces);
00086 
00087     // Counter for coarse faces
00088     label nCoarseFaces = 0;
00089 
00090     // Loop through all fine faces
00091     forAll (upperAddr, fineFacei)
00092     {
00093         label rmUpperAddr = restrictMap[upperAddr[fineFacei]];
00094         label rmLowerAddr = restrictMap[lowerAddr[fineFacei]];
00095 
00096         if (rmUpperAddr == rmLowerAddr)
00097         {
00098             // For each fine face inside of a coarse cell keep the address
00099             // of the cell corresponding to the face in the faceRestrictAddr
00100             // as a negative index
00101             faceRestrictAddr[fineFacei] = -(rmUpperAddr + 1);
00102         }
00103         else
00104         {
00105             // this face is a part of a coarse face
00106 
00107             label cOwn = rmUpperAddr;
00108             label cNei = rmLowerAddr;
00109 
00110             // get coarse owner and neighbour
00111             if (rmUpperAddr > rmLowerAddr)
00112             {
00113                 cOwn = rmLowerAddr;
00114                 cNei = rmUpperAddr;
00115             }
00116 
00117             // check the neighbour to see if this face has already been found
00118             label* ccFaces = &cCellFaces[maxNnbrs*cOwn];
00119 
00120             bool nbrFound = false;
00121             label& ccnFaces = cCellnFaces[cOwn];
00122 
00123             for (int i=0; i<ccnFaces; i++)
00124             {
00125                 if (initCoarseNeighb[ccFaces[i]] == cNei)
00126                 {
00127                     nbrFound = true;
00128                     faceRestrictAddr[fineFacei] = ccFaces[i];
00129                     break;
00130                 }
00131             }
00132 
00133             if (!nbrFound)
00134             {
00135                 if (ccnFaces >= maxNnbrs)
00136                 {
00137                     label oldMaxNnbrs = maxNnbrs;
00138                     maxNnbrs *= 2;
00139 
00140                     cCellFaces.setSize(maxNnbrs*nCoarseCells);
00141 
00142                     forAllReverse(cCellnFaces, i)
00143                     {
00144                         label* oldCcNbrs = &cCellFaces[oldMaxNnbrs*i];
00145                         label* newCcNbrs = &cCellFaces[maxNnbrs*i];
00146 
00147                         for (int j=0; j<cCellnFaces[i]; j++)
00148                         {
00149                             newCcNbrs[j] = oldCcNbrs[j];
00150                         }
00151                     }
00152 
00153                     ccFaces = &cCellFaces[maxNnbrs*cOwn];
00154                 }
00155 
00156                 ccFaces[ccnFaces] = nCoarseFaces;
00157                 initCoarseNeighb[nCoarseFaces] = cNei;
00158                 faceRestrictAddr[fineFacei] = nCoarseFaces;
00159                 ccnFaces++;
00160 
00161                 // new coarse face created
00162                 nCoarseFaces++;
00163             }
00164         }
00165     } // end for all fine faces
00166 
00167 
00168     // Renumber into upper-triangular order
00169 
00170     // All coarse owner-neighbour storage
00171     labelList coarseOwner(nCoarseFaces);
00172     labelList coarseNeighbour(nCoarseFaces);
00173     labelList coarseFaceMap(nCoarseFaces);
00174 
00175     label coarseFacei = 0;
00176 
00177     forAll (cCellnFaces, cci)
00178     {
00179         label* cFaces = &cCellFaces[maxNnbrs*cci];
00180         label ccnFaces = cCellnFaces[cci];
00181 
00182         for (int i=0; i<ccnFaces; i++)
00183         {
00184             coarseOwner[coarseFacei] = cci;
00185             coarseNeighbour[coarseFacei] = initCoarseNeighb[cFaces[i]];
00186             coarseFaceMap[cFaces[i]] = coarseFacei;
00187             coarseFacei++;
00188         }
00189     }
00190 
00191     forAll(faceRestrictAddr, fineFacei)
00192     {
00193         if (faceRestrictAddr[fineFacei] >= 0)
00194         {
00195             faceRestrictAddr[fineFacei] =
00196                 coarseFaceMap[faceRestrictAddr[fineFacei]];
00197         }
00198     }
00199 
00200     // Clear the temporary storage for the coarse cell data
00201     cCellnFaces.setSize(0);
00202     cCellFaces.setSize(0);
00203     initCoarseNeighb.setSize(0);
00204     coarseFaceMap.setSize(0);
00205 
00206 
00207     // Create coarse-level interfaces
00208 
00209     // Get reference to fine-level interfaces
00210     const lduInterfacePtrsList& fineInterfaces =
00211         interfaceLevels_[fineLevelIndex];
00212 
00213     // Create coarse-level interfaces
00214     interfaceLevels_.set
00215     (
00216         fineLevelIndex + 1,
00217         new lduInterfacePtrsList(fineInterfaces.size())
00218     );
00219 
00220     lduInterfacePtrsList& coarseInterfaces =
00221         interfaceLevels_[fineLevelIndex + 1];
00222 
00223     labelListList coarseInterfaceAddr(fineInterfaces.size());
00224 
00225     // Initialise transfer of restrict addressing on the interface
00226     forAll (fineInterfaces, inti)
00227     {
00228         if (fineInterfaces.set(inti))
00229         {
00230             fineInterfaces[inti].initInternalFieldTransfer
00231             (
00232                 Pstream::blocking,
00233                 restrictMap
00234             );
00235         }
00236     }
00237 
00238     // Add the coarse level
00239     forAll (fineInterfaces, inti)
00240     {
00241         if (fineInterfaces.set(inti))
00242         {
00243             coarseInterfaces.set
00244             (
00245                 inti,
00246                 GAMGInterface::New
00247                 (
00248                     fineInterfaces[inti],
00249                     fineInterfaces[inti].interfaceInternalField(restrictMap),
00250                     fineInterfaces[inti].internalFieldTransfer
00251                     (
00252                         Pstream::blocking,
00253                         restrictMap
00254                     )
00255                 ).ptr()
00256             );
00257             
00258             coarseInterfaceAddr[inti] = coarseInterfaces[inti].faceCells();
00259         }
00260     }
00261 
00262 
00263     // Set the coarse ldu addressing onto the list
00264     meshLevels_.set
00265     (
00266         fineLevelIndex,
00267         new lduPrimitiveMesh
00268         (
00269             nCoarseCells,
00270             coarseOwner,
00271             coarseNeighbour,
00272             coarseInterfaceAddr,
00273             coarseInterfaces,
00274             fineMeshAddr.patchSchedule(),
00275             true
00276         )
00277     );
00278 }
00279 
00280 
00281 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines