diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index ab3eea8736..91287cdf42 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -663,8 +663,12 @@ $(mapPolyMesh)/mapPolyMesh.C $(mapPolyMesh)/faceMapper/faceMapper.C $(mapPolyMesh)/cellMapper/cellMapper.C $(mapPolyMesh)/mapDistribute/mapDistribute.C +$(mapPolyMesh)/mapDistribute/mapDistributeIO.C $(mapPolyMesh)/mapDistribute/mapDistributeBase.C +$(mapPolyMesh)/mapDistribute/mapDistributeBaseIO.C +$(mapPolyMesh)/mapDistribute/mapDistributeBaseSubset.C $(mapPolyMesh)/mapDistribute/mapDistributePolyMesh.C +$(mapPolyMesh)/mapDistribute/mapDistributePolyMeshIO.C $(mapPolyMesh)/mapDistribute/IOmapDistribute.C $(mapPolyMesh)/mapDistribute/IOmapDistributePolyMesh.C $(mapPolyMesh)/mapAddedPolyMesh.C diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C index d90582e894..34e244d517 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2015-2019 OpenCFD Ltd. + Copyright (C) 2015-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -134,13 +134,13 @@ void Foam::mapDistribute::printLayout(Ostream& os) const { mapDistributeBase::printLayout(os); - forAll(transformElements_, trafoI) + forAll(transformElements_, i) { - if (transformElements_[trafoI].size() > 0) + if (!transformElements_[i].empty()) { - os << "transform " << trafoI << ':' << endl - << " start : " << transformStart_[trafoI] << endl - << " size : " << transformElements_[trafoI].size() << endl; + os << "transform " << i << ':' << nl + << " start : " << transformStart_[i] << nl + << " size : " << transformElements_[i].size() << endl; } } } @@ -148,12 +148,24 @@ void Foam::mapDistribute::printLayout(Ostream& os) const // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // +Foam::mapDistribute::mapDistribute() +: + mapDistribute(UPstream::worldComm) +{} + + Foam::mapDistribute::mapDistribute(const label comm) : mapDistributeBase(comm) {} +Foam::mapDistribute::mapDistribute(mapDistributeBase&& map) +: + mapDistributeBase(std::move(map)) +{} + + Foam::mapDistribute::mapDistribute(const mapDistribute& map) : mapDistributeBase(map), @@ -170,28 +182,6 @@ Foam::mapDistribute::mapDistribute(mapDistribute&& map) } -Foam::mapDistribute::mapDistribute -( - const label constructSize, - labelListList&& subMap, - labelListList&& constructMap, - const bool subHasFlip, - const bool constructHasFlip, - const label comm -) -: - mapDistributeBase - ( - constructSize, - std::move(subMap), - std::move(constructMap), - subHasFlip, - constructHasFlip, - comm - ) -{} - - Foam::mapDistribute::mapDistribute ( const label constructSize, @@ -218,57 +208,6 @@ Foam::mapDistribute::mapDistribute {} -Foam::mapDistribute::mapDistribute -( - const labelUList& sendProcs, - const labelUList& recvProcs, - const label comm -) -: - mapDistributeBase(sendProcs, recvProcs, comm) -{} - - -Foam::mapDistribute::mapDistribute -( - const globalIndex& globalNumbering, - labelList& elements, - List>& compactMap, - const int tag, - const label comm -) -: - mapDistributeBase - ( - globalNumbering, - elements, - compactMap, - tag, - comm - ) -{} - - -Foam::mapDistribute::mapDistribute -( - const globalIndex& globalNumbering, - labelListList& cellCells, - List>& compactMap, - const int tag, - const label comm -) -: - mapDistributeBase - ( - globalNumbering, - cellCells, - compactMap, - tag, - comm - ) -{} - - Foam::mapDistribute::mapDistribute ( const globalIndex& globalNumbering, @@ -338,8 +277,8 @@ Foam::mapDistribute::mapDistribute transformElements_.setSize(nTrafo); forAll(transformStart_, trafoI) { - transformStart_[trafoI] = constructSize_; - constructSize_ += nPerTransform[trafoI]; + transformStart_[trafoI] = constructSize(); + constructSize() += nPerTransform[trafoI]; transformElements_[trafoI].setSize(nPerTransform[trafoI]); } @@ -391,7 +330,7 @@ Foam::mapDistribute::mapDistribute : mapDistributeBase(comm) { - const label myRank = Pstream::myProcNo(comm_); + const label myRank = Pstream::myProcNo(comm); // Construct per processor compact addressing of the global elements // needed. The ones from the local processor are not included since @@ -454,8 +393,8 @@ Foam::mapDistribute::mapDistribute transformElements_.setSize(nTrafo); forAll(transformStart_, trafoI) { - transformStart_[trafoI] = constructSize_; - constructSize_ += nPerTransform[trafoI]; + transformStart_[trafoI] = constructSize(); + constructSize() += nPerTransform[trafoI]; transformElements_[trafoI].setSize(nPerTransform[trafoI]); } @@ -498,24 +437,6 @@ Foam::mapDistribute::mapDistribute } -Foam::mapDistribute::mapDistribute -( - labelListList&& subMap, - const bool subHasFlip, - const bool constructHasFlip, - const label comm -) -: - mapDistributeBase(std::move(subMap), subHasFlip, constructHasFlip, comm) -{} - - -Foam::mapDistribute::mapDistribute(Istream& is) -{ - is >> *this; -} - - Foam::autoPtr Foam::mapDistribute::clone() const { return autoPtr::New(*this); @@ -530,11 +451,19 @@ Foam::label Foam::mapDistribute::whichTransform(const label index) const } +void Foam::mapDistribute::clear() +{ + mapDistributeBase::clear(); + transformElements_.clear(); + transformStart_.clear(); +} + + void Foam::mapDistribute::transfer(mapDistribute& rhs) { if (this == &rhs) { - // Self-assignment is a no-op + return; // Self-assignment is a no-op } mapDistributeBase::transfer(rhs); @@ -568,29 +497,4 @@ void Foam::mapDistribute::operator=(mapDistribute&& rhs) } -// * * * * * * * * * * * * * * Istream Operator * * * * * * * * * * * * * * // - -Foam::Istream& Foam::operator>>(Istream& is, mapDistribute& map) -{ - is.fatalCheck(FUNCTION_NAME); - - is >> static_cast(map) - >> map.transformElements_ >> map.transformStart_; - - return is; -} - - -// * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * * // - -Foam::Ostream& Foam::operator<<(Ostream& os, const mapDistribute& map) -{ - os << static_cast(map) << token::NL - << map.transformElements_ << token::NL - << map.transformStart_; - - return os; -} - - // ************************************************************************* // diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H index 6ad294043e..81c4e12b38 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2015-2019 OpenCFD Ltd. + Copyright (C) 2015-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -126,15 +126,15 @@ Note: values as index+flip, similar to e.g. faceProcAddressing. The flip will only be applied to fieldTypes (scalar, vector, .. triad) - SourceFiles mapDistribute.C + mapDistributeIO.C mapDistributeTemplates.C \*---------------------------------------------------------------------------*/ -#ifndef mapDistribute_H -#define mapDistribute_H +#ifndef Foam_mapDistribute_H +#define Foam_mapDistribute_H #include "mapDistributeBase.H" #include "transformList.H" @@ -146,11 +146,8 @@ SourceFiles namespace Foam { +// Forward Declarations class globalIndexAndTransform; - - -// Forward declaration of friend functions and operators - class mapDistribute; Istream& operator>>(Istream&, mapDistribute&); @@ -158,17 +155,17 @@ Ostream& operator<<(Ostream&, const mapDistribute&); /*---------------------------------------------------------------------------*\ - Class mapDistribute Declaration + Class mapDistribute Declaration \*---------------------------------------------------------------------------*/ class mapDistribute : public mapDistributeBase { - // Private data + // Private Data //- For every globalIndexAndTransform::transformPermutations - // gives the elements that need to be transformed + //- gives the elements that need to be transformed labelListList transformElements_; //- Destination in constructMap for transformed elements @@ -327,8 +324,17 @@ public: // Constructors - //- Construct null - mapDistribute(const label comm = UPstream::worldComm); + //- Inherit constructors + using mapDistributeBase::mapDistributeBase; + + //- Default construct - uses worldComm + mapDistribute(); + + //- Default construct with specified communicator + explicit mapDistribute(const label comm); + + //- Move construct from base, no transforms + explicit mapDistribute(mapDistributeBase&& map); //- Copy construct explicit mapDistribute(const mapDistribute& map); @@ -336,14 +342,10 @@ public: //- Move construct explicit mapDistribute(mapDistribute&& map); - //- Move construct from components - mapDistribute + //- Read construct from dictionary + explicit mapDistribute ( - const label constructSize, - labelListList&& subMap, - labelListList&& constructMap, - const bool subHasFlip = false, - const bool constructHasFlip = false, + const dictionary& dict, const label comm = UPstream::worldComm ); @@ -360,44 +362,6 @@ public: const label comm = UPstream::worldComm ); - //- Construct from reverse addressing: per data item the send - //- processor and the receive processor. - // - // \note data are not stored per processor so cannot use printLayout. - mapDistribute - ( - const labelUList& sendProcs, - const labelUList& recvProcs, - const label comm = UPstream::worldComm - ); - - //- Construct from list of (possibly) remote elements in globalIndex - //- numbering (or -1). - // Determines compact numbering (see above) and distribute map to - // get data into this ordering and renumbers the elements to be in - // compact numbering. - mapDistribute - ( - const globalIndex&, - labelList& elements, - List>& compactMap, - const int tag = Pstream::msgType(), - const label comm = UPstream::worldComm - ); - - //- Special variant that works with the info sorted into bins - //- according to local indices. - // For example, cellCells where cellCells[localCelli] is a list of - // global cells. - mapDistribute - ( - const globalIndex&, - labelListList& cellCells, - List>& compactMap, - const int tag = Pstream::msgType(), - const label comm = UPstream::worldComm - ); - //- Construct from list of (possibly remote) untransformed elements //- in globalIndex numbering (or -1) and (possibly remote) //- transformed elements in globalIndexAndTransform numbering. @@ -412,7 +376,7 @@ public: const labelPairList& transformedElements, labelList& transformedIndices, List>& compactMap, - const int tag = Pstream::msgType(), + const int tag = UPstream::msgType(), const label comm = UPstream::worldComm ); @@ -425,18 +389,7 @@ public: const List& transformedElements, labelListList& transformedIndices, List>& compactMap, - const int tag = Pstream::msgType(), - const label comm = UPstream::worldComm - ); - - //- Construct from my elements to send. Assumes layout is my elements - // first followed by elements from all other processors in consecutive - // order - explicit mapDistribute - ( - labelListList&& subMap, - const bool subHasFlip = false, - const bool constructHasFlip = false, + const int tag = UPstream::msgType(), const label comm = UPstream::worldComm ); @@ -457,13 +410,13 @@ public: //- For every globalIndexAndTransform::transformPermutations // gives the elements that need to be transformed - const labelListList& transformElements() const + const labelListList& transformElements() const noexcept { return transformElements_; } //- Destination in constructMap for transformed elements - const labelList& transformStart() const + const labelList& transformStart() const noexcept { return transformStart_; } @@ -474,6 +427,9 @@ public: // Other + //- Reset to zero size, only retaining communicator + void clear(); + //- Transfer the contents of the argument and annul the argument. void transfer(mapDistribute& map); @@ -510,7 +466,7 @@ public: void reverseDistribute ( const label constructSize, - List&, + List& fld, const bool dummyTransform = true, const int tag = UPstream::msgType() ) const; @@ -565,11 +521,6 @@ public: // storage (local data first, then non-local data) void printLayout(Ostream& os) const; - //- Correct for topo change. - void updateMesh(const mapPolyMesh&) - { - NotImplemented; - } // Member Operators @@ -580,14 +531,28 @@ public: void operator=(mapDistribute&& rhs); - // IOstream operators + // IOstream Operators - //- Read dictionary from Istream + //- Read entries from dictionary format + void readDict(const dictionary& dict); + + //- Write entries in dictionary format + void writeEntries(Ostream& os) const; + + //- Read plain content (not dictionary) from Istream friend Istream& operator>>(Istream&, mapDistribute&); - //- Write dictionary to Ostream + //- Write plain content (not dictionary) to Ostream friend Ostream& operator<<(Ostream&, const mapDistribute&); + + // Housekeeping + + //- No correction for topo change + void updateMesh(const mapPolyMesh&) + { + NotImplemented; + } }; diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeBase.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeBase.C index 44f8e48953..a3fb7f2355 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeBase.C +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeBase.C @@ -27,6 +27,7 @@ License \*---------------------------------------------------------------------------*/ #include "mapDistributeBase.H" +#include "bitSet.H" #include "commSchedule.H" #include "labelPairHashes.H" #include "globalIndex.H" @@ -40,6 +41,146 @@ namespace Foam } +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +bool Foam::mapDistributeBase::hasFlipAddressing(const labelUList& map) +{ + for (const label val : map) + { + if (!val) + { + // Cannot be flipped addressing if it contains zero. + return false; + } + else if (val < 0) + { + // Must be flipped addressing if it contains negatives. + return true; + } + } + + return false; +} + + +bool Foam::mapDistributeBase::hasFlipAddressing(const labelListList& maps) +{ + for (const labelList& map : maps) + { + for (const label val : map) + { + if (!val) + { + // Cannot be flipped addressing if it contains zero. + return false; + } + else if (val < 0) + { + // Must be flipped addressing if it contains negatives. + return true; + } + } + } + + return false; +} + + +Foam::label Foam::mapDistributeBase::getMappedSize +( + const labelListList& maps, + const bool hasFlip +) +{ + label maxIndex = -1; + + for (const labelList& map : maps) + { + for (label index : map) + { + if (hasFlip) + { + index = mag(index)-1; + } + + maxIndex = max(maxIndex, index); + } + } + + return (maxIndex+1); +} + + +Foam::label Foam::mapDistributeBase::countUnmapped +( + const labelUList& elements, + const labelListList& maps, + const bool hasFlip +) +{ + if (elements.empty()) + { + return 0; + } + + // Moderately efficient markup/search + + bitSet unvisited(elements); + label nUnmapped = unvisited.count(); + + if (hasFlip) + { + for (const labelList& map : maps) + { + for (label index : map) + { + index = mag(index)-1; + + if (unvisited.unset(index)) + { + --nUnmapped; + if (!nUnmapped) break; + } + } + } + } + else + { + for (const labelList& map : maps) + { + for (label index : map) + { + if (unvisited.unset(index)) + { + --nUnmapped; + if (!nUnmapped) break; + } + } + } + } + + return nUnmapped; +} + + +void Foam::mapDistributeBase::checkReceivedSize +( + const label proci, + const label expectedSize, + const label receivedSize +) +{ + if (receivedSize != expectedSize) + { + FatalErrorInFunction + << "Expected from processor " << proci + << " " << expectedSize << " but received " + << receivedSize << " elements." + << abort(FatalError); + } +} + + // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // Foam::List Foam::mapDistributeBase::schedule @@ -121,7 +262,6 @@ Foam::List Foam::mapDistributeBase::schedule // Broadcast: send comms information to all Pstream::broadcast(allComms, comm); - // Determine my schedule. labelList mySchedule ( @@ -134,28 +274,6 @@ Foam::List Foam::mapDistributeBase::schedule // Processors involved in my schedule return List(allComms, mySchedule); - - - //if (debug) - //{ - // Pout<< "I need to:" << endl; - // const List& comms = schedule(); - // forAll(comms, i) - // { - // const labelPair& twoProcs = comms[i]; - // label sendProc = twoProcs[0]; - // label recvProc = twoProcs[1]; - // - // if (recvProc == myRank) - // { - // Pout<< " receive from " << sendProc << endl; - // } - // else - // { - // Pout<< " send to " << recvProc << endl; - // } - // } - //} } @@ -167,29 +285,26 @@ const Foam::List& Foam::mapDistributeBase::schedule() const ( new List ( - schedule(subMap_, constructMap_, Pstream::msgType(), comm_) + schedule(subMap_, constructMap_, UPstream::msgType(), comm_) ) ); } + return *schedulePtr_; } -void Foam::mapDistributeBase::checkReceivedSize +const Foam::List& Foam::mapDistributeBase::whichSchedule ( - const label proci, - const label expectedSize, - const label receivedSize -) + const UPstream::commsTypes commsType +) const { - if (receivedSize != expectedSize) + if (commsType == UPstream::commsTypes::scheduled) { - FatalErrorInFunction - << "Expected from processor " << proci - << " " << expectedSize << " but received " - << receivedSize << " elements." - << abort(FatalError); + return schedule(); } + + return List::null(); } @@ -224,12 +339,9 @@ void Foam::mapDistributeBase::printLayout(Ostream& os) const } } - label localSize; - if (maxIndex[myRank] == labelMin) - { - localSize = 0; - } - else + label localSize(0); + + if (maxIndex[myRank] != labelMin) { localSize = maxIndex[myRank]+1; } @@ -237,18 +349,21 @@ void Foam::mapDistributeBase::printLayout(Ostream& os) const os << "Layout: (constructSize:" << constructSize_ << " subHasFlip:" << subHasFlip_ << " constructHasFlip:" << constructHasFlip_ - << ")" << endl - << "local (processor " << myRank << "):" << endl - << " start : 0" << endl + << ")" << nl + << "local (processor " << myRank << "):" << nl + << " start : 0" << nl << " size : " << localSize << endl; label offset = localSize; forAll(minIndex, proci) { - if (proci != myRank) + if (proci != myRank && !constructMap_[proci].empty()) { - if (constructMap_[proci].size() > 0) + label size(0); + + if (maxIndex[proci] != labelMin) { + size = maxIndex[proci]-minIndex[proci]+1; if (minIndex[proci] != offset) { FatalErrorInFunction @@ -257,14 +372,13 @@ void Foam::mapDistributeBase::printLayout(Ostream& os) const << " minIndex:" << minIndex[proci] << abort(FatalError); } - - label size = maxIndex[proci]-minIndex[proci]+1; - os << "processor " << proci << ':' << endl - << " start : " << offset << endl - << " size : " << size << endl; - - offset += size; } + + os << "processor " << proci << ':' << nl + << " start : " << offset << nl + << " size : " << size << endl; + + offset += size; } } } @@ -280,8 +394,6 @@ void Foam::mapDistributeBase::calcCompactAddressing const label myRank = Pstream::myProcNo(comm_); const label nProcs = Pstream::nProcs(comm_); - compactMap.setSize(nProcs); - // Count all (non-local) elements needed. Just for presizing map. labelList nNonLocal(nProcs, Zero); @@ -294,6 +406,8 @@ void Foam::mapDistributeBase::calcCompactAddressing } } + compactMap.resize_nocopy(nProcs); + forAll(compactMap, proci) { compactMap[proci].clear(); @@ -328,8 +442,6 @@ void Foam::mapDistributeBase::calcCompactAddressing const label myRank = Pstream::myProcNo(comm_); const label nProcs = Pstream::nProcs(comm_); - compactMap.setSize(nProcs); - // Count all (non-local) elements needed. Just for presizing map. labelList nNonLocal(nProcs, Zero); @@ -345,6 +457,8 @@ void Foam::mapDistributeBase::calcCompactAddressing } } + compactMap.resize_nocopy(nProcs); + forAll(compactMap, proci) { compactMap[proci].clear(); @@ -401,7 +515,6 @@ void Foam::mapDistributeBase::exchangeAddressing } - // Find out what to receive/send in compact addressing. // What I want to receive is what others have to send @@ -430,7 +543,7 @@ void Foam::mapDistributeBase::exchangeAddressing const label compactI = compactStart[proci] + iter.val(); remoteElem[i] = iter.key(); localElem[i] = compactI; - iter() = compactI; + iter.val() = compactI; i++; } } @@ -510,7 +623,7 @@ void Foam::mapDistributeBase::exchangeAddressing const label compactI = compactStart[proci] + iter.val(); remoteElem[i] = iter.key(); localElem[i] = compactI; - iter() = compactI; + iter.val() = compactI; i++; } } @@ -538,17 +651,24 @@ void Foam::mapDistributeBase::exchangeAddressing // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // +Foam::mapDistributeBase::mapDistributeBase() +: + mapDistributeBase(UPstream::worldComm) +{} + + Foam::mapDistributeBase::mapDistributeBase(const label comm) : constructSize_(0), + subMap_(), + constructMap_(), subHasFlip_(false), constructHasFlip_(false), comm_(comm), - schedulePtr_() + schedulePtr_(nullptr) {} - Foam::mapDistributeBase::mapDistributeBase(const mapDistributeBase& map) : constructSize_(map.constructSize_), @@ -557,13 +677,13 @@ Foam::mapDistributeBase::mapDistributeBase(const mapDistributeBase& map) subHasFlip_(map.subHasFlip_), constructHasFlip_(map.constructHasFlip_), comm_(map.comm_), - schedulePtr_() + schedulePtr_(nullptr) {} Foam::mapDistributeBase::mapDistributeBase(mapDistributeBase&& map) : - mapDistributeBase() + mapDistributeBase(map.comm()) { transfer(map); } @@ -585,7 +705,7 @@ Foam::mapDistributeBase::mapDistributeBase subHasFlip_(subHasFlip), constructHasFlip_(constructHasFlip), comm_(comm), - schedulePtr_() + schedulePtr_(nullptr) {} @@ -597,10 +717,12 @@ Foam::mapDistributeBase::mapDistributeBase ) : constructSize_(0), + subMap_(), + constructMap_(), subHasFlip_(false), constructHasFlip_(false), comm_(comm), - schedulePtr_() + schedulePtr_(nullptr) { const label myRank = Pstream::myProcNo(comm_); const label nProcs = Pstream::nProcs(comm_); @@ -627,7 +749,7 @@ Foam::mapDistributeBase::mapDistributeBase if (myRank == sendProc) { - // I am the sender. Count destination processor. + // I am the sender. nSend[recvProc]++; } if (myRank == recvProc) @@ -647,6 +769,9 @@ Foam::mapDistributeBase::mapDistributeBase nSend = 0; nRecv = 0; + // Largest entry inside constructMap + label maxRecvIndex = -1; + forAll(sendProcs, sampleI) { const label sendProc = sendProcs[sampleI]; @@ -661,10 +786,11 @@ Foam::mapDistributeBase::mapDistributeBase { // I am the receiver. constructMap_[sendProc][nRecv[sendProc]++] = sampleI; - // Largest entry inside constructMap - constructSize_ = sampleI+1; + maxRecvIndex = sampleI; } } + + constructSize_ = maxRecvIndex+1; } @@ -678,10 +804,12 @@ Foam::mapDistributeBase::mapDistributeBase ) : constructSize_(0), + subMap_(), + constructMap_(), subHasFlip_(false), constructHasFlip_(false), comm_(comm), - schedulePtr_() + schedulePtr_(nullptr) { // Construct per processor compact addressing of the global elements // needed. The ones from the local processor are not included since @@ -739,10 +867,12 @@ Foam::mapDistributeBase::mapDistributeBase ) : constructSize_(0), + subMap_(), + constructMap_(), subHasFlip_(false), constructHasFlip_(false), comm_(comm), - schedulePtr_() + schedulePtr_(nullptr) { // Construct per processor compact addressing of the global elements // needed. The ones from the local processor are not included since @@ -800,10 +930,11 @@ Foam::mapDistributeBase::mapDistributeBase : constructSize_(0), subMap_(std::move(subMap)), + constructMap_(), subHasFlip_(subHasFlip), constructHasFlip_(constructHasFlip), comm_(comm), - schedulePtr_() + schedulePtr_(nullptr) { const label myRank = Pstream::myProcNo(comm_); const label nProcs = Pstream::nProcs(comm_); @@ -847,13 +978,43 @@ Foam::mapDistributeBase::mapDistributeBase } -Foam::mapDistributeBase::mapDistributeBase(Istream& is) +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +Foam::labelList Foam::mapDistributeBase::subMapSizes() const { - is >> *this; + labelList sizes(subMap_.size()); + forAll(subMap_, i) + { + sizes[i] = subMap_[i].size(); + } + + return sizes; } -// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // +Foam::labelList Foam::mapDistributeBase::constructMapSizes() const +{ + labelList sizes(constructMap_.size()); + forAll(constructMap_, i) + { + sizes[i] = constructMap_[i].size(); + } + + return sizes; +} + + +void Foam::mapDistributeBase::clear() +{ + constructSize_ = 0; + subMap_.clear(); + constructMap_.clear(); + subHasFlip_ = false; + constructHasFlip_ = false; + // Leave comm_ intact + schedulePtr_.reset(nullptr); +} + void Foam::mapDistributeBase::transfer(mapDistributeBase& rhs) { @@ -869,7 +1030,7 @@ void Foam::mapDistributeBase::transfer(mapDistributeBase& rhs) subHasFlip_ = rhs.subHasFlip_; constructHasFlip_ = rhs.constructHasFlip_; comm_ = rhs.comm_; - schedulePtr_.clear(); + schedulePtr_.reset(nullptr); rhs.constructSize_ = 0; rhs.subHasFlip_ = false; @@ -1312,7 +1473,7 @@ void Foam::mapDistributeBase::operator=(const mapDistributeBase& rhs) subHasFlip_ = rhs.subHasFlip_; constructHasFlip_ = rhs.constructHasFlip_; comm_ = rhs.comm_; - schedulePtr_.clear(); + schedulePtr_.reset(nullptr); } @@ -1326,32 +1487,4 @@ void Foam::mapDistributeBase::operator=(mapDistributeBase&& rhs) } -// * * * * * * * * * * * * * * Istream Operator * * * * * * * * * * * * * * // - -Foam::Istream& Foam::operator>>(Istream& is, mapDistributeBase& map) -{ - is.fatalCheck(FUNCTION_NAME); - - is >> map.constructSize_ >> map.subMap_ >> map.constructMap_ - >> map.subHasFlip_ >> map.constructHasFlip_ - >> map.comm_; - - return is; -} - - -// * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * * // - -Foam::Ostream& Foam::operator<<(Ostream& os, const mapDistributeBase& map) -{ - os << map.constructSize_ << token::NL - << map.subMap_ << token::NL - << map.constructMap_ << token::NL - << map.subHasFlip_ << token::SPACE << map.constructHasFlip_ - << token::SPACE << map.comm_ << token::NL; - - return os; -} - - // ************************************************************************* // diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeBase.H b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeBase.H index ec3b8b94af..63490af530 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeBase.H +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeBase.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2015-2017 OpenFOAM Foundation - Copyright (C) 2015-2016 OpenCFD Ltd. + Copyright (C) 2015-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -66,31 +66,33 @@ Note: SourceFiles mapDistributeBase.C + mapDistributeBaseIO.C mapDistributeBaseTemplates.C \*---------------------------------------------------------------------------*/ -#ifndef mapDistributeBase_H -#define mapDistributeBase_H +#ifndef Foam_mapDistributeBase_H +#define Foam_mapDistributeBase_H +#include "boolList.H" #include "labelList.H" #include "labelPair.H" #include "Pstream.H" -#include "boolList.H" #include "Map.H" +#include "InfoProxy.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { -class mapPolyMesh; +// Forward Declarations + +class bitSet; +class dictionary; class globalIndex; class PstreamBuffers; - - -// Forward declaration of friend functions and operators - +class mapPolyMesh; class mapDistributeBase; Istream& operator>>(Istream&, mapDistributeBase&); @@ -103,9 +105,7 @@ Ostream& operator<<(Ostream&, const mapDistributeBase&); class mapDistributeBase { -protected: - - // Protected data + // Private Data //- Size of reconstructed data label constructSize_; @@ -129,8 +129,11 @@ protected: mutable autoPtr> schedulePtr_; - // Private Member Functions +protected: + // Protected Member Functions + + //- Fatal if expected and received size are not equal static void checkReceivedSize ( const label proci, @@ -138,6 +141,17 @@ protected: const label receivedSize ); + //- Scan the maps for the max addressed index. + // + // \param maps The maps to scan + // \param hasFlip True if maps has flip addressing + // \return max-size needed for addressing (eg, constructSize) + static label getMappedSize + ( + const labelListList& maps, + const bool hasFlip + ); + //- Construct per processor compact addressing of the global elements // needed. The ones from the local processor are not included since // these are always all needed. @@ -172,6 +186,7 @@ protected: labelList& compactStart ); + template static void flipAndCombine ( @@ -183,15 +198,50 @@ protected: List& lhs ); + //- Lookup a field value at specified index and return its value + //- after any flip negation operations template static T accessAndFlip ( - const UList& fld, + const UList& values, const label index, const bool hasFlip, const NegateOp& negOp ); + //- Lookup field values at specified indices and return + //- after any flip negation operations + template + static List accessAndFlip + ( + const UList& values, + const labelUList& indices, + const bool hasFlip, + const NegateOp& negOp + ); + + +private: + + // Private Member Functions + + //- Helper for renumbering compacted map elements and updating the + //- supplied old-to-new mapping to account for the visit order of + //- the original elements + // + // \param origElements The original elements visited (eg, meshPoints) + // \param[in,out] oldToNew The old-to-new mapping + // \param[in,out] mapElements The map to be renumbered + // \param hasFlip True if map has flip addressing + static void renumberVisitOrder + ( + const labelUList& origElements, + labelList& oldToNew, + labelListList& maps, + const bool hasFlip + ); + + public: // Declare name of the class and its debug switch @@ -200,8 +250,11 @@ public: // Constructors - //- Construct null - mapDistributeBase(const label comm = UPstream::worldComm); + //- Default construct (uses worldComm) + mapDistributeBase(); + + //- Default construct with specified communicator + explicit mapDistributeBase(const label comm); //- Copy construct mapDistributeBase(const mapDistributeBase& map); @@ -209,7 +262,14 @@ public: //- Move construct mapDistributeBase(mapDistributeBase&& map); - //- Construct from components + //- Read construct from dictionary + explicit mapDistributeBase + ( + const dictionary& dict, + const label comm = UPstream::worldComm + ); + + //- Move construct from components mapDistributeBase ( const label constructSize, @@ -221,8 +281,9 @@ public: ); //- Construct from reverse addressing: per data item the send - // processor and the receive processor. (note: data is not stored - // sorted per processor so cannot use printLayout). + //- processor and the receive processor. + // + // \note data is not sorted per processor - cannot use printLayout! mapDistributeBase ( const labelUList& sendProcs, @@ -231,9 +292,11 @@ public: ); //- Construct from list of (possibly) remote elements in globalIndex - // numbering (or -1). Determines compact numbering (see above) and - // distribute map to get data into this ordering and renumbers the - // elements to be in compact numbering. + //- numbering (or -1). + // + // Determines compact numbering (see above) and distribute map + // to get data into this ordering and renumbers the elements to + // be in compact numbering. mapDistributeBase ( const globalIndex&, @@ -244,7 +307,9 @@ public: ); //- Special variant that works with the info sorted into bins - // according to local indices. E.g. think cellCells where + //- according to local indices. + // + // E.g. think cellCells where // cellCells[localCellI] is a list of global cells mapDistributeBase ( @@ -255,9 +320,9 @@ public: const label comm = UPstream::worldComm ); - //- Construct from my elements to send. Assumes layout is my elements - // first followed by elements from all other processors in consecutive - // order + //- Construct from my elements to send. + // Assumes layout is my elements first followed by elements + // from all other processors in consecutive order. explicit mapDistributeBase ( labelListList&& subMap, @@ -267,128 +332,209 @@ public: ); //- Construct from Istream - mapDistributeBase(Istream& is); + explicit mapDistributeBase(Istream& is); + + + // Static Functions + + //- Test for flip addressing, where flips are encoded as negative + //- indices and non-flips are encoded as positive non-zero indices. + // + // Exits early on the first detected zero or negative, which + // makes this more efficient than testing min(map) \< 0. + // + // \note may return a false negative (ie, no flips detected) + // even when flip addressing is used, but the local map does not + // contain any flipped elements + static bool hasFlipAddressing(const labelUList& map); + + //- Test for flip addressing, where flips are encoded as negative + //- indices and non-flips are encoded as positive non-zero indices. + // + // See notes above. + static bool hasFlipAddressing(const labelListList& maps); + + //- Count the number of unmapped elements. + // + // \param elements The elements that are expected to be mapped + // \param maps The maps to scan + // \param hasFlip True if maps has flip addressing + // \return number of unmapped elements + static label countUnmapped + ( + const labelUList& elements, + const labelListList& maps, + const bool hasFlip + ); // Member Functions - // Access + // Access - //- Constructed data size - label constructSize() const - { - return constructSize_; - } + //- Constructed data size + label constructSize() const noexcept + { + return constructSize_; + } - //- Constructed data size - label& constructSize() - { - return constructSize_; - } + //- Constructed data size + label& constructSize() noexcept + { + return constructSize_; + } - //- From subsetted data back to original data - const labelListList& subMap() const - { - return subMap_; - } + //- From subsetted data back to original data + const labelListList& subMap() const noexcept + { + return subMap_; + } - //- From subsetted data back to original data - labelListList& subMap() - { - return subMap_; - } + //- From subsetted data back to original data + labelListList& subMap() noexcept + { + return subMap_; + } - //- From subsetted data to new reconstructed data - const labelListList& constructMap() const - { - return constructMap_; - } + //- From subsetted data to new reconstructed data + const labelListList& constructMap() const noexcept + { + return constructMap_; + } - //- From subsetted data to new reconstructed data - labelListList& constructMap() - { - return constructMap_; - } + //- From subsetted data to new reconstructed data + labelListList& constructMap() noexcept + { + return constructMap_; + } - //- Does subMap include a sign - bool subHasFlip() const - { - return subHasFlip_; - } + //- Does subMap include a sign + bool subHasFlip() const noexcept + { + return subHasFlip_; + } - //- Does subMap include a sign - bool& subHasFlip() - { - return subHasFlip_; - } + //- Does subMap include a sign + bool& subHasFlip() noexcept + { + return subHasFlip_; + } - //- Does constructMap include a sign - bool constructHasFlip() const - { - return constructHasFlip_; - } + //- Does constructMap include a sign + bool constructHasFlip() const noexcept + { + return constructHasFlip_; + } - //- Does constructMap include a sign - bool& constructHasFlip() - { - return constructHasFlip_; - } + //- Does constructMap include a sign + bool& constructHasFlip() noexcept + { + return constructHasFlip_; + } - label comm() const - { - return comm_; - } + //- The communicator used + label comm() const noexcept + { + return comm_; + } - //- Calculate a schedule. See above. - static List schedule - ( - const labelListList& subMap, - const labelListList& constructMap, - const int tag, - const label comm = UPstream::worldComm - ); + //- The number of sub-lists within the maps + label nMaps() const noexcept + { + return constructMap_.size(); + } - //- Return a schedule. Demand driven. See above. - const List& schedule() const; + //- The sizes of the subMap lists + labelList subMapSizes() const; + + //- The sizes of the constructMap lists + labelList constructMapSizes() const; - // Other + // Schedule - //- Transfer the contents of the argument and annul the argument. - void transfer(mapDistributeBase& rhs); + //- Calculate a communication schedule. See above. + static List schedule + ( + const labelListList& subMap, + const labelListList& constructMap, + const int tag, // Message tag: msgType() + const label comm = UPstream::worldComm + ); - //- Helper for construct from globalIndex. Renumbers element - // (in globalIndex numbering) into compact indices. - static label renumber - ( - const globalIndex&, - const List>& compactMap, - const label globalElement - ); + //- Return a schedule. Demand driven. See above. + const List& schedule() const; - //- Compact maps. Gets per field a bool whether it is used (locally) - // and works out itself what this side and sender side can remove - // from maps. Only compacts non-local elements (i.e. the stuff - // that gets sent over), does not change the local layout - void compact - ( - const boolList& elemIsUsed, - const int tag = UPstream::msgType() - ); + //- Return real or dummy schedule depending on the + //- communication type + const List& whichSchedule + ( + const UPstream::commsTypes commsType + ) const; - //- Compact all maps and layout. Returns compaction maps for - // subMap and constructMap - void compact - ( - const boolList& elemIsUsed, - const label localSize, // max index for subMap - labelList& oldToNewSub, - labelList& oldToNewConstruct, - const int tag = UPstream::msgType() - ); - //- Distribute data. Note:schedule only used for - // Pstream::commsTypes::scheduled for now, all others just use + // Other + + //- Reset to zero size, only retaining communicator + void clear(); + + //- Transfer the contents of the argument and annul the argument. + void transfer(mapDistributeBase& rhs); + + //- Helper for construct from globalIndex. Renumbers element + // (in globalIndex numbering) into compact indices. + static label renumber + ( + const globalIndex&, + const List>& compactMap, + const label globalElement + ); + + //- Helper for renumbering the (compacted) map elements + //- using the supplied old-to-new mapping. + // Only compacts the maps, does not change the local layout. + // + // \param[in,out] mapElements The map to be renumbered + // \param oldToNew The old-to-new mapping + // \param hasFlip True if map has flip addressing + // + // \return max-size needed for new addressing (eg, constructSize) + static label renumberMap + ( + labelListList& mapElements, + const labelUList& oldToNew, + const bool hasFlip + ); + + + // Compaction + + //- Compact all maps and layout. + // Returns compaction maps for subMap and constructMap + void compact + ( + const boolList& elemIsUsed, + const int tag = UPstream::msgType() + ); + + //- Compact all maps and layout. + // Returns compaction maps for subMap and constructMap + void compact + ( + const boolList& elemIsUsed, + const label localSize, // max index for subMap + labelList& oldToNewSub, + labelList& oldToNewConstruct, + const int tag = UPstream::msgType() + ); + + + // Distribute + + //- Distribute data with specified negate operator (for flips). + // + // \note schedule currently only used for + // Pstream::commsTypes::scheduled, all others just use // send-to-all, receive-from-all. template static void distribute @@ -400,13 +546,15 @@ public: const bool subHasFlip, const labelListList& constructMap, const bool constructHasFlip, - List&, + List& field, const NegateOp& negOp, const int tag = UPstream::msgType(), const label comm = UPstream::worldComm ); - //- Distribute data. If multiple processors writing to same + //- Distribute data with specified combine operation + // + // If multiple processors writing to same // position adds contributions using cop. template static void distribute @@ -418,7 +566,7 @@ public: const bool subHasFlip, const labelListList& constructMap, const bool constructHasFlip, - List&, + List& field, const T& nullValue, const CombineOp& cop, const NegateOp& negOp, @@ -426,69 +574,139 @@ public: const label comm = UPstream::worldComm ); - //- Distribute data using default commsType. + + //- Distribute data using default commsType + //- and the default flip/negate operator. template void distribute ( - List& fld, + List& values, const int tag = UPstream::msgType() ) const; - //- Distribute data using default commsType. + //- Distribute data using default commsType + //- and the default flip/negate operator. + template + void distribute + ( + DynamicList& values, + const int tag = UPstream::msgType() + ) const; + + //- Distribute data using default commsType + //- and the specified negate operator (for flips). template void distribute ( - List& fld, + List& values, const NegateOp& negOp, const int tag = UPstream::msgType() ) const; - //- Distribute data using default commsType. - template + //- Distribute data using specified commsType + //- and the specified negate operator (for flips). + // Accepts a nullValue to initialize unmapped elements + // (ie, when the constructSize is larger than the number of + // mapped elements). + template void distribute ( - DynamicList& fld, + const Pstream::commsTypes commsType, + List& values, + const NegateOp& negOp, const int tag = UPstream::msgType() ) const; - //- Reverse distribute data using default commsType. + //- Distribute data using specified commsType + //- and the specified negate operator (for flips). + // Accepts a nullValue to initialize unmapped elements + // (ie, when the constructSize is larger than the number of + // mapped elements). + template + void distribute + ( + const Pstream::commsTypes commsType, + const T& nullValue, + List& values, + const NegateOp& negOp, + const int tag = UPstream::msgType() + ) const; + + + //- Reverse distribute data using default commsType + //- and the default flip/negate operator template void reverseDistribute ( const label constructSize, - List&, + List& values, const int tag = UPstream::msgType() ) const; - //- Reverse distribute data using default commsType. - // Since constructSize might be larger than supplied size supply - // a nullValue + //- Reverse distribute data using default commsType + //- and the default flip/negate operator. + // Accepts a nullValue to initialize unmapped elements + // (ie, when the constructSize is larger than the subMap). template void reverseDistribute ( const label constructSize, const T& nullValue, - List& fld, + List& values, const int tag = UPstream::msgType() ) const; + //- Reverse distribute data using specified commsType + //- and the default flip/negate operator + template + void reverseDistribute + ( + const Pstream::commsTypes commsType, + const label constructSize, + List& values, + const int tag = UPstream::msgType() + ) const; + + //- Reverse distribute data using specified commsType + //- and the specified flip/negate operator. + template + void reverseDistribute + ( + const Pstream::commsTypes commsType, + const label constructSize, + List& values, + const NegateOp& negOp, + const int tag = UPstream::msgType() + ) const; + + //- Reverse distribute data using specified commsType + //- and the default flip/negate operator. + // Accepts a nullValue to initialize unmapped elements + // (ie, when the constructSize is larger than the subMap). + template + void reverseDistribute + ( + const Pstream::commsTypes commsType, + const label constructSize, + const T& nullValue, + List& values, + const int tag = UPstream::msgType() + ) const; + + //- Do all sends using PstreamBuffers template - void send(PstreamBuffers&, const List&) const; + void send(PstreamBuffers& pBufs, const List& field) const; + //- Do all receives using PstreamBuffers template - void receive(PstreamBuffers&, List&) const; + void receive(PstreamBuffers& pBufs, List& field) const; + //- Debug: print layout. Can only be used on maps with sorted // storage (local data first, then non-local data) void printLayout(Ostream& os) const; - //- Correct for topo change. - void updateMesh(const mapPolyMesh&) - { - NotImplemented; - } - // Member Operators @@ -499,17 +717,43 @@ public: void operator=(mapDistributeBase&& rhs); - // IOstream operators + // IOstream Operators - //- Read dictionary from Istream + //- Info proxy to print summary information to a stream + InfoProxy info() const + { + return *this; + } + + //- Read entries from dictionary format + void readDict(const dictionary& dict); + + //- Write entries in dictionary format + void writeEntries(Ostream& os) const; + + //- Read plain content (not dictionary) from Istream friend Istream& operator>>(Istream&, mapDistributeBase&); - //- Write dictionary to Ostream + //- Write plain content (not dictionary) to Ostream friend Ostream& operator<<(Ostream&, const mapDistributeBase&); + + // Housekeeping + + //- No correction for topo change + void updateMesh(const mapPolyMesh&) + { + NotImplemented; + } }; +// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // + +template<> +Ostream& operator<<(Ostream& os, const InfoProxy& ip); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeBaseIO.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeBaseIO.C new file mode 100644 index 0000000000..eaeda12c76 --- /dev/null +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeBaseIO.C @@ -0,0 +1,177 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2022 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 . + +\*---------------------------------------------------------------------------*/ + +#include "mapDistributeBase.H" +#include "dictionary.H" + +// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // + +namespace Foam +{ + +// The maps (labelListList) are not human-modifiable but if we need to +// inspect them in ASCII, it is much more convenient if each sub-list +// is flattened on a single line. +static void writeMaps(Ostream& os, const word& key, const labelListList& maps) +{ + if (os.format() == IOstream::BINARY) + { + os.writeEntry(key, maps); + } + else + { + os << indent << key << nl + << maps.size() << nl + << token::BEGIN_LIST << nl; + + // Single-line output + for (const labelList& map : maps) + { + map.writeList(os) << nl; + } + + os << token::END_LIST << token::END_STATEMENT << nl; + } +} + +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::mapDistributeBase::mapDistributeBase +( + const dictionary& dict, + const label comm +) +: + mapDistributeBase(comm) +{ + mapDistributeBase::readDict(dict); +} + + +Foam::mapDistributeBase::mapDistributeBase(Istream& is) +{ + is >> *this; +} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::mapDistributeBase::readDict(const dictionary& dict) +{ + constructSize_ = dict.get