Forward compatibility: flex
[foam-extend-3.2.git] / src / foam / matrices / lduMatrix / solvers / GAMG / interfaces / processorGAMGInterface / processorGAMGInterface.C
blob315c6e888a45c7234c36a910d27a95454fe3c24c
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 "processorGAMGInterface.H"
27 #include "addToRunTimeSelectionTable.H"
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 namespace Foam
33     defineTypeNameAndDebug(processorGAMGInterface, 0);
34     addToRunTimeSelectionTable
35     (
36         GAMGInterface,
37         processorGAMGInterface,
38         lduInterface
39     );
43 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
45 Foam::processorGAMGInterface::processorGAMGInterface
47     const lduPrimitiveMesh& lduMesh,
48     const lduInterface& fineInterface,
49     const labelField& localRestrictAddressing,
50     const labelField& neighbourRestrictAddressing
53     GAMGInterface(lduMesh),
54     fineProcInterface_(refCast<const processorLduInterface>(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     forAll (localRestrictAddressing, ffi)
71     {
72         label curMaster = -1;
73         label curSlave = -1;
75         // Do switching on master/slave indexes based on the owner/neighbour of
76         // the processor index such that both sides get the same answer.
77         if (myProcNo() < neighbProcNo())
78         {
79             // Master side
80             curMaster = localRestrictAddressing[ffi];
81             curSlave = neighbourRestrictAddressing[ffi];
82         }
83         else
84         {
85             // Slave side
86             curMaster = neighbourRestrictAddressing[ffi];
87             curSlave = localRestrictAddressing[ffi];
88         }
90         // Look for the master cell.  If it has already got a face,
91         // add the coefficient to the face.  If not, create a new face.
92         if (neighboursTable.found(curMaster))
93         {
94             // Check all current neighbours to see if the current slave already
95             // exists and if so, add the fine face to the agglomeration.
97             SLList<label>& curNbrs = neighboursTable.find(curMaster)();
99             SLList<SLList<label> >& curFaceFaces =
100                 faceFaceTable.find(curMaster)();
102             bool nbrFound = false;
104             SLList<label>::iterator nbrsIter = curNbrs.begin();
106             SLList<SLList<label> >::iterator faceFacesIter =
107                 curFaceFaces.begin();
109             for
110             (
111                 ;
112                 nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
113                 ++nbrsIter, ++faceFacesIter
114             )
115             {
116                 if (nbrsIter() == curSlave)
117                 {
118                     nbrFound = true;
119                     faceFacesIter().append(ffi);
120                     break;
121                 }
122             }
124             if (!nbrFound)
125             {
126                 curNbrs.append(curSlave);
127                 curFaceFaces.append(SLList<label>(ffi));
129                 // New coarse face created
130                 nCoarseFaces++;
131             }
132         }
133         else
134         {
135             // This master has got no neighbours yet.  Add a neighbour
136             // and a coefficient, thus creating a new face
137             neighboursTable.insert(curMaster, SLList<label>(curSlave));
138             faceFaceTable.insert
139             (
140                 curMaster,
141                 SLList<SLList<label> >(SLList<label>(ffi))
142             );
144             // New coarse face created
145             nCoarseFaces++;
146         }
147     } // end for all fine faces
150     faceCells_.setSize(nCoarseFaces, -1);
151     fineAddressing_.setSize(localRestrictAddressing.size(), -1);
152     restrictAddressing_.setSize(localRestrictAddressing.size(), -1);
154     // All weights are equal to 1: integral matching
155     restrictWeights_.setSize(localRestrictAddressing.size(), 1.0);
157     labelList contents = neighboursTable.toc();
159     // Sort makes sure the order is identical on both sides.
160     // HJ, 20/Feb.2009
161     sort(contents);
163     // Reset face counter for re-use
164     nCoarseFaces = 0;
166     if (myProcNo() < neighbProcNo())
167     {
168         // On master side, the owner addressing is stored in table of contents
169         forAll (contents, masterI)
170         {
171             SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
173             SLList<SLList<label> >& curFaceFaces =
174                 faceFaceTable.find(contents[masterI])();
176             SLList<label>::iterator nbrsIter = curNbrs.begin();
178             SLList<SLList<label> >::iterator faceFacesIter =
179                 curFaceFaces.begin();
181             for
182             (
183                 ;
184                 nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
185                 ++nbrsIter, ++faceFacesIter
186             )
187             {
188                 faceCells_[nCoarseFaces] = contents[masterI];
190                 for
191                 (
192                     SLList<label>::iterator facesIter = faceFacesIter().begin();
193                     facesIter != faceFacesIter().end();
194                     ++facesIter
195                 )
196                 {
197                     fineAddressing_[facesIter()] = facesIter();
198                     restrictAddressing_[facesIter()] = nCoarseFaces;
199                 }
201                 nCoarseFaces++;
202             }
203         }
204     }
205     else
206     {
207         // On slave side, the owner addressing is stored in linked lists
208         forAll (contents, masterI)
209         {
210             SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
212             SLList<SLList<label> >& curFaceFaces =
213                 faceFaceTable.find(contents[masterI])();
215             SLList<label>::iterator nbrsIter = curNbrs.begin();
217             SLList<SLList<label> >::iterator faceFacesIter =
218                 curFaceFaces.begin();
220             for
221             (
222                 ;
223                 nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
224                 ++nbrsIter, ++faceFacesIter
225             )
226             {
227                 faceCells_[nCoarseFaces] = nbrsIter();
229                 for
230                 (
231                     SLList<label>::iterator facesIter = faceFacesIter().begin();
232                     facesIter != faceFacesIter().end();
233                     ++facesIter
234                 )
235                 {
236                     fineAddressing_[facesIter()] = facesIter();
237                     restrictAddressing_[facesIter()] = nCoarseFaces;
238                 }
240                 nCoarseFaces++;
241             }
242         }
243     }
247 // * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
249 Foam::processorGAMGInterface::~processorGAMGInterface()
253 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
255 void Foam::processorGAMGInterface::initTransfer
257     const Pstream::commsTypes commsType,
258     const unallocLabelList& interfaceData
259 ) const
261     send(commsType, interfaceData);
265 Foam::tmp<Foam::labelField> Foam::processorGAMGInterface::transfer
267     const Pstream::commsTypes commsType,
268     const unallocLabelList& interfaceData
269 ) const
271     return receive<label>(commsType, this->size());
275 void Foam::processorGAMGInterface::initInternalFieldTransfer
277     const Pstream::commsTypes commsType,
278     const unallocLabelList& iF
279 ) const
281     send(commsType, interfaceInternalField(iF)());
285 Foam::tmp<Foam::labelField> Foam::processorGAMGInterface::internalFieldTransfer
287     const Pstream::commsTypes commsType,
288     const unallocLabelList&
289 ) const
291     return receive<label>(commsType, this->size());
295 // ************************************************************************* //