FreeFOAM The Cross-Platform CFD Toolkit
cyclicGAMGInterface.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 "cyclicGAMGInterface.H"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
33  defineTypeNameAndDebug(cyclicGAMGInterface, 0);
35  (
36  GAMGInterface,
37  cyclicGAMGInterface,
38  lduInterface
39  );
40 }
41 
42 
43 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
44 
45 Foam::cyclicGAMGInterface::cyclicGAMGInterface
46 (
47  const lduInterface& fineInterface,
48  const labelField& localRestrictAddressing,
49  const labelField& neighbourRestrictAddressing
50 )
51 :
53  (
54  fineInterface,
55  localRestrictAddressing,
56  neighbourRestrictAddressing
57  ),
58  fineCyclicInterface_(refCast<const cyclicLduInterface>(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  label sizeBy2 = localRestrictAddressing.size()/2;
75 
76  for (label ffi=0; ffi<sizeBy2; ffi++)
77  {
78  label curMaster = localRestrictAddressing[ffi];
79  label curSlave = localRestrictAddressing[ffi + sizeBy2];
80 
81  // Look for the master cell. If it has already got a face,
82  // add the coefficient to the face. If not, create a new
83  // face.
84  if (neighboursTable.found(curMaster))
85  {
86  // Check all current neighbours to see if the current
87  // slave already exists. If so, add the coefficient.
88 
89  SLList<label>& curNbrs = neighboursTable.find(curMaster)();
90 
91  SLList<SLList<label> >& curFaceFaces =
92  faceFaceTable.find(curMaster)();
93 
94  bool nbrFound = false;
95 
96  SLList<label>::iterator nbrsIter = curNbrs.begin();
97 
98  SLList<SLList<label> >::iterator faceFacesIter =
99  curFaceFaces.begin();
100 
101  for
102  (
103  ;
104  nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
105  ++nbrsIter, ++faceFacesIter
106  )
107  {
108  if (nbrsIter() == curSlave)
109  {
110  nbrFound = true;
111  faceFacesIter().append(ffi);
112  break;
113  }
114  }
115 
116  if (!nbrFound)
117  {
118  curNbrs.append(curSlave);
119  curFaceFaces.append(ffi);
120 
121  // New coarse face created
122  nCoarseFaces++;
123  }
124  }
125  else
126  {
127  // This master has got no neighbours yet. Add a neighbour
128  // and a coefficient, thus creating a new face
129  neighboursTable.insert(curMaster, SLList<label>(curSlave));
130  faceFaceTable.insert(curMaster, SLList<SLList<label> >(ffi));
131 
132  // New coarse face created
133  nCoarseFaces++;
134  }
135  } // end for all fine faces
136 
137 
138  faceCells_.setSize(2*nCoarseFaces, -1);
139  faceRestrictAddressing_.setSize(localRestrictAddressing.size(), -1);
140 
141  labelList contents = neighboursTable.toc();
142 
143  // Reset face counter for re-use
144  nCoarseFaces = 0;
145 
146  // On master side, the owner addressing is stored in table of contents
147  forAll (contents, masterI)
148  {
149  SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
150 
151  SLList<SLList<label> >& curFaceFaces =
152  faceFaceTable.find(contents[masterI])();
153 
154  SLList<label>::iterator nbrsIter = curNbrs.begin();
155  SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
156 
157  for
158  (
159  ;
160  nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
161  ++nbrsIter, ++faceFacesIter
162  )
163  {
164  faceCells_[nCoarseFaces] = contents[masterI];
165 
166  for
167  (
168  SLList<label>::iterator facesIter = faceFacesIter().begin();
169  facesIter != faceFacesIter().end();
170  ++facesIter
171  )
172  {
173  faceRestrictAddressing_[facesIter()] = nCoarseFaces;
174  }
175 
176  nCoarseFaces++;
177  }
178  }
179 
180  // On slave side, the owner addressing is stored in linked lists
181  forAll (contents, masterI)
182  {
183  SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
184 
185  SLList<SLList<label> >& curFaceFaces =
186  faceFaceTable.find(contents[masterI])();
187 
188  SLList<label>::iterator nbrsIter = curNbrs.begin();
189  SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
190 
191  for
192  (
193  ;
194  nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
195  ++nbrsIter, ++faceFacesIter
196  )
197  {
198  faceCells_[nCoarseFaces] = nbrsIter();
199 
200  for
201  (
202  SLList<label>::iterator facesIter = faceFacesIter().begin();
203  facesIter != faceFacesIter().end();
204  ++facesIter
205  )
206  {
207  faceRestrictAddressing_[facesIter() + sizeBy2] = nCoarseFaces;
208  }
209 
210  nCoarseFaces++;
211  }
212  }
213 }
214 
215 
216 // * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
217 
219 {}
220 
221 
222 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
223 
225 (
226  const Pstream::commsTypes,
227  const unallocLabelList& interfaceData
228 ) const
229 {
230  tmp<labelField> tpnf(new labelField(size()));
231  labelField& pnf = tpnf();
232 
233  label sizeby2 = size()/2;
234 
235  for (label facei=0; facei<sizeby2; facei++)
236  {
237  pnf[facei] = interfaceData[facei + sizeby2];
238  pnf[facei + sizeby2] = interfaceData[facei];
239  }
240 
241  return tpnf;
242 }
243 
244 
246 (
247  const Pstream::commsTypes,
248  const unallocLabelList& iF
249 ) const
250 {
251  tmp<labelField> tpnf(new labelField(size()));
252  labelField& pnf = tpnf();
253 
254  label sizeby2 = size()/2;
255 
256  for (label facei=0; facei<sizeby2; facei++)
257  {
258  pnf[facei] = iF[faceCells_[facei + sizeby2]];
259  pnf[facei + sizeby2] = iF[faceCells_[facei]];
260  }
261 
262  return tpnf;
263 }
264 
265 
266 // ************************ vim: set sw=4 sts=4 et: ************************ //