50 if (debug && (!src.size() || !tgt.size()))
52 Pout<<
"AMI: Patches not on processor: Source faces = "
53 << src.size() <<
", target faces = " << tgt.size()
60 const scalar maxBoundsError = 0.05;
63 boundBox bbSrc(src.points(), src.meshPoints(),
true);
64 boundBox bbTgt(tgt.points(), tgt.meshPoints(),
true);
67 bbTgtInf.
inflate(maxBoundsError);
72 <<
"Source and target patch bounding boxes are not similar"
74 <<
" source box span : " << bbSrc.
span() <<
nl
75 <<
" target box span : " << bbTgt.
span() <<
nl
76 <<
" source box : " << bbSrc <<
nl
77 <<
" target box : " << bbTgt <<
nl
78 <<
" inflated target box : " << bbTgtInf <<
endl;
90 const auto& srcPatch = this->srcPatch();
91 const auto& tgtPatch = this->tgtPatch();
95 (srcMagSf_[srcFacei] < ROOTVSMALL)
96 || (tgtMagSf_[tgtFacei] < ROOTVSMALL)
102 if (maxDistance2_ > 0)
104 const point& srcFc = srcPatch.faceCentres()[srcFacei];
105 const point& tgtFc = tgtPatch.faceCentres()[tgtFacei];
106 const vector& srcN = srcPatch.faceNormals()[srcFacei];
108 const scalar normalDist((tgtFc-srcFc)&srcN);
110 if (
sqr(normalDist) >= maxDistance2_)
116 if (minCosAngle_ > -1)
118 const vector& srcN = srcPatch.faceNormals()[srcFacei];
119 vector tgtN = tgtPatch.faceNormals()[tgtFacei];
125 if ((srcN & tgtN) <= minCosAngle_)
140 extendedTgtMapPtr_.reset(calcProcMap(srcPatch0(), tgtPatch0()));
146 distributeAndMergePatches
158 extendedTgtPatchPtr_.reset
171 const auto& src = this->srcPatch();
172 const auto& tgt = this->tgtPatch();
174 bool foundFace =
false;
181 else if (!tgt.size())
184 << src.size() <<
" source faces but no target faces" <<
endl;
190 treePtr_.reset(createTree(tgt));
193 if ((srcFacei == -1) || (tgtFacei == -1))
199 tgtFacei = findTargetFace(facei);
213 <<
"Unable to find initial target face"
223 Pout<<
"AMI: initial target face = " << tgtFacei <<
endl;
239 static label count = 1;
244 Pout<<
"Face intersection area (" << count <<
"):" <<
nl
245 <<
" f1 face = " << f1 <<
nl
246 <<
" f1 pts = " << f1pts <<
nl
247 <<
" f2 face = " << f2 <<
nl
248 <<
" f2 pts = " << f2pts <<
nl
249 <<
" area = " << area
254 for (
const point& pt : f1pts)
265 for (
const point& pt : f2pts)
270 const label
n = f1pts.
size();
273 os<<
" " <<
n + i + 1;
283 const label srcFacei,
285 const label srcFacePti
288 const auto& src = srcPatch();
290 label targetFacei = -1;
293 const face& srcFace = src[srcFacei];
297 const boundBox bb(srcPts, srcFace,
false);
300 srcFacePti == -1 ? bb.
centre() : srcPts[srcFace[srcFacePti]];
305 if (
sample.hit() && isCandidate(srcFacei,
sample.index()))
307 targetFacei =
sample.index();
311 Pout<<
"Source point = " << srcPt <<
", Sample point = "
312 <<
sample.hitPoint() <<
", Sample index = " <<
sample.index()
331 const labelList& nbrFaces = patch.faceFaces()[facei];
334 for (
const label nbrFacei : nbrFaces)
337 if (!visitedFaces.
found(nbrFacei) && !faceIDs.
found(nbrFacei))
339 const vector& n1 = patch.faceNormals()[facei];
340 const vector& n2 = patch.faceNormals()[nbrFacei];
342 const scalar cosI = n1 & n2;
361 tris.setSize(patch.size());
378 patch[facei].triangles(
points, tris[facei]);
385 for (
const face&
f : triFaces)
401 if (!requireMatch_ && distributed())
409 tgtMagSf_ = tgtPatch0().magFaceAreas();
411 for (
const labelList& smap : this->extendedTgtMapPtr_->subMap())
425 const bool reverseTarget
429 maxDistance2_(
dict.getOrDefault<scalar>(
"maxDistance2", -1)),
430 minCosAngle_(
dict.getOrDefault<scalar>(
"minCosAngle", -1)),
433 extendedTgtPatchPtr_(nullptr),
435 extendedTgtPoints_(),
436 extendedTgtFaceIDs_(),
437 extendedTgtMapPtr_(nullptr),
453 const bool requireMatch,
454 const bool reverseTarget,
455 const scalar lowWeightCorrection,
464 extendedTgtPatchPtr_(nullptr),
466 extendedTgtPoints_(),
467 extendedTgtFaceIDs_(),
468 extendedTgtMapPtr_(nullptr),
477 maxDistance2_(ami.maxDistance2_),
478 minCosAngle_(ami.minCosAngle_),
481 extendedTgtPatchPtr_(nullptr),
483 extendedTgtPoints_(),
484 extendedTgtFaceIDs_(),
485 extendedTgtMapPtr_(nullptr),
487 triMode_(ami.triMode_)
500 if (AMIInterpolation::calculate(srcPatch, tgtPatch, surfPtr))
506 createExtendedTgtPatch();
509 const auto& src = this->srcPatch();
510 const auto& tgt = this->tgtPatch();
513 if (maxDistance2_ > 0)
516 (void)src.faceCentres();
517 (void)tgt.faceCentres();
519 (void)src.faceNormals();
520 (void)tgt.faceNormals();
522 if (minCosAngle_ > -1)
525 (void)src.faceNormals();
526 (void)tgt.faceNormals();
531 srcMagSf_.setSize(src.size(), 1.0);
532 tgtMagSf_.setSize(tgt.size(), 1.0);
535 triangulatePatch(src, srcTris_, srcMagSf_);
536 triangulatePatch(tgt, tgtTris_, tgtMagSf_);
542 srcAddress_.setSize(src.size());
543 srcWeights_.setSize(src.size());
544 tgtAddress_.setSize(tgt.size());
545 tgtWeights_.setSize(tgt.size());
Interpolation class dealing with transfer of data between two primitive patches with an arbitrary mes...
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
void append(const T &val)
Copy append an element to the end of this list.
Minimal example by using system/controlDict.functions:
void setSize(const label n)
Alias for resize()
Output to file stream, using an OSstream.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Ostream & writeEntryIfDifferent(const word &key, const T &value1, const T &value2)
Write a keyword/value entry only when the two values differ.
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
A list of faces which address into the list of points.
A List obtained as a section of another List.
A List with indirect addressing. Like IndirectList but does not store addressing.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
bool found(const T &val, label pos=0) const
True if the value if found in the list.
void size(const label n)
Older name for setAddressableSize.
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.
void checkPatches() const
Check AMI patch coupling.
void appendNbrFaces(const label facei, const primitivePatch &patch, const DynamicList< label > &visitedFaces, DynamicList< label > &faceIDs) const
Add faces neighbouring facei to the ID list.
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 createExtendedTgtPatch()
Create a map that extends tgtPatch so that it covers srcPatch.
void writeIntersectionOBJ(const scalar area, const face &f1, const face &f2, const pointField &f1Points, const pointField &f2Points) const
Write triangle intersection to OBJ file.
const primitivePatch & srcPatch() const
Return const access to the source patch.
void triangulatePatch(const primitivePatch &patch, List< DynamicList< face > > &tris, List< scalar > &magSf) const
Helper function to decompose a patch.
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 bounding box defined in terms of min/max extrema points.
const point & max() const
Maximum describing the bounding box.
bool contains(const point &pt) const
Contains point? (inside or on edge)
void inflate(const scalar s)
Inflate box by factor*mag(span) in all dimensions.
vector span() const
The bounding box span (from minimum to maximum)
point centre() const
The centre (midpoint) of the bounding box.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
static void triangleFan(const face &f, DynamicList< face > &faces)
Decompose face into triangle fan.
static const Enum< triangulationMode > triangulationModeNames_
A face is a list of labels corresponding to mesh vertices.
pointField points(const UList< point > &pts) const
Return the points corresponding to this face.
virtual bool write()
Write the output fields.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Class containing processor-to-processor mapping information.
A class for handling words, derived from Foam::string.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
#define WarningInFunction
Report a warning using Foam::Warning.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Ostream & endl(Ostream &os)
Add newline and flush stream.
constexpr scalar degToRad() noexcept
Multiplication factor for degrees to radians conversion.
triangle< point, const point & > triPointRef
A triangle using referred points.
errorManip< error > abort(error &err)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
dimensionedScalar cos(const dimensionedScalar &ds)
constexpr char nl
The newline '\n' character (0x0a)
#define forAll(list, i)
Loop across all elements in list.
Unit conversion functions.