50 partialFaceAreaWeightAMI,
111 label nFacesRemaining = srcAddr.size();
120 labelList seedFaces(nFacesRemaining, -1);
121 seedFaces[srcFacei] = tgtFacei;
124 bitSet mapFlag(nFacesRemaining,
true);
127 label startSeedi = 0;
132 bool continueWalk =
true;
138 visitedFaces.
clear();
156 mapFlag.
unset(srcFacei);
160 nonOverlapFaces.
append(srcFacei);
175 }
while (continueWalk);
183 const label srcFacei,
184 const label tgtStartFacei,
187 DynamicList<label>& nbrFaces,
189 DynamicList<label>& visitedFaces,
192 List<DynamicList<label>>& srcAddr,
193 List<DynamicList<scalar>>& srcWght,
194 List<DynamicList<point>>& srcCtr,
195 List<DynamicList<label>>& tgtAddr,
196 List<DynamicList<scalar>>& tgtWght
199 addProfiling(ami,
"faceAreaWeightAMI::processSourceFace");
201 if (tgtStartFacei == -1)
206 const auto& tgtPatch = this->tgtPatch();
209 nbrFaces.append(tgtStartFacei);
210 appendNbrFaces(tgtStartFacei, tgtPatch, visitedFaces, nbrFaces);
212 bool faceProcessed =
false;
214 label maxNeighbourFaces = nbrFaces.size();
216 while (!nbrFaces.empty())
219 label tgtFacei = nbrFaces.back();
221 visitedFaces.push_back(tgtFacei);
223 scalar interArea = 0;
225 calcInterArea(srcFacei, tgtFacei, interArea, interCentroid);
230 srcAddr[srcFacei].append(tgtFacei);
231 srcWght[srcFacei].append(interArea);
232 srcCtr[srcFacei].append(interCentroid);
234 tgtAddr[tgtFacei].append(srcFacei);
235 tgtWght[tgtFacei].append(interArea);
237 appendNbrFaces(tgtFacei, tgtPatch, visitedFaces, nbrFaces);
239 faceProcessed =
true;
241 maxNeighbourFaces =
max(maxNeighbourFaces, nbrFaces.size());
250 return faceProcessed;
259 const bitSet& mapFlag,
262 const bool errorOnNotFound
267 if (mapFlag.count() == 0)
273 const auto& srcPatch = this->srcPatch();
274 const labelList& srcNbrFaces = srcPatch.faceFaces()[srcFacei];
280 bool valuesSet =
false;
281 for (label faceS: srcNbrFaces)
283 if (mapFlag.test(faceS) && seedFaces[faceS] == -1)
285 for (label faceT : visitedFaces)
287 const scalar threshold =
291 if (overlaps(faceS, faceT, threshold))
293 seedFaces[faceS] = faceT;
313 label facei = startSeedi;
314 if (!mapFlag.test(startSeedi))
316 facei = mapFlag.find_next(facei);
318 const label startSeedi0 = facei;
320 bool foundNextSeed =
false;
326 foundNextSeed =
true;
329 if (seedFaces[facei] != -1)
332 tgtFacei = seedFaces[facei];
337 facei = mapFlag.find_next(facei);
343 Pout<<
"Advancing front stalled: searching for new "
344 <<
"target face" <<
endl;
351 tgtFacei = findTargetFace(srcFacei, visitedFaces);
358 facei = mapFlag.find_next(facei);
364 <<
"Unable to set target face for source face " << srcFacei
365 <<
" with centre: " << srcPatch.faceCentres()[srcFacei]
375 const label srcFacei,
376 const label tgtFacei,
384 if (!isCandidate(srcFacei, tgtFacei))
389 const auto& srcPatch = this->srcPatch();
390 const auto& tgtPatch = this->tgtPatch();
392 const pointField& srcPoints = srcPatch.points();
393 const pointField& tgtPoints = tgtPatch.points();
407 vector n(-srcPatch.faceNormals()[srcFacei]);
410 n -= tgtPatch.faceNormals()[tgtFacei];
414 n += tgtPatch.faceNormals()[tgtFacei];
416 scalar magN =
mag(
n);
418 const face& src = srcPatch[srcFacei];
419 const face& tgt = tgtPatch[tgtFacei];
421 if (magN > ROOTVSMALL)
423 inter.calc(src, tgt,
n/magN, area, centroid);
428 <<
"Invalid normal for source face " << srcFacei
430 <<
" target face " << tgtFacei
437 static OBJstream tris(
"intersectionTris.obj");
438 const auto& triPts = inter.triangles();
439 for (
const auto& tp : triPts)
441 tris.write(
triPointRef(tp[0], tp[1], tp[2]),
false);
454 const label srcFacei,
455 const label tgtFacei,
456 const scalar threshold
460 if (!isCandidate(srcFacei, tgtFacei))
465 const auto& srcPatch = this->srcPatch();
466 const auto& tgtPatch = this->tgtPatch();
468 const pointField& srcPoints = srcPatch.points();
469 const pointField& tgtPoints = tgtPatch.points();
482 vector n(-srcPatch.faceNormals()[srcFacei]);
485 n -= tgtPatch.faceNormals()[tgtFacei];
489 n += tgtPatch.faceNormals()[tgtFacei];
491 scalar magN =
mag(
n);
493 const face& src = srcPatch[srcFacei];
494 const face& tgt = tgtPatch[tgtFacei];
496 if (magN > ROOTVSMALL)
498 return inter.overlaps(src, tgt,
n/magN, threshold);
503 <<
"Invalid normal for source face " << srcFacei
505 <<
" target face " << tgtFacei
516 List<DynamicList<label>>& srcAddr,
517 List<DynamicList<scalar>>& srcWght,
518 List<DynamicList<point>>& srcCtr,
519 List<DynamicList<label>>& tgtAddr,
520 List<DynamicList<scalar>>& tgtWght
523 addProfiling(ami,
"faceAreaWeightAMI::restartUncoveredSourceFace");
527 label nBelowMinWeight = 0;
528 const scalar minWeight = 0.95;
531 DynamicList<label> nbrFaces(10);
534 DynamicList<label> visitedFaces(10);
536 const auto& srcPatch = this->srcPatch();
540 const scalar
s =
sum(srcWght[srcFacei]);
541 const scalar t =
s/srcMagSf_[srcFacei];
547 const face&
f = srcPatch[srcFacei];
551 const label tgtFacei =
552 findTargetFace(srcFacei, srcAddr[srcFacei], fpi);
557 visitedFaces = srcAddr[srcFacei];
559 (void)processSourceFace
578 if (
debug && nBelowMinWeight)
581 <<
"Restarted search on " << nBelowMinWeight
582 <<
" faces since sum of weights < " << minWeight
593 const bool reverseTarget
596 advancingFrontAMI(
dict, reverseTarget),
597 restartUncoveredSourceFace_
599 dict.getOrDefault(
"restartUncoveredSourceFace", true)
606 const bool requireMatch,
607 const bool reverseTarget,
608 const scalar lowWeightCorrection,
610 const bool restartUncoveredSourceFace
627 restartUncoveredSourceFace_(ami.restartUncoveredSourceFace_)
652 bool ok = initialiseWalk(srcFacei, tgtFacei);
654 srcCentroids_.setSize(srcAddress_.size());
656 const auto& src = this->srcPatch();
657 const auto& tgt = this->tgtPatch();
660 List<DynamicList<label>> srcAddr(src.size());
661 List<DynamicList<scalar>> srcWght(srcAddr.size());
662 List<DynamicList<point>> srcCtr(srcAddr.size());
663 List<DynamicList<label>> tgtAddr(tgt.size());
664 List<DynamicList<scalar>> tgtWght(tgtAddr.size());
679 if (debug && !srcNonOverlap_.empty())
681 Pout<<
" AMI: " << srcNonOverlap_.size()
682 <<
" non-overlap faces identified"
687 if (restartUncoveredSourceFace_)
689 restartUncoveredSourceFace
703 srcAddress_[i].transfer(srcAddr[i]);
704 srcWeights_[i].transfer(srcWght[i]);
705 srcCentroids_[i].transfer(srcCtr[i]);
708 tgtAddress_.setSize(tgtAddr.size());
709 tgtWeights_.setSize(tgtWght.size());
712 tgtAddress_[i].transfer(tgtAddr[i]);
713 tgtWeights_[i].transfer(tgtWght[i]);
716 if (distributed() && comm() != -1)
726 globalIndex globalSrcFaces(srcPatch0.size(), comm());
727 globalIndex globalTgtFaces(tgtPatch0.size(), comm());
729 for (
labelList& addressing : srcAddress_)
731 for (label& addr : addressing)
733 addr = extendedTgtFaceIDs_[addr];
737 for (
labelList& addressing : tgtAddress_)
739 globalSrcFaces.inplaceToGlobal(myRank, addressing);
750 extendedTgtMapPtr_->constructMap(),
752 extendedTgtMapPtr_->subMap(),
767 extendedTgtMapPtr_->constructMap(),
769 extendedTgtMapPtr_->subMap(),
780 extendedTgtMapPtr_->reverseDistribute(tgtPatch0.size(), tgtMagSf_);
814 normaliseWeights(requireMatch_,
true);
816 nonConformalCorrection();
828 if (restartUncoveredSourceFace_)
832 "restartUncoveredSourceFace",
833 restartUncoveredSourceFace_
Macros for easy insertion into run-time selection tables.
#define addAliasToRunTimeSelectionTable(baseType, thisType, argNames, lookup, other, ver)
Add lookup alias for runTime selection.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
Interpolation class dealing with transfer of data between two primitive patches with an arbitrary mes...
bool requireMatch_
Flag to indicate that the two patches must be matched/an overlap exists between them.
bool mustMatchFaces() const
Return true if requireMatch and but not lowWeightCorrection.
bool reverseTarget() const noexcept
Access to the reverseTarget flag.
labelListList srcAddress_
Addresses of target faces per source face.
label comm() const noexcept
Communicator (local or otherwise) for parallel operations.
bool distributed() const noexcept
Distributed across processors (singlePatchProc == -1).
scalarList tgtMagSf_
Target face areas.
const bool reverseTarget_
Flag to indicate that the two patches are co-directional and that the orientation of the target patch...
autoPtr< mapDistribute > srcMapPtr_
Source map pointer - parallel running only.
bool requireMatch() const noexcept
Return the requireMatch flag.
const primitivePatch & tgtPatch0() const
Return the original tgt patch with optionally updated points.
bool upToDate_
Up-to-date flag.
autoPtr< mapDistribute > tgtMapPtr_
Target map pointer - parallel running only.
labelListList tgtAddress_
Addresses of source faces per target face.
pointListList srcCentroids_
Centroid of target faces per source face.
static bool cacheIntersections_
Flag to store face-to-face intersection triangles; default = false.
static void normaliseWeights(const scalarList &patchAreas, const word &patchName, const labelListList &addr, scalarListList &wght, scalarField &wghtSum, const bool conformal, const bool output, const scalar lowWeightTol, const label comm)
Normalise the (area) weights - suppresses numerical error in weights calculation.
scalar lowWeightCorrection() const
Threshold weight below which interpolation is deactivated.
scalarListList tgtWeights_
Weights of source faces per target face.
scalarListList srcWeights_
Weights of target faces per source face.
scalarList srcMagSf_
Source face areas.
const primitivePatch & srcPatch0() const
Return the original src patch with optionally updated points.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
void pop_back(label n=1)
Reduce size by 1 or more elements. Can be called on an empty list.
void append(const T &val)
Copy append an element to the end of this list.
void push_back(const T &val)
Copy append an element to the end of this list.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
static const List< T > & null() noexcept
Return a null List (reference to a nullObject). Behaves like an empty List.
An OFstream that keeps track of vertices and provides convenience output methods for OBJ files.
virtual Ostream & write(const char c) override
Write character.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
A List with indirect addressing. Like IndirectList but does not store addressing.
bool empty() const noexcept
True if List is empty (ie, size() is zero).
T & back()
Access last element of the list, position [size()-1].
void size(const label n)
Older name for setAddressableSize.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
@ nonBlocking
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
static int & msgType() noexcept
Message tag of standard messages.
static int incrMsgType(int val=1) noexcept
Increment the message tag for standard messages.
Base class for Arbitrary Mesh Interface (AMI) methods.
const primitivePatch & tgtPatch() const
Return const access to the target patch.
bool initialiseWalk(label &srcFacei, label &tgtFacei)
Initialise walk and return true if all ok.
List< DynamicList< face > > srcTris_
Storage for src-side triangle decomposition.
virtual bool calculate(const primitivePatch &srcPatch, const primitivePatch &tgtPatch, const autoPtr< searchableSurface > &surfPtr=nullptr)
Update addressing, weights and (optional) centroids.
bool isCandidate(const label srcFacei, const label tgtFacei) const
Is source/target a valid pair (i.e. not too far/different.
virtual void nonConformalCorrection()
Correction for non-conformal interpolations, e.g. for ACMI.
void appendNbrFaces(const label facei, const primitivePatch &patch, const labelUList &visitedFaces, DynamicList< label > &faceIDs) const
Add faces neighbouring facei to the ID list.
virtual void write(Ostream &os) const
Write.
void writeIntersectionOBJ(const scalar area, const face &f1, const face &f2, const pointField &f1Points, const pointField &f2Points) const
Write triangle intersection to OBJ file.
advancingFrontAMI(const dictionary &dict, const bool reverseTarget)
Construct from components.
List< DynamicList< face > > tgtTris_
Storage for tgt-side triangle decomposition.
const primitivePatch & srcPatch() const
Return const access to the source patch.
autoPtr< mapDistribute > extendedTgtMapPtr_
Extended patch map.
labelList extendedTgtFaceIDs_
Extended patch face IDs.
labelList srcNonOverlap_
Labels of faces that are not overlapped by any target faces (should be empty for correct functioning ...
label findTargetFace(const label srcFacei, const UList< label > &excludeFaces=UList< label >::null(), const label srcFacePti=-1) const
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
unsigned int count(const bool on=true) const
Count number of bits set.
bool test(const label pos) const
Test for True value at specified position, never auto-vivify entries.
bitSet & unset(const bitSet &other)
Unset (subtract) the bits specified in the other bitset, which is a set difference corresponds to the...
label find_next(label pos) const
Locate the next bit set, starting one beyond the specified position.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
void calc(const face &faceA, const face &faceB, const vector &n, scalar &area, vector ¢roid) const
Return area of intersection of faceA with faceB and effective face centre.
bool overlaps(const face &faceA, const face &faceB, const vector &n, const scalar threshold) const
Return area of intersection of faceA with faceB.
static scalar & tolerance()
Fraction of local length scale to use as intersection tolerance.
const DynamicList< triPoints > & triangles() const noexcept
Const access to the triangulation.
Face area weighted Arbitrary Mesh Interface (AMI) method.
virtual void calcAddressing(List< DynamicList< label > > &srcAddress, List< DynamicList< scalar > > &srcWeights, List< DynamicList< point > > &srcCentroids, List< DynamicList< label > > &tgtAddress, List< DynamicList< scalar > > &tgtWeights, label srcFacei, label tgtFacei)
Calculate addressing, weights and centroids using temporary storage.
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< point > > &srcCtr, List< DynamicList< label > > &tgtAddr, List< DynamicList< scalar > > &tgtWght)
Determine overlap contributions for source face srcFacei.
faceAreaWeightAMI(const dictionary &dict, const bool reverseTarget=false)
Construct from dictionary.
virtual bool calculate(const primitivePatch &srcPatch, const primitivePatch &tgtPatch, const autoPtr< searchableSurface > &surfPtr=nullptr)
Update addressing, weights and (optional) centroids.
virtual void write(Ostream &os) const
Write.
virtual void restartUncoveredSourceFace(List< DynamicList< label > > &srcAddr, List< DynamicList< scalar > > &srcWght, List< DynamicList< point > > &srcCtr, List< DynamicList< label > > &tgtAddr, List< DynamicList< scalar > > &tgtWght)
Attempt to re-evaluate source faces that have not been included.
virtual void calcInterArea(const label srcFacei, const label tgtFacei, scalar &area, vector ¢roid) const
Area of intersection between source and target faces.
virtual bool setNextFaces(label &startSeedi, label &srcFacei, label &tgtFacei, const bitSet &mapFlag, labelList &seedFaces, const labelUList &visitedFaces, const bool errorOnNotFound=true) const
Set the source and target seed faces.
virtual bool overlaps(const label srcFacei, const label tgtFacei, const scalar threshold) const
Return true if faces overlap.
A face is a list of labels corresponding to mesh vertices.
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
void inplaceToGlobal(const label proci, labelUList &labels) const
From local to global index on proci (inplace).
static void distribute(const UPstream::commsTypes commsType, const UList< labelPair > &schedule, const label constructSize, const labelListList &subMap, const bool subHasFlip, const labelListList &constructMap, const bool constructHasFlip, List< T > &field, const T &nullValue, const CombineOp &cop, const NegateOp &negOp, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Distribute combine data with specified combine operation and negate operator (for flips).
Class containing processor-to-processor mapping information.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.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))
#define WarningInFunction
Report a warning using Foam::Warning.
#define DebugVar(var)
Report a variable name and value.
Namespace for handling debugging switches.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
List< label > labelList
A List of labels.
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field.
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
errorManip< error > abort(error &err)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1, const label comm)
static constexpr const zero Zero
Global zero (0).
triangle< point, const point & > triPointRef
A triangle using referred points.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
vectorField pointField
pointField is a vectorField.
UList< label > labelUList
A UList of labels.
List< scalar > scalarList
List of scalar.
#define addProfiling(Name,...)
Define profiling trigger with specified name and description string. The description is generated by ...
#define forAll(list, i)
Loop across all elements in list.
List helper to append y elements onto the end of x.
Functor to negate primitives. Dummy for most other types.