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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "cellMapper.H"
29 #include "demandDrivenData.H"
30 #include "polyMesh.H"
31 #include "mapPolyMesh.H"
32 
33 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34 
35 void Foam::cellMapper::calcAddressing() const
36 {
37  if
38  (
39  directAddrPtr_
40  || interpolationAddrPtr_
41  || weightsPtr_
42  || insertedCellLabelsPtr_
43  )
44  {
46  << "Addressing already calculated."
47  << abort(FatalError);
48  }
49 
50  if (direct())
51  {
52  // Direct addressing, no weights
53 
54  directAddrPtr_ = new labelList(mpm_.cellMap());
55  labelList& directAddr = *directAddrPtr_;
56 
57  // Not necessary to resize the list as there are no retired cells
58  // directAddr.setSize(mesh_.nCells());
59 
60  insertedCellLabelsPtr_ = new labelList(mesh_.nCells());
61  labelList& insertedCells = *insertedCellLabelsPtr_;
62 
63  label nInsertedCells = 0;
64 
65  forAll(directAddr, celli)
66  {
67  if (directAddr[celli] < 0)
68  {
69  // Found inserted cell
70  directAddr[celli] = 0;
71  insertedCells[nInsertedCells] = celli;
72  nInsertedCells++;
73  }
74  }
75 
76  insertedCells.setSize(nInsertedCells);
77  }
78  else
79  {
80  // Interpolative addressing
81 
82  interpolationAddrPtr_ = new labelListList(mesh_.nCells());
83  labelListList& addr = *interpolationAddrPtr_;
84 
85  weightsPtr_ = new scalarListList(mesh_.nCells());
86  scalarListList& w = *weightsPtr_;
87 
88  const List<objectMap>& cfp = mpm_.cellsFromPointsMap();
89 
90  forAll(cfp, cfpI)
91  {
92  // Get addressing
93  const labelList& mo = cfp[cfpI].masterObjects();
94 
95  label celli = cfp[cfpI].index();
96 
97  if (addr[celli].size())
98  {
100  << "Master cell " << celli
101  << " mapped from point cells " << mo
102  << " already destination of mapping." << abort(FatalError);
103  }
104 
105  // Map from masters, uniform weights
106  addr[celli] = mo;
107  w[celli] = scalarList(mo.size(), 1.0/mo.size());
108  }
109 
110  const List<objectMap>& cfe = mpm_.cellsFromEdgesMap();
111 
112  forAll(cfe, cfeI)
113  {
114  // Get addressing
115  const labelList& mo = cfe[cfeI].masterObjects();
116 
117  label celli = cfe[cfeI].index();
118 
119  if (addr[celli].size())
120  {
122  << "Master cell " << celli
123  << " mapped from edge cells " << mo
124  << " already destination of mapping." << abort(FatalError);
125  }
126 
127  // Map from masters, uniform weights
128  addr[celli] = mo;
129  w[celli] = scalarList(mo.size(), 1.0/mo.size());
130  }
131 
132  const List<objectMap>& cff = mpm_.cellsFromFacesMap();
133 
134  forAll(cff, cffI)
135  {
136  // Get addressing
137  const labelList& mo = cff[cffI].masterObjects();
138 
139  label celli = cff[cffI].index();
140 
141  if (addr[celli].size())
142  {
144  << "Master cell " << celli
145  << " mapped from face cells " << mo
146  << " already destination of mapping." << abort(FatalError);
147  }
148 
149  // Map from masters, uniform weights
150  addr[celli] = mo;
151  w[celli] = scalarList(mo.size(), 1.0/mo.size());
152  }
153 
154  // Volume conservative mapping if possible
155 
156  const List<objectMap>& cfc = mpm_.cellsFromCellsMap();
157 
158  forAll(cfc, cfcI)
159  {
160  // Get addressing
161  const labelList& mo = cfc[cfcI].masterObjects();
162 
163  label celli = cfc[cfcI].index();
164 
165  if (addr[celli].size())
166  {
168  << "Master cell " << celli
169  << " mapped from cell cells " << mo
170  << " already destination of mapping."
171  << abort(FatalError);
172  }
173 
174  // Map from masters
175  addr[celli] = mo;
176  }
177 
178  if (mpm_.hasOldCellVolumes())
179  {
180  // Volume weighted
181 
182  const scalarField& V = mpm_.oldCellVolumes();
183 
184  if (V.size() != sizeBeforeMapping())
185  {
187  << "cellVolumes size " << V.size()
188  << " is not the old number of cells " << sizeBeforeMapping()
189  << ". Are your cellVolumes already mapped?"
190  << " (new number of cells " << size() << ")"
191  << abort(FatalError);
192  }
193 
194  forAll(cfc, cfcI)
195  {
196  const labelList& mo = cfc[cfcI].masterObjects();
197 
198  label celli = cfc[cfcI].index();
199 
200  w[celli].setSize(mo.size());
201 
202  if (mo.size())
203  {
204  scalar sumV = 0;
205  forAll(mo, ci)
206  {
207  w[celli][ci] = V[mo[ci]];
208  sumV += V[mo[ci]];
209  }
210  if (sumV > VSMALL)
211  {
212  forAll(mo, ci)
213  {
214  w[celli][ci] /= sumV;
215  }
216  }
217  else
218  {
219  // Exception: zero volume. Use uniform mapping
220  w[celli] = scalarList(mo.size(), 1.0/mo.size());
221  }
222  }
223  }
224  }
225  else
226  {
227  // Uniform weighted
228 
229  forAll(cfc, cfcI)
230  {
231  const labelList& mo = cfc[cfcI].masterObjects();
232 
233  label celli = cfc[cfcI].index();
234 
235  w[celli] = scalarList(mo.size(), 1.0/mo.size());
236  }
237  }
238 
239 
240  // Do mapped faces. Note that can already be set from cellsFromCells
241  // so check if addressing size still zero.
242 
243  const labelList& cm = mpm_.cellMap();
244 
245  forAll(cm, celli)
246  {
247  if (cm[celli] > -1 && addr[celli].empty())
248  {
249  // Mapped from a single cell
250  addr[celli] = labelList(1, cm[celli]);
251  w[celli] = scalarList(1, 1.0);
252  }
253  }
254 
255  // Grab inserted points (for them the size of addressing is still zero)
256 
257  insertedCellLabelsPtr_ = new labelList(mesh_.nCells());
258  labelList& insertedCells = *insertedCellLabelsPtr_;
259 
260  label nInsertedCells = 0;
261 
262  forAll(addr, celli)
263  {
264  if (addr[celli].empty())
265  {
266  // Mapped from a dummy cell
267  addr[celli] = labelList(1, Zero);
268  w[celli] = scalarList(1, scalar(1));
269 
270  insertedCells[nInsertedCells] = celli;
271  nInsertedCells++;
272  }
273  }
274 
275  insertedCells.setSize(nInsertedCells);
276  }
277 }
278 
279 
280 void Foam::cellMapper::clearOut()
281 {
282  deleteDemandDrivenData(directAddrPtr_);
283  deleteDemandDrivenData(interpolationAddrPtr_);
284  deleteDemandDrivenData(weightsPtr_);
285  deleteDemandDrivenData(insertedCellLabelsPtr_);
286 }
287 
288 
289 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
290 
291 Foam::cellMapper::cellMapper(const mapPolyMesh& mpm)
292 :
293  mesh_(mpm.mesh()),
294  mpm_(mpm),
295  insertedCells_(true),
296  direct_(false),
297  directAddrPtr_(nullptr),
298  interpolationAddrPtr_(nullptr),
299  weightsPtr_(nullptr),
300  insertedCellLabelsPtr_(nullptr)
301 {
302  // Check for possibility of direct mapping
303  if
304  (
305  mpm_.cellsFromPointsMap().empty()
306  && mpm_.cellsFromEdgesMap().empty()
307  && mpm_.cellsFromFacesMap().empty()
308  && mpm_.cellsFromCellsMap().empty()
309  )
310  {
311  direct_ = true;
312  }
313  else
314  {
315  direct_ = false;
316  }
317 
318  // Check for inserted cells
319  if (direct_ && (mpm_.cellMap().empty() || min(mpm_.cellMap()) > -1))
320  {
321  insertedCells_ = false;
322  }
323  else
324  {
325  // Need to check all 3 lists to see if there are inserted cells
326  // with no owner
327 
328  // Make a copy of the cell map, add the entried for cells from points,
329  // cells from edges and cells from faces and check for left-overs
330  labelList cm(mesh_.nCells(), -1);
331 
332  const List<objectMap>& cfp = mpm_.cellsFromPointsMap();
333 
334  forAll(cfp, cfpI)
335  {
336  cm[cfp[cfpI].index()] = 0;
337  }
338 
339  const List<objectMap>& cfe = mpm_.cellsFromEdgesMap();
340 
341  forAll(cfe, cfeI)
342  {
343  cm[cfe[cfeI].index()] = 0;
344  }
345 
346  const List<objectMap>& cff = mpm_.cellsFromFacesMap();
347 
348  forAll(cff, cffI)
349  {
350  cm[cff[cffI].index()] = 0;
351  }
352 
353  const List<objectMap>& cfc = mpm_.cellsFromCellsMap();
354 
355  forAll(cfc, cfcI)
356  {
357  cm[cfc[cfcI].index()] = 0;
358  }
359 
360  if (min(cm) < 0)
361  {
362  insertedCells_ = true;
363  }
364  }
365 }
366 
367 
368 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
369 
371 {
372  clearOut();
373 }
374 
375 
376 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
377 
378 Foam::label Foam::cellMapper::size() const
379 {
380  return mpm_.cellMap().size();
381 }
382 
383 
385 {
386  return mpm_.nOldCells();
387 }
388 
389 
391 {
392  if (!direct())
393  {
395  << "Requested direct addressing for an interpolative mapper."
396  << abort(FatalError);
397  }
398 
399  if (!insertedObjects())
400  {
401  // No inserted cells. Re-use cellMap
402  return mpm_.cellMap();
403  }
404  else
405  {
406  if (!directAddrPtr_)
407  {
408  calcAddressing();
409  }
410 
411  return *directAddrPtr_;
412  }
413 }
414 
415 
417 {
418  if (direct())
419  {
421  << "Requested interpolative addressing for a direct mapper."
422  << abort(FatalError);
423  }
424 
425  if (!interpolationAddrPtr_)
426  {
427  calcAddressing();
428  }
429 
430  return *interpolationAddrPtr_;
431 }
432 
433 
435 {
436  if (direct())
437  {
439  << "Requested interpolative weights for a direct mapper."
440  << abort(FatalError);
441  }
442 
443  if (!weightsPtr_)
444  {
445  calcAddressing();
446  }
447 
448  return *weightsPtr_;
449 }
450 
451 
453 {
454  if (!insertedCellLabelsPtr_)
455  {
456  if (!insertedObjects())
457  {
458  // There are no inserted cells
459  insertedCellLabelsPtr_ = new labelList(0);
460  }
461  else
462  {
463  calcAddressing();
464  }
465  }
466 
467  return *insertedCellLabelsPtr_;
468 }
469 
470 
471 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::scalarListList
List< scalarList > scalarListList
A List of scalarList.
Definition: scalarList.H:66
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::scalarList
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:64
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
mapPolyMesh.H
Foam::cellMapper::directAddressing
virtual const labelUList & directAddressing() const
Return direct addressing.
Definition: cellMapper.C:390
Foam::mapPolyMesh::cellsFromPointsMap
const List< objectMap > & cellsFromPointsMap() const
Cells inflated from points.
Definition: mapPolyMesh.H:441
Foam::cellMapper::~cellMapper
virtual ~cellMapper()
Destructor.
Definition: cellMapper.C:370
polyMesh.H
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
Foam::cellMapper::direct
virtual bool direct() const
Is the mapping direct.
Definition: cellMapper.H:129
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::deleteDemandDrivenData
void deleteDemandDrivenData(DataPtr &dataPtr)
Definition: demandDrivenData.H:42
cellMapper.H
Foam::primitiveMesh::nCells
label nCells() const noexcept
Number of mesh cells.
Definition: primitiveMeshI.H:96
Foam::cellMapper::addressing
virtual const labelListList & addressing() const
Return interpolated addressing.
Definition: cellMapper.C:416
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::mapPolyMesh::cellsFromEdgesMap
const List< objectMap > & cellsFromEdgesMap() const
Cells inflated from edges.
Definition: mapPolyMesh.H:447
Foam::FatalError
error FatalError
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::cellMapper::sizeBeforeMapping
virtual label sizeBeforeMapping() const
Return size before mapping.
Definition: cellMapper.C:384
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::mapPolyMesh::oldCellVolumes
const scalarField & oldCellVolumes() const
Definition: mapPolyMesh.H:651
Foam::cellMapper::weights
virtual const scalarListList & weights() const
Return interpolaion weights.
Definition: cellMapper.C:434
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
Foam::cellMapper::size
virtual label size() const
Return size.
Definition: cellMapper.C:378
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::List< label >
Foam::UList< label >
Foam::mapPolyMesh::hasOldCellVolumes
bool hasOldCellVolumes() const
Definition: mapPolyMesh.H:646
Foam::mapPolyMesh::cellsFromFacesMap
const List< objectMap > & cellsFromFacesMap() const
Cells inflated from faces.
Definition: mapPolyMesh.H:453
Foam::cellMapper::insertedObjectLabels
const virtual labelList & insertedObjectLabels() const
Return list of inserted cells.
Definition: cellMapper.C:452
Foam::mapPolyMesh
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:161
Foam::mapPolyMesh::cellMap
const labelList & cellMap() const
Old cell map.
Definition: mapPolyMesh.H:435
Foam::mapPolyMesh::cellsFromCellsMap
const List< objectMap > & cellsFromCellsMap() const
Cells originating from cells.
Definition: mapPolyMesh.H:459