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-------------------------------------------------------------------------------
10License
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
35void 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
280void Foam::cellMapper::clearOut()
281{
282 deleteDemandDrivenData(directAddrPtr_);
283 deleteDemandDrivenData(interpolationAddrPtr_);
284 deleteDemandDrivenData(weightsPtr_);
285 deleteDemandDrivenData(insertedCellLabelsPtr_);
286}
287
288
289// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
290
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
378Foam::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// ************************************************************************* //
void setSize(const label n)
Alias for resize()
Definition: List.H:218
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:427
This object provides mapping and fill-in information for cell data between the two meshes after the t...
Definition: cellMapper.H:59
virtual ~cellMapper()
Destructor.
Definition: cellMapper.C:370
virtual const labelListList & addressing() const
Return interpolated addressing.
Definition: cellMapper.C:416
virtual const scalarListList & weights() const
Return interpolaion weights.
Definition: cellMapper.C:434
virtual const labelUList & directAddressing() const
Return direct addressing.
Definition: cellMapper.C:390
virtual label size() const
Return size.
Definition: cellMapper.C:378
virtual const labelList & insertedObjectLabels() const
Return list of inserted cells.
Definition: cellMapper.C:452
virtual label sizeBeforeMapping() const
Return size before mapping.
Definition: cellMapper.C:384
virtual bool direct() const
Is the mapping direct.
Definition: cellMapper.H:129
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:162
const List< objectMap > & cellsFromFacesMap() const
Cells inflated from faces.
Definition: mapPolyMesh.H:453
const List< objectMap > & cellsFromPointsMap() const
Cells inflated from points.
Definition: mapPolyMesh.H:441
const List< objectMap > & cellsFromEdgesMap() const
Cells inflated from edges.
Definition: mapPolyMesh.H:447
const labelList & cellMap() const
Old cell map.
Definition: mapPolyMesh.H:435
const scalarField & oldCellVolumes() const
Definition: mapPolyMesh.H:651
const List< objectMap > & cellsFromCellsMap() const
Cells originating from cells.
Definition: mapPolyMesh.H:459
bool hasOldCellVolumes() const
Definition: mapPolyMesh.H:646
label nCells() const noexcept
Number of mesh cells.
dynamicFvMesh & mesh
Template functions to aid in the implementation of demand driven data.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
List< label > labelList
A List of labels.
Definition: List.H:66
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:64
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
errorManip< error > abort(error &err)
Definition: errorManip.H:144
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
error FatalError
List< scalarList > scalarListList
A List of scalarList.
Definition: scalarList.H:66
void deleteDemandDrivenData(DataPtr &dataPtr)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333