Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / foam / matrices / lduMatrix / solvers / GAMG / interfaces / cyclicGAMGInterface / cyclicGAMGInterface.C
blobf0c398409b4a4b57cf762c226d7e1c62408b5657
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend 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 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "cyclicGAMGInterface.H"
27 #include "addToRunTimeSelectionTable.H"
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 namespace Foam
33     defineTypeNameAndDebug(cyclicGAMGInterface, 0);
34     addToRunTimeSelectionTable
35     (
36         GAMGInterface,
37         cyclicGAMGInterface,
38         lduInterface
39     );
43 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
45 Foam::cyclicGAMGInterface::cyclicGAMGInterface
47     const lduPrimitiveMesh& lduMesh,
48     const lduInterface& fineInterface,
49     const labelField& localRestrictAddressing,
50     const labelField& neighbourRestrictAddressing
53     GAMGInterface(lduMesh),
54     fineCyclicInterface_(refCast<const cyclicLduInterface>(fineInterface))
56     // Make a lookup table of entries for owner/neighbour
57     HashTable<SLList<label>, label, Hash<label> > neighboursTable
58     (
59         localRestrictAddressing.size()
60     );
62     // Table of face-sets to be agglomerated
63     HashTable<SLList<SLList<label> >, label, Hash<label> > faceFaceTable
64     (
65         localRestrictAddressing.size()
66     );
68     label nCoarseFaces = 0;
70     label sizeBy2 = localRestrictAddressing.size()/2;
72     for (label ffi=0; ffi<sizeBy2; ffi++)
73     {
74         label curMaster = localRestrictAddressing[ffi];
75         label curSlave = localRestrictAddressing[ffi + sizeBy2];
77         // Look for the master cell.  If it has already got a face,
78         // add the coefficient to the face.  If not, create a new
79         // face.
80         if (neighboursTable.found(curMaster))
81         {
82             // Check all current neighbours to see if the current
83             // slave already exists.  If so, add the coefficient.
85             SLList<label>& curNbrs = neighboursTable.find(curMaster)();
87             SLList<SLList<label> >& curFaceFaces =
88                 faceFaceTable.find(curMaster)();
90             bool nbrFound = false;
92             SLList<label>::iterator nbrsIter = curNbrs.begin();
94             SLList<SLList<label> >::iterator faceFacesIter =
95                 curFaceFaces.begin();
97             for
98             (
99                 ;
100                 nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
101                 ++nbrsIter, ++faceFacesIter
102             )
103             {
104                 if (nbrsIter() == curSlave)
105                 {
106                     nbrFound = true;
107                     faceFacesIter().append(ffi);
108                     break;
109                 }
110             }
112             if (!nbrFound)
113             {
114                 curNbrs.append(curSlave);
115                 curFaceFaces.append(SLList<label>(ffi));
117                 // New coarse face created
118                 nCoarseFaces++;
119             }
120         }
121         else
122         {
123             // This master has got no neighbours yet.  Add a neighbour
124             // and a coefficient, thus creating a new face
125             neighboursTable.insert(curMaster, SLList<label>(curSlave));
126             faceFaceTable.insert
127             (
128                 curMaster,
129                 SLList<SLList<label> >(SLList<label>(ffi))
130             );
132             // New coarse face created
133             nCoarseFaces++;
134         }
135     } // end for all fine faces
138     faceCells_.setSize(2*nCoarseFaces, -1);
139     fineAddressing_.setSize(localRestrictAddressing.size(), -1);
140     restrictAddressing_.setSize(localRestrictAddressing.size(), -1);
142     // All weights are equal to 1: integral matching
143     restrictWeights_.setSize(localRestrictAddressing.size(), 1.0);
145     labelList contents = neighboursTable.toc();
147     // Reset face counter for re-use
148     nCoarseFaces = 0;
150     // On master side, the owner addressing is stored in table of contents
151     forAll (contents, masterI)
152     {
153         SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
155         SLList<SLList<label> >& curFaceFaces =
156             faceFaceTable.find(contents[masterI])();
158         SLList<label>::iterator nbrsIter = curNbrs.begin();
159         SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
161         for
162         (
163             ;
164             nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
165             ++nbrsIter, ++faceFacesIter
166         )
167         {
168             faceCells_[nCoarseFaces] = contents[masterI];
170             for
171             (
172                 SLList<label>::iterator facesIter = faceFacesIter().begin();
173                 facesIter != faceFacesIter().end();
174                 ++facesIter
175             )
176             {
177                 fineAddressing_[facesIter()] = facesIter();
178                 restrictAddressing_[facesIter()] = nCoarseFaces;
179             }
181             nCoarseFaces++;
182         }
183     }
185     // On slave side, the owner addressing is stored in linked lists
186     forAll (contents, masterI)
187     {
188         SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
190         SLList<SLList<label> >& curFaceFaces =
191             faceFaceTable.find(contents[masterI])();
193         SLList<label>::iterator nbrsIter = curNbrs.begin();
194         SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
196         for
197         (
198             ;
199             nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
200             ++nbrsIter, ++faceFacesIter
201         )
202         {
203             faceCells_[nCoarseFaces] = nbrsIter();
205             for
206             (
207                 SLList<label>::iterator facesIter = faceFacesIter().begin();
208                 facesIter != faceFacesIter().end();
209                 ++facesIter
210             )
211             {
212                 fineAddressing_[facesIter() + sizeBy2] = facesIter() + sizeBy2;
213                 restrictAddressing_[facesIter() + sizeBy2] = nCoarseFaces;
214             }
216             nCoarseFaces++;
217         }
218     }
222 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
224 Foam::cyclicGAMGInterface::~cyclicGAMGInterface()
228 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
230 Foam::tmp<Foam::labelField> Foam::cyclicGAMGInterface::transfer
232     const Pstream::commsTypes,
233     const unallocLabelList& interfaceData
234 ) const
236     tmp<labelField> tpnf(new labelField(size()));
237     labelField& pnf = tpnf();
239     label sizeby2 = size()/2;
241     for (label facei=0; facei<sizeby2; facei++)
242     {
243         pnf[facei] = interfaceData[facei + sizeby2];
244         pnf[facei + sizeby2] = interfaceData[facei];
245     }
247     return tpnf;
251 Foam::tmp<Foam::labelField> Foam::cyclicGAMGInterface::internalFieldTransfer
253     const Pstream::commsTypes,
254     const unallocLabelList& iF
255 ) const
257     tmp<labelField> tpnf(new labelField(size()));
258     labelField& pnf = tpnf();
260     label sizeby2 = size()/2;
262     for (label facei=0; facei<sizeby2; facei++)
263     {
264         pnf[facei] = iF[faceCells_[facei + sizeby2]];
265         pnf[facei + sizeby2] = iF[faceCells_[facei]];
266     }
268     return tpnf;
272 // ************************************************************************* //