1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
28 Implementation of the topoCellMapper class
32 University of Massachusetts Amherst
35 \*---------------------------------------------------------------------------*/
37 #include "topoMapper.H"
38 #include "mapPolyMesh.H"
39 #include "topoCellMapper.H"
40 #include "demandDrivenData.H"
45 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
47 //- Clear out local storage
48 void topoCellMapper::clearOut()
50 deleteDemandDrivenData(directAddrPtr_);
51 deleteDemandDrivenData(interpolationAddrPtr_);
52 deleteDemandDrivenData(weightsPtr_);
53 deleteDemandDrivenData(insertedCellLabelsPtr_);
54 deleteDemandDrivenData(volumesPtr_);
55 deleteDemandDrivenData(centresPtr_);
59 //- Calculate addressing for interpolative mapping
60 void topoCellMapper::calcAddressing() const
62 if (directAddrPtr_ || interpolationAddrPtr_)
64 FatalErrorIn("void topoCellMapper::calcAddressing() const")
65 << "Addressing already calculated."
69 // Allocate for inserted cell labels
70 label nInsertedCells = 0;
72 insertedCellLabelsPtr_ = new labelList(mesh_.nCells(), -1);
73 labelList& insertedCells = *insertedCellLabelsPtr_;
77 // Direct addressing, no weights
78 directAddrPtr_ = new labelList(mpm_.cellMap());
82 // Interpolative addressing
83 interpolationAddrPtr_ = new labelListList(mesh_.nCells());
84 labelListList& addr = *interpolationAddrPtr_;
86 const List<objectMap>& cfc = mpm_.cellsFromCellsMap();
91 const labelList& mo = cfc[cfcI].masterObjects();
93 label cellI = cfc[cfcI].index();
95 if (addr[cellI].size() > 0)
97 FatalErrorIn("void topoCellMapper::calcAddressing() const")
98 << "Master cell " << cellI
99 << " mapped from cells " << mo
100 << " is already destination for mapping."
101 << abort(FatalError);
104 // Set master objects
108 // Do mapped cells. Note that this can already be set by cellsFromCells
109 // so check if addressing size still zero.
110 const labelList& cm = mpm_.cellMap();
114 // Mapped from a single cell
115 if (cm[cellI] > -1 && addr[cellI].empty())
117 addr[cellI] = labelList(1, cm[cellI]);
120 // Check for inserted cells without any addressing
121 if (cm[cellI] < 0 && addr[cellI].empty())
123 insertedCells[nInsertedCells++] = cellI;
128 // Shorten inserted cells to actual size
129 insertedCells.setSize(nInsertedCells);
133 FatalErrorIn("void topoCellMapper::calcAddressing() const")
134 << " Found " << nInsertedCells << " which are"
135 << " not mapped from any parent cells." << nl
138 << abort(FatalError);
143 //- Calculate inverse-distance weights for interpolative mapping
144 void topoCellMapper::calcInverseDistanceWeights() const
150 "void topoCellMapper::calcInverseDistanceWeights() const"
152 << "Weights already calculated."
153 << abort(FatalError);
156 // Fetch interpolative addressing
157 const labelListList& addr = addressing();
160 weightsPtr_ = new scalarListList(size());
161 scalarListList& w = *weightsPtr_;
163 // Obtain cell-centre information from old/new meshes
164 const vectorField& oldCentres = tMapper_.internalCentres();
165 const vectorField& newCentres = mesh_.cellCentres();
169 const labelList& mo = addr[cellI];
174 w[cellI] = scalarList(1, 1.0);
178 // Map from masters, inverse-distance weights
179 scalar totalWeight = 0.0;
180 w[cellI] = scalarList(mo.size(), 0.0);
182 forAll (mo, oldCellI)
191 - oldCentres[mo[oldCellI]]
197 totalWeight += w[cellI][oldCellI];
201 scalar normFactor = (1.0/totalWeight);
203 forAll (mo, oldCellI)
205 w[cellI][oldCellI] *= normFactor;
212 //- Calculate intersection weights for conservative mapping
213 void topoCellMapper::calcIntersectionWeightsAndCentres() const
215 if (volumesPtr_ || centresPtr_)
219 "void topoCellMapper::"
220 "calcIntersectionWeightsAndCentres() const"
222 << "Weights already calculated."
223 << abort(FatalError);
226 // Fetch interpolative addressing
227 const labelListList& addr = addressing();
230 volumesPtr_ = new List<scalarField>(size(), scalarField(0));
231 List<scalarField>& v = *volumesPtr_;
233 centresPtr_ = new List<vectorField>(size(), vectorField(0));
234 List<vectorField>& x = *centresPtr_;
236 // Obtain stored cell-centres
237 const vectorField& cellCentres = tMapper_.internalCentres();
240 const List<objectMap>& cfc = mpm_.cellsFromCellsMap();
241 const List<vectorField>& mapCellCentres = tMapper_.cellCentres();
242 const List<scalarField>& mapCellWeights = tMapper_.cellWeights();
244 // Fill in maps first
247 x[cfc[indexI].index()] = mapCellCentres[indexI];
248 v[cfc[indexI].index()] = mapCellWeights[indexI];
251 // Now do mapped cells
254 const labelList& mo = addr[cellI];
256 // Check if this is indeed a mapped cell
257 if (mo.size() == 1 && x[cellI].empty() && v[cellI].empty())
259 x[cellI] = vectorField(1, cellCentres[mo[0]]);
260 v[cellI] = scalarField(1, 1.0);
266 const List<scalarField>& topoCellMapper::intersectionWeights() const
272 "const List<scalarField>& "
273 "topoCellMapper::intersectionWeights() const"
274 ) << "Requested interpolative weights for a direct mapper."
275 << abort(FatalError);
280 calcIntersectionWeightsAndCentres();
287 const List<vectorField>& topoCellMapper::intersectionCentres() const
293 "const List<vectorField>& "
294 "topoCellMapper::intersectionCentres() const"
295 ) << "Requested interpolative weights for a direct mapper."
296 << abort(FatalError);
301 calcIntersectionWeightsAndCentres();
308 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
310 // Construct from components
311 topoCellMapper::topoCellMapper
313 const mapPolyMesh& mpm,
314 const topoMapper& mapper
321 sizeBeforeMapping_(mpm.nOldCells()),
322 directAddrPtr_(NULL),
323 interpolationAddrPtr_(NULL),
325 insertedCellLabelsPtr_(NULL),
329 // Fetch offset sizes from topoMapper
330 const labelList& sizes = tMapper_.cellSizes();
337 sizeBeforeMapping_ += sizes[pI];
341 // Check for possibility of direct mapping
344 (min(mpm_.cellMap()) > -1)
345 && mpm_.cellsFromPointsMap().empty()
346 && mpm_.cellsFromEdgesMap().empty()
347 && mpm_.cellsFromFacesMap().empty()
348 && mpm_.cellsFromCellsMap().empty()
359 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
361 topoCellMapper::~topoCellMapper()
366 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
369 label topoCellMapper::size() const
371 return mesh_.nCells();
375 //- Return size before mapping
376 label topoCellMapper::sizeBeforeMapping() const
378 return sizeBeforeMapping_;
382 //- Is the mapping direct
383 bool topoCellMapper::direct() const
389 //- Return direct addressing
390 const unallocLabelList& topoCellMapper::directAddressing() const
396 "const unallocLabelList& "
397 "topoCellMapper::directAddressing() const"
398 ) << "Requested direct addressing for an interpolative mapper."
399 << abort(FatalError);
407 return *directAddrPtr_;
411 //- Return interpolation addressing
412 const labelListList& topoCellMapper::addressing() const
418 "const labelListList& "
419 "topoCellMapper::addressing() const"
420 ) << "Requested interpolative addressing for a direct mapper."
421 << abort(FatalError);
424 if (!interpolationAddrPtr_)
429 return *interpolationAddrPtr_;
434 const scalarListList& topoCellMapper::weights() const
440 "const scalarListList& "
441 "topoCellMapper::weights() const"
442 ) << "Requested interpolative weights for a direct mapper."
443 << abort(FatalError);
448 calcInverseDistanceWeights();
455 //- Are there any inserted cells
456 bool topoCellMapper::insertedObjects() const
458 return insertedObjectLabels().size();
462 //- Return list of inserted cells
463 const labelList& topoCellMapper::insertedObjectLabels() const
465 if (!insertedCellLabelsPtr_)
470 return *insertedCellLabelsPtr_;
474 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
476 void topoCellMapper::operator=(const topoCellMapper& rhs)
478 // Check for assignment to self
481 FatalErrorIn("void topoCellMapper::operator=")
482 << "Attempted assignment to self"
483 << abort(FatalError);
487 } // End namespace Foam
489 // ************************************************************************* //