correctedCellVolumeWeightMethod.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) 2015 OpenFOAM Foundation
9  Copyright (C) 2015 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36  defineTypeNameAndDebug(correctedCellVolumeWeightMethod, 0);
38  (
39  meshToMeshMethod,
40  correctedCellVolumeWeightMethod,
41  components
42  );
43 }
44 
45 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
46 
48 (
49  labelListList& srcToTgtCellAddr,
50  scalarListList& srcToTgtCellWght,
51  pointListList& srcToTgtCellVec,
52  labelListList& tgtToSrcCellAddr,
53  scalarListList& tgtToSrcCellWght,
54  pointListList& tgtToSrcCellVec,
55  const label srcSeedI,
56  const label tgtSeedI,
57  const labelList& srcCellIDs,
58  boolList& mapFlag,
59  label& startSeedI
60 )
61 {
62  label srcCellI = srcSeedI;
63  label tgtCellI = tgtSeedI;
64 
65  List<DynamicList<label>> srcToTgtAddr(src_.nCells());
66  List<DynamicList<scalar>> srcToTgtWght(src_.nCells());
67  List<DynamicList<point>> srcToTgtVec(src_.nCells());
68 
69  List<DynamicList<label>> tgtToSrcAddr(tgt_.nCells());
70  List<DynamicList<scalar>> tgtToSrcWght(tgt_.nCells());
71  List<DynamicList<point>> tgtToSrcVec(tgt_.nCells());
72 
73  // List of tgt cell neighbour cells
74  DynamicList<label> queuedCells(10);
75 
76  // List of tgt cells currently visited for srcCellI to avoid multiple hits
77  DynamicList<label> visitedCells(10);
78 
79  // List to keep track of tgt cells used to seed src cells
80  labelList seedCells(src_.nCells(), -1);
81  seedCells[srcCellI] = tgtCellI;
82 
83  const scalarField& srcVol = src_.cellVolumes();
84  const pointField& srcCc = src_.cellCentres();
85  const pointField& tgtCc = tgt_.cellCentres();
86 
87  do
88  {
89  queuedCells.clear();
90  visitedCells.clear();
91 
92  // Initial target cell and neighbours
93  queuedCells.push_back(tgtCellI);
94  appendNbrCells(tgtCellI, tgt_, visitedCells, queuedCells);
95 
96  while (!queuedCells.empty())
97  {
98  // Process new target cell as LIFO
99  tgtCellI = queuedCells.back();
100  queuedCells.pop_back();
101  visitedCells.push_back(tgtCellI);
102 
104  (
105  srcCellI,
106  tgtCellI
107  );
108 
109  // accumulate addressing and weights for valid intersection
110  if (vol.first()/srcVol[srcCellI] > tolerance_)
111  {
112  // store src/tgt cell pair
113  srcToTgtAddr[srcCellI].append(tgtCellI);
114  srcToTgtWght[srcCellI].append(vol.first());
115  srcToTgtVec[srcCellI].append(vol.second()-tgtCc[tgtCellI]);
116 
117  tgtToSrcAddr[tgtCellI].append(srcCellI);
118  tgtToSrcWght[tgtCellI].append(vol.first());
119  tgtToSrcVec[tgtCellI].append(vol.second()-srcCc[srcCellI]);
120 
121  appendNbrCells(tgtCellI, tgt_, visitedCells, queuedCells);
122 
123  // accumulate intersection volume
124  V_ += vol.first();
125  }
126  }
127 
128  mapFlag[srcCellI] = false;
129 
130  // find new source seed cell
132  (
133  startSeedI,
134  srcCellI,
135  tgtCellI,
136  srcCellIDs,
137  mapFlag,
138  visitedCells,
139  seedCells
140  );
141  }
142  while (srcCellI != -1);
143 
144  // transfer addressing into persistent storage
145  forAll(srcToTgtCellAddr, i)
146  {
147  srcToTgtCellAddr[i].transfer(srcToTgtAddr[i]);
148  srcToTgtCellWght[i].transfer(srcToTgtWght[i]);
149  srcToTgtCellVec[i].transfer(srcToTgtVec[i]);
150  }
151 
152  forAll(tgtToSrcCellAddr, i)
153  {
154  tgtToSrcCellAddr[i].transfer(tgtToSrcAddr[i]);
155  tgtToSrcCellWght[i].transfer(tgtToSrcWght[i]);
156  tgtToSrcCellVec[i].transfer(tgtToSrcVec[i]);
157  }
158 
159 
160  if (debug%2)
161  {
162  // At this point the overlaps are still in volume so we could
163  // get out the relative error
164  forAll(srcToTgtCellAddr, cellI)
165  {
166  scalar srcVol = src_.cellVolumes()[cellI];
167  scalar tgtVol = sum(srcToTgtCellWght[cellI]);
168 
169  if (mag(srcVol) > ROOTVSMALL && mag((tgtVol-srcVol)/srcVol) > 1e-6)
170  {
172  << "At cell " << cellI << " cc:"
173  << src_.cellCentres()[cellI]
174  << " vol:" << srcVol
175  << " total overlap volume:" << tgtVol
176  << endl;
177  }
178  }
179 
180  forAll(tgtToSrcCellAddr, cellI)
181  {
182  scalar tgtVol = tgt_.cellVolumes()[cellI];
183  scalar srcVol = sum(tgtToSrcCellWght[cellI]);
184 
185  if (mag(tgtVol) > ROOTVSMALL && mag((srcVol-tgtVol)/tgtVol) > 1e-6)
186  {
188  << "At cell " << cellI << " cc:"
189  << tgt_.cellCentres()[cellI]
190  << " vol:" << tgtVol
191  << " total overlap volume:" << srcVol
192  << endl;
193  }
194  }
195  }
196 }
197 
198 
199 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
200 
202 (
203  const polyMesh& src,
204  const polyMesh& tgt
205 )
206 :
207  cellVolumeWeightMethod(src, tgt)
208 {}
209 
210 
211 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
212 
214 {}
215 
216 
217 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
218 
220 (
221  labelListList& srcToTgtAddr,
222  scalarListList& srcToTgtWght,
223  pointListList& srcToTgtVec,
224 
225  labelListList& tgtToSrcAddr,
226  scalarListList& tgtToSrcWght,
227  pointListList& tgtToSrcVec
228 )
229 {
230  bool ok = initialise
231  (
232  srcToTgtAddr,
233  srcToTgtWght,
234  tgtToSrcAddr,
235  tgtToSrcWght
236  );
237 
238  if (!ok)
239  {
240  return;
241  }
242 
243  srcToTgtVec.setSize(srcToTgtAddr.size());
244  tgtToSrcVec.setSize(tgtToSrcAddr.size());
245 
246 
247  // (potentially) participating source mesh cells
248  const labelList srcCellIDs(maskCells());
249 
250  // list to keep track of whether src cell can be mapped
251  boolList mapFlag(src_.nCells(), false);
252  boolUIndList(mapFlag, srcCellIDs) = true;
253 
254  // find initial point in tgt mesh
255  label srcSeedI = -1;
256  label tgtSeedI = -1;
257  label startSeedI = 0;
258 
259  bool startWalk =
260  findInitialSeeds
261  (
262  srcCellIDs,
263  mapFlag,
264  startSeedI,
265  srcSeedI,
266  tgtSeedI
267  );
268 
269  if (startWalk)
270  {
271  calculateAddressing
272  (
273  srcToTgtAddr,
274  srcToTgtWght,
275  srcToTgtVec,
276  tgtToSrcAddr,
277  tgtToSrcWght,
278  tgtToSrcVec,
279  srcSeedI,
280  tgtSeedI,
281  srcCellIDs,
282  mapFlag,
283  startSeedI
284  );
285  }
286  else
287  {
288  // if meshes are collocated, after inflating the source mesh bounding
289  // box tgt mesh cells may be transferred, but may still not overlap
290  // with the source mesh
291  return;
292  }
293 }
294 
295 
296 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1)
void calculateAddressing(labelListList &srcToTgtCellAddr, scalarListList &srcToTgtCellWght, pointListList &srcToTgtCellVec, labelListList &tgtToSrcCellAddr, scalarListList &tgtToSrcCellWght, pointListList &tgtToSrcCellVec, const label srcSeedI, const label tgtSeedI, const labelList &srcCellIDs, boolList &mapFlag, label &startSeedI)
Calculate the mesh-to-mesh addressing and weights.
const polyMesh & src_
Reference to the source mesh.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Definition: List.C:326
void append(const T &val)
Append an element at the end of the list.
Definition: List.H:517
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
Cell-volume-weighted mesh-to-mesh interpolation class.
virtual void calculate(labelListList &srcToTgtAddr, scalarListList &srcToTgtWght, pointListList &srcToTgtVec, labelListList &tgtToSrcAddr, scalarListList &tgtToSrcWght, pointListList &tgtToSrcVec)
Calculate addressing and weights and optionally offset vectors.
Macros for easy insertion into run-time selection tables.
static scalar tolerance_
Tolerance used in volume overlap calculations.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
void setSize(const label n)
Alias for resize()
Definition: List.H:316
correctedCellVolumeWeightMethod(const correctedCellVolumeWeightMethod &)=delete
No copy construct.
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:137
const vectorField & cellCentres() const
const polyMesh & tgt_
Reference to the target mesh.
int debug
Static debugging option.
defineTypeNameAndDebug(combustionModel, 0)
virtual void appendNbrCells(const label tgtCelli, const polyMesh &mesh, const DynamicList< label > &visitedTgtCells, DynamicList< label > &nbrTgtCellIDs) const
Append target cell neighbour cells to cellIDs list.
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.
virtual Tuple2< scalar, point > interVolAndCentroid(const label srcCellI, const label tgtCellI)
Return the intersection volume and centroid between two cells.
#define WarningInFunction
Report a warning using Foam::Warning.
label nCells() const noexcept
Number of mesh cells.
const T2 & second() const noexcept
Access the second element.
Definition: Tuple2.H:142
scalar V_
Cell total volume in overlap region [m3].
List< label > labelList
A List of labels.
Definition: List.H:62
const T1 & first() const noexcept
Access the first element.
Definition: Tuple2.H:132
List< bool > boolList
A List of bools.
Definition: List.H:60
UIndirectList< bool > boolUIndList
UIndirectList of bools.
Definition: IndirectList.H:61
Namespace for OpenFOAM.
addToRunTimeSelectionTable(functionObject, pointHistory, dictionary)
const scalarField & cellVolumes() const