cellVolumeWeightMethod.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2013-2019 OpenFOAM Foundation
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 "cellVolumeWeightMethod.H"
27 #include "indexedOctree.H"
28 #include "treeDataCell.H"
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35  defineTypeNameAndDebug(cellVolumeWeightMethod, 0);
37  (
38  meshToMeshMethod,
39  cellVolumeWeightMethod,
40  components
41  );
42 }
43 
44 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
45 
47 (
48  const labelList& srcCellIDs,
49  const boolList& mapFlag,
50  const label startSeedI,
51  label& srcSeedI,
52  label& tgtSeedI
53 ) const
54 {
55  const cellList& srcCells = src_.cells();
56  const faceList& srcFaces = src_.faces();
57  const pointField& srcPts = src_.points();
58 
59  for (label i = startSeedI; i < srcCellIDs.size(); i++)
60  {
61  label srcI = srcCellIDs[i];
62 
63  if (mapFlag[srcI])
64  {
65  const pointField pts
66  (
67  srcCells[srcI].points(srcFaces, srcPts)
68  );
69 
70  forAll(pts, ptI)
71  {
72  const point& pt = pts[ptI];
73  label tgtI = tgt_.cellTree().findInside(pt);
74 
75  if (tgtI != -1 && intersect(srcI, tgtI))
76  {
77  srcSeedI = srcI;
78  tgtSeedI = tgtI;
79 
80  return true;
81  }
82  }
83  }
84  }
85 
86  if (debug)
87  {
88  Pout<< "could not find starting seed" << endl;
89  }
90 
91  return false;
92 }
93 
94 
96 (
97  labelListList& srcToTgtCellAddr,
98  scalarListList& srcToTgtCellWght,
99  labelListList& tgtToSrcCellAddr,
100  scalarListList& tgtToSrcCellWght,
101  const label srcSeedI,
102  const label tgtSeedI,
103  const labelList& srcCellIDs,
104  boolList& mapFlag,
105  label& startSeedI
106 )
107 {
108  label srcCelli = srcSeedI;
109  label tgtCelli = tgtSeedI;
110 
111  List<DynamicList<label>> srcToTgtAddr(src_.nCells());
112  List<DynamicList<scalar>> srcToTgtWght(src_.nCells());
113 
114  List<DynamicList<label>> tgtToSrcAddr(tgt_.nCells());
115  List<DynamicList<scalar>> tgtToSrcWght(tgt_.nCells());
116 
117  // list of tgt cell neighbour cells
118  DynamicList<label> nbrTgtCells(10);
119 
120  // list of tgt cells currently visited for srcCelli to avoid multiple hits
121  DynamicList<label> visitedTgtCells(10);
122 
123  // list to keep track of tgt cells used to seed src cells
124  labelList seedCells(src_.nCells(), -1);
125  seedCells[srcCelli] = tgtCelli;
126 
127  const scalarField& srcVol = src_.cellVolumes();
128 
129  do
130  {
131  nbrTgtCells.clear();
132  visitedTgtCells.clear();
133 
134  // append initial target cell and neighbours
135  nbrTgtCells.append(tgtCelli);
136  appendNbrCells(tgtCelli, tgt_, visitedTgtCells, nbrTgtCells);
137 
138  do
139  {
140  tgtCelli = nbrTgtCells.remove();
141  visitedTgtCells.append(tgtCelli);
142 
143  scalar vol = interVol(srcCelli, tgtCelli);
144 
145  // accumulate addressing and weights for valid intersection
146  if (vol/srcVol[srcCelli] > tolerance_)
147  {
148  // store src/tgt cell pair
149  srcToTgtAddr[srcCelli].append(tgtCelli);
150  srcToTgtWght[srcCelli].append(vol);
151 
152  tgtToSrcAddr[tgtCelli].append(srcCelli);
153  tgtToSrcWght[tgtCelli].append(vol);
154 
155  appendNbrCells(tgtCelli, tgt_, visitedTgtCells, nbrTgtCells);
156 
157  // accumulate intersection volume
158  V_ += vol;
159  }
160  }
161  while (!nbrTgtCells.empty());
162 
163  mapFlag[srcCelli] = false;
164 
165  // find new source seed cell
166  setNextCells
167  (
168  startSeedI,
169  srcCelli,
170  tgtCelli,
171  srcCellIDs,
172  mapFlag,
173  visitedTgtCells,
174  seedCells
175  );
176  }
177  while (srcCelli != -1);
178 
179  // transfer addressing into persistent storage
180  forAll(srcToTgtCellAddr, i)
181  {
182  srcToTgtCellAddr[i].transfer(srcToTgtAddr[i]);
183  srcToTgtCellWght[i].transfer(srcToTgtWght[i]);
184  }
185 
186  forAll(tgtToSrcCellAddr, i)
187  {
188  tgtToSrcCellAddr[i].transfer(tgtToSrcAddr[i]);
189  tgtToSrcCellWght[i].transfer(tgtToSrcWght[i]);
190  }
191 }
192 
193 
195 (
196  label& startSeedI,
197  label& srcCelli,
198  label& tgtCelli,
199  const labelList& srcCellIDs,
200  const boolList& mapFlag,
201  const DynamicList<label>& visitedCells,
202  labelList& seedCells
203 ) const
204 {
205  const labelList& srcNbrCells = src_.cellCells()[srcCelli];
206 
207  // set possible seeds for later use by querying all src cell neighbours
208  // with all visited target cells
209  bool valuesSet = false;
210  forAll(srcNbrCells, i)
211  {
212  label cellS = srcNbrCells[i];
213 
214  if (mapFlag[cellS] && seedCells[cellS] == -1)
215  {
216  forAll(visitedCells, j)
217  {
218  label cellT = visitedCells[j];
219 
220  if (intersect(cellS, cellT))
221  {
222  seedCells[cellS] = cellT;
223 
224  if (!valuesSet)
225  {
226  srcCelli = cellS;
227  tgtCelli = cellT;
228  valuesSet = true;
229  }
230  }
231  }
232  }
233  }
234 
235  // set next src and tgt cells if not set above
236  if (valuesSet)
237  {
238  return;
239  }
240  else
241  {
242  // try to use existing seed
243  bool foundNextSeed = false;
244  for (label i = startSeedI; i < srcCellIDs.size(); i++)
245  {
246  label cellS = srcCellIDs[i];
247 
248  if (mapFlag[cellS])
249  {
250  if (!foundNextSeed)
251  {
252  startSeedI = i;
253  foundNextSeed = true;
254  }
255 
256  if (seedCells[cellS] != -1)
257  {
258  srcCelli = cellS;
259  tgtCelli = seedCells[cellS];
260 
261  return;
262  }
263  }
264  }
265 
266  // perform new search to find match
267  if (debug)
268  {
269  Pout<< "Advancing front stalled: searching for new "
270  << "target cell" << endl;
271  }
272 
273  bool restart =
274  findInitialSeeds
275  (
276  srcCellIDs,
277  mapFlag,
278  startSeedI,
279  srcCelli,
280  tgtCelli
281  );
282 
283  if (restart)
284  {
285  // successfully found new starting seed-pair
286  return;
287  }
288  }
289 
290  // if we have got to here, there are no more src/tgt cell intersections
291  srcCelli = -1;
292  tgtCelli = -1;
293 }
294 
295 
296 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
297 
299 (
300  const polyMesh& src,
301  const polyMesh& tgt
302 )
303 :
304  meshToMeshMethod(src, tgt)
305 {}
306 
307 
308 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
309 
311 {}
312 
313 
314 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
315 
317 (
318  labelListList& srcToTgtAddr,
319  scalarListList& srcToTgtWght,
320  labelListList& tgtToSrcAddr,
321  scalarListList& tgtToSrcWght
322 )
323 {
324  bool ok = initialise
325  (
326  srcToTgtAddr,
327  srcToTgtWght,
328  tgtToSrcAddr,
329  tgtToSrcWght
330  );
331 
332  if (!ok)
333  {
334  return;
335  }
336 
337  // (potentially) participating source mesh cells
338  const labelList srcCellIDs(maskCells());
339 
340  // list to keep track of whether src cell can be mapped
341  boolList mapFlag(src_.nCells(), false);
342  UIndirectList<bool>(mapFlag, srcCellIDs) = true;
343 
344  // find initial point in tgt mesh
345  label srcSeedI = -1;
346  label tgtSeedI = -1;
347  label startSeedI = 0;
348 
349  bool startWalk =
350  findInitialSeeds
351  (
352  srcCellIDs,
353  mapFlag,
354  startSeedI,
355  srcSeedI,
356  tgtSeedI
357  );
358 
359  if (startWalk)
360  {
361  calculateAddressing
362  (
363  srcToTgtAddr,
364  srcToTgtWght,
365  tgtToSrcAddr,
366  tgtToSrcWght,
367  srcSeedI,
368  tgtSeedI,
369  srcCellIDs,
370  mapFlag,
371  startSeedI
372  );
373  }
374  else
375  {
376  // if meshes are collocated, after inflating the source mesh bounding
377  // box tgt mesh cells may be transferred, but may still not overlap
378  // with the source mesh
379  return;
380  }
381 }
382 
383 
384 // ************************************************************************* //
cellVolumeWeightMethod(const polyMesh &src, const polyMesh &tgt)
Construct from source and target meshes.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
bool empty() const
Return true if the UList is empty (ie, size() is zero)
Definition: UListI.H:313
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
virtual ~cellVolumeWeightMethod()
Destructor.
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:163
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:256
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.
Macros for easy insertion into run-time selection tables.
virtual void calculate(labelListList &srcToTgtAddr, scalarListList &srcToTgtWght, labelListList &tgtToTgtAddr, scalarListList &tgtToTgtWght)
Calculate addressing and weights.
const pointField & points
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:124
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:177
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
defineTypeNameAndDebug(combustionModel, 0)
Base class for mesh-to-mesh calculation methods.
void setNextCells(label &startSeedI, label &srcCelli, label &tgtCelli, const labelList &srcCellIDs, const boolList &mapFlag, const DynamicList< label > &visitedCells, labelList &seedCells) const
Set the next cells in the advancing front algorithm.
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
A List with indirect addressing.
Definition: fvMatrix.H:106
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:236
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.
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
Namespace for OpenFOAM.