mapNearestAMI.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-2018 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 "mapNearestAMI.H"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
33  defineTypeNameAndDebug(mapNearestAMI, 0);
34  addToRunTimeSelectionTable(AMIMethod, mapNearestAMI, components);
35 }
36 
37 
38 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 
40 void Foam::mapNearestAMI::findNearestFace
41 (
42  const primitivePatch& srcPatch,
43  const primitivePatch& tgtPatch,
44  const label& srcFacei,
45  label& tgtFacei
46 ) const
47 {
48  const vectorField& srcCf = srcPatch.faceCentres();
49  const vectorField& tgtCf = tgtPatch.faceCentres();
50 
51  const vector srcP = srcCf[srcFacei];
52 
53  DynamicList<label> tgtFaces(10);
54  tgtFaces.append(tgtFacei);
55 
56  DynamicList<label> visitedFaces(10);
57 
58  scalar d = great;
59 
60  do
61  {
62  label tgtI = tgtFaces.remove();
63  visitedFaces.append(tgtI);
64 
65  scalar dTest = magSqr(tgtCf[tgtI] - srcP);
66  if (dTest < d)
67  {
68  tgtFacei = tgtI;
69  d = dTest;
70 
71  this->appendNbrFaces
72  (
73  tgtFacei,
74  tgtPatch,
75  visitedFaces,
76  tgtFaces
77  );
78  }
79 
80  } while (tgtFaces.size() > 0);
81 }
82 
83 
84 void Foam::mapNearestAMI::setNextNearestFaces
85 (
86  boolList& mapFlag,
87  label& startSeedI,
88  label& srcFacei,
89  label& tgtFacei
90 ) const
91 {
92  const labelList& srcNbr = this->srcPatch_.faceFaces()[srcFacei];
93 
94  srcFacei = -1;
95 
96  forAll(srcNbr, i)
97  {
98  label facei = srcNbr[i];
99  if (mapFlag[facei])
100  {
101  srcFacei = facei;
102  startSeedI = facei + 1;
103 
104  return;
105  }
106  }
107 
108  forAll(mapFlag, facei)
109  {
110  if (mapFlag[facei])
111  {
112  srcFacei = facei;
113  tgtFacei = this->findTargetFace(facei);
114 
115  if (tgtFacei == -1)
116  {
117  const vectorField& srcCf = this->srcPatch_.faceCentres();
118 
120  << "Unable to find target face for source face "
121  << srcFacei << " with face centre " << srcCf[srcFacei]
122  << abort(FatalError);
123  }
124 
125  break;
126  }
127  }
128 }
129 
130 
131 Foam::label Foam::mapNearestAMI::findMappedSrcFace
132 (
133  const label tgtFacei,
134  const List<DynamicList<label>>& tgtToSrc
135 ) const
136 {
137  DynamicList<label> testFaces(10);
138  DynamicList<label> visitedFaces(10);
139 
140  testFaces.append(tgtFacei);
141 
142  do
143  {
144  // search target tgtFacei neighbours for match with source face
145  label tgtI = testFaces.remove();
146 
147  if (findIndex(visitedFaces, tgtI) == -1)
148  {
149  visitedFaces.append(tgtI);
150 
151  if (tgtToSrc[tgtI].size())
152  {
153  return tgtToSrc[tgtI][0];
154  }
155  else
156  {
157  const labelList& nbrFaces = this->tgtPatch_.faceFaces()[tgtI];
158 
159  forAll(nbrFaces, i)
160  {
161  if (findIndex(visitedFaces, nbrFaces[i]) == -1)
162  {
163  testFaces.append(nbrFaces[i]);
164  }
165  }
166  }
167  }
168  } while (testFaces.size());
169 
170  // did not find any match - should not be possible to get here!
171  return -1;
172 }
173 
174 
175 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
176 
178 (
179  const primitivePatch& srcPatch,
180  const primitivePatch& tgtPatch,
181  const scalarField& srcMagSf,
182  const scalarField& tgtMagSf,
184  const bool reverseTarget,
185  const bool requireMatch
186 )
187 :
188  AMIMethod
189  (
190  srcPatch,
191  tgtPatch,
192  srcMagSf,
193  tgtMagSf,
194  triMode,
195  reverseTarget,
196  requireMatch
197  )
198 {}
199 
200 
201 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
202 
204 {}
205 
206 
207 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
208 
210 (
211  labelListList& srcAddress,
212  scalarListList& srcWeights,
213  labelListList& tgtAddress,
214  scalarListList& tgtWeights,
215  label srcFacei,
216  label tgtFacei
217 )
218 {
219  bool ok =
220  this->initialise
221  (
222  srcAddress,
223  srcWeights,
224  tgtAddress,
225  tgtWeights,
226  srcFacei,
227  tgtFacei
228  );
229 
230  if (!ok)
231  {
232  return;
233  }
234 
235 
236  // temporary storage for addressing and weights
237  List<DynamicList<label>> srcAddr(this->srcPatch_.size());
238  List<DynamicList<label>> tgtAddr(this->tgtPatch_.size());
239 
240 
241  // construct weights and addressing
242  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
243 
244  // list to keep track of whether src face can be mapped
245  boolList mapFlag(srcAddr.size(), true);
246 
247  // reset starting seed
248  label startSeedI = 0;
249 
250  DynamicList<label> nonOverlapFaces;
251  do
252  {
253  findNearestFace(this->srcPatch_, this->tgtPatch_, srcFacei, tgtFacei);
254 
255  srcAddr[srcFacei].append(tgtFacei);
256  tgtAddr[tgtFacei].append(srcFacei);
257 
258  mapFlag[srcFacei] = false;
259 
260  // Do advancing front starting from srcFacei, tgtFacei
261  setNextNearestFaces
262  (
263  mapFlag,
264  startSeedI,
265  srcFacei,
266  tgtFacei
267  );
268  } while (srcFacei >= 0);
269 
270 
271  // for the case of multiple source faces per target face, select the
272  // nearest source face only and discard the others
273  const vectorField& srcCf = this->srcPatch_.faceCentres();
274  const vectorField& tgtCf = this->tgtPatch_.faceCentres();
275 
276  forAll(tgtAddr, targetFacei)
277  {
278  if (tgtAddr[targetFacei].size() > 1)
279  {
280  const vector& tgtC = tgtCf[tgtFacei];
281 
282  DynamicList<label>& srcFaces = tgtAddr[targetFacei];
283 
284  label srcFacei = srcFaces[0];
285  scalar d = magSqr(tgtC - srcCf[srcFacei]);
286 
287  for (label i = 1; i < srcFaces.size(); i++)
288  {
289  label srcI = srcFaces[i];
290  scalar dNew = magSqr(tgtC - srcCf[srcI]);
291  if (dNew < d)
292  {
293  d = dNew;
294  srcFacei = srcI;
295  }
296  }
297 
298  srcFaces.clear();
299  srcFaces.append(srcFacei);
300  }
301  }
302 
303  // If there are more target faces than source faces, some target faces
304  // might not yet be mapped
305  forAll(tgtAddr, tgtFacei)
306  {
307  if (tgtAddr[tgtFacei].empty())
308  {
309  label srcFacei = findMappedSrcFace(tgtFacei, tgtAddr);
310 
311  if (srcFacei >= 0)
312  {
313  // note - reversed search from src->tgt to tgt->src
314  findNearestFace
315  (
316  this->tgtPatch_,
317  this->srcPatch_,
318  tgtFacei,
319  srcFacei
320  );
321 
322  tgtAddr[tgtFacei].append(srcFacei);
323  }
324  }
325  }
326 
327 
328  // transfer data to persistent storage
329  forAll(srcAddr, i)
330  {
331  srcAddress[i].transfer(srcAddr[i]);
332  srcWeights[i] = scalarList(1, 1.0);
333  }
334  forAll(tgtAddr, i)
335  {
336  tgtAddress[i].transfer(tgtAddr[i]);
337  tgtWeights[i] = scalarList(1, 1.0);
338  }
339 }
340 
341 
342 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
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
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:323
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
virtual ~mapNearestAMI()
Destructor.
virtual void calculate(labelListList &srcAddress, scalarListList &srcWeights, labelListList &tgtAddress, scalarListList &tgtWeights, label srcFacei=-1, label tgtFacei=-1)
Update addressing and weights.
Macros for easy insertion into run-time selection tables.
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
A list of faces which address into the list of points.
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:50
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
List< label > labelList
A List of labels.
Definition: labelList.H:56
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Base class for Arbitrary Mesh Interface (AMI) methods.
Definition: AMIMethod.H:55
dimensioned< scalar > magSqr(const dimensioned< Type > &)
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
defineTypeNameAndDebug(combustionModel, 0)
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
Addressing for a faceList slice.
Field< vector > vectorField
Specialisation of Field<T> for vector.
mapNearestAMI(const primitivePatch &srcPatch, const primitivePatch &tgtPatch, const scalarField &srcMagSf, const scalarField &tgtMagSf, const faceAreaIntersect::triangulationMode &triMode, const bool reverseTarget=false, const bool requireMatch=true)
Construct from components.
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:236
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
Namespace for OpenFOAM.