From 8eef91c5e2b423ff22686a166dcca142421e4746 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Sat, 1 May 2021 16:09:48 +0200 Subject: [PATCH 1/8] ENH: improve edge access for face/triFace - additional rcEdge(), rcEdges() methods for reverse order walk - accept generic edge() method as alternative to faceEdge() for single edge retrieval. - edge() method with points -> returns the vector - reduce the number of operations in edgeDirection methods DEFEATURE: remove longestEdge global function - deprecated and replaced by face::longestEdge() method (2017-04) --- applications/test/faces/Test-faces.C | 103 +++++++++++- src/OpenFOAM/meshes/meshShapes/face/face.C | 158 ++++++++---------- src/OpenFOAM/meshes/meshShapes/face/face.H | 58 ++++--- src/OpenFOAM/meshes/meshShapes/face/faceI.H | 78 +++++---- .../meshes/meshShapes/triFace/triFace.H | 54 ++++-- .../meshes/meshShapes/triFace/triFaceI.H | 146 +++++++++++----- src/conversion/fire/checkFireEdges.C | 6 +- .../polyTopoChange/edgeCollapser.C | 10 +- .../cfdTools/general/levelSet/levelSet.C | 5 +- .../general/levelSet/levelSetTemplates.C | 5 +- src/lagrangian/basic/particle/particle.C | 2 +- .../surfaceIntersectionFuncs.C | 4 +- .../cutting/cuttingSurfaceBaseTemplates.C | 2 +- 13 files changed, 412 insertions(+), 219 deletions(-) diff --git a/applications/test/faces/Test-faces.C b/applications/test/faces/Test-faces.C index b967f4b5ba..7909cac61b 100644 --- a/applications/test/faces/Test-faces.C +++ b/applications/test/faces/Test-faces.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016 OpenCFD Ltd. + Copyright (C) 2016-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -33,6 +33,8 @@ Description #include "argList.H" #include "labelledTri.H" +#include "faceList.H" +#include "triFaceList.H" #include "pointList.H" #include "ListOps.H" @@ -63,6 +65,35 @@ void testSign } +template +void testEdges(const Face& f) +{ + const label nEdges = f.nEdges(); + Info<< "face: " << f << nl + << "flip: " << f.reverseFace() << nl + << " fc edges:" << flatOutput(f.edges()) << nl + << " rc edges:" << flatOutput(f.rcEdges()) << nl; + + Info<< " forward edges" << nl; + for (label edgei = 0; edgei < nEdges; ++edgei) + { + Info<< " " << edgei << " : " << f.edge(edgei) << nl; + } + Info<< " reverse edges" << nl; + for (label edgei = 0; edgei < nEdges; ++edgei) + { + Info<< " " << edgei << " : " << f.rcEdge(edgei) << nl; + } +} + + +void testCompare(const triFace& a, const triFace& b) +{ + Info<< "compare: " << a << " with " << b + << " == " << triFace::compare(a, b) << nl; +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Main program: @@ -92,7 +123,7 @@ int main(int argc, char *argv[]) { 2, 2, 2} }); - face f1{ 1, 2, 3, 4 }; + face f1({1, 2, 3, 4}); Info<< "face:"; faceInfo(f1, points1); Info << nl; testSign(f1, points1, testPoints); @@ -100,7 +131,7 @@ int main(int argc, char *argv[]) testSign(f1, points2, testPoints); Info<< nl; - triFace t1{ 1, 2, 3 }; + triFace t1({1, 2, 3}); Info<< "triFace:"; faceInfo(t1, points1); Info << nl; testSign(t1, points1, testPoints); @@ -115,11 +146,12 @@ int main(int argc, char *argv[]) f1 = t1.triFaceFace(); Info<< "face:" << f1 << nl; - // expect these to fail + #if 0 + // Expect failure, but triggers abort which cannot be caught const bool throwingError = FatalError.throwExceptions(); try { - labelledTri l1{ 1, 2, 3, 10, 24 }; + labelledTri l1({1, 2, 3, 10, 24}); Info<< "labelled:" << l1 << nl; } catch (const Foam::error& err) @@ -128,11 +160,12 @@ int main(int argc, char *argv[]) << "Caught FatalError " << err << nl << endl; } FatalError.throwExceptions(throwingError); + #endif - labelledTri l2{ 1, 2, 3 }; + labelledTri l2({1, 2, 3}); Info<< "labelled:" << l2 << nl; - labelledTri l3{ 1, 2, 3, 10 }; + labelledTri l3({1, 2, 3, 10}); Info<< "labelled:" << l3 << nl; t1.flip(); @@ -141,6 +174,62 @@ int main(int argc, char *argv[]) Info<< "flip:" << t1 << nl; Info<< "flip:" << l3 << nl; + { + triFaceList faceList1 + ({ + triFace{1, 2, 3}, + triFace{4, 2, 100}, + triFace{1, 3, 2}, + }); + + Info<< nl << "Test edges" << nl; + + for (const auto& f : faceList1) + { + testEdges(f); + Info<< nl; + } + } + + { + faceList faceList1 + ({ + face{1, 2, 3, 4}, + face{1, 4, 3, 2}, + face{4, 2, 100, 8, 35}, + }); + + Info<< nl << "Test edges" << nl; + + for (const auto& f : faceList1) + { + testEdges(f); + Info<< nl; + } + } + + { + triFaceList faceList1 + ({ + triFace{1, 2, 3}, + triFace{1, 3, 2}, + triFace{3, 1, 2}, + triFace{4, 5, 1}, + }); + + Info<< nl << "Test triFace compare" << nl; + for (const triFace& a : faceList1) + { + for (const triFace& b : faceList1) + { + testCompare(a, b); + } + } + Info<< nl; + } + + Info<< "\nEnd\n" << endl; + return 0; } diff --git a/src/OpenFOAM/meshes/meshShapes/face/face.C b/src/OpenFOAM/meshes/meshShapes/face/face.C index d7fd7c3d07..cfd4d85516 100644 --- a/src/OpenFOAM/meshes/meshShapes/face/face.C +++ b/src/OpenFOAM/meshes/meshShapes/face/face.C @@ -31,6 +31,7 @@ License #include "triPointRef.H" #include "mathematicalConstants.H" #include "ConstCirculator.H" +#include // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -40,25 +41,18 @@ const char* const Foam::face::typeName = "face"; // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // Foam::tmp -Foam::face::calcEdges(const UList& points) const +Foam::face::calcEdgeVectors(const UList& points) const { - tmp tedges(new vectorField(size())); - vectorField& edges = tedges.ref(); + auto tedgeVecs = tmp::New(size()); + auto& edgeVecs = tedgeVecs.ref(); forAll(*this, i) { - label ni = fcIndex(i); - - point thisPt = points[operator[](i)]; - point nextPt = points[operator[](ni)]; - - vector vec(nextPt - thisPt); - vec /= Foam::mag(vec) + VSMALL; - - edges[i] = vec; + edgeVecs[i] = vector(points[nextLabel(i)] - points[thisLabel(i)]); + edgeVecs[i].normalise(); } - return tedges; + return tedgeVecs; } @@ -68,11 +62,11 @@ Foam::scalar Foam::face::edgeCos const label index ) const { - label leftEdgeI = left(index); - label rightEdgeI = right(index); + const vector& leftEdge = edges[rcIndex(index)]; + const vector& rightEdge = edges[index]; // Note negate on left edge to get correct left-pointing edge. - return -(edges[leftEdgeI] & edges[rightEdgeI]); + return -(leftEdge & rightEdge); } @@ -90,12 +84,12 @@ Foam::label Foam::face::mostConcaveAngle forAll(edges, i) { - label leftEdgeI = left(i); - label rightEdgeI = right(i); + const vector& leftEdge = edges[rcIndex(i)]; + const vector& rightEdge = edges[i]; - vector edgeNormal = edges[rightEdgeI] ^ edges[leftEdgeI]; + vector edgeNormal = (rightEdge ^ leftEdge); - scalar edgeCos = edges[leftEdgeI] & edges[rightEdgeI]; + scalar edgeCos = (leftEdge & rightEdge); scalar edgeAngle = acos(max(-1.0, min(1.0, edgeCos))); scalar angle; @@ -133,15 +127,15 @@ Foam::label Foam::face::split faceList& quadFaces ) const { - label oldIndices = (triI + quadI); + const label oldIndices = (triI + quadI); - if (size() <= 2) + if (size() < 3) { FatalErrorInFunction << "Serious problem: asked to split a face with < 3 vertices" << abort(FatalError); } - if (size() == 3) + else if (size() == 3) { // Triangle. Just copy. if (mode == COUNTTRIANGLE || mode == COUNTQUAD) @@ -166,7 +160,7 @@ Foam::label Foam::face::split else if (mode == SPLITTRIANGLE) { // Start at point with largest internal angle. - const vectorField edges(calcEdges(points)); + const vectorField edges(calcEdgeVectors(points)); scalar minAngle; label startIndex = mostConcaveAngle(points, edges, minAngle); @@ -197,13 +191,13 @@ Foam::label Foam::face::split { // General case. Like quad: search for largest internal angle. - const vectorField edges(calcEdges(points)); + const vectorField edges(calcEdgeVectors(points)); scalar minAngle = 1; label startIndex = mostConcaveAngle(points, edges, minAngle); scalar bisectAngle = minAngle/2; - vector rightEdge = edges[right(startIndex)]; + const vector& rightEdge = edges[startIndex]; // // Look for opposite point which as close as possible bisects angle @@ -222,7 +216,7 @@ Foam::label Foam::face::split points[operator[](index)] - points[operator[](startIndex)] ); - splitEdge /= Foam::mag(splitEdge) + VSMALL; + splitEdge.normalise(); const scalar splitCos = splitEdge & rightEdge; const scalar splitAngle = acos(max(-1.0, min(1.0, splitCos))); @@ -786,62 +780,57 @@ Foam::tensor Foam::face::inertia Foam::edgeList Foam::face::edges() const { - const labelList& points = *this; + const labelList& verts = *this; + const label nVerts = verts.size(); - edgeList e(points.size()); + edgeList theEdges(nVerts); - for (label pointi = 0; pointi < points.size() - 1; ++pointi) + // Last edge closes the polygon + theEdges.last().first() = verts.last(); + theEdges.last().second() = verts[0]; + + for (label verti = 0; verti < nVerts - 1; ++verti) { - e[pointi] = edge(points[pointi], points[pointi + 1]); + theEdges[verti].first() = verts[verti]; + theEdges[verti].second() = verts[verti + 1]; } - // Add last edge - e.last() = edge(points.last(), points[0]); - - return e; + return theEdges; } -int Foam::face::edgeDirection(const edge& e) const +Foam::edgeList Foam::face::rcEdges() const { - forAll(*this, i) + const labelList& verts = *this; + const label nVerts = verts.size(); + + edgeList theEdges(nVerts); + + // First edge closes the polygon + theEdges.first().first() = verts[0]; + theEdges.first().second() = verts.last(); + + for (label verti = 1; verti < nVerts; ++verti) { - if (operator[](i) == e.first()) - { - if (operator[](rcIndex(i)) == e.second()) - { - // Reverse direction - return -1; - } - else if (operator[](fcIndex(i)) == e.second()) - { - // Forward direction - return 1; - } - - // No match - return 0; - } - else if (operator[](i) == e.second()) - { - if (operator[](rcIndex(i)) == e.first()) - { - // Forward direction - return 1; - } - else if (operator[](fcIndex(i)) == e.first()) - { - // Reverse direction - return -1; - } - - // No match - return 0; - } + theEdges[verti].first() = verts[nVerts - verti]; + theEdges[verti].second() = verts[nVerts - verti - 1]; } - // Not found - return 0; + return theEdges; +} + + +int Foam::face::edgeDirection(const Foam::edge& e) const +{ + const label idx = find(e.first()); + + if (idx != -1) + { + if (e.second() == nextLabel(idx)) return 1; // Forward + if (e.second() == prevLabel(idx)) return -1; // Reverse + } + + return 0; // Not found } @@ -894,29 +883,26 @@ Foam::label Foam::face::trianglesQuads Foam::label Foam::face::longestEdge(const UList& pts) const { - const edgeList& eds = this->edges(); + const labelList& verts = *this; + const label nVerts = verts.size(); - label longestEdgeI = -1; - scalar longestEdgeLength = -SMALL; + // Last edge closes the polygon. Use it to initialize loop + label longest = nVerts - 1; + scalar longestLen = Foam::edge(verts.first(), verts.last()).mag(pts); - forAll(eds, edI) + // Examine other edges + for (label edgei = 0; edgei < nVerts - 1; ++edgei) { - scalar edgeLength = eds[edI].mag(pts); + scalar edgeLen = Foam::edge(verts[edgei], verts[edgei + 1]).mag(pts); - if (edgeLength > longestEdgeLength) + if (longestLen < edgeLen) { - longestEdgeI = edI; - longestEdgeLength = edgeLength; + longest = edgei; + longestLen = edgeLen; } } - return longestEdgeI; -} - - -Foam::label Foam::longestEdge(const face& f, const UList& pts) -{ - return f.longestEdge(pts); + return longest; } diff --git a/src/OpenFOAM/meshes/meshShapes/face/face.H b/src/OpenFOAM/meshes/meshShapes/face/face.H index 9c5565fcf8..8862402896 100644 --- a/src/OpenFOAM/meshes/meshShapes/face/face.H +++ b/src/OpenFOAM/meshes/meshShapes/face/face.H @@ -76,14 +76,8 @@ class face { // Private Member Functions - //- Edge to the right of face vertex i - inline label right(const label i) const; - - //- Edge to the left of face vertex i - inline label left(const label i) const; - //- Construct list of edge vectors for face - tmp calcEdges + tmp calcEdgeVectors ( const UList& points ) const; @@ -190,7 +184,7 @@ public: void flip(); //- Return the points corresponding to this face - inline pointField points(const UList& points) const; + inline pointField points(const UList& pts) const; //- Centre point of face point centre(const UList& points) const; @@ -227,13 +221,14 @@ public: // Navigation through face vertices - //- Return true if the point label is found in face. - inline bool found(const label pointLabel) const; - - //- Find local index on face for the point label, + //- Find local index on face for the point label, same as find() // \return position in face (0,1,2,...) or -1 if not found. inline label which(const label pointLabel) const; + //- The vertex on face - identical to operator[], but with naming + //- similar to nextLabel(), prevLabel() + inline label thisLabel(const label i) const; + //- Next vertex on face inline label nextLabel(const label i) const; @@ -342,25 +337,45 @@ public: ) const; //- Return number of edges - inline label nEdges() const; + inline label nEdges() const noexcept; - //- Return edges in face point ordering, + //- Return i-th face edge in forward walk order. + //- The faceEdge(0) is the edge between [0] and [1] + inline Foam::edge faceEdge(const label edgei) const; + + //- Return i-th face edge in forward walk order. + //- Identical to faceEdge() but with generic name + inline Foam::edge edge(const label edgei) const; + + //- Return vector of i-th face edge in forward walk order. + inline vector edge(const label edgei, const UList& pts) const; + + //- Return i-th face edge in reverse walk order. + //- The rcEdge(0) is the edge between [0] and [n-1] + inline Foam::edge rcEdge(const label edgei) const; + + //- Return vector of i-th face edge in reverse walk order. + inline vector rcEdge(const label edgei, const UList& pts) const; + + //- Return list of edges in forward walk order. // i.e. edges()[0] is edge between [0] and [1] edgeList edges() const; - //- Return n-th face edge - inline edge faceEdge(const label n) const; + //- Return list of edges in reverse walk order. + // i.e. rcEdges()[0] is edge between [0] and [n-1] + edgeList rcEdges() const; - //- The edge direction on the face + //- Test the edge direction on the face // \return // - 0: edge not found on the face // - +1: forward (counter-clockwise) on the face // - -1: reverse (clockwise) on the face - int edgeDirection(const edge& e) const; + int edgeDirection(const Foam::edge& e) const; //- Find the longest edge on a face. label longestEdge(const UList& pts) const; + // Face splitting utilities //- Number of triangles after splitting @@ -493,13 +508,6 @@ struct offsetOp }; -//- Deprecated(2017-04) find the longest edge on a face. -//- Face point labels index into pts. -// \deprecated(2017-04) use class method instead -FOAM_DEPRECATED_FOR(2017-04, "use face::longestEdge() method") -label longestEdge(const face& f, const UList& pts); - - // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * // inline bool operator==(const face& a, const face& b); diff --git a/src/OpenFOAM/meshes/meshShapes/face/faceI.H b/src/OpenFOAM/meshes/meshShapes/face/faceI.H index 631d8cad45..fe2ca3f754 100644 --- a/src/OpenFOAM/meshes/meshShapes/face/faceI.H +++ b/src/OpenFOAM/meshes/meshShapes/face/faceI.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011 OpenFOAM Foundation - Copyright (C) 2017-2020 OpenCFD Ltd. + Copyright (C) 2017-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,20 +26,6 @@ License \*---------------------------------------------------------------------------*/ -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -inline Foam::label Foam::face::right(const label i) const -{ - return i; -} - - -inline Foam::label Foam::face::left(const label i) const -{ - return rcIndex(i); -} - - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // inline Foam::face::face(const label sz) @@ -98,23 +84,19 @@ inline Foam::face::face(Istream& is) // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -inline Foam::pointField Foam::face::points -( - const UList& meshPoints -) const +inline Foam::pointField Foam::face::points(const UList& pts) const { // There are as many points as there are labels for them pointField p(size()); - // For each point in list, set it to the point in 'pnts' addressed - // by 'labs' - label i = 0; + auto iter = p.begin(); + for (const label pointi : *this) { - p[i++] = meshPoints[pointi]; + *iter = pts[pointi]; + ++iter; } - // Return list return p; } @@ -133,22 +115,54 @@ inline Foam::scalar Foam::face::mag(const UList& p) const } -inline Foam::label Foam::face::nEdges() const +inline Foam::label Foam::face::nEdges() const noexcept { // for a closed polygon a number of edges is the same as number of points return size(); } -inline Foam::edge Foam::face::faceEdge(const label n) const +inline Foam::edge Foam::face::faceEdge(const label edgei) const { - return edge(operator[](n), operator[](fcIndex(n))); + return Foam::edge(thisLabel(edgei), nextLabel(edgei)); } -inline bool Foam::face::found(const label pointLabel) const +inline Foam::edge Foam::face::edge(const label edgei) const { - return labelList::found(pointLabel); + return faceEdge(edgei); +} + + +inline Foam::vector Foam::face::edge +( + const label edgei, + const UList& pts +) const +{ + return vector(pts[nextLabel(edgei)] - pts[thisLabel(edgei)]); +} + + +inline Foam::edge Foam::face::rcEdge(const label edgei) const +{ + // Edge 0 (forward and reverse) always starts at [0] + // for consistency with face flipping + const label pointi = edgei ? (nEdges() - edgei) : 0; + return Foam::edge(thisLabel(pointi), prevLabel(pointi)); +} + + +inline Foam::vector Foam::face::rcEdge +( + const label edgei, + const UList& pts +) const +{ + // Edge 0 (forward and reverse) always starts at [0] + // for consistency with face flipping + const label pointi = edgei ? (3 - edgei) : 0; + return vector(pts[prevLabel(pointi)] - pts[thisLabel(pointi)]); } @@ -158,6 +172,12 @@ inline Foam::label Foam::face::which(const label pointLabel) const } +inline Foam::label Foam::face::thisLabel(const label i) const +{ + return labelList::operator[](i); +} + + inline Foam::label Foam::face::nextLabel(const label i) const { return labelList::fcValue(i); diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H index 50fd55fe87..8083f16e9c 100644 --- a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H +++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H @@ -116,7 +116,7 @@ public: inline void flip(); //- Return the points corresponding to this face - inline pointField points(const UList& points) const; + inline pointField points(const UList& pts) const; //- Return triangle as a face inline face triFaceFace() const; @@ -148,20 +148,27 @@ public: //- Magnitude of face area inline scalar mag(const UList& points) const; - //- Number of triangles after splitting - inline label nTriangles() const; + //- Number of triangles after splitting == 1 + inline label nTriangles() const noexcept; //- Return face with reverse direction // The starting points of the original and reverse face are identical. inline triFace reverseFace() const; - //- Return true if the point label is found in face. - inline bool found(const label pointLabel) const; - - //- Find local index on face for the point label. + //- Find local index on face for the point label, same as find() // \return position in face (0,1,2) or -1 if not found. inline label which(const label pointLabel) const; + //- Next vertex on face + inline label nextLabel(const label i) const; + + //- Previous vertex on face + inline label prevLabel(const label i) const; + + //- The vertex on face - identical to operator[], but with naming + //- similar to nextLabel(), prevLabel() + inline label thisLabel(const label i) const; + //- Return swept-volume from old-points to new-points inline scalar sweptVol ( @@ -243,22 +250,41 @@ public: const scalar tol = SMALL ) const; - //- Return number of edges - inline label nEdges() const; + //- Return number of edges == 3 + inline label nEdges() const noexcept; - //- Return edges in face point ordering, + //- Return i-th face edge in forward walk order. + //- The faceEdge(0) is the edge between [0] and [1] + inline Foam::edge faceEdge(const label edgei) const; + + //- Return i-th face edge in forward walk order. + //- Identical to faceEdge() but with generic name + inline Foam::edge edge(const label edgei) const; + + //- Return vector of i-th face edge in forward walk order. + inline vector edge(const label edgei, const UList& pts) const; + + //- Return i-th face edge in reverse walk order. + //- The rcEdge(0) is the edge between [0] to [n-1] + inline Foam::edge rcEdge(const label edgei) const; + + //- Return vector of i-th face edge in reverse walk order. + inline vector rcEdge(const label edgei, const UList& pts) const; + + //- Return list of edges in forward walk order. // i.e. edges()[0] is edge between [0] and [1] inline edgeList edges() const; - //- Return n-th face edge - inline edge faceEdge(const label n) const; + //- Return list of edges in reverse walk order. + // i.e. rcEdges()[0] is edge between [0] to [n-1] + inline edgeList rcEdges() const; - //- Return the edge direction on the face + //- Test the edge direction on the face // \return // - +1: forward (counter-clockwise) on the face // - -1: reverse (clockwise) on the face // - 0: edge not found on the face - inline int edgeDirection(const edge& e) const; + inline int edgeDirection(const Foam::edge& e) const; //- Compare triFaces // \return: diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H index e1f2c00869..40d70f246b 100644 --- a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H +++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H @@ -29,7 +29,7 @@ License #include "IOstreams.H" #include "face.H" #include "triPointRef.H" -#include "Swap.H" +#include // For std::swap // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // @@ -144,13 +144,13 @@ inline void Foam::triFace::flip() } -inline Foam::pointField Foam::triFace::points(const UList& points) const +inline Foam::pointField Foam::triFace::points(const UList& pts) const { pointField p(3); - p[0] = points[operator[](0)]; - p[1] = points[operator[](1)]; - p[2] = points[operator[](2)]; + p[0] = pts[operator[](0)]; + p[1] = pts[operator[](1)]; + p[2] = pts[operator[](2)]; return p; } @@ -209,7 +209,7 @@ inline Foam::scalar Foam::triFace::mag(const UList& points) const } -inline Foam::label Foam::triFace::nTriangles() const +inline Foam::label Foam::triFace::nTriangles() const noexcept { return 1; } @@ -222,18 +222,30 @@ inline Foam::triFace Foam::triFace::reverseFace() const } -inline bool Foam::triFace::found(const label pointLabel) const -{ - return FixedList::found(pointLabel); -} - - inline Foam::label Foam::triFace::which(const label pointLabel) const { return FixedList::find(pointLabel); } +inline Foam::label Foam::triFace::thisLabel(const label i) const +{ + return operator[](i); +} + + +inline Foam::label Foam::triFace::nextLabel(const label i) const +{ + return operator[]((i == 2 ? 0 : i+1)); +} + + +inline Foam::label Foam::triFace::prevLabel(const label i) const +{ + return operator[]((i ? i-1 : 2)); +} + + inline Foam::scalar Foam::triFace::sweptVol ( const UList& opts, @@ -353,61 +365,109 @@ inline int Foam::triFace::sign } -inline Foam::label Foam::triFace::nEdges() const +inline Foam::label Foam::triFace::nEdges() const noexcept { return 3; } +inline Foam::edge Foam::triFace::faceEdge(const label edgei) const +{ + return Foam::edge(thisLabel(edgei), nextLabel(edgei)); +} + + +inline Foam::edge Foam::triFace::edge(const label edgei) const +{ + return faceEdge(edgei); +} + + +inline Foam::vector Foam::triFace::edge +( + const label edgei, + const UList& pts +) const +{ + return vector(pts[nextLabel(edgei)] - pts[thisLabel(edgei)]); +} + + +inline Foam::edge Foam::triFace::rcEdge(const label edgei) const +{ + // Edge 0 (forward and reverse) always starts at [0] + // for consistency with face flipping + const label pointi = edgei ? (3 - edgei) : 0; + return Foam::edge(thisLabel(pointi), prevLabel(pointi)); +} + + +inline Foam::vector Foam::triFace::rcEdge +( + const label edgei, + const UList& pts +) const +{ + // Edge 0 (forward and reverse) always starts at [0] + // for consistency with face flipping + const label pointi = edgei ? (3 - edgei) : 0; + return vector(pts[prevLabel(pointi)] - pts[thisLabel(pointi)]); +} + + inline Foam::edgeList Foam::triFace::edges() const { - edgeList e(3); + edgeList theEdges(3); - e[0].first() = operator[](0); - e[0].second() = operator[](1); + theEdges[0].first() = operator[](0); + theEdges[0].second() = operator[](1); - e[1].first() = operator[](1); - e[1].second() = operator[](2); + theEdges[1].first() = operator[](1); + theEdges[1].second() = operator[](2); - e[2].first() = operator[](2); - e[2].second() = operator[](0); + theEdges[2].first() = operator[](2); + theEdges[2].second() = operator[](0); - return e; + return theEdges; } -inline Foam::edge Foam::triFace::faceEdge(const label n) const +inline Foam::edgeList Foam::triFace::rcEdges() const { - return edge(operator[](n), operator[](fcIndex(n))); + edgeList theEdges(3); + + theEdges[0].first() = operator[](0); + theEdges[0].second() = operator[](2); + + theEdges[1].first() = operator[](2); + theEdges[1].second() = operator[](1); + + theEdges[2].first() = operator[](1); + theEdges[2].second() = operator[](0); + + return theEdges; } -// return -// - +1: forward (counter-clockwise) on the face -// - -1: reverse (clockwise) on the face -// - 0: edge not found on the face -inline int Foam::triFace::edgeDirection(const edge& e) const +inline int Foam::triFace::edgeDirection(const Foam::edge& e) const { - if - ( - (operator[](0) == e.first() && operator[](1) == e.second()) - || (operator[](1) == e.first() && operator[](2) == e.second()) - || (operator[](2) == e.first() && operator[](0) == e.second()) - ) + if (e.first() == operator[](0)) { - return 1; + if (e.second() == operator[](1)) return 1; // Forward + if (e.second() == operator[](2)) return -1; // Reverse } - else if - ( - (operator[](0) == e.second() && operator[](1) == e.first()) - || (operator[](1) == e.second() && operator[](2) == e.first()) - || (operator[](2) == e.second() && operator[](0) == e.first()) - ) + if (e.first() == operator[](1)) { - return -1; + if (e.second() == operator[](2)) return 1; // Forward + if (e.second() == operator[](0)) return -1; // Reverse + } + if (e.first() == operator[](2)) + { + if (e.second() == operator[](0)) return 1; // Forward + if (e.second() == operator[](1)) return -1; // Reverse } - return 0; + return 0; // Not found } diff --git a/src/conversion/fire/checkFireEdges.C b/src/conversion/fire/checkFireEdges.C index fe01fa5cc4..d19c2da1af 100644 --- a/src/conversion/fire/checkFireEdges.C +++ b/src/conversion/fire/checkFireEdges.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2018 OpenCFD Ltd. + Copyright (C) 2016-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -81,9 +81,9 @@ Foam::label Foam::checkFireEdges { const face& faceA = faces[faceI]; - forAll(faceA, edgeI) + forAll(faceA, edgei) { - const edge currEdge = faceA.faceEdge(edgeI); + const edge currEdge = faceA.edge(edgei); // all faces attached to the first point const labelList& otherFaceIds = pointFaces[currEdge[0]]; diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/edgeCollapser.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/edgeCollapser.C index 85f5dada83..2e1b557c42 100644 --- a/src/dynamicMesh/polyTopoChange/polyTopoChange/edgeCollapser.C +++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/edgeCollapser.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -37,7 +37,7 @@ License #include "motionSmoother.H" #include "OFstream.H" -// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { @@ -45,6 +45,8 @@ defineTypeNameAndDebug(edgeCollapser, 0); } +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + Foam::labelHashSet Foam::edgeCollapser::checkBadFaces ( const polyMesh& mesh, @@ -415,7 +417,7 @@ void Foam::edgeCollapser::faceCollapseAxisAndAspectRatio { // It is possible that all the points of a face are the same - collapseAxis = f.edges()[f.longestEdge(pts)].unitVec(pts); + collapseAxis = f.edge(f.longestEdge(pts)).unitVec(pts); // Empirical correlation for high aspect ratio faces @@ -432,7 +434,7 @@ void Foam::edgeCollapser::faceCollapseAxisAndAspectRatio // Cannot necessarily determine linearly independent // eigenvectors, or any at all, use longest edge direction. - collapseAxis = f.edges()[f.longestEdge(pts)].unitVec(pts); + collapseAxis = f.edge(f.longestEdge(pts)).unitVec(pts); aspectRatio = 1.0; } diff --git a/src/finiteVolume/cfdTools/general/levelSet/levelSet.C b/src/finiteVolume/cfdTools/general/levelSet/levelSet.C index 9a100b8726..4e800b71a0 100644 --- a/src/finiteVolume/cfdTools/general/levelSet/levelSet.C +++ b/src/finiteVolume/cfdTools/general/levelSet/levelSet.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2017 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -122,9 +123,9 @@ Foam::tmp Foam::levelSetFraction vector a(Zero); vector r(Zero); - for (label eI = 0; eI < f.size(); ++eI) + for (label edgei = 0; edgei < f.nEdges(); ++edgei) { - const edge e = f.faceEdge(eI); + const edge e = f.edge(edgei); const FixedList tri = diff --git a/src/finiteVolume/cfdTools/general/levelSet/levelSetTemplates.C b/src/finiteVolume/cfdTools/general/levelSet/levelSetTemplates.C index 943d7b87fe..f5e154f93b 100644 --- a/src/finiteVolume/cfdTools/general/levelSet/levelSetTemplates.C +++ b/src/finiteVolume/cfdTools/general/levelSet/levelSetTemplates.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2017 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -141,9 +142,9 @@ Foam::tmp> Foam::levelSetAverage vector a(Zero); sumType r = Zero; - for (label eI = 0; eI < f.size(); ++eI) + for (label edgei = 0; edgei < f.nEdges(); ++edgei) { - const edge e = f.faceEdge(eI); + const edge e = f.edge(edgei); const FixedList tri = diff --git a/src/lagrangian/basic/particle/particle.C b/src/lagrangian/basic/particle/particle.C index a0eaddfc02..a71de211aa 100644 --- a/src/lagrangian/basic/particle/particle.C +++ b/src/lagrangian/basic/particle/particle.C @@ -297,7 +297,7 @@ void Foam::particle::changeFace(const label tetTriI) ( ; edgeI < newFace.size() - && edge::compare(sharedEdge, newFace.faceEdge(edgeI)) != edgeComp; + && edge::compare(sharedEdge, newFace.edge(edgeI)) != edgeComp; ++ edgeI ); diff --git a/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersectionFuncs.C b/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersectionFuncs.C index 7f7e547046..724c8000ee 100644 --- a/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersectionFuncs.C +++ b/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersectionFuncs.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -84,7 +84,7 @@ Foam::label Foam::surfaceIntersection::getEdge const label fp ) { - const edge faceEdge = surf.localFaces()[facei].faceEdge(fp); + const edge faceEdge = surf.localFaces()[facei].edge(fp); const labelList& eLabels = surf.faceEdges()[facei]; diff --git a/src/sampling/surface/cutting/cuttingSurfaceBaseTemplates.C b/src/sampling/surface/cutting/cuttingSurfaceBaseTemplates.C index 5fd36c392b..9438c64eed 100644 --- a/src/sampling/surface/cutting/cuttingSurfaceBaseTemplates.C +++ b/src/sampling/surface/cutting/cuttingSurfaceBaseTemplates.C @@ -134,7 +134,7 @@ void Foam::cuttingSurfaceBase::walkCellCuts forAll(f, fp) { - edge e(f.faceEdge(fp)); + edge e(f.edge(fp)); // Action #1: Orient edge (+ve gradient) and detect intersect if (!edgeOrientIntersect(e)) From c0138ee8b67102e20ef92386de4e0c9fe0bcd053 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Tue, 4 May 2021 10:09:55 +0200 Subject: [PATCH 2/8] ENH: add forward/reverse circular index/value accessors for indirect lists - improves interchangeability of List vs IndirectList --- .../IndirectListBase/IndirectListBase.H | 70 ++++++++++-------- .../IndirectListBase/IndirectListBaseI.H | 74 ++++++++++++++++++- src/OpenFOAM/containers/Lists/UList/UList.H | 12 +-- src/OpenFOAM/containers/Lists/UList/UListI.H | 22 +++--- 4 files changed, 127 insertions(+), 51 deletions(-) diff --git a/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBase.H b/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBase.H index cef22166d9..c9b01667ed 100644 --- a/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBase.H +++ b/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBase.H @@ -123,52 +123,25 @@ public: // Access //- The number of elements in the list - inline label size() const + inline label size() const noexcept { return addr_.size(); } //- True if the list is empty (ie, size() is zero). - inline bool empty() const + inline bool empty() const noexcept { return addr_.empty(); } - //- True if all entries have identical values, and list is non-empty - inline bool uniform() const; - - //- The first element of the list. - inline T& first() - { - return values_[addr_.first()]; - } - - //- The first element of the list. - inline const T& first() const - { - return values_[addr_.first()]; - } - - //- The last element of the list. - inline T& last() - { - return values_[addr_.last()]; - } - - //- The last element of the list. - inline const T& last() const - { - return values_[addr_.last()]; - } - //- The list of values (without addressing) - inline const UList& values() const + inline const UList& values() const noexcept { return values_; } //- The list of values (without addressing) - inline UList& values() + inline UList& values() noexcept { return values_; } @@ -179,6 +152,41 @@ public: return addr_; } + //- True if all entries have identical values, and list is non-empty + inline bool uniform() const; + + //- The first element of the list. + inline const T& first() const; + + //- The first element of the list. + inline T& first(); + + //- The last element of the list. + inline const T& last() const; + + //- The last element of the list. + inline T& last(); + + //- The forward circular index. The next index in the list + //- which returns to the first at the end of the list + inline label fcIndex(const label i) const; + + //- The reverse circular index. The previous index in the list + //- which returns to the last at the beginning of the list + inline label rcIndex(const label i) const; + + //- Return forward circular value (ie, next value in the list) + inline const T& fcValue(const label i) const; + + //- Return forward circular value (ie, next value in the list) + inline T& fcValue(const label i); + + //- Return reverse circular value (ie, previous value in the list) + inline const T& rcValue(const label i) const; + + //- Return reverse circular value (ie, previous value in the list) + inline T& rcValue(const label i); + // Search diff --git a/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBaseI.H b/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBaseI.H index bc1aa07431..a6f87e688a 100644 --- a/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBaseI.H +++ b/src/OpenFOAM/containers/IndirectLists/IndirectListBase/IndirectListBaseI.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2020 OpenCFD Ltd. + Copyright (C) 2018-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -84,9 +84,9 @@ inline bool Foam::IndirectListBase::uniform() const return false; } - const T& val = (*this)[0]; + const T& val = (*this)[0]; // first - for (label i=1; i::found } +template +inline Foam::label Foam::IndirectListBase::fcIndex(const label i) const +{ + return (i == addr_.size()-1 ? 0 : i+1); +} + + +template +inline Foam::label Foam::IndirectListBase::rcIndex(const label i) const +{ + return (i ? i-1 : addr_.size()-1); +} + + +template +inline const T& Foam::IndirectListBase::first() const +{ + return values_[addr_.first()]; +} + +template +inline T& Foam::IndirectListBase::first() +{ + return values_[addr_.first()]; +} + + +template +inline const T& Foam::IndirectListBase::last() const +{ + return values_[addr_.last()]; +} + +template +inline T& Foam::IndirectListBase::last() +{ + return values_[addr_.last()]; +} + + +template +inline const T& Foam::IndirectListBase::fcValue(const label i) const +{ + return values_[this->fcIndex(i)]; +} + + +template +inline T& Foam::IndirectListBase::fcValue(const label i) +{ + return values_[this->fcIndex(i)]; +} + + +template +inline const T& Foam::IndirectListBase::rcValue(const label i) const +{ + return values_[this->rcIndex(i)]; +} + + +template +inline T& Foam::IndirectListBase::rcValue(const label i) +{ + return values_[this->rcIndex(i)]; +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template diff --git a/src/OpenFOAM/containers/Lists/UList/UList.H b/src/OpenFOAM/containers/Lists/UList/UList.H index 9df3e1f912..1493a88637 100644 --- a/src/OpenFOAM/containers/Lists/UList/UList.H +++ b/src/OpenFOAM/containers/Lists/UList/UList.H @@ -232,9 +232,13 @@ public: // Access - //- Return the forward circular index, i.e. next index + //- The forward circular index. The next index in the list //- which returns to the first at the end of the list - inline label fcIndex(const label i) const; + inline label fcIndex(const label i) const noexcept; + + //- The reverse circular index. The previous index in the list + //- which returns to the last at the beginning of the list + inline label rcIndex(const label i) const noexcept; //- Return forward circular value (ie, next value in the list) inline const T& fcValue(const label i) const; @@ -242,10 +246,6 @@ public: //- Return forward circular value (ie, next value in the list) inline T& fcValue(const label i); - //- Return the reverse circular index, i.e. previous index - //- which returns to the last at the beginning of the list - inline label rcIndex(const label i) const; - //- Return reverse circular value (ie, previous value in the list) inline const T& rcValue(const label i) const; diff --git a/src/OpenFOAM/containers/Lists/UList/UListI.H b/src/OpenFOAM/containers/Lists/UList/UListI.H index 923e896f23..dc46db9faf 100644 --- a/src/OpenFOAM/containers/Lists/UList/UListI.H +++ b/src/OpenFOAM/containers/Lists/UList/UListI.H @@ -57,12 +57,19 @@ inline const Foam::UList& Foam::UList::null() template -inline Foam::label Foam::UList::fcIndex(const label i) const +inline Foam::label Foam::UList::fcIndex(const label i) const noexcept { return (i == size()-1 ? 0 : i+1); } +template +inline Foam::label Foam::UList::rcIndex(const label i) const noexcept +{ + return (i ? i-1 : size()-1); +} + + template inline const T& Foam::UList::fcValue(const label i) const { @@ -77,13 +84,6 @@ inline T& Foam::UList::fcValue(const label i) } -template -inline Foam::label Foam::UList::rcIndex(const label i) const -{ - return (i ? i-1 : size()-1); -} - - template inline const T& Foam::UList::rcValue(const label i) const { @@ -146,14 +146,14 @@ inline bool Foam::UList::uniform() const { const label len = size(); - if (len == 0) + if (!len) { return false; } - const T& val = first(); + const T& val = (*this)[0]; // first - for (label i=1; i Date: Tue, 4 May 2021 14:25:28 +0200 Subject: [PATCH 3/8] DEFEATURE: remove construct List from two iterators (#2083) - this constructor was added for similarity with std::vector, but continues to cause various annoyances. The main problem is that the templated parameter tends to grab anything that is not a perfect match for other constructors. Typically seen with two integers (in 64-bit mode), but various other cases as well. If required, the ListOps::create() function provides a lengthier alternative but one that can also incorporate transformations. Eg, pointField pts = ....; List mags ( List::create ( pts.begin(), pts.end(), [](const vector& v){ return magSqr(v); } ); --- applications/test/List/Test-List.C | 16 ++++++++++++++++ .../test/zoneDistribute/Test-zoneDistribute.C | 2 -- .../containers/Lists/DynamicList/DynamicList.H | 5 ----- .../containers/Lists/DynamicList/DynamicListI.H | 13 ------------- src/OpenFOAM/containers/Lists/List/List.C | 8 -------- src/OpenFOAM/containers/Lists/List/List.H | 5 ----- 6 files changed, 16 insertions(+), 33 deletions(-) diff --git a/applications/test/List/Test-List.C b/applications/test/List/Test-List.C index 16b3210958..4f52872b94 100644 --- a/applications/test/List/Test-List.C +++ b/applications/test/List/Test-List.C @@ -55,6 +55,9 @@ See also #include #include +// see issue #2083 +#undef Foam_constructList_from_iterators + namespace Foam { @@ -254,8 +257,12 @@ int main(int argc, char *argv[]) Info<< "list4: " << list4 << nl << "list5: " << list5 << endl; + #ifdef Foam_constructList_from_iterators List list6(list4.begin(), list4.end()); Info<< "list6: " << list6 << endl; + #else + Info<< "NOTE: no construction from two iterators" << endl; + #endif // Subset const labelList map{0, 2}; @@ -273,9 +280,13 @@ int main(int argc, char *argv[]) // scalarList slist = identity(15); // // More writing, but does work: + #ifdef Foam_constructList_from_iterators scalarList slist(labelRange().begin(), labelRange(15).end()); Info<<"scalar identity:" << flatOutput(slist) << endl; + #else + Info<<"No iterator means of creating a scalar identity list" << endl; + #endif printListOutputType