initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / fvAgglomerationMethods / MGridGenGamgAgglomeration / MGridGenGAMGAgglomeration.C
blob53d45497ccc54972caa4bfbcfcf869436e711fe9
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software; you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "MGridGenGAMGAgglomeration.H"
28 #include "fvMesh.H"
29 #include "addToRunTimeSelectionTable.H"
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 namespace Foam
35     defineTypeNameAndDebug(MGridGenGAMGAgglomeration, 0);
37     addToRunTimeSelectionTable
38     (
39         GAMGAgglomeration,
40         MGridGenGAMGAgglomeration,
41         lduMesh
42     );
46 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
48 Foam::MGridGenGAMGAgglomeration::MGridGenGAMGAgglomeration
50     const lduMesh& mesh,
51     const dictionary& controlDict
54     GAMGAgglomeration(mesh, controlDict),
55     fvMesh_(refCast<const fvMesh>(mesh))
57     // Min, max size of agglomerated cells
58     label minSize(readLabel(controlDict.lookup("minSize")));
59     label maxSize(readLabel(controlDict.lookup("maxSize")));
62     // Get the finest-level interfaces from the mesh
63     interfaceLevels_.set
64     (
65         0,
66         new lduInterfacePtrsList(fvMesh_.boundary().interfaces())
67     );
69     // Start geometric agglomeration from the cell volumes and areas of the mesh
70     scalarField* VPtr = const_cast<scalarField*>(&fvMesh_.cellVolumes());
71     vectorField* SfPtr = const_cast<vectorField*>(&fvMesh_.faceAreas());
73     // Create the boundary area cell field
74     scalarField* SbPtr(new scalarField(fvMesh_.nCells(), 0));
76     {
77         scalarField& Sb = *SbPtr;
79         const labelList& own = fvMesh_.faceOwner();
80         const vectorField& Sf = fvMesh_.faceAreas();
82         forAll(Sf, facei)
83         {
84             if (!fvMesh_.isInternalFace(facei))
85             {
86                 Sb[own[facei]] += mag(Sf[facei]);
87             }
88         }
89     }
92     // Agglomerate until the required number of cells in the coarsest level
93     // is reached
95     label nCreatedLevels = 0;
97     while (nCreatedLevels < maxLevels_ - 1)
98     {
99         label nCoarseCells = -1;
101         tmp<labelField> finalAgglomPtr = agglomerate
102         (
103             nCoarseCells,
104             minSize,
105             maxSize,
106             meshLevel(nCreatedLevels).lduAddr(),
107             *VPtr,
108             *SfPtr,
109             *SbPtr
110         );
112         if (continueAgglomerating(nCoarseCells))
113         {
114             nCells_[nCreatedLevels] = nCoarseCells;
115             restrictAddressing_.set(nCreatedLevels, finalAgglomPtr);
116         }
117         else
118         {
119             break;
120         }
122         agglomerateLduAddressing(nCreatedLevels);
124         // Agglomerate the cell volumes field for the next level
125         {
126             scalarField* aggVPtr
127             (
128                 new scalarField(meshLevels_[nCreatedLevels].size())
129             );
131             restrictField(*aggVPtr, *VPtr, nCreatedLevels);
133             if (nCreatedLevels)
134             {
135                 delete VPtr;
136             }
138             VPtr = aggVPtr;
139         }
141         // Agglomerate the face areas field for the next level
142         {
143             vectorField* aggSfPtr
144             (
145                 new vectorField
146                 (
147                     meshLevels_[nCreatedLevels].upperAddr().size(),
148                     vector::zero
149                 )
150             );
152             restrictFaceField(*aggSfPtr, *SfPtr, nCreatedLevels);
154             if (nCreatedLevels)
155             {
156                 delete SfPtr;
157             }
159             SfPtr = aggSfPtr;
160         }
162         // Agglomerate the cell boundary areas field for the next level
163         {
164             scalarField* aggSbPtr
165             (
166                 new scalarField(meshLevels_[nCreatedLevels].size())
167             );
169             restrictField(*aggSbPtr, *SbPtr, nCreatedLevels);
171             delete SbPtr;
172             SbPtr = aggSbPtr;
173         }
175         nCreatedLevels++;
176     }
178     // Shrink the storage of the levels to those created
179     compactLevels(nCreatedLevels);
181     // Delete temporary geometry storage
182     if (nCreatedLevels)
183     {
184         delete VPtr;
185         delete SfPtr;
186     }
187     delete SbPtr;
191 // ************************************************************************* //