directAMI.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) 2013-2016 OpenFOAM Foundation
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "directAMI.H"
29 
30 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
31 
32 template<class SourcePatch, class TargetPatch>
34 (
35  labelList& mapFlag,
36  labelList& srcTgtSeed,
37  DynamicList<label>& srcSeeds,
38  DynamicList<label>& nonOverlapFaces,
39  label& srcFacei,
40  label& tgtFacei
41 ) const
42 {
43  const labelList& srcNbr = this->srcPatch_.faceFaces()[srcFacei];
44  const labelList& tgtNbr = this->tgtPatch_.faceFaces()[tgtFacei];
45 
46  const pointField& srcPoints = this->srcPatch_.points();
47  const pointField& tgtPoints = this->tgtPatch_.points();
48 
49  const vectorField& srcCf = this->srcPatch_.faceCentres();
50 
51  for (const label srcI : srcNbr)
52  {
53  if ((mapFlag[srcI] == 0) && (srcTgtSeed[srcI] == -1))
54  {
55  // first attempt: match by comparing face centres
56  const face& srcF = this->srcPatch_[srcI];
57  const point& srcC = srcCf[srcI];
58 
59  scalar tol = GREAT;
60  forAll(srcF, fpI)
61  {
62  const point& p = srcPoints[srcF[fpI]];
63  scalar d2 = magSqr(p - srcC);
64  if (d2 < tol)
65  {
66  tol = d2;
67  }
68  }
69  tol = max(SMALL, 0.0001*sqrt(tol));
70 
71  bool found = false;
72  for (const label tgtI : tgtNbr)
73  {
74  const face& tgtF = this->tgtPatch_[tgtI];
75  const point tgtC = tgtF.centre(tgtPoints);
76 
77  if (mag(srcC - tgtC) < tol)
78  {
79  // new match - append to lists
80  found = true;
81 
82  srcTgtSeed[srcI] = tgtI;
83  srcSeeds.append(srcI);
84 
85  break;
86  }
87  }
88 
89  // second attempt: match by shooting a ray into the tgt face
90  if (!found)
91  {
92  const vector srcN = srcF.areaNormal(srcPoints);
93 
94  for (const label tgtI : tgtNbr)
95  {
96  const face& tgtF = this->tgtPatch_[tgtI];
97  pointHit ray = tgtF.ray(srcCf[srcI], srcN, tgtPoints);
98 
99  if (ray.hit())
100  {
101  // new match - append to lists
102  found = true;
103 
104  srcTgtSeed[srcI] = tgtI;
105  srcSeeds.append(srcI);
106 
107  break;
108  }
109  }
110  }
111 
112  // no match available for source face srcI
113  if (!found)
114  {
115  mapFlag[srcI] = -1;
116  nonOverlapFaces.append(srcI);
117 
118  if (debug)
119  {
120  Pout<< "source face not found: id=" << srcI
121  << " centre=" << srcCf[srcI]
122  << " normal=" << srcF.areaNormal(srcPoints)
123  << " points=" << srcF.points(srcPoints)
124  << endl;
125 
126  Pout<< "target neighbours:" << nl;
127  for (const label tgtI : tgtNbr)
128  {
129  const face& tgtF = this->tgtPatch_[tgtI];
130 
131  Pout<< "face id: " << tgtI
132  << " centre=" << tgtF.centre(tgtPoints)
133  << " normal=" << tgtF.areaNormal(tgtPoints)
134  << " points=" << tgtF.points(tgtPoints)
135  << endl;
136  }
137  }
138  }
139  }
140  }
141 
142  if (srcSeeds.size())
143  {
144  srcFacei = srcSeeds.remove();
145  tgtFacei = srcTgtSeed[srcFacei];
146  }
147  else
148  {
149  srcFacei = -1;
150  tgtFacei = -1;
151  }
152 }
153 
154 
155 template<class SourcePatch, class TargetPatch>
157 (
158  labelList& mapFlag,
159  DynamicList<label>& nonOverlapFaces,
160  label& srcFacei,
161  label& tgtFacei
162 ) const
163 {
164  forAll(mapFlag, facei)
165  {
166  if (mapFlag[facei] == 0)
167  {
168  tgtFacei = this->findTargetFace(facei);
169 
170  if (tgtFacei < 0)
171  {
172  mapFlag[facei] = -1;
173  nonOverlapFaces.append(facei);
174  }
175  else
176  {
177  srcFacei = facei;
178  break;
179  }
180  }
181  }
182 }
183 
184 
185 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
186 
187 template<class SourcePatch, class TargetPatch>
189 (
190  const SourcePatch& srcPatch,
191  const TargetPatch& tgtPatch,
193  const bool reverseTarget,
194  const bool requireMatch
195 )
196 :
198  (
199  srcPatch,
200  tgtPatch,
201  triMode,
202  reverseTarget,
203  requireMatch
204  )
205 {}
206 
207 
208 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
209 
210 template<class SourcePatch, class TargetPatch>
212 {}
213 
214 
215 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
216 
217 template<class SourcePatch, class TargetPatch>
219 (
220  labelListList& srcAddress,
221  scalarListList& srcWeights,
222  labelListList& tgtAddress,
223  scalarListList& tgtWeights,
224  label srcFacei,
225  label tgtFacei
226 )
227 {
228  bool ok =
229  this->initialise
230  (
231  srcAddress,
232  srcWeights,
233  tgtAddress,
234  tgtWeights,
235  srcFacei,
236  tgtFacei
237  );
238 
239  if (!ok)
240  {
241  return;
242  }
243 
244 
245  // temporary storage for addressing and weights
246  List<DynamicList<label>> srcAddr(this->srcPatch_.size());
247  List<DynamicList<label>> tgtAddr(this->tgtPatch_.size());
248 
249 
250  // construct weights and addressing
251  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
252 
253  // list of faces currently visited for srcFacei to avoid multiple hits
254  DynamicList<label> srcSeeds(10);
255 
256  // list to keep track of tgt faces used to seed src faces
257  labelList srcTgtSeed(srcAddr.size(), -1);
258  srcTgtSeed[srcFacei] = tgtFacei;
259 
260  // list to keep track of whether src face can be mapped
261  // 1 = mapped, 0 = untested, -1 = cannot map
262  labelList mapFlag(srcAddr.size(), Zero);
263 
264  label nTested = 0;
265  DynamicList<label> nonOverlapFaces;
266  do
267  {
268  srcAddr[srcFacei].append(tgtFacei);
269  tgtAddr[tgtFacei].append(srcFacei);
270 
271  mapFlag[srcFacei] = 1;
272 
273  nTested++;
274 
275  // Do advancing front starting from srcFacei, tgtFacei
276  appendToDirectSeeds
277  (
278  mapFlag,
279  srcTgtSeed,
280  srcSeeds,
281  nonOverlapFaces,
282  srcFacei,
283  tgtFacei
284  );
285 
286  if (srcFacei < 0 && nTested < this->srcPatch_.size())
287  {
288  restartAdvancingFront(mapFlag, nonOverlapFaces, srcFacei, tgtFacei);
289  }
290 
291  } while (srcFacei >= 0);
292 
293  if (nonOverlapFaces.size() != 0)
294  {
295  Pout<< " AMI: " << nonOverlapFaces.size()
296  << " non-overlap faces identified"
297  << endl;
298 
299  this->srcNonOverlap_.transfer(nonOverlapFaces);
300  }
301 
302  // transfer data to persistent storage
303  forAll(srcAddr, i)
304  {
305  scalar magSf = this->srcMagSf_[i];
306  srcAddress[i].transfer(srcAddr[i]);
307  srcWeights[i] = scalarList(1, magSf);
308  }
309  forAll(tgtAddr, i)
310  {
311  scalar magSf = this->tgtMagSf_[i];
312  tgtAddress[i].transfer(tgtAddr[i]);
313  tgtWeights[i] = scalarList(1, magSf);
314  }
315 }
316 
317 
318 template<class SourcePatch, class TargetPatch>
320 (
321  const TargetPatch& tgtPatch,
322  const mapDistribute& map,
323  scalarList& srcMagSf,
324  scalarList& tgtMagSf
325 ) const
326 {
327  srcMagSf = std::move(this->srcMagSf_);
328  tgtMagSf = scalarList(tgtPatch.size(), 1.0);
329 }
330 
331 
332 template<class SourcePatch, class TargetPatch>
334 (
335  const bool verbose,
337 )
338 {
339  inter.normaliseWeights(this->conformal(), verbose);
340 }
341 
342 
343 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:74
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::scalarList
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:64
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::faceAreaIntersect::triangulationMode
triangulationMode
Definition: faceAreaIntersect.H:62
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
Foam::DynamicList< label >
Foam::directAMI::normaliseWeights
virtual void normaliseWeights(const bool verbose, AMIInterpolation< SourcePatch, TargetPatch > &inter)
Normalise the weight. Can optionally subset addressing.
Definition: directAMI.C:334
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::Pout
prefixOSstream Pout
An Ostream wrapper for parallel output to std::cout.
Foam::directAMI::setMagSf
virtual void setMagSf(const TargetPatch &tgtPatch, const mapDistribute &map, scalarList &srcMagSf, scalarList &tgtMagSf) const
Set the face areas for parallel runs.
Definition: directAMI.C:320
Foam::AMIMethod
Base class for Arbitrary Mesh Interface (AMI) methods.
Definition: AMIMethod.H:60
Foam::directAMI
Direct mapped Arbitrary Mesh Interface (AMI) method.
Definition: directAMI.H:51
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
Foam::magSqr
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
Foam::directAMI::~directAMI
virtual ~directAMI()
Destructor.
Definition: directAMI.C:211
Foam::directAMI::calculate
virtual void calculate(labelListList &srcAddress, scalarListList &srcWeights, labelListList &tgtAddress, scalarListList &tgtWeights, label srcFacei=-1, label tgtFacei=-1)
Update addressing and weights.
Definition: directAMI.C:219
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:62
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:472
Foam::mapDistribute
Class containing processor-to-processor mapping information.
Definition: mapDistribute.H:163
Foam::List::transfer
void transfer(List< T > &list)
Definition: List.C:436
Foam::Vector::centre
const Vector< Cmpt > & centre(const Foam::List< Vector< Cmpt >> &) const
Return *this (used for point which is a typedef to Vector<scalar>.
Definition: VectorI.H:119
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::pointHit
PointHit< point > pointHit
Definition: pointHit.H:43
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
found
bool found
Definition: TABSMDCalcMethod2.H:32
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::List< labelList >
Foam::sqrt
dimensionedScalar sqrt(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:144
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::AMIInterpolation
Interpolation class dealing with transfer of data between two primitive patches with an arbitrary mes...
Definition: AMIInterpolation.H:81
Foam::point
vector point
Point is a vector.
Definition: point.H:43
directAMI.H