From 8659d34b1955fd40e7a42ee93011cef7c4a8f179 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Thu, 6 May 2021 15:35:01 +0200 Subject: [PATCH] ENH: support fa/fv field decomposers without the complete mesh (#2084) --- .../decompose/decompose/fvFieldDecomposer.C | 222 ++++++++++++++--- .../decompose/decompose/fvFieldDecomposer.H | 59 ++++- .../decompose/faDecompose/faFieldDecomposer.C | 234 +++++++++++++++--- .../decompose/faDecompose/faFieldDecomposer.H | 71 +++++- 4 files changed, 508 insertions(+), 78 deletions(-) diff --git a/src/parallel/decompose/decompose/fvFieldDecomposer.C b/src/parallel/decompose/decompose/fvFieldDecomposer.C index 077c177fc13..61ade1be3bc 100644 --- a/src/parallel/decompose/decompose/fvFieldDecomposer.C +++ b/src/parallel/decompose/decompose/fvFieldDecomposer.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -48,21 +49,19 @@ Foam::fvFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer Foam::fvFieldDecomposer::processorVolPatchFieldDecomposer:: processorVolPatchFieldDecomposer ( - const fvMesh& mesh, + const labelUList& owner, // == mesh.faceOwner() + const labelUList& neigh, // == mesh.faceNeighbour() const labelUList& addressingSlice ) : directAddressing_(addressingSlice.size()) { - const labelList& own = mesh.faceOwner(); - const labelList& neighb = mesh.faceNeighbour(); - forAll(directAddressing_, i) { // Subtract one to align addressing. label ai = mag(addressingSlice[i]) - 1; - if (ai < neighb.size()) + if (ai < neigh.size()) { // This is a regular face. it has been an internal face // of the original mesh and now it has become a face @@ -72,11 +71,11 @@ processorVolPatchFieldDecomposer if (addressingSlice[i] >= 0) { // I have the owner so use the neighbour value - directAddressing_[i] = neighb[ai]; + directAddressing_[i] = neigh[ai]; } else { - directAddressing_[i] = own[ai]; + directAddressing_[i] = owner[ai]; } } else @@ -87,12 +86,28 @@ processorVolPatchFieldDecomposer // up the different (face) list of data), so I will // just grab the value from the owner cell - directAddressing_[i] = own[ai]; + directAddressing_[i] = owner[ai]; } } } +Foam::fvFieldDecomposer::processorVolPatchFieldDecomposer:: +processorVolPatchFieldDecomposer +( + const fvMesh& mesh, + const labelUList& addressingSlice +) +: + processorVolPatchFieldDecomposer + ( + mesh.faceOwner(), + mesh.faceNeighbour(), + addressingSlice + ) +{} + + Foam::fvFieldDecomposer::processorSurfacePatchFieldDecomposer:: processorSurfacePatchFieldDecomposer ( @@ -104,8 +119,8 @@ processorSurfacePatchFieldDecomposer { forAll(addressing_, i) { - addressing_[i].setSize(1); - weights_[i].setSize(1); + addressing_[i].resize(1); + weights_[i].resize(1); addressing_[i][0] = mag(addressingSlice[i]) - 1; weights_[i][0] = 1; @@ -115,32 +130,184 @@ processorSurfacePatchFieldDecomposer Foam::fvFieldDecomposer::fvFieldDecomposer ( - const fvMesh& completeMesh, + const Foam::zero, const fvMesh& procMesh, const labelList& faceAddressing, const labelList& cellAddressing, const labelList& boundaryAddressing ) : - completeMesh_(completeMesh), procMesh_(procMesh), faceAddressing_(faceAddressing), cellAddressing_(cellAddressing), boundaryAddressing_(boundaryAddressing), - patchFieldDecomposerPtrs_(procMesh_.boundary().size()), - processorVolPatchFieldDecomposerPtrs_(procMesh_.boundary().size()), - processorSurfacePatchFieldDecomposerPtrs_(procMesh_.boundary().size()), - faceSign_(procMesh_.boundary().size()) + // Mappers + patchFieldDecomposerPtrs_(), + processorVolPatchFieldDecomposerPtrs_(), + processorSurfacePatchFieldDecomposerPtrs_(), + faceSign_() +{} + + +Foam::fvFieldDecomposer::fvFieldDecomposer +( + const fvMesh& completeMesh, + const fvMesh& procMesh, + const labelList& faceAddressing, + const labelList& cellAddressing, + const labelList& boundaryAddressing +) +: + fvFieldDecomposer + ( + zero{}, + procMesh, + faceAddressing, + cellAddressing, + boundaryAddressing + ) +{ + reset(completeMesh); +} + + +Foam::fvFieldDecomposer::fvFieldDecomposer +( + const List<labelRange>& boundaryRanges, + const labelUList& faceOwner, + const labelUList& faceNeighbour, + + const fvMesh& procMesh, + const labelList& faceAddressing, + const labelList& cellAddressing, + const labelList& boundaryAddressing +) +: + fvFieldDecomposer + ( + zero{}, + procMesh, + faceAddressing, + cellAddressing, + boundaryAddressing + ) +{ + reset(boundaryRanges, faceOwner, faceNeighbour); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::fvFieldDecomposer::empty() const +{ + return patchFieldDecomposerPtrs_.empty(); +} + + +void Foam::fvFieldDecomposer::clear() +{ + patchFieldDecomposerPtrs_.clear(); + processorVolPatchFieldDecomposerPtrs_.clear(); + processorSurfacePatchFieldDecomposerPtrs_.clear(); + faceSign_.clear(); +} + + +void Foam::fvFieldDecomposer::reset +( + const List<labelRange>& boundaryRanges, + const labelUList& faceOwner, + const labelUList& faceNeighbour +) +{ + clear(); + const label nMappers = procMesh_.boundary().size(); + patchFieldDecomposerPtrs_.resize(nMappers); + processorVolPatchFieldDecomposerPtrs_.resize(nMappers); + processorSurfacePatchFieldDecomposerPtrs_.resize(nMappers); + faceSign_.resize(nMappers); + + forAll(boundaryAddressing_, patchi) + { + const label oldPatchi = boundaryAddressing_[patchi]; + const fvPatch& fvp = procMesh_.boundary()[patchi]; + const labelSubList localPatchSlice(fvp.patchSlice(faceAddressing_)); + + if + ( + oldPatchi >= 0 + && !isA<processorLduInterface>(procMesh_.boundary()[patchi]) + ) + { + patchFieldDecomposerPtrs_.set + ( + patchi, + new patchFieldDecomposer + ( + localPatchSlice, + boundaryRanges[oldPatchi].start() + ) + ); + } + else + { + processorVolPatchFieldDecomposerPtrs_.set + ( + patchi, + new processorVolPatchFieldDecomposer + ( + faceOwner, + faceNeighbour, + localPatchSlice + ) + ); + + processorSurfacePatchFieldDecomposerPtrs_.set + ( + patchi, + new processorSurfacePatchFieldDecomposer + ( + static_cast<const labelUList&>(localPatchSlice) + ) + ); + + faceSign_.set + ( + patchi, + new scalarField(localPatchSlice.size()) + ); + + { + scalarField& s = faceSign_[patchi]; + forAll(s, i) + { + s[i] = sign(localPatchSlice[i]); + } + } + } + } +} + + +void Foam::fvFieldDecomposer::reset(const fvMesh& completeMesh) { + clear(); + const label nMappers = procMesh_.boundary().size(); + patchFieldDecomposerPtrs_.resize(nMappers); + processorVolPatchFieldDecomposerPtrs_.resize(nMappers); + processorSurfacePatchFieldDecomposerPtrs_.resize(nMappers); + faceSign_.resize(nMappers); + forAll(boundaryAddressing_, patchi) { const label oldPatchi = boundaryAddressing_[patchi]; const fvPatch& fvp = procMesh_.boundary()[patchi]; + const labelSubList localPatchSlice(fvp.patchSlice(faceAddressing_)); if ( oldPatchi >= 0 - && !isA<processorLduInterface>(procMesh.boundary()[patchi]) + && !isA<processorLduInterface>(procMesh_.boundary()[patchi]) ) { patchFieldDecomposerPtrs_.set @@ -148,8 +315,8 @@ Foam::fvFieldDecomposer::fvFieldDecomposer patchi, new patchFieldDecomposer ( - fvp.patchSlice(faceAddressing_), - completeMesh_.boundaryMesh()[oldPatchi].start() + localPatchSlice, + completeMesh.boundaryMesh()[oldPatchi].start() ) ); } @@ -160,8 +327,8 @@ Foam::fvFieldDecomposer::fvFieldDecomposer patchi, new processorVolPatchFieldDecomposer ( - completeMesh_, - fvp.patchSlice(faceAddressing_) + completeMesh, + localPatchSlice ) ); @@ -170,28 +337,21 @@ Foam::fvFieldDecomposer::fvFieldDecomposer patchi, new processorSurfacePatchFieldDecomposer ( - static_cast<const labelUList&> - ( - fvp.patchSlice - ( - faceAddressing_ - ) - ) + static_cast<const labelUList&>(localPatchSlice) ) ); faceSign_.set ( patchi, - new scalarField(fvp.patchSlice(faceAddressing_).size()) + new scalarField(localPatchSlice.size()) ); { - const SubList<label> fa = fvp.patchSlice(faceAddressing_); scalarField& s = faceSign_[patchi]; forAll(s, i) { - s[i] = sign(fa[i]); + s[i] = sign(localPatchSlice[i]); } } } diff --git a/src/parallel/decompose/decompose/fvFieldDecomposer.H b/src/parallel/decompose/decompose/fvFieldDecomposer.H index d9358224e63..bfb91e75adc 100644 --- a/src/parallel/decompose/decompose/fvFieldDecomposer.H +++ b/src/parallel/decompose/decompose/fvFieldDecomposer.H @@ -115,7 +115,15 @@ public: public: - //- Construct given addressing + //- Construct addressing from details + processorVolPatchFieldDecomposer + ( + const labelUList& faceOwner, + const labelUList& faceNeigbour, + const labelUList& addressingSlice + ); + + //- Construct given addressing from complete mesh processorVolPatchFieldDecomposer ( const fvMesh& mesh, @@ -201,7 +209,7 @@ private: // Private Data //- Reference to complete mesh - const fvMesh& completeMesh_; + //REMOVED const fvMesh& completeMesh_; //- Reference to processor mesh const fvMesh& procMesh_; @@ -238,7 +246,17 @@ public: // Constructors - //- Construct from components + //- Construct without mappers, added later with reset() + fvFieldDecomposer + ( + const Foam::zero, + const fvMesh& procMesh, + const labelList& faceAddressing, + const labelList& cellAddressing, + const labelList& boundaryAddressing + ); + + //- Construct from components using information from the complete mesh fvFieldDecomposer ( const fvMesh& completeMesh, @@ -248,6 +266,21 @@ public: const labelList& boundaryAddressing ); + //- Construct from components without the complete mesh + fvFieldDecomposer + ( + // Information about the complete mesh + const List<labelRange>& boundaryRanges, + const labelUList& faceOwner, + const labelUList& faceNeigbour, + + // Addressing for processor mesh + const fvMesh& procMesh, + const labelList& faceAddressing, + const labelList& cellAddressing, + const labelList& boundaryAddressing + ); + //- Destructor ~fvFieldDecomposer() = default; @@ -255,6 +288,26 @@ public: // Member Functions + //- True if no mappers have been allocated + bool empty() const; + + //- Remove all mappers + void clear(); + + //- Reset mappers using information from the complete mesh + void reset(const fvMesh& completeMesh); + + //- Reset mapper using information about the complete mesh + void reset + ( + const List<labelRange>& boundaryRanges, + const labelUList& faceOwner, + const labelUList& faceNeigbour + ); + + + // Mapping + //- Decompose internal field template<class Type> tmp<DimensionedField<Type, volMesh>> diff --git a/src/parallel/decompose/faDecompose/faFieldDecomposer.C b/src/parallel/decompose/faDecompose/faFieldDecomposer.C index 122eaa5fb38..f0966dfe47a 100644 --- a/src/parallel/decompose/faDecompose/faFieldDecomposer.C +++ b/src/parallel/decompose/faDecompose/faFieldDecomposer.C @@ -53,37 +53,46 @@ Foam::faFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer Foam::faFieldDecomposer::processorAreaPatchFieldDecomposer:: processorAreaPatchFieldDecomposer ( - const faMesh& mesh, - const labelUList& addressingSlice + const label nTotalFaces, + const labelUList& owner, // == mesh.edgeOwner() + const labelUList& neigh, // == mesh.edgeNeighbour() + const labelUList& addressingSlice, + const scalarField& weights ) : - sizeBeforeMapping_(mesh.nFaces()), + sizeBeforeMapping_(nTotalFaces), addressing_(addressingSlice.size()), weights_(addressingSlice.size()) { - const scalarField& weights = mesh.weights().internalField(); - const labelList& own = mesh.edgeOwner(); - const labelList& neighb = mesh.edgeNeighbour(); - forAll(addressing_, i) { // Subtract one to align addressing. label ai = addressingSlice[i]; // label ai = mag(addressingSlice[i]) - 1; - if (ai < neighb.size()) + if (ai < neigh.size()) { // This is a regular edge. it has been an internal edge // of the original mesh and now it has become a edge // on the parallel boundary - addressing_[i].setSize(2); - weights_[i].setSize(2); + addressing_[i].resize(2); + weights_[i].resize(2); - addressing_[i][0] = own[ai]; - addressing_[i][1] = neighb[ai]; + addressing_[i][0] = owner[ai]; + addressing_[i][1] = neigh[ai]; - weights_[i][0] = weights[ai]; - weights_[i][1] = 1.0 - weights[ai]; + if (ai < weights.size()) + { + // Edge weights exist/are usable + weights_[i][0] = weights[ai]; + weights_[i][1] = 1.0 - weights[ai]; + } + else + { + // No edge weights. use equal weighting + weights_[i][0] = 0.5; + weights_[i][1] = 0.5; + } } else { @@ -92,11 +101,11 @@ processorAreaPatchFieldDecomposer // do the interpolation properly (I would need to look // up the different (edge) list of data), so I will // just grab the value from the owner face - // - addressing_[i].setSize(1); - weights_[i].setSize(1); - addressing_[i][0] = own[ai]; + addressing_[i].resize(1); + weights_[i].resize(1); + + addressing_[i][0] = owner[ai]; weights_[i][0] = 1.0; } @@ -104,6 +113,24 @@ processorAreaPatchFieldDecomposer } +Foam::faFieldDecomposer::processorAreaPatchFieldDecomposer:: +processorAreaPatchFieldDecomposer +( + const faMesh& mesh, + const labelUList& addressingSlice +) +: + processorAreaPatchFieldDecomposer + ( + mesh.nFaces(), + mesh.edgeOwner(), + mesh.edgeNeighbour(), + addressingSlice, + mesh.weights().internalField() + ) +{} + + Foam::faFieldDecomposer::processorEdgePatchFieldDecomposer:: processorEdgePatchFieldDecomposer ( @@ -117,8 +144,8 @@ processorEdgePatchFieldDecomposer { forAll(addressing_, i) { - addressing_[i].setSize(1); - weights_[i].setSize(1); + addressing_[i].resize(1); + weights_[i].resize(1); addressing_[i][0] = mag(addressingSlice[i]) - 1; weights_[i][0] = sign(addressingSlice[i]); @@ -126,28 +153,167 @@ processorEdgePatchFieldDecomposer } +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + Foam::faFieldDecomposer::faFieldDecomposer ( - const faMesh& completeMesh, + const Foam::zero, const faMesh& procMesh, const labelList& edgeAddressing, const labelList& faceAddressing, const labelList& boundaryAddressing ) : - completeMesh_(completeMesh), procMesh_(procMesh), edgeAddressing_(edgeAddressing), faceAddressing_(faceAddressing), boundaryAddressing_(boundaryAddressing), + // Mappers + patchFieldDecomposerPtrs_(), + processorAreaPatchFieldDecomposerPtrs_(), + processorEdgePatchFieldDecomposerPtrs_() +{} + + +Foam::faFieldDecomposer::faFieldDecomposer +( + const faMesh& completeMesh, + const faMesh& procMesh, + const labelList& edgeAddressing, + const labelList& faceAddressing, + const labelList& boundaryAddressing +) +: + faFieldDecomposer + ( + zero{}, + procMesh, + edgeAddressing, + faceAddressing, + boundaryAddressing + ) +{ + reset(completeMesh); +} + + +Foam::faFieldDecomposer::faFieldDecomposer +( + const label nTotalFaces, + const List<labelRange>& boundaryRanges, + const labelUList& edgeOwner, + const labelUList& edgeNeigbour, + + const faMesh& procMesh, + const labelList& edgeAddressing, + const labelList& faceAddressing, + const labelList& boundaryAddressing +) +: + faFieldDecomposer + ( + zero{}, + procMesh, + edgeAddressing, + faceAddressing, + boundaryAddressing + ) +{ + reset(nTotalFaces, boundaryRanges, edgeOwner, edgeNeigbour); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::faFieldDecomposer::empty() const +{ + return patchFieldDecomposerPtrs_.empty(); +} - patchFieldDecomposerPtrs_(procMesh_.boundary().size()), - processorAreaPatchFieldDecomposerPtrs_(procMesh_.boundary().size()), - processorEdgePatchFieldDecomposerPtrs_(procMesh_.boundary().size()) + +void Foam::faFieldDecomposer::clear() +{ + patchFieldDecomposerPtrs_.clear(); + processorAreaPatchFieldDecomposerPtrs_.clear(); + processorEdgePatchFieldDecomposerPtrs_.clear(); +} + + +void Foam::faFieldDecomposer::reset +( + const label nTotalFaces, + const List<labelRange>& boundaryRanges, + const labelUList& edgeOwner, + const labelUList& edgeNeigbour +) +{ + clear(); + const label nMappers = procMesh_.boundary().size(); + + patchFieldDecomposerPtrs_.resize(nMappers); + processorAreaPatchFieldDecomposerPtrs_.resize(nMappers); + processorEdgePatchFieldDecomposerPtrs_.resize(nMappers); + + forAll(boundaryAddressing_, patchi) + { + const label oldPatchi = boundaryAddressing_[patchi]; + const faPatch& fap = procMesh_.boundary()[patchi]; + const labelSubList localPatchSlice(fap.patchSlice(edgeAddressing_)); + + if (oldPatchi >= 0) + { + patchFieldDecomposerPtrs_.set + ( + patchi, + new patchFieldDecomposer + ( + boundaryRanges[oldPatchi].size(), + localPatchSlice, + boundaryRanges[oldPatchi].start() + ) + ); + } + else + { + processorAreaPatchFieldDecomposerPtrs_.set + ( + patchi, + new processorAreaPatchFieldDecomposer + ( + nTotalFaces, + edgeOwner, + edgeNeigbour, + localPatchSlice + ) + ); + + processorEdgePatchFieldDecomposerPtrs_.set + ( + patchi, + new processorEdgePatchFieldDecomposer + ( + procMesh_.boundary()[patchi].size(), + static_cast<const labelUList&>(localPatchSlice) + ) + ); + } + } +} + + +void Foam::faFieldDecomposer::reset(const faMesh& completeMesh) { + clear(); + const label nMappers = procMesh_.boundary().size(); + patchFieldDecomposerPtrs_.resize(nMappers); + processorAreaPatchFieldDecomposerPtrs_.resize(nMappers); + processorEdgePatchFieldDecomposerPtrs_.resize(nMappers); + forAll(boundaryAddressing_, patchi) { const label oldPatchi = boundaryAddressing_[patchi]; + const faPatch& fap = procMesh_.boundary()[patchi]; + const labelSubList localPatchSlice(fap.patchSlice(edgeAddressing_)); if (oldPatchi >= 0) { @@ -156,9 +322,9 @@ Foam::faFieldDecomposer::faFieldDecomposer patchi, new patchFieldDecomposer ( - completeMesh_.boundary()[oldPatchi].size(), - procMesh_.boundary()[patchi].patchSlice(edgeAddressing_), - completeMesh_.boundary()[oldPatchi].start() + completeMesh.boundary()[oldPatchi].size(), + localPatchSlice, + completeMesh.boundary()[oldPatchi].start() ) ); } @@ -169,8 +335,8 @@ Foam::faFieldDecomposer::faFieldDecomposer patchi, new processorAreaPatchFieldDecomposer ( - completeMesh_, - procMesh_.boundary()[patchi].patchSlice(edgeAddressing_) + completeMesh, + localPatchSlice ) ); @@ -180,13 +346,7 @@ Foam::faFieldDecomposer::faFieldDecomposer new processorEdgePatchFieldDecomposer ( procMesh_.boundary()[patchi].size(), - static_cast<const labelUList&> - ( - procMesh_.boundary()[patchi].patchSlice - ( - edgeAddressing_ - ) - ) + static_cast<const labelUList&>(localPatchSlice) ) ); } diff --git a/src/parallel/decompose/faDecompose/faFieldDecomposer.H b/src/parallel/decompose/faDecompose/faFieldDecomposer.H index 18008a20773..18e896801fc 100644 --- a/src/parallel/decompose/faDecompose/faFieldDecomposer.H +++ b/src/parallel/decompose/faDecompose/faFieldDecomposer.H @@ -120,7 +120,7 @@ public: : public faPatchFieldMapper { - // Private data + // Private Data label sizeBeforeMapping_; labelListList addressing_; @@ -128,7 +128,17 @@ public: public: - //- Construct given addressing + //- Construct addressing from details + processorAreaPatchFieldDecomposer + ( + const label nTotalFaces, + const labelUList& edgeOwner, + const labelUList& edgeNeigbour, + const labelUList& addressingSlice, + const scalarField& edgeWeights = scalarField::null() + ); + + //- Construct given addressing from complete mesh processorAreaPatchFieldDecomposer ( const faMesh& mesh, @@ -136,7 +146,7 @@ public: ); - // Member functions + // Member Functions label size() const { @@ -225,10 +235,10 @@ public: private: - // Private data + // Private Data //- Reference to complete mesh - const faMesh& completeMesh_; + //REMOVED: const faMesh& completeMesh_; //- Reference to processor mesh const faMesh& procMesh_; @@ -265,7 +275,17 @@ public: // Constructors - //- Construct from components + //- Construct without mappers, added later with reset() + faFieldDecomposer + ( + const Foam::zero, + const faMesh& procMesh, + const labelList& edgeAddressing, + const labelList& faceAddressing, + const labelList& boundaryAddressing + ); + + //- Construct from components using information from the complete mesh faFieldDecomposer ( const faMesh& completeMesh, @@ -275,13 +295,50 @@ public: const labelList& boundaryAddressing ); + //- Construct from components without the complete mesh + faFieldDecomposer + ( + // Information about the complete mesh + const label nTotalFaces, + const List<labelRange>& boundaryRanges, + const labelUList& edgeOwner, + const labelUList& edgeNeigbour, + + // Addressing for processor mesh + const faMesh& procMesh, + const labelList& edgeAddressing, + const labelList& faceAddressing, + const labelList& boundaryAddressing + ); + - // Destructor + //- Destructor ~faFieldDecomposer() = default; // Member Functions + //- True if no mappers have been allocated + bool empty() const; + + //- Remove all mappers + void clear(); + + //- Reset mappers using information from the complete mesh + void reset(const faMesh& completeMesh); + + //- Reset mapper using information about the complete mesh + void reset + ( + const label nTotalFaces, + const List<labelRange>& boundaryRanges, + const labelUList& edgeOwner, + const labelUList& edgeNeigbour + ); + + + // Mapping + //- Decompose area field template<class Type> tmp<GeometricField<Type, faPatchField, areaMesh>> -- GitLab