30 template<
class SourcePatch,
class TargetPatch>
44 label nFacesRemaining = srcAddr.size();
54 seedFaces[srcFacei] = tgtFacei;
57 boolList mapFlag(nFacesRemaining,
true);
66 bool faceProcessed = processSourceFace
80 mapFlag[srcFacei] =
false;
86 nonOverlapFaces.
append(srcFacei);
90 if (nFacesRemaining > 0)
102 }
while (nFacesRemaining > 0);
104 this->srcNonOverlap_.transfer(nonOverlapFaces);
108 template<
class SourcePatch,
class TargetPatch>
111 const label srcFacei,
112 const label tgtStartFacei,
126 if (tgtStartFacei == -1)
132 visitedFaces.
clear();
135 nbrFaces.
append(tgtStartFacei);
144 bool faceProcessed =
false;
150 visitedFaces.
append(tgtFacei);
151 scalar area = interArea(srcFacei, tgtFacei);
154 if (area/this->srcMagSf_[srcFacei] > faceAreaIntersect::tolerance())
156 srcAddr[srcFacei].append(tgtFacei);
157 srcWght[srcFacei].append(area);
159 tgtAddr[tgtFacei].append(srcFacei);
160 tgtWght[tgtFacei].append(area);
170 faceProcessed =
true;
173 }
while (nbrFaces.
size() > 0);
175 return faceProcessed;
179 template<
class SourcePatch,
class TargetPatch>
191 const labelList& srcNbrFaces = this->srcPatch_.faceFaces()[srcFacei];
197 bool valuesSet =
false;
200 label faceS = srcNbrFaces[i];
202 if (mapFlag[faceS] && seedFaces[faceS] == -1)
206 label faceT = visitedFaces[j];
207 scalar area = interArea(faceS, faceT);
208 scalar areaTotal = this->srcMagSf_[srcFacei];
211 if (area/areaTotal > faceAreaIntersect::tolerance())
215 seedFaces[faceS] = faceT;
236 bool foundNextSeed =
false;
237 for (
label facei = startSeedI; facei < mapFlag.
size(); facei++)
244 foundNextSeed =
true;
247 if (seedFaces[facei] != -1)
250 tgtFacei = seedFaces[facei];
260 Pout<<
"Advancing front stalled: searching for new " 261 <<
"target face" <<
endl;
264 foundNextSeed =
false;
265 for (
label facei = startSeedI; facei < mapFlag.
size(); facei++)
271 startSeedI = facei + 1;
272 foundNextSeed =
true;
276 tgtFacei = this->findTargetFace(srcFacei);
294 template<
class SourcePatch,
class TargetPatch>
297 const label srcFacei,
303 const pointField& srcPoints = this->srcPatch_.points();
304 const pointField& tgtPoints = this->tgtPatch_.points();
307 const face& src = this->srcPatch_[srcFacei];
308 const face& tgt = this->tgtPatch_[tgtFacei];
312 const scalar tgtMag = tgt.
mag(tgtPoints);
313 if ((this->srcMagSf_[srcFacei] < ROOTVSMALL) || (tgtMag < ROOTVSMALL))
322 vector n(-this->srcPatch_.faceNormals()[srcFacei]);
323 if (this->reverseTarget_)
325 n -= this->tgtPatch_.faceNormals()[tgtFacei];
329 n += this->tgtPatch_.faceNormals()[tgtFacei];
331 scalar magN =
mag(
n);
333 if (magN > ROOTVSMALL)
335 area = inter.
calc(src, tgt,
n/magN, this->triMode_);
340 <<
"Invalid normal for source face " << srcFacei
342 <<
" target face " << tgtFacei
348 if ((debug > 1) && (area > 0))
350 this->writeIntersectionOBJ(area, src, tgt, srcPoints, tgtPoints);
357 template<
class SourcePatch,
class TargetPatch>
373 scalar
s =
sum(srcWght[srcFacei]);
374 scalar t = s/this->srcMagSf_[srcFacei];
378 lowWeightFaces.
insert(srcFacei);
384 Pout<<
"faceAreaWeightAMI: restarting search on " 385 << lowWeightFaces.
size() <<
" faces since sum of weights < 0.5" 389 if (lowWeightFaces.
size() > 0)
399 okSrcWeights.
clear();
404 if (!lowWeightFaces.
found(srcFaces[i]))
406 okSrcFaces.
append(srcFaces[i]);
407 okSrcWeights.
append(srcWeights[i]);
410 if (okSrcFaces.
size() < srcFaces.
size())
430 label srcFacei = iter.key();
431 label tgtFacei = this->findTargetFace(srcFacei);
457 template<
class SourcePatch,
class TargetPatch>
460 const SourcePatch& srcPatch,
461 const TargetPatch& tgtPatch,
465 const bool reverseTarget,
466 const bool requireMatch,
467 const bool restartUncoveredSourceFace
480 restartUncoveredSourceFace_(restartUncoveredSourceFace)
486 template<
class SourcePatch,
class TargetPatch>
493 template<
class SourcePatch,
class TargetPatch>
536 if (debug && !this->srcNonOverlap_.empty())
538 Pout<<
" AMI: " << this->srcNonOverlap_.size()
539 <<
" non-overlap faces identified" 545 if (restartUncoveredSourceFace_)
547 restartUncoveredSourceFace
virtual void calcAddressing(List< DynamicList< label >> &srcAddress, List< DynamicList< scalar >> &srcWeights, List< DynamicList< label >> &tgtAddress, List< DynamicList< scalar >> &tgtWeights, label srcFacei, label tgtFacei)
Calculate addressing and weights using temporary storage.
virtual scalar interArea(const label srcFacei, const label tgtFacei) const
Area of intersection between source and target faces.
virtual bool processSourceFace(const label srcFacei, const label tgtStartFacei, DynamicList< label > &nbrFaces, DynamicList< label > &visitedFaces, List< DynamicList< label >> &srcAddr, List< DynamicList< scalar >> &srcWght, List< DynamicList< label >> &tgtAddr, List< DynamicList< scalar >> &tgtWght)
Determine overlap contributions for source face srcFacei.
#define forAll(list, i)
Loop across all elements in list.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
A face is a list of labels corresponding to mesh vertices.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void size(const label)
Override size to be inconsistent with allocated storage.
Ostream & endl(Ostream &os)
Add newline and flush stream.
bool insert(const Key &key)
Insert a new entry.
virtual ~faceAreaWeightAMI()
Destructor.
label size() const
Return number of elements in table.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
virtual void calculate(labelListList &srcAddress, scalarListList &srcWeights, labelListList &tgtAddress, scalarListList &tgtWeights, label srcFacei=-1, label tgtFacei=-1)
Update addressing and weights.
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
bool found(const Key &) const
Return true if hashedEntry is found in table.
scalar mag(const pointField &) const
Magnitude of face area.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
scalar calc(const face &faceA, const face &faceB, const vector &n, const triangulationMode &triMode)
Return area of intersection of faceA with faceB.
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
errorManip< error > abort(error &err)
virtual void setNextFaces(label &startSeedI, label &srcFacei, label &tgtFacei, const boolList &mapFlag, labelList &seedFaces, const DynamicList< label > &visitedFaces, bool errorOnNotFound=true) const
Set the source and target seed faces.
Base class for Arbitrary Mesh Interface (AMI) methods.
T remove()
Remove and return the top element.
virtual void restartUncoveredSourceFace(List< DynamicList< label >> &srcAddr, List< DynamicList< scalar >> &srcWght, List< DynamicList< label >> &tgtAddr, List< DynamicList< scalar >> &tgtWght)
Attempt to re-evaluate source faces that have not been included.
#define WarningInFunction
Report a warning using Foam::Warning.
prefixOSstream Pout(cout, "Pout")
A List with indirect addressing.
dimensioned< scalar > mag(const dimensioned< Type > &)
void clear()
Clear the addressed list, i.e. set the size to zero.
void transfer(List< T > &)
Transfer contents of the argument List into this.
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
faceAreaWeightAMI(const faceAreaWeightAMI &)
Disallow default bitwise copy construct.