mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: globalIndex: helper function to get remote values
This commit is contained in:
@ -36,6 +36,7 @@ Description
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
#include "IOstreams.H"
|
||||
#include "Random.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -163,6 +164,54 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Get a few cell indices
|
||||
const label nTotalCells = globalNumbering.size();
|
||||
|
||||
Random rndGen(Pstream::myProcNo());
|
||||
DynamicList<label> globalIDs;
|
||||
for (label i = 0; i < 100; i++)
|
||||
{
|
||||
globalIDs.append(rndGen.position(0, nTotalCells-1));
|
||||
}
|
||||
|
||||
// Get the cell centres at those cell indices
|
||||
List<point> ccs;
|
||||
globalNumbering.get
|
||||
(
|
||||
ccs,
|
||||
globalIDs,
|
||||
[&mesh](List<point>& ccs, const labelUList& localIds)
|
||||
{
|
||||
ccs = UIndirectList<point>(mesh.cellCentres(), localIds);
|
||||
}
|
||||
);
|
||||
|
||||
// Do the brute-force method as well : collect all cell centres on all
|
||||
// processors
|
||||
pointField allCcs(globalNumbering.size());
|
||||
globalNumbering.gather
|
||||
(
|
||||
Pstream::worldComm,
|
||||
Pstream::procID(Pstream::worldComm),
|
||||
mesh.cellCentres(),
|
||||
allCcs
|
||||
);
|
||||
Pstream::scatter(allCcs);
|
||||
|
||||
// Compare
|
||||
forAll(ccs, i)
|
||||
{
|
||||
const point& cc = ccs[i];
|
||||
const point& allCc = allCcs[globalIDs[i]];
|
||||
if (cc != allCc)
|
||||
{
|
||||
FatalErrorInFunction << "Problem cc:" << cc
|
||||
<< " allCc:" << allCc << exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -37,6 +37,66 @@ Foam::globalIndex::globalIndex(Istream& is)
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::globalIndex::bin
|
||||
(
|
||||
const labelUList& offsets,
|
||||
const labelUList& globalIds,
|
||||
labelList& order,
|
||||
CompactListList<label>& bins,
|
||||
DynamicList<label>& validBins
|
||||
)
|
||||
{
|
||||
sortedOrder(globalIds, order);
|
||||
|
||||
bins.m() = UIndirectList<label>(globalIds, order);
|
||||
|
||||
labelList& binOffsets = bins.offsets();
|
||||
binOffsets.setSize(offsets.size());
|
||||
binOffsets = 0;
|
||||
|
||||
validBins.clear();
|
||||
|
||||
if (globalIds.size())
|
||||
{
|
||||
const label id = bins.m()[0];
|
||||
label proci = findLower(offsets, id+1);
|
||||
|
||||
validBins.append(proci);
|
||||
label binSize = 1;
|
||||
|
||||
for (label i = 1; i < order.size(); i++)
|
||||
{
|
||||
const label id = bins.m()[i];
|
||||
|
||||
if (id < offsets[proci+1])
|
||||
{
|
||||
binSize++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not local. Reset proci
|
||||
label oldProci = proci;
|
||||
proci = findLower(offsets, id+1);
|
||||
|
||||
// Set offsets
|
||||
for (label j = oldProci+1; j < proci; ++j)
|
||||
{
|
||||
binOffsets[j] = binOffsets[oldProci]+binSize;
|
||||
}
|
||||
binOffsets[proci] = i;
|
||||
validBins.append(proci);
|
||||
binSize = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (label j = proci+1; j < binOffsets.size(); ++j)
|
||||
{
|
||||
binOffsets[j] = binOffsets[proci]+binSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::globalIndex::reset
|
||||
(
|
||||
const label localSize,
|
||||
|
||||
@ -44,6 +44,8 @@ SourceFiles
|
||||
#define globalIndex_H
|
||||
|
||||
#include "Pstream.H"
|
||||
#include "CompactListList.H"
|
||||
#include "DynamicList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -65,6 +67,19 @@ Ostream& operator<<(Ostream& os, const globalIndex& gi);
|
||||
|
||||
class globalIndex
|
||||
{
|
||||
// Private Member Functions
|
||||
|
||||
//- Sort and bin. validBins contains bins with non-zero size.
|
||||
static void bin
|
||||
(
|
||||
const labelUList& offsets,
|
||||
const labelUList& globalIds,
|
||||
labelList& order,
|
||||
CompactListList<label>& sortedElems,
|
||||
DynamicList<label>& validBins
|
||||
);
|
||||
|
||||
|
||||
// Private data
|
||||
|
||||
//- Start of proci. Size is nProcs()+1. (so like CompactListList)
|
||||
@ -363,6 +378,18 @@ public:
|
||||
Pstream::commsTypes::nonBlocking
|
||||
) const;
|
||||
|
||||
//- Get (potentially remote) data. Elements required given as
|
||||
// global indices
|
||||
template<class Type, class CombineOp>
|
||||
void get
|
||||
(
|
||||
List<Type>& allFld,
|
||||
const labelUList& globalIds,
|
||||
const CombineOp& cop,
|
||||
const label comm = Pstream::worldComm,
|
||||
const int tag = UPstream::msgType()
|
||||
) const;
|
||||
|
||||
|
||||
// IOstream Operators
|
||||
|
||||
|
||||
@ -461,4 +461,88 @@ void Foam::globalIndex::scatter
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class CombineOp>
|
||||
void Foam::globalIndex::get
|
||||
(
|
||||
List<Type>& allFld,
|
||||
const labelUList& globalIds,
|
||||
const CombineOp& cop,
|
||||
const label comm,
|
||||
const int tag
|
||||
) const
|
||||
{
|
||||
allFld.setSize(globalIds.size());
|
||||
if (globalIds.size())
|
||||
{
|
||||
// Sort according to processor
|
||||
labelList order;
|
||||
CompactListList<label> bins;
|
||||
DynamicList<label> validBins(Pstream::nProcs());
|
||||
bin
|
||||
(
|
||||
offsets(),
|
||||
globalIds,
|
||||
order,
|
||||
bins,
|
||||
validBins
|
||||
);
|
||||
|
||||
// Send local indices to individual processors as local index
|
||||
PstreamBuffers sendBufs(Pstream::commsTypes::nonBlocking, tag, comm);
|
||||
|
||||
for (const auto proci : validBins)
|
||||
{
|
||||
const labelUList& es = bins[proci];
|
||||
|
||||
labelList localIDs(es.size());
|
||||
forAll(es, i)
|
||||
{
|
||||
localIDs[i] = toLocal(proci, es[i]);
|
||||
}
|
||||
|
||||
UOPstream os(proci, sendBufs);
|
||||
os << localIDs;
|
||||
}
|
||||
labelList recvSizes;
|
||||
sendBufs.finishedSends(recvSizes);
|
||||
|
||||
|
||||
PstreamBuffers returnBufs(Pstream::commsTypes::nonBlocking, tag, comm);
|
||||
|
||||
forAll(recvSizes, proci)
|
||||
{
|
||||
if (recvSizes[proci])
|
||||
{
|
||||
UIPstream is(proci, sendBufs);
|
||||
labelList localIDs(is);
|
||||
|
||||
// Collect entries
|
||||
List<Type> fld(localIDs.size());
|
||||
cop(fld, localIDs);
|
||||
|
||||
UOPstream os(proci, returnBufs);
|
||||
os << fld;
|
||||
}
|
||||
}
|
||||
returnBufs.finishedSends();
|
||||
|
||||
// Slot back
|
||||
for (const auto proci : validBins)
|
||||
{
|
||||
label start = bins.offsets()[proci];
|
||||
const SubList<label> es
|
||||
(
|
||||
order,
|
||||
bins.offsets()[proci+1]-start, // start
|
||||
start
|
||||
);
|
||||
UIPstream is(proci, returnBufs);
|
||||
List<Type> fld(is);
|
||||
|
||||
UIndirectList<Type>(allFld, es) = fld;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
Reference in New Issue
Block a user