initial commit for version 1.5.x patch release
[OpenFOAM-1.5.x.git] / src / OpenFOAM / matrices / lduMatrix / solvers / GAMG / interfaces / cyclicGAMGInterface / cyclicGAMGInterface.C
blobc7c2c859b0666c3465db79216649c9e81e409b66
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2008 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 "cyclicGAMGInterface.H"
28 #include "addToRunTimeSelectionTable.H"
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 namespace Foam
34     defineTypeNameAndDebug(cyclicGAMGInterface, 0);
35     addToRunTimeSelectionTable
36     (
37         GAMGInterface,
38         cyclicGAMGInterface,
39         lduInterface
40     );
44 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
46 Foam::cyclicGAMGInterface::cyclicGAMGInterface
48     const lduInterface& fineInterface,
49     const labelField& localRestrictAddressing,
50     const labelField& neighbourRestrictAddressing
53     GAMGInterface
54     (
55         fineInterface,
56         localRestrictAddressing,
57         neighbourRestrictAddressing
58     ),
59     fineCyclicInterface_(refCast<const cyclicLduInterface>(fineInterface))
61     // Make a lookup table of entries for owner/neighbour
62     HashTable<SLList<label>, label, Hash<label> > neighboursTable
63     (
64         localRestrictAddressing.size()
65     );
67     // Table of face-sets to be agglomerated
68     HashTable<SLList<SLList<label> >, label, Hash<label> > faceFaceTable
69     (
70         localRestrictAddressing.size()
71     );
73     label nCoarseFaces = 0;
75     label sizeBy2 = localRestrictAddressing.size()/2;
77     for (label ffi=0; ffi<sizeBy2; ffi++)
78     {
79         label curMaster = localRestrictAddressing[ffi];
80         label curSlave = localRestrictAddressing[ffi + sizeBy2];
82         // Look for the master cell.  If it has already got a face,
83         // add the coefficient to the face.  If not, create a new
84         // face.
85         if (neighboursTable.found(curMaster))
86         {
87             // Check all current neighbours to see if the current
88             // slave already exists.  If so, add the coefficient.
90             SLList<label>& curNbrs = neighboursTable.find(curMaster)();
92             SLList<SLList<label> >& curFaceFaces =
93                 faceFaceTable.find(curMaster)();
95             bool nbrFound = false;
97             SLList<label>::iterator nbrsIter = curNbrs.begin();
99             SLList<SLList<label> >::iterator faceFacesIter =
100                 curFaceFaces.begin();
102             for
103             (
104                 ;
105                 nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
106                 ++nbrsIter, ++faceFacesIter
107             )
108             {
109                 if (nbrsIter() == curSlave)
110                 {
111                     nbrFound = true;
112                     faceFacesIter().append(ffi);
113                     break;
114                 }
115             }
117             if (!nbrFound)
118             {
119                 curNbrs.append(curSlave);
120                 curFaceFaces.append(ffi);
122                 // New coarse face created
123                 nCoarseFaces++;
124             }
125         }
126         else
127         {
128             // This master has got no neighbours yet.  Add a neighbour
129             // and a coefficient, thus creating a new face
130             neighboursTable.insert(curMaster, SLList<label>(curSlave));
131             faceFaceTable.insert(curMaster, SLList<SLList<label> >(ffi));
133             // New coarse face created
134             nCoarseFaces++;
135         }
136     } // end for all fine faces
139     faceCells_.setSize(2*nCoarseFaces, -1);
140     faceRestrictAddressing_.setSize(localRestrictAddressing.size(), -1);
142     labelList contents = neighboursTable.toc();
144     // Reset face counter for re-use
145     nCoarseFaces = 0;
147     // On master side, the owner addressing is stored in table of contents
148     forAll (contents, masterI)
149     {
150         SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
152         SLList<SLList<label> >& curFaceFaces =
153             faceFaceTable.find(contents[masterI])();
155         SLList<label>::iterator nbrsIter = curNbrs.begin();
156         SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
158         for
159         (
160             ;
161             nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
162             ++nbrsIter, ++faceFacesIter
163         )
164         {
165             faceCells_[nCoarseFaces] = contents[masterI];
167             for
168             (
169                 SLList<label>::iterator facesIter = faceFacesIter().begin();
170                 facesIter != faceFacesIter().end();
171                 ++facesIter
172             )
173             {
174                 faceRestrictAddressing_[facesIter()] = nCoarseFaces;
175             }
177             nCoarseFaces++;
178         }
179     }
181     // On slave side, the owner addressing is stored in linked lists
182     forAll (contents, masterI)
183     {
184         SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
186         SLList<SLList<label> >& curFaceFaces =
187             faceFaceTable.find(contents[masterI])();
189         SLList<label>::iterator nbrsIter = curNbrs.begin();
190         SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
192         for
193         (
194             ;
195             nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
196             ++nbrsIter, ++faceFacesIter
197         )
198         {
199             faceCells_[nCoarseFaces] = nbrsIter();
201             for
202             (
203                 SLList<label>::iterator facesIter = faceFacesIter().begin();
204                 facesIter != faceFacesIter().end();
205                 ++facesIter
206             )
207             {
208                 faceRestrictAddressing_[facesIter() + sizeBy2] = nCoarseFaces;
209             }
211             nCoarseFaces++;
212         }
213     }
217 // * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
219 Foam::cyclicGAMGInterface::~cyclicGAMGInterface()
223 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
225 Foam::tmp<Foam::labelField> Foam::cyclicGAMGInterface::transfer
227     const Pstream::commsTypes,
228     const unallocLabelList& interfaceData
229 ) const
231     tmp<labelField> tpnf(new labelField(size()));
232     labelField& pnf = tpnf();
234     label sizeby2 = size()/2;
236     for (label facei=0; facei<sizeby2; facei++)
237     {
238         pnf[facei] = interfaceData[facei + sizeby2];
239         pnf[facei + sizeby2] = interfaceData[facei];
240     }
242     return tpnf;
246 Foam::tmp<Foam::labelField> Foam::cyclicGAMGInterface::internalFieldTransfer
248     const Pstream::commsTypes,
249     const unallocLabelList& iF
250 ) const
252     tmp<labelField> tpnf(new labelField(size()));
253     labelField& pnf = tpnf();
255     label sizeby2 = size()/2;
257     for (label facei=0; facei<sizeby2; facei++)
258     {
259         pnf[facei] = iF[faceCells_[facei + sizeby2]];
260         pnf[facei + sizeby2] = iF[faceCells_[facei]];
261     }
263     return tpnf;
267 // ************************************************************************* //