diff --git a/src/finiteArea/Make/files b/src/finiteArea/Make/files index 14d538ace1..85d56a5e87 100644 --- a/src/finiteArea/Make/files +++ b/src/finiteArea/Make/files @@ -2,6 +2,7 @@ faMesh/faGlobalMeshData/faGlobalMeshData.C faMesh/faMesh.C faMesh/faMeshDemandDrivenData.C faMesh/faMeshPatches.C +faMesh/faMeshTopology.C faMesh/faMeshUpdate.C faMesh/faBoundaryMesh/faBoundaryMesh.C diff --git a/src/finiteArea/faMesh/faMesh.C b/src/finiteArea/faMesh/faMesh.C index ef64e0541e..021b83a327 100644 --- a/src/finiteArea/faMesh/faMesh.C +++ b/src/finiteArea/faMesh/faMesh.C @@ -111,15 +111,15 @@ static labelList selectPatchFaces void Foam::faMesh::initPatch() const { - if (patchPtr_) - { - delete patchPtr_; - } - patchPtr_ = new uindirectPrimitivePatch + patchPtr_.reset ( - UIndirectList(mesh().faces(), faceLabels_), - mesh().points() + new uindirectPrimitivePatch + ( + UIndirectList(mesh().faces(), faceLabels_), + mesh().points() + ) ); + bndConnectPtr_.reset(nullptr); } @@ -172,8 +172,9 @@ void Foam::faMesh::clearGeomNotAreas() const { DebugInFunction << "Clearing geometry" << endl; + patchPtr_.reset(nullptr); + bndConnectPtr_.reset(nullptr); deleteDemandDrivenData(SPtr_); - deleteDemandDrivenData(patchPtr_); deleteDemandDrivenData(patchStartsPtr_); deleteDemandDrivenData(LePtr_); deleteDemandDrivenData(magLePtr_); @@ -256,6 +257,7 @@ Foam::faMesh::faMesh(const polyMesh& pMesh) ), comm_(Pstream::worldComm), patchPtr_(nullptr), + bndConnectPtr_(nullptr), lduPtr_(nullptr), curTimeIndex_(time().timeIndex()), SPtr_(nullptr), @@ -349,6 +351,7 @@ Foam::faMesh::faMesh ), comm_(Pstream::worldComm), patchPtr_(nullptr), + bndConnectPtr_(nullptr), lduPtr_(nullptr), curTimeIndex_(time().timeIndex()), SPtr_(nullptr), diff --git a/src/finiteArea/faMesh/faMesh.H b/src/finiteArea/faMesh/faMesh.H index 8a9b165011..313db0517a 100644 --- a/src/finiteArea/faMesh/faMesh.H +++ b/src/finiteArea/faMesh/faMesh.H @@ -33,6 +33,9 @@ Description SourceFiles faMesh.C faMeshDemandDrivenData.C + faMeshPatches.C + faMeshTopology.C + faMeshUpdate.C Author Zeljko Tukovic, FMENA @@ -71,7 +74,6 @@ namespace Foam class faMeshLduAddressing; class faMeshMapper; class faPatchData; -template class LabelledItem; /*---------------------------------------------------------------------------*\ Class faMesh Declaration @@ -86,6 +88,107 @@ class faMesh public faSolution, public data { + // Private (internal) classes/structures + + //- A (proc, patchi, patchEdgei) tuple used internally for managing + //- patch/patch bookkeeping during construction. + // Finite-area patches are stored with negated indices, which makes + // them readily identifiable and always sort before normal patches. + // Note + struct patchTuple + : + public FixedList + { + + // Constructors + + // Inherit constructors + using FixedList::FixedList; + + //- Default construct as 'invalid' + patchTuple() + { + clear(); + } + + + // Static Member Functions + + // Globally consistent ordering + // + // 1. sort left/right as lower/higher processor connection + // 2. sort by proc/patch/patch index + static void sort(UList>& list) + { + for (auto& tuples : list) + { + tuples.sort(); + } + Foam::stableSort(list); + } + + + // Member Functions + + //- Reset to 'invalid' + void clear() + { + procNo(-1); + patchi(labelMax); + patchEdgei(-1); + meshFacei(-1); + } + + //- Valid if proc and edge are non-negative + bool valid() const noexcept + { + return (procNo() >= 0 && patchEdgei() >= 0); + } + + // Processor is the first sort index + label procNo() const { return (*this)[0]; } + void procNo(label val) { (*this)[0] = val; } + + // PatchId (-ve for finiteArea patches) is the second sort index + label patchi() const { return (*this)[1]; } + void patchi(label val) { (*this)[1] = val; } + + // The patch edge index (on the finiteArea patch) + // is the third sort index + label patchEdgei() const { return (*this)[2]; } + void patchEdgei(label val) { (*this)[2] = val; } + + // The processor-local mesh face is the fourth sort index + label meshFacei() const { return (*this)[3]; } + void meshFacei(label val) { (*this)[3] = val; } + + //- Return the real patchId + label realPatchi() const + { + const label id = patchi(); + return (id < 0 ? -(id + 1) : id); + } + + //- Set patchId as finiteArea + void faPatchi(label val) + { + patchi(-(val + 1)); + } + + //- Considered to be finiteArea if patchi < 0 + bool is_finiteArea() const noexcept + { + return (patchi() < 0); + } + + //- Considered to be processor local + bool is_localProc() const noexcept + { + return (procNo() == Pstream::myProcNo()); + } + }; + + // Private Data //- Face labels @@ -131,7 +234,10 @@ class faMesh // Demand-driven data //- Primitive patch - mutable uindirectPrimitivePatch* patchPtr_; + mutable std::unique_ptr patchPtr_; + + //- List of proc/mesh-face for boundary edge neighbours + mutable std::unique_ptr> bndConnectPtr_; //- Ldu addressing data mutable faMeshLduAddressing* lduPtr_; @@ -211,6 +317,20 @@ class faMesh //- Set primitive mesh data void setPrimitiveMeshData(); + //- Get list of (proc/patchi/patchEdgei/meshFacei) tuple pairs in an + //- globally consistent ordering + List> getBoundaryEdgeConnections() const; + + //- Determine the boundary edge neighbour connections + void calcBoundaryConnections() const; + + //- Define boundary edge neighbours (proc/face) based on + //- gathered topology information + void setBoundaryConnections + ( + const List>& bndEdgeConnections + ) const; + // Private member functions to calculate demand driven data @@ -268,9 +388,6 @@ class faMesh // Helpers - //- Get the polyPatch pairs for the boundary edges (natural order) - List> getBoundaryEdgePatchPairs() const; - //- Create a single patch PtrList createOnePatch ( @@ -286,14 +403,6 @@ class faMesh const dictionary* defaultPatchDefinition = nullptr ) const; - //- Reorder processor edges using order of the - //- neighbour processorPolyPatch - void reorderProcEdges - ( - faPatchData& patchDef, - const List>& bndEdgePatchPairs - ) const; - public: @@ -451,7 +560,7 @@ public: //- Return constant reference to boundary mesh inline const faBoundaryMesh& boundary() const noexcept; - //- Return faMesh face labels + //- Return the underlying polyMesh face labels inline const labelList& faceLabels() const noexcept; @@ -486,6 +595,18 @@ public: return (edgeIndex < nInternalEdges_); } + //- List of proc/face for the boundary edge neighbours + //- using primitive patch edge numbering. + inline const List& boundaryConnections() const; + + //- Boundary edge neighbour processors + //- (does not include own proc) + labelList boundaryProcs() const; + + //- List of proc/size for the boundary edge neighbour processors + //- (does not include own proc) + List boundaryProcSizes() const; + // Mesh motion and morphing @@ -590,6 +711,7 @@ public: } // End namespace Foam + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #include "faMeshI.H" diff --git a/src/finiteArea/faMesh/faMeshI.H b/src/finiteArea/faMesh/faMeshI.H index a3d7932860..dc1b238c3d 100644 --- a/src/finiteArea/faMesh/faMeshI.H +++ b/src/finiteArea/faMesh/faMeshI.H @@ -139,4 +139,15 @@ inline Foam::uindirectPrimitivePatch& Foam::faMesh::patch() } +inline const Foam::List& +Foam::faMesh::boundaryConnections() const +{ + if (!bndConnectPtr_) + { + calcBoundaryConnections(); + } + return *bndConnectPtr_; +} + + // ************************************************************************* // diff --git a/src/finiteArea/faMesh/faMeshPatches.C b/src/finiteArea/faMesh/faMeshPatches.C index 436f3f5678..42d8d99d6a 100644 --- a/src/finiteArea/faMesh/faMeshPatches.C +++ b/src/finiteArea/faMesh/faMeshPatches.C @@ -27,311 +27,10 @@ License \*---------------------------------------------------------------------------*/ #include "faMesh.H" -#include "IndirectList.H" #include "faPatchData.H" #include "processorPolyPatch.H" #include "processorFaPatch.H" -#include "globalMeshData.H" -#include "indirectPrimitivePatch.H" -#include "edgeHashes.H" -#include "LabelledItem.H" - -// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // - -namespace Foam -{ - -// Manage patch pairs with a 'labelled' edge. -// The edge first/second correspond to the owner/neighbour patches. -// The index is a face index on the neighbour patch (FUTURE). - -// Local typedefs - -typedef LabelledItem patchPairInfo; -typedef List patchPairInfoList; -typedef UIndirectList patchPairInfoUIndList; - - -// Handling of dangling coupled edges. -// Tag values to "push" with special -(patchId+2) -struct combineDanglingEdge -{ - const label upperLimit; - - // Set dangling patchId from real patchId - static void setDangling(patchPairInfo& pairing, const label patchId) - { - pairing.first() = pairing.second() = -(patchId + 2); - pairing.setIndex(-1); // Invalidate - } - - // Convert dangling patchId to real patchId - static void correct(patchPairInfo& pairing) - { - if (pairing.first() < -1) - { - pairing.first() = -(pairing.first() + 2); - } - if (pairing.second() < -1) - { - pairing.second() = -(pairing.second() + 2); - } - } - - //- Construct with upper limit (the number of non-processor patches) - explicit combineDanglingEdge(const label nNonProcessor) - : - upperLimit(nNonProcessor) - {} - - - // Combine operation: overwrite unused or processor patches with - // 'dangling' patch information only - void operator()(patchPairInfo& x, const patchPairInfo& y) const - { - if (y.first() < -1 && edge::compare(x, y) == 0) - { - if (x.first() == -1 || x.first() >= upperLimit) - { - x.first() = y.first(); - } - if (x.second() == -1 || x.second() >= upperLimit) - { - x.second() = y.first(); - x.index() = y.index(); - } - } - } -}; - - -// Populate patch pairings according to the boundary edges -void findEdgePatchPairing -( - const polyBoundaryMesh& pbm, - const EdgeMap