diff --git a/applications/test/edges/Make/files b/applications/test/edges/Make/files new file mode 100644 index 0000000000..8903c60b8c --- /dev/null +++ b/applications/test/edges/Make/files @@ -0,0 +1,3 @@ +Test-edges.C + +EXE = $(FOAM_USER_APPBIN)/Test-edges diff --git a/applications/test/edges/Make/options b/applications/test/edges/Make/options new file mode 100644 index 0000000000..e69de29bb2 diff --git a/applications/test/edges/Test-edges.C b/applications/test/edges/Test-edges.C new file mode 100644 index 0000000000..abd5f9d8a1 --- /dev/null +++ b/applications/test/edges/Test-edges.C @@ -0,0 +1,114 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Application + Test-edges + +Description + Simple tests for edges + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "edgeList.H" + +using namespace Foam; + +void printInfo(const edge& e) +{ + Info<< "edge: " << e << " count:" << e.count() << nl; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + edge e1; + printInfo(e1); + Info<<"has '2'? " << e1.found(2) << endl; + + edge e2(1, 2); + printInfo(e2); + Info<<"has '2'? " << e2.found(2) << endl; + + edge e3{2, 3}; + printInfo(e3); + Info<<"has '2'? " << e3.found(2) << endl; + + edge e4(4, 4); + printInfo(e4); + Info<<"has '2'? " << e4.found(2) << endl; + + Info<<"collapse? -> " << e4.collapse() << endl; + printInfo(e4); + + Info<< e3 << " connects " << e2 << " => " << e2.connects(e3) << endl; + + Info<< nl << "hash-like functionality" << nl; + + // doesn't work e4 = -1; + e4.start() = e4.end() = -1; + + printInfo(e4); + for (label i : {2, -1, 2, 1, 4, 1, 2, 3}) + { + bool ok = e4.insert(i); + Info<< "insert(" << i << ") = " << ok << " resulting "; + printInfo(e4); + } + + for (label i : {-1, 0, 1, 3}) + { + bool ok = e4.erase(i); + Info<< "erase(" << i << ") = " << ok << " resulting "; + printInfo(e4); + } + + for (label i : {-1, 0, 1, 3}) + { + bool ok = e4.insert(i); + Info<< "insert(" << i << ") = " << ok << " resulting "; + printInfo(e4); + } + e4.flip(); + Info<< "flipped "; + printInfo(e4); + + for (label i : {-1, 0, 1, 3}) + { + bool ok = e4.erase(i); + Info<< "erase(" << i << ") = " << ok << " resulting "; + printInfo(e4); + } + + e4.sort(); + Info<< "sorted "; + printInfo(e4); + + return 0; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/meshes/meshShapes/edge/edge.H b/src/OpenFOAM/meshes/meshShapes/edge/edge.H index e1c314d1f2..f804fda814 100644 --- a/src/OpenFOAM/meshes/meshShapes/edge/edge.H +++ b/src/OpenFOAM/meshes/meshShapes/edge/edge.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -70,17 +70,23 @@ public: // Constructors - //- Null constructor for lists + //- Construct null with invalid point labels (-1) inline edge(); //- Construct from components - inline edge(const label a, const label b); + inline edge(const label from, const label to); + + //- Construct, optionally sorted with start less-than end + inline edge(const label from, const label to, const bool doSort); //- Construct from FixedList - inline edge(const FixedList&); + inline edge(const FixedList& lst); + + //- Construct, optionally sorted with start less-than end + inline edge(const FixedList& lst, const bool doSort); //- Construct from Istream - inline edge(Istream&); + inline edge(Istream& is); // Member Functions @@ -97,11 +103,45 @@ public: //- Return end vertex label inline label& end(); - //- Given one vertex, return the other - inline label otherVertex(const label a) const; + //- Do the edges share a common vertex index? + inline bool connects(const edge& other) const; - //- Return common vertex - inline label commonVertex(const edge& a) const; + //- Return vertex common with otherEdge or -1 on failure + inline label commonVertex(const edge& other) const; + + //- Given one vertex index, return the other one. + inline label otherVertex(const label index) const; + + //- 'Collapse' edge by marking duplicate point labels. + // Duplicates point labels are marked with '-1'. + // (the lower vertex is retained). + // Return the collapsed size. + inline label collapse(); + + //- Return true if point label is found in edge + // No special treatment for '-1'. + inline bool found(const label index) const; + + //- Return the number of unique, valid (non -1) point labels. + // Similar to a HashTable::size(). + inline label count() const; + + //- Insert the index if it did not previously exist on the edge. + // Returns true on success. A negative label never inserts. + // Similar to a HashTable::insert(). + inline bool insert(const label index); + + //- Remove an existing index from the edge and set its location to '-1'. + // Returns true on success. A negative label never removes. + // Similar to a HashTable::erase(). + inline bool erase(const label index); + + + //- True if the edge is sorted such that start is less-than end + inline bool sorted() const; + + //- Sort start/end that start is less-than end + inline void sort(); //- Flip the edge in-place. inline void flip(); @@ -110,23 +150,26 @@ public: inline edge reverseEdge() const; //- Return centre (centroid) - inline point centre(const pointField&) const; + inline point centre(const UList& pts) const; //- Return the vector (end - start) - inline vector vec(const pointField&) const; + inline vector vec(const UList& pts) const; + + //- Return the unit vector (end - start) + inline vector unitVec(const UList& pts) const; //- Return scalar magnitude - inline scalar mag(const pointField&) const; + inline scalar mag(const UList& pts) const; //- Return edge line - inline linePointRef line(const pointField&) const; + inline linePointRef line(const UList& pts) const; //- Compare edges // Returns: // - 0: different // - +1: identical // - -1: same edge, but different orientation - static inline int compare(const edge&, const edge&); + static inline int compare(const edge& a, const edge& b); // Friend Operators diff --git a/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H b/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H index 8e967880fe..b1b4f49368 100644 --- a/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H +++ b/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,11 +28,6 @@ License // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // - -// return -// - 0: different -// - +1: identical -// - -1: same edge, but different orientation inline int Foam::edge::compare(const edge& a, const edge& b) { if (a[0] == b[0] && a[1] == b[1]) @@ -53,20 +48,52 @@ inline int Foam::edge::compare(const edge& a, const edge& b) // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // inline Foam::edge::edge() +: + FixedList(-1) {} -inline Foam::edge::edge(const label a, const label b) +inline Foam::edge::edge(const label from, const label to) { - start() = a; - end() = b; + start() = from; + end() = to; } -inline Foam::edge::edge(const FixedList& a) +inline Foam::edge::edge(const label from, const label to, const bool doSort) { - start() = a[0]; - end() = a[1]; + if (doSort && from > to) + { + start() = to; + end() = from; + } + else + { + start() = from; + end() = to; + } +} + + +inline Foam::edge::edge(const FixedList& lst) +{ + start() = lst[0]; + end() = lst[1]; +} + + +inline Foam::edge::edge(const FixedList& lst, const bool doSort) +{ + if (doSort && lst[0] > lst[1]) + { + start() = lst[1]; + end() = lst[0]; + } + else + { + start() = lst[0]; + end() = lst[1]; + } } @@ -100,13 +127,43 @@ inline Foam::label& Foam::edge::end() } -inline Foam::label Foam::edge::otherVertex(const label a) const +inline bool Foam::edge::found(const label index) const { - if (a == start()) + return (index == start() || index == end()); +} + + +inline bool Foam::edge::connects(const edge& other) const +{ + return (other.found(this->start()) || other.found(this->end())); +} + + +inline Foam::label Foam::edge::commonVertex(const edge& other) const +{ + if (other.found(this->start())) + { + return this->start(); + } + else if (other.found(this->end())) + { + return this->end(); + } + else + { + // No shared vertex. + return -1; + } +} + + +inline Foam::label Foam::edge::otherVertex(const label index) const +{ + if (index == start()) { return end(); } - else if (a == end()) + else if (index == end()) { return start(); } @@ -118,20 +175,112 @@ inline Foam::label Foam::edge::otherVertex(const label a) const } -inline Foam::label Foam::edge::commonVertex(const edge& a) const +inline Foam::label Foam::edge::collapse() { - if (start() == a.start() || start() == a.end()) + // Cannot resize FixedList, so mark duplicates with '-1' + // (the lower vertex is retained) + // catch any '-1' (eg, if called multiple times) + + label n = 2; + if (start() == end() || end() == -1) { - return start(); + end() = -1; + --n; } - else if (end() == a.start() || end() == a.end()) + if (start() == -1) { - return end(); + --n; } - else + + return n; +} + + +inline Foam::label Foam::edge::count() const +{ + label n = 2; + if (start() == end() || end() == -1) { - // No shared vertex. - return -1; + --n; + } + + if (start() == -1) + { + --n; + } + + return n; +} + + +inline bool Foam::edge::insert(const label index) +{ + if (index < 0) + { + // Can never insert invalid point labels. + // Use direct assignment for that. + return false; + } + else if (start() == -1) + { + // Store at [0], if not duplicate of [1] + if (index != end()) + { + start() = index; + return true; + } + } + else if (end() == -1) + { + // Store at [1], if not duplicate of [0] + if (index != start()) + { + end() = index; + return true; + } + } + + return false; +} + + +inline bool Foam::edge::erase(const label index) +{ + if (index < 0) + { + // Can never remove invalid point labels! + return false; + } + + int n = 0; + if (index == start()) + { + start() = -1; + ++n; + } + + // Automatically handle duplicates, should not have been there anyhow + if (index == end()) + { + end() = -1; + ++n; + } + + return n; +} + + +inline bool Foam::edge::sorted() const +{ + return (start() < end()); +} + + +inline void Foam::edge::sort() +{ + if (start() > end()) + { + flip(); } } @@ -148,27 +297,36 @@ inline Foam::edge Foam::edge::reverseEdge() const } -inline Foam::point Foam::edge::centre(const pointField& p) const +inline Foam::point Foam::edge::centre(const UList& pts) const { - return 0.5*(p[start()] + p[end()]); + return 0.5*(pts[start()] + pts[end()]); } -inline Foam::vector Foam::edge::vec(const pointField& p) const +inline Foam::vector Foam::edge::vec(const UList& pts) const { - return p[end()] - p[start()]; + return pts[end()] - pts[start()]; } -inline Foam::scalar Foam::edge::mag(const pointField& p) const +inline Foam::vector Foam::edge::unitVec(const UList& pts) const { - return ::Foam::mag(vec(p)); + Foam::vector v = pts[end()] - pts[start()]; + v /= ::Foam::mag(v) + VSMALL; + + return v; } -inline Foam::linePointRef Foam::edge::line(const pointField& p) const +inline Foam::scalar Foam::edge::mag(const UList& pts) const { - return linePointRef(p[start()], p[end()]); + return ::Foam::mag(vec(pts)); +} + + +inline Foam::linePointRef Foam::edge::line(const UList& pts) const +{ + return linePointRef(pts[start()], pts[end()]); }