36 namespace patchToPatches
53 Foam::patchToPatches::intersection::triPointValues
62 result[i] = values[t[i]];
81 const scalar l =
sqrt(
mag(srcFace.
area(srcPoints)));
83 forAll(srcFace, srcFacePointi)
85 const label srcPointi = srcFace[srcFacePointi];
87 const point&
p = srcPoints[srcPointi];
88 const vector&
n = srcPointNormals[srcPointi];
107 return srcBoxStatic(srcFace, srcPoints, srcPointNormals);
111 bool Foam::patchToPatches::intersection::intersectFaces
117 const label srcFacei,
130 if (!srcFaceBox.
overlaps(tgtFaceBox))
return false;
133 if (srcTriPoints_[srcFacei].empty())
135 triEngine_.triangulate
144 srcTriPoints_[srcFacei] =
145 triEngine_.triPoints(srcPatch.
localFaces()[srcFacei]);
146 srcTriFaceEdges_[srcFacei] = triEngine_.triEdges();
148 if (tgtTriPoints_[tgtFacei].empty())
150 triEngine_.triangulate
159 tgtTriPoints_[tgtFacei] =
160 triEngine_.triPoints(tgtPatch.
localFaces()[tgtFacei]);
161 tgtTriFaceEdges_[tgtFacei] = triEngine_.triEdges();
165 bool srcCouples =
false;
167 srcFaceEdgePart_.resize(srcPatch[srcFacei].size());
168 forAll(srcFaceEdgePart_, srcFaceEdgei)
171 srcPatch.
localFaces()[srcFacei].faceEdge(srcFaceEdgei);
173 srcFaceEdgePart_[srcFaceEdgei] = part(
Zero, eC);
176 bool tgtCouples =
false;
178 tgtFaceEdgePart_.resize(tgtPatch[tgtFacei].size());
179 forAll(tgtFaceEdgePart_, tgtFaceEdgei)
182 tgtPatch.
localFaces()[tgtFacei].faceEdge(tgtFaceEdgei);
184 tgtFaceEdgePart_[tgtFaceEdgei] = part(
Zero, eC);
190 const scalar srcMagA =
mag(srcPatch.
faceAreas()[srcFacei]);
191 const scalar tgtMagA =
mag(tgtPatch.
faceAreas()[tgtFacei]);
194 const bool debugTriIntersect =
195 (debugSrcFacei != -1 || debugTgtFacei != -1)
196 && (debugSrcFacei == -1 || debugSrcFacei == srcFacei)
197 && (debugTgtFacei == -1 || debugTgtFacei == tgtFacei);
200 bool anyCouples =
false;
201 forAll(srcTriPoints_[srcFacei], srcFaceTrii)
203 const triFace& srcT = srcTriPoints_[srcFacei][srcFaceTrii];
205 const FixedList<point, 3> srcPs =
207 const FixedList<vector, 3> srcNs =
208 triPointValues(srcT, srcPointNormals);
210 forAll(tgtTriPoints_[tgtFacei], tgtFaceTrii)
214 ? tgtTriPoints_[tgtFacei][tgtFaceTrii].reverseFace()
215 : tgtTriPoints_[tgtFacei][tgtFaceTrii];
217 const FixedList<point, 3> tgtPs =
221 ictSrcPoints_.clear();
222 ictSrcPointNormals_.clear();
223 ictTgtPoints_.clear();
224 ictPointLocations_.clear();
229 {
false,
false,
false},
232 {
false,
false,
false},
246 (srcFaceTrii*tgtTriPoints_[tgtFacei].size() + tgtFaceTrii)
252 if (ictPointLocations_.empty())
261 const part ictSrcPart(ictSrcPoints_);
262 const part ictTgtPart(ictTgtPoints_);
267 mag(ictSrcPart.area) < small*srcMagA
268 ||
mag(ictTgtPart.area) < small*tgtMagA
275 srcCouples = tgtCouples =
true;
278 srcCouple += ictSrcPart;
279 srcCouple.nbr += ictTgtPart;
282 tgtCouple += ictTgtPart;
283 tgtCouple.nbr += ictSrcPart;
287 tgtCouple -= ictTgtPart;
288 tgtCouple.nbr -= ictSrcPart;
292 const label debugSrcPoint0 = debugPoints_.size();
293 const label debugTgtPoint0 =
294 debugPoints_.size() + ictSrcPoints_.size();
297 debugPoints_.append(ictSrcPoints_);
298 debugPoints_.append(ictTgtPoints_);
303 debugFaceSrcFaces_.append(srcFacei);
304 debugFaceTgtFaces_.append(tgtFacei);
305 debugFaceSides_.append(1);
310 debugFaceSrcFaces_.append(srcFacei);
311 debugFaceTgtFaces_.append(tgtFacei);
312 debugFaceSides_.append(-1);
316 forAll(ictPointLocations_, i0)
318 const label i1 = ictPointLocations_.fcIndex(i0);
322 const triIntersect::location l0 = ictPointLocations_[i0];
323 const triIntersect::location l1 = ictPointLocations_[i1];
326 const part ictEdgePart
345 l0.isSrcNotTgtPoint()
346 || l1.isSrcNotTgtPoint()
349 && l1.isIntersection()
350 && l0.srcEdgei() == l1.srcEdgei()
355 l0.isSrcPoint() ? l0.srcPointi()
356 : l1.isSrcPoint() ? (l1.srcPointi() + 2) % 3
359 const label srcFaceEdgei =
360 srcTriFaceEdges_[srcFacei][srcFaceTrii][srcEi];
362 if (srcFaceEdgei < srcPatch[srcFacei].size())
364 srcFaceEdgePart_[srcFaceEdgei] += ictEdgePart;
369 errorPart += ictEdgePart;
378 l0.isTgtNotSrcPoint()
379 || l1.isTgtNotSrcPoint()
382 && l1.isIntersection()
383 && l0.tgtEdgei() == l1.tgtEdgei()
388 l0.isTgtPoint() ? (l0.tgtPointi() + 2) % 3
389 : l1.isTgtPoint() ? l1.tgtPointi()
392 const label tgtFaceEdgei =
393 tgtTriFaceEdges_[tgtFacei][tgtFaceTrii]
394 [
reverse() ? 2 - tgtEi : tgtEi];
396 if (tgtFaceEdgei < tgtPatch[tgtFacei].size())
398 tgtFaceEdgePart_[tgtFaceEdgei] +=
399 reverse() ? ictEdgePart : -ictEdgePart;
404 errorPart += ictEdgePart;
414 <<
"The intersection topology " << ictPointLocations_
415 <<
" between triangle #" << srcFaceTrii
416 <<
" of source face #" << srcFacei
417 <<
" and triangle #" << tgtFaceTrii
418 <<
" of target face #" << tgtFacei
419 <<
" was not recognised. This is a bug."
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] +=
461 srcErrorParts_[srcFacei] += errorPart;
467 tgtLocalSrcFaces_[tgtFacei].append(srcFacei);
468 tgtCouples_[tgtFacei].append(tgtCouple);
475 void Foam::patchToPatches::intersection::initialise
491 srcCouples_.resize(srcPatch.size());
492 forAll(srcLocalTgtFaces_, i)
494 srcCouples_[i].clear();
497 srcEdgeParts_.resize(srcPatch.nEdges());
498 forAll(srcEdgeParts_, srcEdgei)
500 const edge&
e = srcPatch.edges()[srcEdgei];
501 const point c =
e.centre(srcPatch.localPoints());
502 srcEdgeParts_[srcEdgei] = part(
Zero,
c);
505 srcErrorParts_.resize(srcPatch.size());
506 forAll(srcErrorParts_, srcFacei)
508 srcErrorParts_[srcFacei] =
509 part(
Zero, srcPatch.faceCentres()[srcFacei]);
512 tgtCouples_.resize(tgtPatch.size());
513 forAll(tgtLocalSrcFaces_, i)
515 tgtCouples_[i].clear();
518 srcTriPoints_ = List<triFaceList>(srcPatch.size());
519 srcTriFaceEdges_ = List<List<FixedList<label, 3>>>(srcPatch.size());
520 tgtTriPoints_ = List<triFaceList>(tgtPatch.size());
521 tgtTriFaceEdges_ = List<List<FixedList<label, 3>>>(tgtPatch.size());
523 srcFaceEdgeParts_.resize(srcPatch.size());
524 forAll(srcFaceEdgeParts_, srcFacei)
526 srcFaceEdgeParts_[srcFacei].resize(srcPatch[srcFacei].size());
527 forAll(srcFaceEdgeParts_[srcFacei], srcFaceEdgei)
529 const label srcEdgei =
530 srcPatch.faceEdges()[srcFacei][srcFaceEdgei];
531 srcFaceEdgeParts_[srcFacei][srcFaceEdgei] = srcEdgeParts_[srcEdgei];
537 debugPoints_.clear();
539 debugFaceSrcFaces_.clear();
540 debugFaceTgtFaces_.clear();
541 debugFaceSides_.clear();
563 tgtCouples_ = List<DynamicList<couple>>(tgtCouples_, newToOldLocalTgtFace);
565 return newToOldLocalTgtFace;
569 void Foam::patchToPatches::intersection::rDistributeTgt
585 Foam::label Foam::patchToPatches::intersection::finalise
591 const transformer& tgtToSrc
594 const label nCouples =
605 labelList srcEdgeNParts(srcEdgeParts_.size(), 0);
606 forAll(srcEdgeParts_, srcEdgei)
608 const edge&
e = srcPatch.edges()[srcEdgei];
610 srcEdgeParts_[srcEdgei] = part();
612 forAll(srcPatch.edgeFaces()[srcEdgei], i)
614 const label srcFacei = srcPatch.edgeFaces()[srcEdgei][i];
615 const label srcFaceEdgei =
616 findIndex(srcPatch.faceEdges()[srcFacei], srcEdgei);
619 srcPatch.localFaces()[srcFacei].faceEdge(srcFaceEdgei);
623 srcEdgeParts_[srcEdgei] +=
624 srcFaceEdgeParts_[srcFacei][srcFaceEdgei];
628 srcEdgeParts_[srcEdgei] -=
629 srcFaceEdgeParts_[srcFacei][srcFaceEdgei];
632 srcEdgeNParts[srcEdgei] ++;
635 forAll(srcEdgeParts_, srcEdgei)
637 srcEdgeParts_[srcEdgei].area /= srcEdgeNParts[srcEdgei];
642 forAll(srcEdgeParts_, srcEdgei)
644 const edge&
e = srcPatch.edges()[srcEdgei];
646 forAll(srcPatch.edgeFaces()[srcEdgei], i)
648 const label srcFacei = srcPatch.edgeFaces()[srcEdgei][i];
649 const label srcFaceEdgei =
650 findIndex(srcPatch.faceEdges()[srcFacei], srcEdgei);
653 srcPatch.localFaces()[srcFacei].faceEdge(srcFaceEdgei);
657 srcErrorParts_[srcFacei] -= srcEdgeParts_[srcEdgei];
661 srcErrorParts_[srcFacei] += srcEdgeParts_[srcEdgei];
664 srcErrorParts_[srcFacei] +=
665 srcFaceEdgeParts_[srcFacei][srcFaceEdgei];
672 forAll(tgtCouples_, tgtFacei)
674 forAll(tgtCouples_[tgtFacei], i)
676 couple&
c = tgtCouples_[tgtFacei][i];
678 c.area = tgtToSrc.invTransform(
c.area);
679 c.centre = tgtToSrc.invTransformPosition(
c.centre);
680 c.nbr.area = tgtToSrc.invTransform(
c.nbr.area);
681 c.nbr.centre = tgtToSrc.invTransformPosition(
c.nbr.centre);
690 const List<DynamicList<couple>>& couples,
693 List<scalar>& coverage
698 coverage.resize(patch.size());
702 const scalar magA =
mag(patch.faceAreas()[facei]);
707 aCouple += couples[facei][i].area;
709 const scalar magACouple =
mag(aCouple);
712 coupleArea += magACouple;
713 coverage[facei] = magACouple/magA;
716 reduce(area, sumOp<scalar>());
717 reduce(coupleArea, sumOp<scalar>());
719 scalar srcArea = 0, srcCoupleArea = 0;
720 scalar tgtArea = 0, tgtCoupleArea = 0;
721 coverage(srcPatch, srcCouples_, srcArea, srcCoupleArea, srcCoverage_);
722 coverage(tgtPatch, tgtCouples_, tgtArea, tgtCoupleArea, tgtCoverage_);
725 srcTriPoints_.clear();
726 srcTriFaceEdges_.clear();
727 tgtTriPoints_.clear();
728 tgtTriFaceEdges_.clear();
731 srcFaceEdgePart_.clear();
732 tgtFaceEdgePart_.clear();
733 srcFaceEdgeParts_.clear();
742 forAll(srcPatch, srcFacei)
744 const vector& a = srcPatch.faceAreas()[srcFacei];
745 const scalar magA =
mag(a);
746 const point&
c = srcPatch.faceCentres()[srcFacei];
749 forAll(srcCouples_[srcFacei], srcTgtFacei)
751 const couple& cpl = srcCouples_[srcFacei][srcTgtFacei];
758 scalar projectionV = 0;
759 forAll(srcCouples_[srcFacei], srcTgtFacei)
761 const couple& cpl = srcCouples_[srcFacei][srcTgtFacei];
763 projectionA += cpl.nbr.area;
765 - (cpl.area/3 & (cpl.centre - Cpl.centre))
766 + (cpl.nbr.area/3 & (cpl.nbr.centre - Cpl.centre));
768 forAll(srcPatch.faceEdges()[srcFacei], srcFaceEdgei)
770 const label srcEdgei =
771 srcPatch.faceEdges()[srcFacei][srcFaceEdgei];
773 const edge&
e = srcPatch.edges()[srcEdgei];
775 srcPatch.localFaces()[srcFacei].faceEdge(srcFaceEdgei);
779 projectionA +=
sign*srcEdgeParts_[srcEdgei].area;
781 sign*srcEdgeParts_[srcEdgei].area/3
782 & (srcEdgeParts_[srcEdgei].centre - Cpl.centre);
784 projectionA += srcErrorParts_[srcFacei].area;
786 srcErrorParts_[srcFacei].area/3
787 & (srcErrorParts_[srcFacei].centre - Cpl.centre);
791 srcAngleDeg[srcFacei] =
793 srcOpenness[srcFacei] =
mag(projectionA - Cpl.area)/magA;
794 srcError[srcFacei] =
mag(srcErrorParts_[srcFacei].area)/magA;
795 srcDepth[srcFacei] =
mag(projectionV)/
pow3(
sqrt(magA));
798 reduce(tgtArea, sumOp<scalar>());
799 reduce(tgtCoupleArea, sumOp<scalar>());
801 Info<<
indent <<
"Source min/average/max coverage = "
802 <<
gMin(srcCoverage_) <<
'/' << srcCoupleArea/srcArea <<
'/'
804 <<
indent <<
"Target min/average/max coverage = "
805 <<
gMin(tgtCoverage_) <<
'/' << tgtCoupleArea/tgtArea <<
'/'
807 <<
indent <<
"Source average openness/error/depth/angle = "
810 <<
indent <<
"Source max openness/error/depth/angle = "
811 <<
gMax(srcOpenness) <<
'/' <<
gMax(srcError) <<
'/'
816 word
name = patchToPatch::typeName +
'_' + typeName;
827 name +
"_srcPatch" +
".vtk",
830 srcPatch.localPoints(),
833 srcPatch.localFaces(),
835 "openness",
false, srcOpenness,
836 "error",
false, srcError,
837 "depth",
false, srcDepth,
838 "angle",
false, srcAngleDeg,
839 "normals",
true, srcPointNormals
846 name +
"_tgtPatch" +
".vtk",
849 tgtPatch.localPoints(),
852 tgtPatch.localFaces(),
858 Info<<
indent <<
"Writing intersected faces to "
869 "srcFace",
false, Field<label>(debugFaceSrcFaces_),
870 "tgtFace",
false, Field<label>(debugFaceTgtFaces_),
871 "side",
false, Field<label>(debugFaceSides_)
874 debugPoints_.clear();
876 debugFaceSrcFaces_.clear();
877 debugFaceTgtFaces_.clear();
878 debugFaceSides_.clear();
888 Foam::patchToPatches::intersection::srcWeights()
const
890 List<DynamicList<scalar>>* resultPtr
892 new List<DynamicList<scalar>>(srcCouples_.size())
894 List<DynamicList<scalar>>& result = *resultPtr;
896 forAll(srcCouples_, srcFacei)
898 result[srcFacei].resize(srcCouples_[srcFacei].size());
901 forAll(srcCouples_[srcFacei], i)
903 const scalar a =
mag(srcCouples_[srcFacei][i].area);
904 result[srcFacei][i] = a;
908 forAll(srcCouples_[srcFacei], i)
910 result[srcFacei][i] *=
911 min(
max(srcCoverage_[srcFacei], small), scalar(1))/aSum;
915 return tmpNrc<List<DynamicList<scalar>>>(resultPtr);
920 Foam::patchToPatches::intersection::tgtWeights()
const
922 List<DynamicList<scalar>>* resultPtr
924 new List<DynamicList<scalar>>(tgtCouples_.size())
926 List<DynamicList<scalar>>& result = *resultPtr;
928 forAll(tgtCouples_, tgtFacei)
930 result[tgtFacei].resize(tgtCouples_[tgtFacei].size());
933 forAll(tgtCouples_[tgtFacei], i)
935 const scalar a =
mag(tgtCouples_[tgtFacei][i].area);
936 result[tgtFacei][i] = a;
940 forAll(tgtCouples_[tgtFacei], i)
942 result[tgtFacei][i] *=
943 min(
max(tgtCoverage_[tgtFacei], small), scalar(1))/aSum;
947 return tmpNrc<List<DynamicList<scalar>>>(resultPtr);
972 ictSrcPointNormals_(),
974 ictPointLocations_(),
983 debugFaceSrcFaces_(),
984 debugFaceTgtFaces_(),
#define forAll(list, i)
Loop across all elements in list.
Macros for easy insertion into run-time selection tables.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
void clear()
Clear the addressed list, i.e. set the size to zero.
const Field< PointType > & faceAreas() const
Return face areas for patch.
const Field< PointType > & points() const
Return reference to global points.
const List< FaceType > & localFaces() const
Return patch faces addressing into local point list.
const Field< PointType > & localPoints() const
Return pointField of points in patch.
const Field< PointType > & faceCentres() const
Return face centres for patch.
A List with indirect addressing.
static bool & parRun()
Is this a parallel run?
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
static int compare(const edge &, const edge &)
Compare edges.
A face is a list of labels corresponding to mesh vertices.
static vector area(const PointField &ps)
Return vector area given face points.
Class to generate coupling geometry between two primitive patches.
virtual void rDistributeTgt(const primitiveOldTimePatch &tgtPatch)
Send data that resulted from an intersection between the source.
virtual labelList finaliseLocal(const primitiveOldTimePatch &srcPatch, const vectorField &srcPointNormals, const vectorField &srcPointNormals0, const primitiveOldTimePatch &tgtPatch)
Finalise the intersection locally. Trims the local target patch.
virtual void initialise(const primitiveOldTimePatch &srcPatch, const vectorField &srcPointNormals, const vectorField &srcPointNormals0, const primitiveOldTimePatch &tgtPatch)
Initialisation.
virtual label finalise(const primitiveOldTimePatch &srcPatch, const vectorField &srcPointNormals, const vectorField &srcPointNormals0, const primitiveOldTimePatch &tgtPatch, const transformer &tgtToSrc)
Finalising.
Class to generate patchToPatch coupling geometry. A full geometric intersection is done between a fac...
~intersection()
Destructor.
static treeBoundBox srcBoxStatic(const face &srcFace, const pointField &srcPoints, const vectorField &srcPointNormals)
Get the bound box for a source face.
static int debugSrcFacei
Extra debugging for intersections between specific faces. Named.
intersection(const bool reverse)
Construct from components.
A class for managing temporary objects without reference counting.
Standard boundBox + extra functionality for use in octree.
bool overlaps(const boundBox &) const
Overlaps other bounding box?
A triangular face using a FixedList of labels corresponding to mesh vertices.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const dimensionedScalar c
Speed of light in a vacuum.
int debugSwitch(const char *name, const int defaultValue=0)
Lookup debug switch or add default value.
addToRunTimeSelectionTable(patchToPatch, intersection, bool)
defineTypeNameAndDebug(intersection, 0)
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.
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.
errorManipArg< error, int > exit(error &err, const int errNo=1)
scalar radToDeg(const scalar rad)
Convert radians to degrees.
List< label > labelList
A List of labels.
dimensionedScalar sign(const dimensionedScalar &ds)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensionedScalar pow3(const dimensionedScalar &ds)
word name(const bool)
Return a word representation of a bool.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
vector point
Point is a vector.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
void reverse(UList< T > &, const label n)
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
Addressing for a faceList slice.
Vector< scalar > vector
A scalar version of the templated Vector.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
dimensionedScalar sqrt(const dimensionedScalar &ds)
PrimitiveOldTimePatch< SubList< face >, const pointField & > primitiveOldTimePatch
Addressing for a faceList slice.
List< labelList > labelListList
A List of labelList.
dimensionSet normalised(const dimensionSet &)
dimensioned< scalar > mag(const dimensioned< Type > &)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
Field< vector > vectorField
Specialisation of Field<T> for vector.
Type gAverage(const FieldField< Field, Type > &f)
bool isNull(const T &t)
Return true if t is a reference to the nullObject of type T.
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
Type gMin(const FieldField< Field, Type > &f)
static const label labelMax
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
Ostream & indent(Ostream &os)
Indent stream.
Type gMax(const FieldField< Field, Type > &f)
dimensionedScalar acos(const dimensionedScalar &ds)
Functions with which to perform an intersection of a pair of triangles; the source and target....