35 namespace patchToPatches
52 Foam::patchToPatches::intersection::triPointValues
61 result[i] = values[t[i]];
80 const scalar l =
sqrt(
mag(srcFace.
area(srcPoints)));
82 forAll(srcFace, srcFacePointi)
84 const label srcPointi = srcFace[srcFacePointi];
86 const point&
p = srcPoints[srcPointi];
87 const vector&
n = srcPointNormals[srcPointi];
106 return srcBoxStatic(srcFace, srcPoints, srcPointNormals);
110 bool Foam::patchToPatches::intersection::intersectFaces
116 const label srcFacei,
129 if (!srcFaceBox.
overlaps(tgtFaceBox))
return false;
132 if (srcTriPoints_[srcFacei].empty())
134 triEngine_.triangulate
143 srcTriPoints_[srcFacei] =
144 triEngine_.triPoints(srcPatch.
localFaces()[srcFacei]);
145 srcTriFaceEdges_[srcFacei] = triEngine_.triEdges();
147 if (tgtTriPoints_[tgtFacei].empty())
149 triEngine_.triangulate
158 tgtTriPoints_[tgtFacei] =
159 triEngine_.triPoints(tgtPatch.
localFaces()[tgtFacei]);
160 tgtTriFaceEdges_[tgtFacei] = triEngine_.triEdges();
164 bool srcCouples =
false;
166 srcFaceEdgePart_.resize(srcPatch[srcFacei].size());
167 forAll(srcFaceEdgePart_, srcFaceEdgei)
170 srcPatch.
localFaces()[srcFacei].faceEdge(srcFaceEdgei);
172 srcFaceEdgePart_[srcFaceEdgei] =
part(
Zero, eC);
175 bool tgtCouples =
false;
177 tgtFaceEdgePart_.resize(tgtPatch[tgtFacei].size());
178 forAll(tgtFaceEdgePart_, tgtFaceEdgei)
181 tgtPatch.
localFaces()[tgtFacei].faceEdge(tgtFaceEdgei);
183 tgtFaceEdgePart_[tgtFaceEdgei] =
part(
Zero, eC);
189 const scalar srcMagA =
mag(srcPatch.
faceAreas()[srcFacei]);
190 const scalar tgtMagA =
mag(tgtPatch.
faceAreas()[tgtFacei]);
193 const bool debugTriIntersect =
194 (debugSrcFacei != -1 || debugTgtFacei != -1)
195 && (debugSrcFacei == -1 || debugSrcFacei == srcFacei)
196 && (debugTgtFacei == -1 || debugTgtFacei == tgtFacei);
199 bool anyCouples =
false;
200 forAll(srcTriPoints_[srcFacei], srcFaceTrii)
202 const triFace& srcT = srcTriPoints_[srcFacei][srcFaceTrii];
207 triPointValues(srcT, srcPointNormals);
209 forAll(tgtTriPoints_[tgtFacei], tgtFaceTrii)
213 ? tgtTriPoints_[tgtFacei][tgtFaceTrii].reverseFace()
214 : tgtTriPoints_[tgtFacei][tgtFaceTrii];
220 ictSrcPoints_.clear();
221 ictSrcPointNormals_.clear();
222 ictTgtPoints_.clear();
223 ictPointLocations_.clear();
228 {
false,
false,
false},
231 {
false,
false,
false},
245 (srcFaceTrii*tgtTriPoints_[tgtFacei].size() + tgtFaceTrii)
251 if (ictPointLocations_.empty())
260 const part ictSrcPart(ictSrcPoints_);
261 const part ictTgtPart(ictTgtPoints_);
266 mag(ictSrcPart.
area) < small*srcMagA
267 ||
mag(ictTgtPart.
area) < small*tgtMagA
274 srcCouples = tgtCouples =
true;
277 srcCouple += ictSrcPart;
278 srcCouple.
nbr += ictTgtPart;
281 tgtCouple += ictTgtPart;
282 tgtCouple.
nbr += ictSrcPart;
286 tgtCouple -= ictTgtPart;
287 tgtCouple.
nbr -= ictSrcPart;
291 const label debugSrcPoint0 = debugPoints_.size();
292 const label debugTgtPoint0 =
293 debugPoints_.size() + ictSrcPoints_.size();
296 debugPoints_.append(ictSrcPoints_);
297 debugPoints_.append(ictTgtPoints_);
300 debugSrcPoint0 +
identity(ictSrcPoints_.size())
302 debugFaceSrcFaces_.append(srcFacei);
303 debugFaceTgtFaces_.append(tgtFacei);
304 debugFaceSides_.append(1);
307 debugTgtPoint0 +
identity(ictTgtPoints_.size())
309 debugFaceSrcFaces_.append(srcFacei);
310 debugFaceTgtFaces_.append(tgtFacei);
311 debugFaceSides_.append(-1);
315 forAll(ictPointLocations_, i0)
317 const label i1 = ictPointLocations_.fcIndex(i0);
325 const part ictEdgePart
358 const label srcFaceEdgei =
359 srcTriFaceEdges_[srcFacei][srcFaceTrii][srcEi];
361 if (srcFaceEdgei < srcPatch[srcFacei].size())
363 srcFaceEdgePart_[srcFaceEdgei] += ictEdgePart;
368 errorPart += ictEdgePart;
391 const label tgtFaceEdgei =
392 tgtTriFaceEdges_[tgtFacei][tgtFaceTrii]
393 [
reverse() ? 2 - tgtEi : tgtEi];
395 if (tgtFaceEdgei < tgtPatch[tgtFacei].size())
399 tgtFaceEdgePart_[tgtFaceEdgei] += ictEdgePart;
403 tgtFaceEdgePart_[tgtFaceEdgei] -= ictEdgePart;
409 errorPart += ictEdgePart;
419 <<
"Tri-intersection topology not recognised. " 436 debugFaceSrcFaces_.append(srcFacei);
437 debugFaceTgtFaces_.append(tgtFacei);
438 debugFaceSides_.append(ictEdgeSide);
447 srcLocalTgtFaces_[srcFacei].append(tgtFacei);
448 srcCouples_[srcFacei].append(srcCouple);
454 forAll(srcFaceEdgeParts_[srcFacei], srcFaceEdgei)
456 srcFaceEdgeParts_[srcFacei][srcFaceEdgei] +=
457 srcFaceEdgePart_[srcFaceEdgei];
459 srcErrorParts_[srcFacei] -=
sum(tgtFaceEdgePart_);
460 srcErrorParts_[srcFacei] += errorPart;
466 tgtLocalSrcFaces_[tgtFacei].append(srcFacei);
467 tgtCouples_[tgtFacei].append(tgtCouple);
474 void Foam::patchToPatches::intersection::initialise
490 srcCouples_.resize(srcPatch.size());
491 forAll(srcLocalTgtFaces_, i)
493 srcCouples_[i].clear();
496 srcEdgeParts_.resize(srcPatch.
nEdges());
497 forAll(srcEdgeParts_, srcEdgei)
501 srcEdgeParts_[srcEdgei] =
part(
Zero, c);
504 srcErrorParts_.resize(srcPatch.size());
505 forAll(srcErrorParts_, srcFacei)
507 srcErrorParts_[srcFacei] =
511 tgtCouples_.resize(tgtPatch.size());
512 forAll(tgtLocalSrcFaces_, i)
514 tgtCouples_[i].clear();
522 srcFaceEdgeParts_.
resize(srcPatch.size());
523 forAll(srcFaceEdgeParts_, srcFacei)
525 srcFaceEdgeParts_[srcFacei].resize(srcPatch[srcFacei].size());
526 forAll(srcFaceEdgeParts_[srcFacei], srcFaceEdgei)
528 const label srcEdgei =
529 srcPatch.
faceEdges()[srcFacei][srcFaceEdgei];
530 srcFaceEdgeParts_[srcFacei][srcFaceEdgei] = srcEdgeParts_[srcEdgei];
536 debugPoints_.
clear();
538 debugFaceSrcFaces_.clear();
539 debugFaceTgtFaces_.clear();
540 debugFaceSides_.clear();
545 void Foam::patchToPatches::intersection::rDistributeTgt
553 rDistributeListList(tgtPatch.size(), tgtMap, tgtCouples_);
557 Foam::label Foam::patchToPatches::intersection::finalise
566 const label nCouples =
577 labelList srcEdgeNParts(srcEdgeParts_.size(), 0);
578 forAll(srcEdgeParts_, srcEdgei)
582 srcEdgeParts_[srcEdgei] =
part();
587 const label srcFaceEdgei =
591 srcPatch.
localFaces()[srcFacei].faceEdge(srcFaceEdgei);
595 srcEdgeParts_[srcEdgei] +=
596 srcFaceEdgeParts_[srcFacei][srcFaceEdgei];
600 srcEdgeParts_[srcEdgei] -=
601 srcFaceEdgeParts_[srcFacei][srcFaceEdgei];
604 srcEdgeNParts[srcEdgei] ++;
607 forAll(srcEdgeParts_, srcEdgei)
609 srcEdgeParts_[srcEdgei].area /= srcEdgeNParts[srcEdgei];
614 forAll(srcEdgeParts_, srcEdgei)
621 const label srcFaceEdgei =
625 srcPatch.
localFaces()[srcFacei].faceEdge(srcFaceEdgei);
629 srcErrorParts_[srcFacei] -= srcEdgeParts_[srcEdgei];
633 srcErrorParts_[srcFacei] += srcEdgeParts_[srcEdgei];
636 srcErrorParts_[srcFacei] +=
637 srcFaceEdgeParts_[srcFacei][srcFaceEdgei];
644 forAll(tgtCouples_, tgtFacei)
646 forAll(tgtCouples_[tgtFacei], i)
648 couple&
c = tgtCouples_[tgtFacei][i];
659 srcTriPoints_.clear();
660 srcTriFaceEdges_.clear();
661 tgtTriPoints_.clear();
662 tgtTriFaceEdges_.clear();
665 srcFaceEdgePart_.clear();
666 tgtFaceEdgePart_.clear();
667 srcFaceEdgeParts_.clear();
672 scalar srcArea = 0, srcCoupleArea = 0;
678 forAll(srcPatch, srcFacei)
681 const scalar magA =
mag(a);
685 forAll(srcCouples_[srcFacei], srcTgtFacei)
687 const couple& cpl = srcCouples_[srcFacei][srcTgtFacei];
692 const scalar magCA =
mag(Cpl.
area);
695 srcCoupleArea += magCA;
696 srcCoverage[srcFacei] = magCA/magA;
699 scalar projectionV = 0;
700 forAll(srcCouples_[srcFacei], srcTgtFacei)
702 const couple& cpl = srcCouples_[srcFacei][srcTgtFacei];
711 const label srcEdgei =
712 srcPatch.
faceEdges()[srcFacei][srcFaceEdgei];
716 srcPatch.
localFaces()[srcFacei].faceEdge(srcFaceEdgei);
720 projectionA += sign*srcEdgeParts_[srcEdgei].area;
722 sign*srcEdgeParts_[srcEdgei].area/3
723 & (srcEdgeParts_[srcEdgei].centre - Cpl.
centre);
725 projectionA += srcErrorParts_[srcFacei].area;
727 srcErrorParts_[srcFacei].area/3
728 & (srcErrorParts_[srcFacei].centre - Cpl.
centre);
734 srcOpenness[srcFacei] =
mag(projectionA - Cpl.
area)/magA;
735 srcError[srcFacei] =
mag(srcErrorParts_[srcFacei].area)/magA;
736 srcDepth[srcFacei] =
mag(projectionV)/
pow3(
sqrt(magA));
742 scalar tgtArea = 0, tgtCoupleArea = 0;
744 forAll(tgtPatch, tgtFacei)
746 const scalar magA =
mag(tgtPatch.
faceAreas()[tgtFacei]);
749 forAll(tgtCouples_[tgtFacei], tgtSrcFacei)
751 aCouple += tgtCouples_[tgtFacei][tgtSrcFacei].area;
753 const scalar magACouple =
mag(aCouple);
756 tgtCoupleArea += magACouple;
757 tgtCoverage[tgtFacei] = magACouple/magA;
763 Info<<
indent <<
"Source min/average/max coverage = " 764 <<
gMin(srcCoverage) <<
'/' << srcCoupleArea/srcArea <<
'/' 766 <<
indent <<
"Target min/average/max coverage = " 767 <<
gMin(tgtCoverage) <<
'/' << tgtCoupleArea/tgtArea <<
'/' 769 <<
indent <<
"Source average openness/error/depth/angle = " 772 <<
indent <<
"Source max openness/error/depth/angle = " 773 <<
gMax(srcOpenness) <<
'/' <<
gMax(srcError) <<
'/' 778 word name = patchToPatch::typeName +
'_' + typeName;
785 Info<<
indent <<
"Writing intersected faces to " 786 << name +
".vtk" <<
endl;
801 debugPoints_.clear();
803 debugFaceSrcFaces_.clear();
804 debugFaceTgtFaces_.clear();
805 debugFaceSides_.clear();
808 << name +
"_srcPatch.vtk" <<
endl;
811 name +
"_srcPatch" +
".vtk",
818 "coverage",
false, srcCoverage,
819 "openness",
false, srcOpenness,
820 "error",
false, srcError,
821 "depth",
false, srcDepth,
822 "angle",
false, srcAngle
826 << name +
"_tgtPatch.vtk" <<
endl;
829 name +
"_tgtPatch" +
".vtk",
836 "coverage",
false, tgtCoverage
864 ictSrcPointNormals_(),
866 ictPointLocations_(),
875 debugFaceSrcFaces_(),
876 debugFaceTgtFaces_(),
901 forAll(srcCouples_, srcFacei)
903 result[srcFacei].
resize(srcCouples_[srcFacei].size());
905 const scalar magA =
mag(srcPatch.
faceAreas()[srcFacei]);
907 forAll(srcCouples_[srcFacei], i)
909 result[srcFacei][i] =
mag(srcCouples_[srcFacei][i].area)/magA;
929 forAll(tgtCouples_, tgtFacei)
931 result[tgtFacei].
resize(tgtCouples_[tgtFacei].size());
933 const scalar magA =
mag(tgtPatch.
faceAreas()[tgtFacei]);
935 forAll(tgtCouples_[tgtFacei], i)
937 result[tgtFacei][i] =
mag(tgtCouples_[tgtFacei][i].area)/magA;
addToRunTimeSelectionTable(patchToPatch, intersection, bool)
dimensionedScalar sign(const dimensionedScalar &ds)
bool overlaps(const boundBox &) const
Overlaps/touches boundingBox?
List< labelList > labelListList
A List of labelList.
dimensionedScalar acos(const dimensionedScalar &ds)
bool isTgtNotSrcPoint() const
Return whether the location is a target point and not a source.
#define forAll(list, i)
Loop across all elements in list.
point centre
The centre of this part.
virtual void rDistributeTgt(const primitiveOldTimePatch &tgtPatch, const distributionMap &tgtMap)
Send data that resulted from an intersection between the source.
virtual tmpNrc< List< DynamicList< scalar > > > tgtWeights(const primitivePatch &tgtPatch) const
For each target face, the coupled source weights.
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
scalar radToDeg(const scalar rad)
Conversion from radians to degrees.
Ostream & indent(Ostream &os)
Indent stream.
bool isIntersection() const
Return whether the location is an intersection.
errorManipArg< error, int > exit(error &err, const int errNo=1)
A face is a list of labels corresponding to mesh vertices.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const Field< PointType > & faceCentres() const
Return face centres for patch.
Type gMin(const FieldField< Field, Type > &f)
static int compare(const edge &, const edge &)
Compare edges.
~intersection()
Destructor.
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
bool isSrcPoint() const
Return whether the location is a source point.
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
static vector area(const PointField &ps)
Return vector area given face points.
Structure to store the geometry associated with part of a patch.
bool isSrcNotTgtPoint() const
Return whether the location is a source point and not a target.
const Field< PointType > & localPoints() const
Return pointField of points in patch.
void resize(const label)
Alias for setSize(const label)
Class to generate patchToPatch coupling geometry. A full geometric intersection is done between a fac...
bool isTgtPoint() const
Return whether the location is a target point.
const dimensionedScalar c
Speed of light in a vacuum.
const Field< PointType > & faceAreas() const
Return face areas for patch.
Macros for easy insertion into run-time selection tables.
void intersectTris(const FixedList< point, 3 > &srcPs, const FixedList< vector, 3 > &srcNs, const FixedList< bool, 3 > &srcOwns, const FixedList< label, 3 > &srcTgtPis, const FixedList< point, 3 > &tgtPs, const FixedList< bool, 3 > &tgtOwns, const FixedList< label, 3 > &tgtSrcPis, DynamicList< point > &srcPoints, DynamicList< vector > &srcPointNormals, DynamicList< point > &tgtPoints, DynamicList< location > &pointLocations, const bool debug, const word &writePrefix=word::null)
Construct the intersection of a source triangle's projected volume and a.
point centre(const pointField &) const
Return centre (centroid)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
label tgtPointi() const
Return the target point index.
label srcPointi() const
Return the source point index.
static int debugSrcFacei
Extra debugging for intersections between specific faces. Named.
A list of faces which address into the list of points.
vector area
The area of this part.
bool isNull(const T &t)
Return true if t is a reference to the nullObject of type T.
Form normalised(const VectorSpace< Form, Cmpt, Ncmpts > &vs)
defineTypeNameAndDebug(intersection, 0)
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
void clear()
Clear the list, i.e. set size to zero.
A class for handling words, derived from string.
A triangular face using a FixedList of labels corresponding to mesh vertices.
part nbr
The neighbour part.
int debugSwitch(const char *name, const int defaultValue=0)
Lookup debug switch or add default value.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
const Field< PointType > & points() const
Return reference to global points.
static const word null
An empty word.
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
const labelListList & edgeFaces() const
Return edge-face addressing.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
static const label labelMax
List< label > labelList
A List of labels.
label nEdges() const
Return number of edges in patch.
void reverse(UList< T > &, const label n)
Type gMax(const FieldField< Field, Type > &f)
void write(const fileName &file, const word &title, const bool binary, const PointField &points, const VertexList &vertices, const LineList &lines, const FaceList &faces, const wordList &fieldNames, const boolList &fieldIsPointValues, const UPtrList< const Field< label >> &fieldLabelValues #define FieldTypeValuesConstArg(Type, nullArg))
Write VTK polygonal data to a file. Takes a PtrList of fields of labels and.
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
word name(const complex &)
Return a string representation of a complex.
A class for managing temporary objects without reference counting.
virtual label finalise(const primitiveOldTimePatch &srcPatch, const vectorField &srcPointNormals, const vectorField &srcPointNormals0, const primitiveOldTimePatch &tgtPatch, const transformer &tgtToSrc)
Finalising.
virtual tmpNrc< List< DynamicList< scalar > > > srcWeights(const primitivePatch &srcPatch) const
For each source face, the coupled target weights.
Structure to store the geometry associated with the coupling.
dimensionedScalar pow3(const dimensionedScalar &ds)
Class containing processor-to-processor mapping information.
static bool & parRun()
Is this a parallel run?
Type gAverage(const FieldField< Field, Type > &f)
const List< FaceType > & localFaces() const
Return patch faces addressing into local point list.
A List with indirect addressing.
Standard boundBox + extra functionality for use in octree.
const labelListList & faceEdges() const
Return face-edge addressing.
dimensioned< scalar > mag(const dimensioned< Type > &)
static treeBoundBox srcBoxStatic(const face &srcFace, const pointField &srcPoints, const vectorField &srcPointNormals)
Get the bound box for a source face.
const doubleScalar e
Elementary charge.
Functions with which to perform an intersection of a pair of triangles; the source and target...
virtual void initialise(const primitiveOldTimePatch &srcPatch, const vectorField &srcPointNormals, const vectorField &srcPointNormals0, const primitiveOldTimePatch &tgtPatch)
Initialisation.
intersection(const bool reverse)
Construct from components.
void clear()
Clear the addressed list, i.e. set the size to zero.
Class to generate coupling geometry between two primitive patches.
label tgtEdgei() const
Return the target edge index.
label srcEdgei() const
Return the source edge index.