FreeFOAM The Cross-Platform CFD Toolkit
cellMapper.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 "cellMapper.H"
28 #include <OpenFOAM/polyMesh.H>
29 #include <OpenFOAM/mapPolyMesh.H>
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 
34 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35 
36 void Foam::cellMapper::calcAddressing() const
37 {
38  if
39  (
40  directAddrPtr_
41  || interpolationAddrPtr_
42  || weightsPtr_
43  || insertedCellLabelsPtr_
44  )
45  {
46  FatalErrorIn("void cellMapper::calcAddressing() const")
47  << "Addressing already calculated."
48  << abort(FatalError);
49  }
50 
51  if (direct())
52  {
53  // Direct addressing, no weights
54 
55  directAddrPtr_ = new labelList(mpm_.cellMap());
56  labelList& directAddr = *directAddrPtr_;
57 
58  // Not necessary to resize the list as there are no retired cells
59  // directAddr.setSize(mesh_.nCells());
60 
61  insertedCellLabelsPtr_ = new labelList(mesh_.nCells());
62  labelList& insertedCells = *insertedCellLabelsPtr_;
63 
64  label nInsertedCells = 0;
65 
66  forAll (directAddr, cellI)
67  {
68  if (directAddr[cellI] < 0)
69  {
70  // Found inserted cell
71  directAddr[cellI] = 0;
72  insertedCells[nInsertedCells] = cellI;
73  nInsertedCells++;
74  }
75  }
76 
77  insertedCells.setSize(nInsertedCells);
78  }
79  else
80  {
81  // Interpolative addressing
82 
83  interpolationAddrPtr_ = new labelListList(mesh_.nCells());
84  labelListList& addr = *interpolationAddrPtr_;
85 
86  weightsPtr_ = new scalarListList(mesh_.nCells());
87  scalarListList& w = *weightsPtr_;
88 
89  const List<objectMap>& cfp = mpm_.cellsFromPointsMap();
90 
91  forAll (cfp, cfpI)
92  {
93  // Get addressing
94  const labelList& mo = cfp[cfpI].masterObjects();
95 
96  label cellI = cfp[cfpI].index();
97 
98  if (addr[cellI].size())
99  {
100  FatalErrorIn("void cellMapper::calcAddressing() const")
101  << "Master cell " << cellI
102  << " mapped from point cells " << mo
103  << " already destination of mapping." << abort(FatalError);
104  }
105 
106  // Map from masters, uniform weights
107  addr[cellI] = mo;
108  w[cellI] = scalarList(mo.size(), 1.0/mo.size());
109  }
110 
111  const List<objectMap>& cfe = mpm_.cellsFromEdgesMap();
112 
113  forAll (cfe, cfeI)
114  {
115  // Get addressing
116  const labelList& mo = cfe[cfeI].masterObjects();
117 
118  label cellI = cfe[cfeI].index();
119 
120  if (addr[cellI].size())
121  {
122  FatalErrorIn("void cellMapper::calcAddressing() const")
123  << "Master cell " << cellI
124  << " mapped from edge cells " << mo
125  << " already destination of mapping." << abort(FatalError);
126  }
127 
128  // Map from masters, uniform weights
129  addr[cellI] = mo;
130  w[cellI] = scalarList(mo.size(), 1.0/mo.size());
131  }
132 
133  const List<objectMap>& cff = mpm_.cellsFromFacesMap();
134 
135  forAll (cff, cffI)
136  {
137  // Get addressing
138  const labelList& mo = cff[cffI].masterObjects();
139 
140  label cellI = cff[cffI].index();
141 
142  if (addr[cellI].size())
143  {
144  FatalErrorIn("void cellMapper::calcAddressing() const")
145  << "Master cell " << cellI
146  << " mapped from face cells " << mo
147  << " already destination of mapping." << abort(FatalError);
148  }
149 
150  // Map from masters, uniform weights
151  addr[cellI] = mo;
152  w[cellI] = scalarList(mo.size(), 1.0/mo.size());
153  }
154 
155  const List<objectMap>& cfc = mpm_.cellsFromCellsMap();
156 
157  forAll (cfc, cfcI)
158  {
159  // Get addressing
160  const labelList& mo = cfc[cfcI].masterObjects();
161 
162  label cellI = cfc[cfcI].index();
163 
164  if (addr[cellI].size())
165  {
166  FatalErrorIn("void cellMapper::calcAddressing() const")
167  << "Master cell " << cellI
168  << " mapped from cell cells " << mo
169  << " already destination of mapping." << abort(FatalError);
170  }
171 
172  // Map from masters, uniform weights
173  addr[cellI] = mo;
174  w[cellI] = scalarList(mo.size(), 1.0/mo.size());
175  }
176 
177 
178  // Do mapped faces. Note that can already be set from cellsFromCells
179  // so check if addressing size still zero.
180 
181  const labelList& cm = mpm_.cellMap();
182 
183  forAll (cm, cellI)
184  {
185  if (cm[cellI] > -1 && addr[cellI].empty())
186  {
187  // Mapped from a single cell
188  addr[cellI] = labelList(1, cm[cellI]);
189  w[cellI] = scalarList(1, 1.0);
190  }
191  }
192 
193  // Grab inserted points (for them the size of addressing is still zero)
194 
195  insertedCellLabelsPtr_ = new labelList(mesh_.nCells());
196  labelList& insertedCells = *insertedCellLabelsPtr_;
197 
198  label nInsertedCells = 0;
199 
200  forAll (addr, cellI)
201  {
202  if (addr[cellI].empty())
203  {
204  // Mapped from a dummy cell
205  addr[cellI] = labelList(1, 0);
206  w[cellI] = scalarList(1, 1.0);
207 
208  insertedCells[nInsertedCells] = cellI;
209  nInsertedCells++;
210  }
211  }
212 
213  insertedCells.setSize(nInsertedCells);
214  }
215 }
216 
217 
218 void Foam::cellMapper::clearOut()
219 {
220  deleteDemandDrivenData(directAddrPtr_);
221  deleteDemandDrivenData(interpolationAddrPtr_);
222  deleteDemandDrivenData(weightsPtr_);
223  deleteDemandDrivenData(insertedCellLabelsPtr_);
224 }
225 
226 
227 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
228 
229 // Construct from components
230 Foam::cellMapper::cellMapper(const mapPolyMesh& mpm)
231 :
232  mesh_(mpm.mesh()),
233  mpm_(mpm),
234  insertedCells_(true),
235  direct_(false),
236  directAddrPtr_(NULL),
237  interpolationAddrPtr_(NULL),
238  weightsPtr_(NULL),
239  insertedCellLabelsPtr_(NULL)
240 {
241  // Check for possibility of direct mapping
242  if
243  (
244  mpm_.cellsFromPointsMap().empty()
245  && mpm_.cellsFromEdgesMap().empty()
246  && mpm_.cellsFromFacesMap().empty()
247  && mpm_.cellsFromCellsMap().empty()
248  )
249  {
250  direct_ = true;
251  }
252  else
253  {
254  direct_ = false;
255  }
256 
257  // Check for inserted cells
258  if (direct_ && (mpm_.cellMap().empty() || min(mpm_.cellMap()) > -1))
259  {
260  insertedCells_ = false;
261  }
262  else
263  {
264  // Need to check all 3 lists to see if there are inserted cells
265  // with no owner
266 
267  // Make a copy of the cell map, add the entried for cells from points,
268  // cells from edges and cells from faces and check for left-overs
269  labelList cm(mesh_.nCells(), -1);
270 
271  const List<objectMap>& cfp = mpm_.cellsFromPointsMap();
272 
273  forAll (cfp, cfpI)
274  {
275  cm[cfp[cfpI].index()] = 0;
276  }
277 
278  const List<objectMap>& cfe = mpm_.cellsFromEdgesMap();
279 
280  forAll (cfe, cfeI)
281  {
282  cm[cfe[cfeI].index()] = 0;
283  }
284 
285  const List<objectMap>& cff = mpm_.cellsFromFacesMap();
286 
287  forAll (cff, cffI)
288  {
289  cm[cff[cffI].index()] = 0;
290  }
291 
292  const List<objectMap>& cfc = mpm_.cellsFromCellsMap();
293 
294  forAll (cfc, cfcI)
295  {
296  cm[cfc[cfcI].index()] = 0;
297  }
298 
299  if (min(cm) < 0)
300  {
301  insertedCells_ = true;
302  }
303  }
304 }
305 
306 
307 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
308 
310 {
311  clearOut();
312 }
313 
314 
315 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
316 
317 Foam::label Foam::cellMapper::size() const
318 {
319  return mpm_.cellMap().size();
320 }
321 
322 
324 {
325  return mpm_.nOldCells();
326 }
327 
328 
330 {
331  if (!direct())
332  {
334  (
335  "const unallocLabelList& cellMapper::directAddressing() const"
336  ) << "Requested direct addressing for an interpolative mapper."
337  << abort(FatalError);
338  }
339 
340  if (!insertedObjects())
341  {
342  // No inserted cells. Re-use cellMap
343  return mpm_.cellMap();
344  }
345  else
346  {
347  if (!directAddrPtr_)
348  {
349  calcAddressing();
350  }
351 
352  return *directAddrPtr_;
353  }
354 }
355 
356 
358 {
359  if (direct())
360  {
362  (
363  "const labelListList& cellMapper::addressing() const"
364  ) << "Requested interpolative addressing for a direct mapper."
365  << abort(FatalError);
366  }
367 
368  if (!interpolationAddrPtr_)
369  {
370  calcAddressing();
371  }
372 
373  return *interpolationAddrPtr_;
374 }
375 
376 
378 {
379  if (direct())
380  {
382  (
383  "const scalarListList& cellMapper::weights() const"
384  ) << "Requested interpolative weights for a direct mapper."
385  << abort(FatalError);
386  }
387 
388  if (!weightsPtr_)
389  {
390  calcAddressing();
391  }
392 
393  return *weightsPtr_;
394 }
395 
396 
398 {
399  if (!insertedCellLabelsPtr_)
400  {
401  if (!insertedObjects())
402  {
403  // There are no inserted cells
404  insertedCellLabelsPtr_ = new labelList(0);
405  }
406  else
407  {
408  calcAddressing();
409  }
410  }
411 
412  return *insertedCellLabelsPtr_;
413 }
414 
415 
416 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
417 
418 
419 // * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
420 
421 
422 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
423 
424 
425 // ************************ vim: set sw=4 sts=4 et: ************************ //