mapNearestMethod.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) 2013-2014 OpenFOAM Foundation
6  \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
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 "mapNearestMethod.H"
27 #include "pointIndexHit.H"
28 #include "indexedOctree.H"
29 #include "treeDataCell.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36  defineTypeNameAndDebug(mapNearestMethod, 0);
37  addToRunTimeSelectionTable(meshToMeshMethod, mapNearestMethod, components);
38 }
39 
40 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
41 
43 (
44  const labelList& srcCellIDs,
45  const boolList& mapFlag,
46  const label startSeedI,
47  label& srcSeedI,
48  label& tgtSeedI
49 ) const
50 {
51  const vectorField& srcCcs = src_.cellCentres();
52 
53  for (label i = startSeedI; i < srcCellIDs.size(); i++)
54  {
55  label srcI = srcCellIDs[i];
56 
57  if (mapFlag[srcI])
58  {
59  const point& srcCc = srcCcs[srcI];
60  pointIndexHit hit =
61  tgt_.cellTree().findNearest(srcCc, GREAT);
62 
63  if (hit.hit())
64  {
65  srcSeedI = srcI;
66  tgtSeedI = hit.index();
67 
68  return true;
69  }
70  else
71  {
73  << "Unable to find nearest target cell"
74  << " for source cell " << srcI
75  << " with centre " << srcCc
76  << abort(FatalError);
77  }
78 
79  break;
80  }
81  }
82 
83  if (debug)
84  {
85  Pout<< "could not find starting seed" << endl;
86  }
87 
88  return false;
89 }
90 
91 
93 (
94  labelListList& srcToTgtCellAddr,
95  scalarListList& srcToTgtCellWght,
96  labelListList& tgtToSrcCellAddr,
97  scalarListList& tgtToSrcCellWght,
98  const label srcSeedI,
99  const label tgtSeedI,
100  const labelList& srcCellIDs,
101  boolList& mapFlag,
102  label& startSeedI
103 )
104 {
105  List<DynamicList<label> > srcToTgt(src_.nCells());
106  List<DynamicList<label> > tgtToSrc(tgt_.nCells());
107 
108  const scalarField& srcVc = src_.cellVolumes();
109  const scalarField& tgtVc = tgt_.cellVolumes();
110 
111  {
112  label srcCellI = srcSeedI;
113  label tgtCellI = tgtSeedI;
114 
115  do
116  {
117  // find nearest tgt cell
118  findNearestCell(src_, tgt_, srcCellI, tgtCellI);
119 
120  // store src/tgt cell pair
121  srcToTgt[srcCellI].append(tgtCellI);
122  tgtToSrc[tgtCellI].append(srcCellI);
123 
124  // mark source cell srcCellI and tgtCellI as matched
125  mapFlag[srcCellI] = false;
126 
127  // accumulate intersection volume
128  V_ += srcVc[srcCellI];
129 
130  // find new source cell
131  setNextNearestCells
132  (
133  startSeedI,
134  srcCellI,
135  tgtCellI,
136  mapFlag,
137  srcCellIDs
138  );
139  }
140  while (srcCellI >= 0);
141  }
142 
143  // for the case of multiple source cells per target cell, select the
144  // nearest source cell only and discard the others
145  const vectorField& srcCc = src_.cellCentres();
146  const vectorField& tgtCc = tgt_.cellCentres();
147 
148  forAll(tgtToSrc, targetCellI)
149  {
150  if (tgtToSrc[targetCellI].size() > 1)
151  {
152  const vector& tgtC = tgtCc[targetCellI];
153 
154  DynamicList<label>& srcCells = tgtToSrc[targetCellI];
155 
156  label srcCellI = srcCells[0];
157  scalar d = magSqr(tgtC - srcCc[srcCellI]);
158 
159  for (label i = 1; i < srcCells.size(); i++)
160  {
161  label srcI = srcCells[i];
162  scalar dNew = magSqr(tgtC - srcCc[srcI]);
163  if (dNew < d)
164  {
165  d = dNew;
166  srcCellI = srcI;
167  }
168  }
169 
170  srcCells.clear();
171  srcCells.append(srcCellI);
172  }
173  }
174 
175  // If there are more target cells than source cells, some target cells
176  // might not yet be mapped
177  forAll(tgtToSrc, tgtCellI)
178  {
179  if (tgtToSrc[tgtCellI].empty())
180  {
181  label srcCellI = findMappedSrcCell(tgtCellI, tgtToSrc);
182 
183  findNearestCell(tgt_, src_, tgtCellI, srcCellI);
184 
185  tgtToSrc[tgtCellI].append(srcCellI);
186  }
187  }
188 
189  // transfer addressing into persistent storage
190  forAll(srcToTgtCellAddr, i)
191  {
192  srcToTgtCellWght[i] = scalarList(srcToTgt[i].size(), srcVc[i]);
193  srcToTgtCellAddr[i].transfer(srcToTgt[i]);
194  }
195 
196  forAll(tgtToSrcCellAddr, i)
197  {
198  tgtToSrcCellWght[i] = scalarList(tgtToSrc[i].size(), tgtVc[i]);
199  tgtToSrcCellAddr[i].transfer(tgtToSrc[i]);
200  }
201 }
202 
203 
205 (
206  const polyMesh& mesh1,
207  const polyMesh& mesh2,
208  const label cell1,
209  label& cell2
210 ) const
211 {
212  const vectorField& Cc1 = mesh1.cellCentres();
213  const vectorField& Cc2 = mesh2.cellCentres();
214 
215  const vector& p1 = Cc1[cell1];
216 
217  DynamicList<label> cells2(10);
218  cells2.append(cell2);
219 
220  DynamicList<label> visitedCells(10);
221 
222  scalar d = GREAT;
223 
224  do
225  {
226  label c2 = cells2.remove();
227  visitedCells.append(c2);
228 
229  scalar dTest = magSqr(Cc2[c2] - p1);
230  if (dTest < d)
231  {
232  cell2 = c2;
233  d = dTest;
234  appendNbrCells(cell2, mesh2, visitedCells, cells2);
235  }
236 
237  } while (cells2.size() > 0);
238 }
239 
240 
242 (
243  label& startSeedI,
244  label& srcCellI,
245  label& tgtCellI,
246  boolList& mapFlag,
247  const labelList& srcCellIDs
248 ) const
249 {
250  const labelList& srcNbr = src_.cellCells()[srcCellI];
251 
252  srcCellI = -1;
253  forAll(srcNbr, i)
254  {
255  label cellI = srcNbr[i];
256  if (mapFlag[cellI])
257  {
258  srcCellI = cellI;
259  return;
260  }
261  }
262 
263  for (label i = startSeedI; i < srcCellIDs.size(); i++)
264  {
265  label cellI = srcCellIDs[i];
266  if (mapFlag[cellI])
267  {
268  startSeedI = i;
269  break;
270  }
271  }
272 
273  (void)findInitialSeeds
274  (
275  srcCellIDs,
276  mapFlag,
277  startSeedI,
278  srcCellI,
279  tgtCellI
280  );
281 }
282 
283 
285 (
286  const label tgtCellI,
287  const List<DynamicList<label> >& tgtToSrc
288 ) const
289 {
290  DynamicList<label> testCells(10);
291  DynamicList<label> visitedCells(10);
292 
293  testCells.append(tgtCellI);
294 
295  do
296  {
297  // search target tgtCellI neighbours for match with source cell
298  label tgtI = testCells.remove();
299 
300  if (findIndex(visitedCells, tgtI) == -1)
301  {
302  visitedCells.append(tgtI);
303 
304  if (tgtToSrc[tgtI].size())
305  {
306  return tgtToSrc[tgtI][0];
307  }
308  else
309  {
310  const labelList& nbrCells = tgt_.cellCells()[tgtI];
311 
312  forAll(nbrCells, i)
313  {
314  if (findIndex(visitedCells, nbrCells[i]) == -1)
315  {
316  testCells.append(nbrCells[i]);
317  }
318  }
319  }
320  }
321  } while (testCells.size());
322 
323  // did not find any match - should not be possible to get here!
324  return -1;
325 }
326 
327 
328 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
329 
331 (
332  const polyMesh& src,
333  const polyMesh& tgt
334 )
335 :
336  meshToMeshMethod(src, tgt)
337 {}
338 
339 
340 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
341 
343 {}
344 
345 
346 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
347 
349 (
350  labelListList& srcToTgtAddr,
351  scalarListList& srcToTgtWght,
352  pointListList& srcToTgtVec,
353  labelListList& tgtToSrcAddr,
354  scalarListList& tgtToSrcWght,
355  pointListList& tgtToSrcVec
356 )
357 {
358  bool ok = initialise
359  (
360  srcToTgtAddr,
361  srcToTgtWght,
362  tgtToSrcAddr,
363  tgtToSrcWght
364  );
365 
366  if (!ok)
367  {
368  return;
369  }
370 
371  // (potentially) participating source mesh cells
372  const labelList srcCellIDs(maskCells());
373 
374  // list to keep track of whether src cell can be mapped
375  boolList mapFlag(src_.nCells(), false);
376  UIndirectList<bool>(mapFlag, srcCellIDs) = true;
377 
378  // find initial point in tgt mesh
379  label srcSeedI = -1;
380  label tgtSeedI = -1;
381  label startSeedI = 0;
382 
383  bool startWalk =
384  findInitialSeeds
385  (
386  srcCellIDs,
387  mapFlag,
388  startSeedI,
389  srcSeedI,
390  tgtSeedI
391  );
392 
393  if (startWalk)
394  {
395  calculateAddressing
396  (
397  srcToTgtAddr,
398  srcToTgtWght,
399  tgtToSrcAddr,
400  tgtToSrcWght,
401  srcSeedI,
402  tgtSeedI,
403  srcCellIDs,
404  mapFlag,
405  startSeedI
406  );
407  }
408  else
409  {
410  // if meshes are collocated, after inflating the source mesh bounding
411  // box tgt mesh cells may be transferred, but may still not overlap
412  // with the source mesh
413  return;
414  }
415 }
416 
417 
418 // ************************************************************************* //
Foam::scalarList
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:50
Foam::PointIndexHit::index
label index() const
Return index.
Definition: PointIndexHit.H:111
Foam::mapNearestMethod::setNextNearestCells
virtual void setNextNearestCells(label &startSeedI, label &srcCellI, label &tgtCellI, boolList &mapFlag, const labelList &srcCellIDs) const
Set the next cells for the marching front algorithm.
Definition: mapNearestMethod.C:242
pointIndexHit.H
Foam::mapNearestMethod::calculate
virtual void calculate(labelListList &srcToTgtAddr, scalarListList &srcToTgtWght, pointListList &srcToTgtVec, labelListList &tgtToSrcAddr, scalarListList &tgtToSrcWght, pointListList &tgtToSrcVec)
Calculate addressing and weights and optionally offset vectors.
Definition: mapNearestMethod.C:349
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::findIndex
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
Foam::DynamicList< label >
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
indexedOctree.H
Foam::PointIndexHit::hit
bool hit() const
Is there a hit.
Definition: PointIndexHit.H:105
Foam::List::transfer
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
Foam::mapNearestMethod::~mapNearestMethod
virtual ~mapNearestMethod()
Destructor.
Definition: mapNearestMethod.C:342
mapNearestMethod.H
Foam::meshToMeshMethod
Base class for mesh-to-mesh calculation methods.
Definition: meshToMeshMethod.H:48
Foam::PointIndexHit
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
Definition: PointIndexHit.H:53
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::mapNearestMethod::findInitialSeeds
virtual bool findInitialSeeds(const labelList &srcCellIDs, const boolList &mapFlag, const label startSeedI, label &srcSeedI, label &tgtSeedI) const
Find indices of overlapping cells in src and tgt meshes - returns.
Definition: mapNearestMethod.C:43
Foam::List::append
void append(const T &)
Append an element at the end of the list.
Foam::mapNearestMethod::findMappedSrcCell
virtual label findMappedSrcCell(const label tgtCellI, const List< DynamicList< label > > &tgtToSrc) const
Find a source cell mapped to target cell tgtCellI.
Definition: mapNearestMethod.C:285
Foam::DynamicList::clear
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:242
Foam::mapNearestMethod::calculateAddressing
virtual void calculateAddressing(labelListList &srcToTgtCellAddr, scalarListList &srcToTgtCellWght, labelListList &tgtToSrcCellAddr, scalarListList &tgtToSrcCellWght, const label srcSeedI, const label tgtSeedI, const labelList &srcCellIDs, boolList &mapFlag, label &startSeedI)
Calculate the mesh-to-mesh addressing and weights.
Definition: mapNearestMethod.C:93
Foam::FatalError
error FatalError
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::mapNearestMethod::mapNearestMethod
mapNearestMethod(const mapNearestMethod &)
Disallow default bitwise copy construct.
Foam::mapNearestMethod::findNearestCell
virtual void findNearestCell(const polyMesh &mesh1, const polyMesh &mesh2, const label cell1, label &cell2) const
Find the nearest cell on mesh2 for cell1 on mesh1.
Definition: mapNearestMethod.C:205
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::constant::physicoChemical::c2
const dimensionedScalar c2
Second radiation constant: default SI units: [m.K].
treeDataCell.H
Foam::DynamicList::append
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Foam::primitiveMesh::cellCentres
const vectorField & cellCentres() const
Definition: primitiveMeshCellCentresAndVols.C:211
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::Pout
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::DynamicList::remove
T remove()
Remove and return the top element.
Definition: DynamicListI.H:365
Foam::UIndirectList
A List with indirect addressing.
Definition: fvMatrix.H:106
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::magSqr
dimensioned< scalar > magSqr(const dimensioned< Type > &)