matchingCellsToCells.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-2025 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 "matchingCellsToCells.H"
27 #include "meshSearch.H"
28 #include "pointInCell.H"
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35 namespace cellsToCellss
36 {
39 }
40 }
41 
42 
43 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
44 
45 bool Foam::cellsToCellss::matching::intersect
46 (
47  const polyMesh& srcMesh,
48  const polyMesh& tgtMesh,
49  const label srcCelli,
50  const label tgtCelli
51 ) const
52 {
54  (
55  srcMesh.cellCentres()[srcCelli],
56  tgtMesh,
57  tgtCelli
58  );
59 }
60 
61 
62 bool Foam::cellsToCellss::matching::findInitialSeeds
63 (
64  const polyMesh& srcMesh,
65  const polyMesh& tgtMesh,
66  const labelList& srcCellIDs,
67  const boolList& mapFlag,
68  const label startSeedI,
69  label& srcSeedI,
70  label& tgtSeedI
71 ) const
72 {
73  const cellList& srcCells = srcMesh.cells();
74  const faceList& srcFaces = srcMesh.faces();
75  const pointField& srcPts = srcMesh.points();
76 
77  const meshSearch& tgtSearchEngine = meshSearch::New(tgtMesh);
78 
79  for (label i = startSeedI; i < srcCellIDs.size(); i++)
80  {
81  label srcI = srcCellIDs[i];
82 
83  if (mapFlag[srcI])
84  {
85  const point srcCtr(srcCells[srcI].centre(srcPts, srcFaces));
86 
87  label tgtI = tgtSearchEngine.findCell(srcCtr);
88 
89  if (tgtI != -1 && intersect(srcMesh, tgtMesh, srcI, tgtI))
90  {
91  srcSeedI = srcI;
92  tgtSeedI = tgtI;
93 
94  return true;
95  }
96  }
97  }
98 
99  if (debug)
100  {
101  Pout<< "could not find starting seed" << endl;
102  }
103 
104  return false;
105 }
106 
107 
108 Foam::scalar Foam::cellsToCellss::matching::calculateAddressing
109 (
110  const polyMesh& srcMesh,
111  const polyMesh& tgtMesh,
112  labelListList& srcToTgtCellAddr,
113  scalarListList& srcToTgtCellWght,
114  labelListList& tgtToSrcCellAddr,
115  scalarListList& tgtToSrcCellWght,
116  const label srcSeedI,
117  const label tgtSeedI,
118  const labelList& srcCellIDs, // not used
119  boolList& mapFlag,
120  label& startSeedI
121 )
122 {
123  scalar V = 0;
124 
125  // store a list of src cells already mapped
126  labelList srcTgtSeed(srcMesh.nCells(), -1);
127 
128  List<DynamicList<label>> srcToTgt(srcMesh.nCells());
129  List<DynamicList<label>> tgtToSrc(tgtMesh.nCells());
130 
131  DynamicList<label> srcSeeds(10);
132 
133  const scalarField& srcVc = srcMesh.cellVolumes();
134 
135  label srcCelli = srcSeedI;
136  label tgtCelli = tgtSeedI;
137 
138  do
139  {
140  // store src/tgt cell pair
141  srcToTgt[srcCelli].append(tgtCelli);
142  tgtToSrc[tgtCelli].append(srcCelli);
143 
144  // mark source cell srcSeedI as matched
145  mapFlag[srcCelli] = false;
146 
147  // accumulate intersection volume
148  V += srcVc[srcCelli];
149 
150  // find new source seed cell
151  appendToDirectSeeds
152  (
153  srcMesh,
154  tgtMesh,
155  mapFlag,
156  srcTgtSeed,
157  srcSeeds,
158  srcCelli,
159  tgtCelli
160  );
161  }
162  while (srcCelli >= 0);
163 
164  // transfer addressing into persistent storage
165  forAll(srcToTgtCellAddr, i)
166  {
167  srcToTgtCellWght[i] = scalarList(srcToTgt[i].size(), scalar(1));
168  srcToTgtCellAddr[i].transfer(srcToTgt[i]);
169  }
170 
171  forAll(tgtToSrcCellAddr, i)
172  {
173  tgtToSrcCellWght[i] = scalarList(tgtToSrc[i].size(), scalar(1));
174  tgtToSrcCellAddr[i].transfer(tgtToSrc[i]);
175  }
176 
177  return V;
178 }
179 
180 
181 void Foam::cellsToCellss::matching::appendToDirectSeeds
182 (
183  const polyMesh& srcMesh,
184  const polyMesh& tgtMesh,
185  boolList& mapFlag,
186  labelList& srcTgtSeed,
187  DynamicList<label>& srcSeeds,
188  label& srcSeedI,
189  label& tgtSeedI
190 ) const
191 {
192  const labelList& srcNbr = srcMesh.cellCells()[srcSeedI];
193  const labelList& tgtNbr = tgtMesh.cellCells()[tgtSeedI];
194 
195  forAll(srcNbr, i)
196  {
197  label srcI = srcNbr[i];
198 
199  if (mapFlag[srcI] && (srcTgtSeed[srcI] == -1))
200  {
201  // source cell srcI not yet mapped
202 
203  // identify if target cell exists for source cell srcI
204  bool found = false;
205  forAll(tgtNbr, j)
206  {
207  label tgtI = tgtNbr[j];
208 
209  if (intersect(srcMesh, tgtMesh, srcI, tgtI))
210  {
211  // new match - append to lists
212  found = true;
213 
214  srcTgtSeed[srcI] = tgtI;
215  srcSeeds.append(srcI);
216 
217  break;
218  }
219  }
220 
221  if (!found)
222  {
223  // no match available for source cell srcI
224  mapFlag[srcI] = false;
225  }
226  }
227  }
228 
229  if (srcSeeds.size())
230  {
231  srcSeedI = srcSeeds.remove();
232  tgtSeedI = srcTgtSeed[srcSeedI];
233  }
234  else
235  {
236  srcSeedI = -1;
237  tgtSeedI = -1;
238  }
239 }
240 
241 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
242 
244 (
245  const polyMesh& srcMesh,
246  const polyMesh& tgtMesh
247 )
248 {
249  initialise(srcMesh, tgtMesh);
250 
251  // Determine (potentially) participating source mesh cells
252  const labelList srcCellIDs(maskCells(srcMesh, tgtMesh));
253 
254  // Initialise list to keep track of whether src cell can be mapped
255  boolList mapFlag(srcMesh.nCells(), false);
256  UIndirectList<bool>(mapFlag, srcCellIDs) = true;
257 
258  // Find initial point in tgt mesh
259  label srcSeedI = -1;
260  label tgtSeedI = -1;
261  label startSeedI = 0;
262  bool startWalk =
263  findInitialSeeds
264  (
265  srcMesh,
266  tgtMesh,
267  srcCellIDs,
268  mapFlag,
269  startSeedI,
270  srcSeedI,
271  tgtSeedI
272  );
273 
274  if (startWalk)
275  {
276  return
277  calculateAddressing
278  (
279  srcMesh,
280  tgtMesh,
281  srcLocalTgtCells_,
282  srcWeights_,
283  tgtLocalSrcCells_,
284  tgtWeights_,
285  srcSeedI,
286  tgtSeedI,
287  srcCellIDs,
288  mapFlag,
289  startSeedI
290  );
291  }
292  else
293  {
294  return 0;
295  }
296 }
297 
298 
300 (
301  const polyMesh& srcMesh,
302  labelListList& srcToTgtAddr,
303  scalarListList& srcToTgtWght
304 ) const
305 {
306  forAll(srcToTgtWght, srcCelli)
307  {
308  if (srcToTgtWght[srcCelli].size() > 1)
309  {
310  srcToTgtAddr[srcCelli].resize(1);
311  srcToTgtWght[srcCelli].resize(1);
312  }
313  }
314 }
315 
316 
317 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
318 
320 :
321  cellsToCells()
322 {}
323 
324 
325 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
326 
328 {}
329 
330 
331 // ************************************************************************* //
bool found
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
Macros for easy insertion into run-time selection tables.
void resize(const label)
Alias for setSize(const label)
Definition: ListI.H:138
A List with indirect addressing.
Definition: UIndirectList.H:61
Class to calculate interpolative addressing and weights between the cells of two overlapping meshes.
Definition: cellsToCells.H:56
Matching, one-to-one, cells-to-cells interpolation class.
virtual scalar calculate(const polyMesh &srcMesh, const polyMesh &tgtMesh)
Calculate the addressing and weights.
virtual void normalise(const polyMesh &mesh, labelListList &localOtherCells, scalarListList &weights) const
Normalise the weights for a given mesh.
static const meshSearch & New(const polyMesh &mesh, const pointInCellShapes=pointInCellShapes::tets)
Lookup or construct from mesh and cell decomposition option.
Definition: meshSearch.C:61
Motion of the mesh specified as a list of pointMeshMovers.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:78
label nCells() const
A class for handling words, derived from string.
Definition: word.H:63
defineTypeNameAndDebug(intersection, 0)
addToRunTimeSelectionTable(cellsToCells, intersection, word)
Namespace for OpenFOAM.
List< scalarList > scalarListList
Definition: scalarList.H:51
List< label > labelList
A List of labels.
Definition: labelList.H:56
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
List< cell > cellList
list of cells
Definition: cellList.H:42
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:50
vector point
Point is a vector.
Definition: point.H:41
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
bool pointInCellFacePlanes(const point &p, const polyMesh &mesh, const label celli)
Test if a point is in a given cell. For each of the cell's faces, define a.
Definition: pointInCell.C:32
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
List< face > faceList
Definition: faceListFwd.H:41
Function for determining if a point is within a cell of a polyMesh.