56 Info<<
"NO MATCH for source face " << srcFacei <<
endl;
69 const face& srcF = src[srcFacei];
71 for (
const label pointi : srcF)
73 const point&
p = srcPoints[pointi];
74 os <<
"v " <<
p.x() <<
" " <<
p.y() <<
" " <<
p.z() <<
nl;
78 os << faceStr.c_str() <<
" " << (np - srcF.size() + 1) <<
nl;
81 for (
const label tgtFacei : tgtFaceCandidates)
83 const face& tgtF = tgt[tgtFacei];
86 const point&
p = tgtPoints[tgtF[pointi]];
87 os <<
"v " <<
p.x() <<
" " <<
p.y() <<
" " <<
p.z() <<
nl;
91 os <<
"l " << np-1 <<
" " << np <<
nl;
94 os <<
"l " << (np - tgtF.size() + 1) <<
" " << np <<
nl;
99 OFstream
os(
"no_match_" +
Foam::name(srcFacei) +
"_bb.obj");
104 os <<
"v " <<
p.x() <<
" " <<
p.y() <<
" " <<
p.z() <<
endl;
124 const label srcFacei,
125 const label tgtFacei,
126 DynamicList<label>& srcAddr,
127 DynamicList<scalar>& srcWght,
128 DynamicList<vector>& srcCtr,
129 DynamicList<label>& tgtAddr,
130 DynamicList<scalar>& tgtWght
133 addProfiling(ami,
"faceAreaWeightAMI2D::calcInterArea");
136 if (!isCandidate(srcFacei, tgtFacei))
141 const auto& srcPatch = this->srcPatch();
142 const auto& tgtPatch = this->tgtPatch();
144 const pointField& srcPoints = srcPatch.points();
145 const pointField& tgtPoints = tgtPatch.points();
147 const auto& srcTris = srcTris_[srcFacei];
148 const auto& tgtTris = tgtTris_[tgtFacei];
150 const auto& srcFaceNormals = srcPatch.faceNormals();
157 for (
const auto& tris : srcTris)
159 const vector& origin = srcPoints[tris[0]];
160 const vector p10(srcPoints[tris[1]] - origin);
161 const vector p20(srcPoints[tris[2]] - origin);
162 const vector axis1(p10/(
mag(p10) + ROOTVSMALL));
163 const vector axis2(srcFaceNormals[srcFacei]^axis1);
172 for (
const auto& trit : tgtTris)
177 tgtPoints[trit[0]] - origin,
178 tgtPoints[trit[2]] - origin,
179 tgtPoints[trit[1]] - origin,
187 if (t.snapClosePoints(
s) == 3)
194 s.interArea(t, c, da);
198 centroid += da*(origin +
c.x()*axis1 +
c.y()*axis2);
206 centroid /=
area + ROOTVSMALL;
209 srcWght.append(area);
210 srcCtr.append(centroid);
212 tgtAddr.append(srcFacei);
213 tgtWght.append(area);
220 const AABBTree<face>&
tree,
221 const List<boundBox>& tgtFaceBbs,
222 const boundBox& srcFaceBb
227 const auto& treeBb =
tree.boundBoxes();
228 const auto& treeAddr =
tree.addressing();
232 const auto& tbb = treeBb[boxi];
234 if (srcFaceBb.overlaps(tbb))
236 const auto& boxAddr = treeAddr[boxi];
238 for (
const auto& tgtFacei : boxAddr)
240 if (srcFaceBb.overlaps(tgtFaceBbs[tgtFacei]))
242 faceIds.insert(tgtFacei);
248 return faceIds.toc();
257 const bool reverseTarget
267 const bool requireMatch,
268 const bool reverseTarget,
269 const scalar lowWeightCorrection,
271 const bool restartUncoveredSourceFace
313 const auto& src = this->srcPatch();
314 const auto& tgt = this->tgtPatch();
316 bool validSize =
true;
323 else if (!tgt.size())
326 << src.size() <<
" source faces but no target faces" <<
endl;
331 srcCentroids_.setSize(srcAddress_.size());
343 const bool equalBinSize =
true;
344 const label maxLevel = 10;
345 const label minBinSize = 4;
355 const auto& tgtPoints = tgt.points();
359 tgtFaceBbs[facei] =
boundBox(tgtPoints, tgt[facei],
false);
364 const auto& srcPoints = src.points();
368 const face& srcFace = src[srcFacei];
375 overlappingTgtFaces(
tree, tgtFaceBbs, srcFaceBb)
382 for (
const label tgtFacei : tgtFaces)
396 if (mustMatchFaces() && srcAddr.empty())
398 if (
debug) writeNoMatch(srcFacei, tgtFaces, srcFaceBb);
405 srcAddress_[srcFacei].transfer(srcAddr);
406 srcWeights_[srcFacei].transfer(srcWght);
407 srcCentroids_[srcFacei].transfer(srcCtr);
410 srcNonOverlap_.transfer(nonOverlapFaces);
412 if (
debug && !srcNonOverlap_.empty())
414 Pout<<
" AMI: " << srcNonOverlap_.size()
415 <<
" non-overlap faces identified"
424 tgtAddress_[i].transfer(tgtAddr[i]);
425 tgtWeights_[i].transfer(tgtWght[i]);
428 if (distributed() && comm() != -1)
438 const globalIndex globalSrcFaces(srcPatch0.size(), comm());
439 const globalIndex globalTgtFaces(tgtPatch0.size(), comm());
441 for (
labelList& addressing : srcAddress_)
443 for (label& addr : addressing)
445 addr = extendedTgtFaceIDs_[addr];
449 for (
labelList& addressing : tgtAddress_)
451 globalSrcFaces.inplaceToGlobal(myRank, addressing);
462 extendedTgtMapPtr_->constructMap(),
464 extendedTgtMapPtr_->subMap(),
479 extendedTgtMapPtr_->constructMap(),
481 extendedTgtMapPtr_->subMap(),
492 extendedTgtMapPtr_->reverseDistribute(tgtPatch0.size(), tgtMagSf_);
526 normaliseWeights(requireMatch_,
true);
528 nonConformalCorrection();
539 os.writeEntryIfDifferent<scalar>(
"Cbb", 0.1, Cbb_);
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
Templated tree of axis-aligned bounding boxes (AABB).
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.
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 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 append(const T &val)
Copy append an element to the end of this list.
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
List< Key > toc() const
The table of contents (the keys) in unsorted order.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void append(const T &val)
Append an element at the end of the list.
static const List< T > & null() noexcept
Return a null List (reference to a nullObject). Behaves like an empty List.
Output to file stream as an OSstream, normally using std::ofstream for the actual output.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
bool empty() const noexcept
True if List is empty (ie, size() is zero).
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.
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.
virtual void write(Ostream &os) const
Write.
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 ...
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.
void grow(const scalar delta)
Expand box by adjusting min/max by specified amount in each dimension.
bool overlaps(const boundBox &bb) const
Overlaps/touches boundingBox?
tmp< pointField > points() const
Corner points in an order corresponding to a 'hex' cell.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Face area weighted Arbitrary Mesh Interface (AMI) method that performs the intersection of src and tg...
void storeInterArea(const label srcFacei, const label tgtFacei, DynamicList< label > &srcAddr, DynamicList< scalar > &srcWght, DynamicList< vector > &srcCtr, DynamicList< label > &tgtAddr, DynamicList< scalar > &tgtWght) const
Calculate and store the area of intersection between source and target faces.
virtual bool calculate(const primitivePatch &srcPatch, const primitivePatch &tgtPatch, const autoPtr< searchableSurface > &surfPtr=nullptr)
Update addressing, weights and (optional) centroids.
scalar Cbb_
Face bounding box factor.
virtual void write(Ostream &os) const
Write.
labelList overlappingTgtFaces(const AABBTree< face > &tree, const List< boundBox > &tgtFaceBbs, const boundBox &srcFaceBb) const
Return the set of tgt face IDs that overlap the src face bb.
void writeNoMatch(const label srcFacei, const labelList &tgtFaceCandidates, const boundBox &srcFaceBb) const
Helper function to write non-matched source faces to the set of candidate faces.
faceAreaWeightAMI2D(const dictionary &dict, const bool reverseTarget=false)
Construct from dictionary.
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.
Standard boundBox with extra functionality for use in octree.
label snapClosePoints(const triangle2D &triB)
Snap [this] triangle's points to those of triB if they are within absTol.
static scalar relTol
Relative tolerance.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
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.
const dimensionedScalar c
Speed of light in a vacuum.
Namespace for handling debugging switches.
const wordList area
Standard area field types (scalar, vector, tensor, etc).
Type gAverage(const FieldField< Field, Type > &f, const label comm)
The global arithmetic average of a FieldField.
List< label > labelList
A List of labels.
Vector2D< scalar > vector2D
A 2D vector of scalars obtained from the generic Vector2D.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
messageStream Info
Information stream (stdout output on master, null elsewhere).
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field.
MinMax< scalar > scalarMinMax
A scalar min/max range.
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
vector point
Point is a vector.
static constexpr const zero Zero
Global zero (0).
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
vectorField pointField
pointField is a vectorField.
List< scalar > scalarList
List of scalar.
constexpr char nl
The newline '\n' character (0x0a).
#define addProfiling(Name,...)
Define profiling trigger with specified name and description string. The description is generated by ...
Tree tree(triangles.begin(), triangles.end())
#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.