FreeFOAM The Cross-Platform CFD Toolkit
processorGAMGInterface.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
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.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "processorGAMGInterface.H"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
33  defineTypeNameAndDebug(processorGAMGInterface, 0);
35  (
36  GAMGInterface,
37  processorGAMGInterface,
38  lduInterface
39  );
40 }
41 
42 
43 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
44 
45 Foam::processorGAMGInterface::processorGAMGInterface
46 (
47  const lduInterface& fineInterface,
48  const labelField& localRestrictAddressing,
49  const labelField& neighbourRestrictAddressing
50 )
51 :
53  (
54  fineInterface,
55  localRestrictAddressing,
56  neighbourRestrictAddressing
57  ),
58  fineProcInterface_(refCast<const processorLduInterface>(fineInterface))
59 {
60  // Make a lookup table of entries for owner/neighbour
61  HashTable<SLList<label>, label, Hash<label> > neighboursTable
62  (
63  localRestrictAddressing.size()
64  );
65 
66  // Table of face-sets to be agglomerated
67  HashTable<SLList<SLList<label> >, label, Hash<label> > faceFaceTable
68  (
69  localRestrictAddressing.size()
70  );
71 
72  label nCoarseFaces = 0;
73 
74  forAll (localRestrictAddressing, ffi)
75  {
76  label curMaster = -1;
77  label curSlave = -1;
78 
79  // Do switching on master/slave indexes based on the owner/neighbour of
80  // the processor index such that both sides get the same answer.
81  if (myProcNo() < neighbProcNo())
82  {
83  // Master side
84  curMaster = localRestrictAddressing[ffi];
85  curSlave = neighbourRestrictAddressing[ffi];
86  }
87  else
88  {
89  // Slave side
90  curMaster = neighbourRestrictAddressing[ffi];
91  curSlave = localRestrictAddressing[ffi];
92  }
93 
94  // Look for the master cell. If it has already got a face,
95  // add the coefficient to the face. If not, create a new face.
96  if (neighboursTable.found(curMaster))
97  {
98  // Check all current neighbours to see if the current slave already
99  // exists and if so, add the fine face to the agglomeration.
100 
101  SLList<label>& curNbrs = neighboursTable.find(curMaster)();
102 
103  SLList<SLList<label> >& curFaceFaces =
104  faceFaceTable.find(curMaster)();
105 
106  bool nbrFound = false;
107 
108  SLList<label>::iterator nbrsIter = curNbrs.begin();
109 
110  SLList<SLList<label> >::iterator faceFacesIter =
111  curFaceFaces.begin();
112 
113  for
114  (
115  ;
116  nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
117  ++nbrsIter, ++faceFacesIter
118  )
119  {
120  if (nbrsIter() == curSlave)
121  {
122  nbrFound = true;
123  faceFacesIter().append(ffi);
124  break;
125  }
126  }
127 
128  if (!nbrFound)
129  {
130  curNbrs.append(curSlave);
131  curFaceFaces.append(ffi);
132 
133  // New coarse face created
134  nCoarseFaces++;
135  }
136  }
137  else
138  {
139  // This master has got no neighbours yet. Add a neighbour
140  // and a coefficient, thus creating a new face
141  neighboursTable.insert(curMaster, SLList<label>(curSlave));
142  faceFaceTable.insert(curMaster, SLList<SLList<label> >(ffi));
143 
144  // New coarse face created
145  nCoarseFaces++;
146  }
147  } // end for all fine faces
148 
149 
150 
151  faceCells_.setSize(nCoarseFaces, -1);
152  faceRestrictAddressing_.setSize(localRestrictAddressing.size());
153 
154  labelList contents = neighboursTable.toc();
155 
156  // Reset face counter for re-use
157  nCoarseFaces = 0;
158 
159  if (myProcNo() < neighbProcNo())
160  {
161  // On master side, the owner addressing is stored in table of contents
162  forAll (contents, masterI)
163  {
164  SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
165 
166  SLList<SLList<label> >& curFaceFaces =
167  faceFaceTable.find(contents[masterI])();
168 
169  SLList<label>::iterator nbrsIter = curNbrs.begin();
170 
171  SLList<SLList<label> >::iterator faceFacesIter =
172  curFaceFaces.begin();
173 
174  for
175  (
176  ;
177  nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
178  ++nbrsIter, ++faceFacesIter
179  )
180  {
181  faceCells_[nCoarseFaces] = contents[masterI];
182 
183  for
184  (
185  SLList<label>::iterator facesIter = faceFacesIter().begin();
186  facesIter != faceFacesIter().end();
187  ++facesIter
188  )
189  {
190  faceRestrictAddressing_[facesIter()] = nCoarseFaces;
191  }
192 
193  nCoarseFaces++;
194  }
195  }
196  }
197  else
198  {
199  // On slave side, the owner addressing is stored in linked lists
200  forAll (contents, masterI)
201  {
202  SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
203 
204  SLList<SLList<label> >& curFaceFaces =
205  faceFaceTable.find(contents[masterI])();
206 
207  SLList<label>::iterator nbrsIter = curNbrs.begin();
208 
209  SLList<SLList<label> >::iterator faceFacesIter =
210  curFaceFaces.begin();
211 
212  for
213  (
214  ;
215  nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
216  ++nbrsIter, ++faceFacesIter
217  )
218  {
219  faceCells_[nCoarseFaces] = nbrsIter();
220 
221  for
222  (
223  SLList<label>::iterator facesIter = faceFacesIter().begin();
224  facesIter != faceFacesIter().end();
225  ++facesIter
226  )
227  {
228  faceRestrictAddressing_[facesIter()] = nCoarseFaces;
229  }
230 
231  nCoarseFaces++;
232  }
233  }
234  }
235 }
236 
237 
238 // * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
239 
241 {}
242 
243 
244 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
245 
247 (
248  const Pstream::commsTypes commsType,
249  const unallocLabelList& interfaceData
250 ) const
251 {
252  send(commsType, interfaceData);
253 }
254 
255 
257 (
258  const Pstream::commsTypes commsType,
259  const unallocLabelList& interfaceData
260 ) const
261 {
262  return receive<label>(commsType, this->size());
263 }
264 
265 
267 (
268  const Pstream::commsTypes commsType,
269  const unallocLabelList& iF
270 ) const
271 {
272  send(commsType, interfaceInternalField(iF)());
273 }
274 
275 
277 (
278  const Pstream::commsTypes commsType,
279  const unallocLabelList& iF
280 ) const
281 {
282  return receive<label>(commsType, this->size());
283 }
284 
285 
286 // ************************ vim: set sw=4 sts=4 et: ************************ //