ENH: mpi: use per-application communicator.

This commit is contained in:
mattijs
2020-12-08 13:57:42 +00:00
committed by Andrew Heather
parent 627d79dba6
commit 89f2cda3ab
42 changed files with 4245 additions and 597 deletions

View File

@ -511,9 +511,9 @@ void writeProcAddressing
patchDistMap.constructMap(), patchDistMap.constructMap(),
patchDistMap.constructHasFlip(), patchDistMap.constructHasFlip(),
patchMap, patchMap,
label(-1),
eqOp<label>(), eqOp<label>(),
flipOp(), flipOp(),
label(-1),
UPstream::msgType() UPstream::msgType()
); );
} }

View File

@ -90,8 +90,8 @@ void Foam::UPstream::setParRun(const label nProcs, const bool haveThreads)
<< Foam::exit(FatalError); << Foam::exit(FatalError);
} }
Pout.prefix() = '[' + name(myProcNo(Pstream::worldComm)) + "] "; Pout.prefix() = '[' + name(myProcNo(comm)) + "] ";
Perr.prefix() = '[' + name(myProcNo(Pstream::worldComm)) + "] "; Perr.prefix() = '[' + name(myProcNo(comm)) + "] ";
} }
} }
@ -373,6 +373,8 @@ Foam::DynamicList<Foam::List<int>> Foam::UPstream::procIDs_(10);
Foam::DynamicList<Foam::label> Foam::UPstream::parentCommunicator_(10); Foam::DynamicList<Foam::label> Foam::UPstream::parentCommunicator_(10);
Foam::wordList Foam::UPstream::allWorlds_(1, "");
Foam::labelList Foam::UPstream::worldIDs_(1, 0);
Foam::DynamicList<Foam::List<Foam::UPstream::commsStruct>> Foam::DynamicList<Foam::List<Foam::UPstream::commsStruct>>
Foam::UPstream::linearCommunication_(10); Foam::UPstream::linearCommunication_(10);

View File

@ -194,6 +194,13 @@ private:
//- Standard transfer message type //- Standard transfer message type
static int msgType_; static int msgType_;
//- Names of all worlds
static wordList allWorlds_;
//- Per processor the name of the world
static labelList worldIDs_;
// Communicator specific data // Communicator specific data
//- Free communicators //- Free communicators
@ -437,7 +444,7 @@ public:
} }
//- Number of processes in parallel run, and 1 for serial run //- Number of processes in parallel run, and 1 for serial run
static label nProcs(const label communicator = 0) static label nProcs(const label communicator = worldComm)
{ {
return procIDs_[communicator].size(); return procIDs_[communicator].size();
} }
@ -449,13 +456,13 @@ public:
} }
//- Am I the master process //- Am I the master process
static bool master(const label communicator = 0) static bool master(const label communicator = worldComm)
{ {
return myProcNo_[communicator] == masterNo(); return myProcNo_[communicator] == masterNo();
} }
//- Number of this process (starting from masterNo() = 0) //- Number of this process (starting from masterNo() = 0)
static int myProcNo(const label communicator = 0) static int myProcNo(const label communicator = worldComm)
{ {
return myProcNo_[communicator]; return myProcNo_[communicator];
} }
@ -471,15 +478,43 @@ public:
return procIDs_[communicator]; return procIDs_[communicator];
} }
// Worlds
//- All worlds
static const wordList& allWorlds()
{
return allWorlds_;
}
//- worldID (index in allWorlds) of all processes
static const labelList& worldIDs()
{
return worldIDs_;
}
//- My worldID
static label myWorldID()
{
return worldIDs_[myProcNo(0)];
}
//- My world
static const word& myWorld()
{
return allWorlds()[myWorldID()];
}
//- Range of process indices for all processes //- Range of process indices for all processes
static rangeType allProcs(const label communicator = 0) static rangeType allProcs(const label communicator = worldComm)
{ {
// Proc 0 -> nProcs (int value) // Proc 0 -> nProcs (int value)
return rangeType(static_cast<int>(nProcs(communicator))); return rangeType(static_cast<int>(nProcs(communicator)));
} }
//- Range of process indices for sub-processes //- Range of process indices for sub-processes
static rangeType subProcs(const label communicator = 0) static rangeType subProcs(const label communicator = worldComm)
{ {
// Proc 1 -> nProcs (int value) // Proc 1 -> nProcs (int value)
return rangeType(1, static_cast<int>(nProcs(communicator)-1)); return rangeType(1, static_cast<int>(nProcs(communicator)-1));
@ -488,7 +523,7 @@ public:
//- Communication schedule for linear all-to-master (proc 0) //- Communication schedule for linear all-to-master (proc 0)
static const List<commsStruct>& linearCommunication static const List<commsStruct>& linearCommunication
( (
const label communicator = 0 const label communicator = worldComm
) )
{ {
return linearCommunication_[communicator]; return linearCommunication_[communicator];
@ -497,7 +532,7 @@ public:
//- Communication schedule for tree all-to-master (proc 0) //- Communication schedule for tree all-to-master (proc 0)
static const List<commsStruct>& treeCommunication static const List<commsStruct>& treeCommunication
( (
const label communicator = 0 const label communicator = worldComm
) )
{ {
return treeCommunication_[communicator]; return treeCommunication_[communicator];
@ -542,7 +577,7 @@ public:
( (
const labelUList& sendData, const labelUList& sendData,
labelUList& recvData, labelUList& recvData,
const label communicator = 0 const label communicator = worldComm
); );
//- Exchange data with all processors (in the communicator) //- Exchange data with all processors (in the communicator)
@ -559,7 +594,7 @@ public:
const UList<int>& recvSizes, const UList<int>& recvSizes,
const UList<int>& recvOffsets, const UList<int>& recvOffsets,
const label communicator = 0 const label communicator = worldComm
); );
//- Receive data from all processors on the master //- Receive data from all processors on the master
@ -571,7 +606,7 @@ public:
char* recvData, char* recvData,
const UList<int>& recvSizes, const UList<int>& recvSizes,
const UList<int>& recvOffsets, const UList<int>& recvOffsets,
const label communicator = 0 const label communicator = worldComm
); );
//- Send data to all processors from the root of the communicator //- Send data to all processors from the root of the communicator
@ -583,7 +618,7 @@ public:
char* recvData, char* recvData,
int recvSize, int recvSize,
const label communicator = 0 const label communicator = worldComm
); );
@ -598,7 +633,7 @@ public:
//- Process index of last sub-process //- Process index of last sub-process
// \deprecated(2020-09) use subProcs() method instead // \deprecated(2020-09) use subProcs() method instead
static int lastSlave(const label communicator = 0) static int lastSlave(const label communicator = worldComm)
{ {
return nProcs(communicator) - 1; return nProcs(communicator) - 1;
} }

View File

@ -166,6 +166,20 @@ Foam::argList::initValidTables::initValidTables()
true // advanced option true // advanced option
); );
argList::addOption
(
"world",
"Name",
"Name of local world",
true
);
validParOptions.set
(
"world",
"Name of local world"
);
// Some standard option aliases (with or without version warnings) // Some standard option aliases (with or without version warnings)
// argList::addOptionCompat // argList::addOptionCompat
// ( // (
@ -493,6 +507,7 @@ void Foam::argList::noParallel()
removeOption("roots"); removeOption("roots");
removeOption("decomposeParDict"); removeOption("decomposeParDict");
removeOption("hostRoots"); removeOption("hostRoots");
removeOption("world");
validParOptions.clear(); validParOptions.clear();
} }
@ -711,6 +726,7 @@ void Foam::argList::setCasePaths()
} }
else else
{ {
caseDir.expand();
caseDir.toAbsolute(); caseDir.toAbsolute();
} }
} }
@ -1241,7 +1257,7 @@ void Foam::argList::parse
dictNProcs = roots.size()+1; dictNProcs = roots.size()+1;
} }
} }
else if (checkProcessorDirectories_) else if (checkProcessorDirectories_ && Pstream::nProcs() > 1)
{ {
// Use values from decomposeParDict, the location was already // Use values from decomposeParDict, the location was already
// established above. // established above.
@ -1268,6 +1284,13 @@ void Foam::argList::parse
Pstream::parRun(oldParRun); // Restore parallel state Pstream::parRun(oldParRun); // Restore parallel state
decompDict.readEntry("numberOfSubdomains", dictNProcs); decompDict.readEntry("numberOfSubdomains", dictNProcs);
if (Pstream::nProcs() == 1)
{
WarningInFunction
<< "Running parallel on single processor. This only"
<< " makes sense for multi-world simulation" << endl;
dictNProcs = 1;
}
if (decompDict.getOrDefault("distributed", false)) if (decompDict.getOrDefault("distributed", false))
{ {
@ -1300,7 +1323,12 @@ void Foam::argList::parse
// - normal running : nProcs = dictNProcs = nProcDirs // - normal running : nProcs = dictNProcs = nProcDirs
// - decomposition to more processors : nProcs = dictNProcs // - decomposition to more processors : nProcs = dictNProcs
// - decomposition to fewer processors : nProcs = nProcDirs // - decomposition to fewer processors : nProcs = nProcDirs
if (checkProcessorDirectories_ && dictNProcs > Pstream::nProcs()) if
(
checkProcessorDirectories_
&& Pstream::nProcs() > 1
&& dictNProcs > Pstream::nProcs()
)
{ {
FatalError FatalError
<< source << source
@ -1353,6 +1381,7 @@ void Foam::argList::parse
if if
( (
checkProcessorDirectories_ checkProcessorDirectories_
&& Pstream::nProcs() > 1
&& dictNProcs < Pstream::nProcs() && dictNProcs < Pstream::nProcs()
) )
{ {
@ -1405,7 +1434,14 @@ void Foam::argList::parse
} }
nProcs = Pstream::nProcs(); nProcs = Pstream::nProcs();
case_ = globalCase_/("processor" + Foam::name(Pstream::myProcNo())); if (Pstream::nProcs() > 1)
{
case_ = globalCase_/("processor" + Foam::name(Pstream::myProcNo()));
}
else
{
case_ = globalCase_;
}
} }
else else
{ {
@ -1468,6 +1504,13 @@ void Foam::argList::parse
<< Pstream::commsTypeNames[Pstream::defaultCommsType] << nl << Pstream::commsTypeNames[Pstream::defaultCommsType] << nl
<< " polling iterations : " << Pstream::nPollProcInterfaces << " polling iterations : " << Pstream::nPollProcInterfaces
<< endl; << endl;
if (UPstream::allWorlds().size() > 1)
{
Info<< " worlds : "
<< flatOutput(UPstream::allWorlds()) << nl
<< " world : " << UPstream::myWorld()
<< endl;
}
} }
} }

View File

@ -93,7 +93,7 @@ inline Foam::label Foam::globalIndex::size() const
inline void Foam::globalIndex::reset(const label localSize) inline void Foam::globalIndex::reset(const label localSize)
{ {
reset(localSize, Pstream::msgType(), 0, true); reset(localSize, Pstream::msgType(), UPstream::worldComm, true);
} }

View File

@ -2745,13 +2745,16 @@ void Foam::globalMeshData::updateMesh()
// *** Temporary hack to avoid problems with overlapping communication // *** Temporary hack to avoid problems with overlapping communication
// *** between these reductions and the calculation of deltaCoeffs // *** between these reductions and the calculation of deltaCoeffs
//label comm = UPstream::worldComm + 1; //const label comm = UPstream::worldComm + 1;
label comm = UPstream::allocateCommunicator const label comm = UPstream::allocateCommunicator
( (
UPstream::worldComm, UPstream::worldComm,
identity(UPstream::nProcs(UPstream::worldComm)), identity(UPstream::nProcs(UPstream::worldComm)),
true true
); );
const label oldWarnComm = UPstream::warnComm;
UPstream::warnComm = comm;
// Total number of faces. // Total number of faces.
nTotalFaces_ = returnReduce nTotalFaces_ = returnReduce
@ -2789,6 +2792,7 @@ void Foam::globalMeshData::updateMesh()
); );
UPstream::freeCommunicator(comm); UPstream::freeCommunicator(comm);
UPstream::warnComm = oldWarnComm;
if (debug) if (debug)
{ {

View File

@ -148,9 +148,9 @@ void Foam::mapDistribute::printLayout(Ostream& os) const
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::mapDistribute::mapDistribute() Foam::mapDistribute::mapDistribute(const label comm)
: :
mapDistributeBase() mapDistributeBase(comm)
{} {}
@ -176,7 +176,8 @@ Foam::mapDistribute::mapDistribute
labelListList&& subMap, labelListList&& subMap,
labelListList&& constructMap, labelListList&& constructMap,
const bool subHasFlip, const bool subHasFlip,
const bool constructHasFlip const bool constructHasFlip,
const label comm
) )
: :
mapDistributeBase mapDistributeBase
@ -185,7 +186,8 @@ Foam::mapDistribute::mapDistribute
std::move(subMap), std::move(subMap),
std::move(constructMap), std::move(constructMap),
subHasFlip, subHasFlip,
constructHasFlip constructHasFlip,
comm
) )
{} {}
@ -198,7 +200,8 @@ Foam::mapDistribute::mapDistribute
labelListList&& transformElements, labelListList&& transformElements,
labelList&& transformStart, labelList&& transformStart,
const bool subHasFlip, const bool subHasFlip,
const bool constructHasFlip const bool constructHasFlip,
const label comm
) )
: :
mapDistributeBase mapDistributeBase
@ -207,7 +210,8 @@ Foam::mapDistribute::mapDistribute
std::move(subMap), std::move(subMap),
std::move(constructMap), std::move(constructMap),
subHasFlip, subHasFlip,
constructHasFlip constructHasFlip,
comm
), ),
transformElements_(std::move(transformElements)), transformElements_(std::move(transformElements)),
transformStart_(std::move(transformStart)) transformStart_(std::move(transformStart))
@ -217,10 +221,11 @@ Foam::mapDistribute::mapDistribute
Foam::mapDistribute::mapDistribute Foam::mapDistribute::mapDistribute
( (
const labelUList& sendProcs, const labelUList& sendProcs,
const labelUList& recvProcs const labelUList& recvProcs,
const label comm
) )
: :
mapDistributeBase(sendProcs, recvProcs) mapDistributeBase(sendProcs, recvProcs, comm)
{} {}
@ -229,7 +234,8 @@ Foam::mapDistribute::mapDistribute
const globalIndex& globalNumbering, const globalIndex& globalNumbering,
labelList& elements, labelList& elements,
List<Map<label>>& compactMap, List<Map<label>>& compactMap,
const int tag const int tag,
const label comm
) )
: :
mapDistributeBase mapDistributeBase
@ -237,7 +243,8 @@ Foam::mapDistribute::mapDistribute
globalNumbering, globalNumbering,
elements, elements,
compactMap, compactMap,
tag tag,
comm
) )
{} {}
@ -247,7 +254,8 @@ Foam::mapDistribute::mapDistribute
const globalIndex& globalNumbering, const globalIndex& globalNumbering,
labelListList& cellCells, labelListList& cellCells,
List<Map<label>>& compactMap, List<Map<label>>& compactMap,
const int tag const int tag,
const label comm
) )
: :
mapDistributeBase mapDistributeBase
@ -255,7 +263,8 @@ Foam::mapDistribute::mapDistribute
globalNumbering, globalNumbering,
cellCells, cellCells,
compactMap, compactMap,
tag tag,
comm
) )
{} {}
@ -268,11 +277,14 @@ Foam::mapDistribute::mapDistribute
const labelPairList& transformedElements, const labelPairList& transformedElements,
labelList& transformedIndices, labelList& transformedIndices,
List<Map<label>>& compactMap, List<Map<label>>& compactMap,
const int tag const int tag,
const label comm
) )
: :
mapDistributeBase() mapDistributeBase(comm)
{ {
const label myRank = Pstream::myProcNo(comm);
// Construct per processor compact addressing of the global elements // Construct per processor compact addressing of the global elements
// needed. The ones from the local processor are not included since // needed. The ones from the local processor are not included since
// these are always all needed. // these are always all needed.
@ -288,7 +300,7 @@ Foam::mapDistribute::mapDistribute
{ {
labelPair elem = transformedElements[i]; labelPair elem = transformedElements[i];
label proci = globalTransforms.processor(elem); label proci = globalTransforms.processor(elem);
if (proci != Pstream::myProcNo()) if (proci != myRank)
{ {
label index = globalTransforms.index(elem); label index = globalTransforms.index(elem);
label nCompact = compactMap[proci].size(); label nCompact = compactMap[proci].size();
@ -345,7 +357,7 @@ Foam::mapDistribute::mapDistribute
// Get compact index for untransformed element // Get compact index for untransformed element
label rawElemI = label rawElemI =
( (
proci == Pstream::myProcNo() proci == myRank
? index ? index
: compactMap[proci][index] : compactMap[proci][index]
); );
@ -373,11 +385,14 @@ Foam::mapDistribute::mapDistribute
const List<labelPairList>& transformedElements, const List<labelPairList>& transformedElements,
labelListList& transformedIndices, labelListList& transformedIndices,
List<Map<label>>& compactMap, List<Map<label>>& compactMap,
const int tag const int tag,
const label comm
) )
: :
mapDistributeBase() mapDistributeBase(comm)
{ {
const label myRank = Pstream::myProcNo(comm_);
// Construct per processor compact addressing of the global elements // Construct per processor compact addressing of the global elements
// needed. The ones from the local processor are not included since // needed. The ones from the local processor are not included since
// these are always all needed. // these are always all needed.
@ -396,7 +411,7 @@ Foam::mapDistribute::mapDistribute
forAll(elems, i) forAll(elems, i)
{ {
label proci = globalTransforms.processor(elems[i]); label proci = globalTransforms.processor(elems[i]);
if (proci != Pstream::myProcNo()) if (proci != myRank)
{ {
label index = globalTransforms.index(elems[i]); label index = globalTransforms.index(elems[i]);
label nCompact = compactMap[proci].size(); label nCompact = compactMap[proci].size();
@ -462,7 +477,7 @@ Foam::mapDistribute::mapDistribute
// Get compact index for untransformed element // Get compact index for untransformed element
label rawElemI = label rawElemI =
( (
proci == Pstream::myProcNo() proci == myRank
? index ? index
: compactMap[proci][index] : compactMap[proci][index]
); );
@ -487,10 +502,11 @@ Foam::mapDistribute::mapDistribute
( (
labelListList&& subMap, labelListList&& subMap,
const bool subHasFlip, const bool subHasFlip,
const bool constructHasFlip const bool constructHasFlip,
const label comm
) )
: :
mapDistributeBase(std::move(subMap), subHasFlip, constructHasFlip) mapDistributeBase(std::move(subMap), subHasFlip, constructHasFlip, comm)
{} {}

View File

@ -328,7 +328,7 @@ public:
// Constructors // Constructors
//- Construct null //- Construct null
mapDistribute(); mapDistribute(const label comm = UPstream::worldComm);
//- Copy construct //- Copy construct
explicit mapDistribute(const mapDistribute& map); explicit mapDistribute(const mapDistribute& map);
@ -343,7 +343,8 @@ public:
labelListList&& subMap, labelListList&& subMap,
labelListList&& constructMap, labelListList&& constructMap,
const bool subHasFlip = false, const bool subHasFlip = false,
const bool constructHasFlip = false const bool constructHasFlip = false,
const label comm = UPstream::worldComm
); );
//- Move construct from components //- Move construct from components
@ -355,7 +356,8 @@ public:
labelListList&& transformElements, labelListList&& transformElements,
labelList&& transformStart, labelList&& transformStart,
const bool subHasFlip = false, const bool subHasFlip = false,
const bool constructHasFlip = false const bool constructHasFlip = false,
const label comm = UPstream::worldComm
); );
//- Construct from reverse addressing: per data item the send //- Construct from reverse addressing: per data item the send
@ -365,7 +367,8 @@ public:
mapDistribute mapDistribute
( (
const labelUList& sendProcs, const labelUList& sendProcs,
const labelUList& recvProcs const labelUList& recvProcs,
const label comm = UPstream::worldComm
); );
//- Construct from list of (possibly) remote elements in globalIndex //- Construct from list of (possibly) remote elements in globalIndex
@ -378,7 +381,8 @@ public:
const globalIndex&, const globalIndex&,
labelList& elements, labelList& elements,
List<Map<label>>& compactMap, List<Map<label>>& compactMap,
const int tag = Pstream::msgType() const int tag = Pstream::msgType(),
const label comm = UPstream::worldComm
); );
//- Special variant that works with the info sorted into bins //- Special variant that works with the info sorted into bins
@ -390,7 +394,8 @@ public:
const globalIndex&, const globalIndex&,
labelListList& cellCells, labelListList& cellCells,
List<Map<label>>& compactMap, List<Map<label>>& compactMap,
const int tag = Pstream::msgType() const int tag = Pstream::msgType(),
const label comm = UPstream::worldComm
); );
//- Construct from list of (possibly remote) untransformed elements //- Construct from list of (possibly remote) untransformed elements
@ -407,7 +412,8 @@ public:
const labelPairList& transformedElements, const labelPairList& transformedElements,
labelList& transformedIndices, labelList& transformedIndices,
List<Map<label>>& compactMap, List<Map<label>>& compactMap,
const int tag = Pstream::msgType() const int tag = Pstream::msgType(),
const label comm = UPstream::worldComm
); );
//- As above but with ListLists. //- As above but with ListLists.
@ -419,7 +425,8 @@ public:
const List<labelPairList>& transformedElements, const List<labelPairList>& transformedElements,
labelListList& transformedIndices, labelListList& transformedIndices,
List<Map<label>>& compactMap, List<Map<label>>& compactMap,
const int tag = Pstream::msgType() const int tag = Pstream::msgType(),
const label comm = UPstream::worldComm
); );
//- Construct from my elements to send. Assumes layout is my elements //- Construct from my elements to send. Assumes layout is my elements
@ -429,7 +436,8 @@ public:
( (
labelListList&& subMap, labelListList&& subMap,
const bool subHasFlip = false, const bool subHasFlip = false,
const bool constructHasFlip = false const bool constructHasFlip = false,
const label comm = UPstream::worldComm
); );
//- Construct from Istream //- Construct from Istream

View File

@ -46,29 +46,33 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
( (
const labelListList& subMap, const labelListList& subMap,
const labelListList& constructMap, const labelListList& constructMap,
const int tag const int tag,
const label comm
) )
{ {
const label myRank = Pstream::myProcNo(comm);
const label nProcs = Pstream::nProcs(comm);
// Communications: send and receive processor // Communications: send and receive processor
List<labelPair> allComms; List<labelPair> allComms;
{ {
labelPairHashSet commsSet(Pstream::nProcs()); labelPairHashSet commsSet(nProcs);
// Find what communication is required // Find what communication is required
forAll(subMap, proci) forAll(subMap, proci)
{ {
if (proci != Pstream::myProcNo()) if (proci != myRank)
{ {
if (subMap[proci].size()) if (subMap[proci].size())
{ {
// I need to send to proci // I need to send to proci
commsSet.insert(labelPair(Pstream::myProcNo(), proci)); commsSet.insert(labelPair(myRank, proci));
} }
if (constructMap[proci].size()) if (constructMap[proci].size())
{ {
// I need to receive from proci // I need to receive from proci
commsSet.insert(labelPair(proci, Pstream::myProcNo())); commsSet.insert(labelPair(proci, myRank));
} }
} }
} }
@ -77,12 +81,19 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
// Reduce // Reduce
if (Pstream::master()) if (Pstream::master(comm))
{ {
// Receive and merge // Receive and merge
for (const int slave : Pstream::subProcs()) for (const int slave : Pstream::subProcs(comm))
{ {
IPstream fromSlave(Pstream::commsTypes::scheduled, slave, 0, tag); IPstream fromSlave
(
Pstream::commsTypes::scheduled,
slave,
0,
tag,
comm
);
List<labelPair> nbrData(fromSlave); List<labelPair> nbrData(fromSlave);
forAll(nbrData, i) forAll(nbrData, i)
@ -96,9 +107,16 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
} }
} }
// Send back // Send back
for (const int slave : Pstream::subProcs()) for (const int slave : Pstream::subProcs(comm))
{ {
OPstream toSlave(Pstream::commsTypes::scheduled, slave, 0, tag); OPstream toSlave
(
Pstream::commsTypes::scheduled,
slave,
0,
tag,
comm
);
toSlave << allComms; toSlave << allComms;
} }
} }
@ -110,7 +128,8 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
Pstream::commsTypes::scheduled, Pstream::commsTypes::scheduled,
Pstream::masterNo(), Pstream::masterNo(),
0, 0,
tag tag,
comm
); );
toMaster << allComms; toMaster << allComms;
} }
@ -120,7 +139,8 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
Pstream::commsTypes::scheduled, Pstream::commsTypes::scheduled,
Pstream::masterNo(), Pstream::masterNo(),
0, 0,
tag tag,
comm
); );
fromMaster >> allComms; fromMaster >> allComms;
} }
@ -132,9 +152,9 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
( (
commSchedule commSchedule
( (
Pstream::nProcs(), nProcs,
allComms allComms
).procSchedule()[Pstream::myProcNo()] ).procSchedule()[myRank]
); );
// Processors involved in my schedule // Processors involved in my schedule
@ -151,7 +171,7 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
// label sendProc = twoProcs[0]; // label sendProc = twoProcs[0];
// label recvProc = twoProcs[1]; // label recvProc = twoProcs[1];
// //
// if (recvProc == Pstream::myProcNo()) // if (recvProc == myRank)
// { // {
// Pout<< " receive from " << sendProc << endl; // Pout<< " receive from " << sendProc << endl;
// } // }
@ -172,7 +192,7 @@ const Foam::List<Foam::labelPair>& Foam::mapDistributeBase::schedule() const
( (
new List<labelPair> new List<labelPair>
( (
schedule(subMap_, constructMap_, Pstream::msgType()) schedule(subMap_, constructMap_, Pstream::msgType(), comm_)
) )
); );
} }
@ -200,9 +220,12 @@ void Foam::mapDistributeBase::checkReceivedSize
void Foam::mapDistributeBase::printLayout(Ostream& os) const void Foam::mapDistributeBase::printLayout(Ostream& os) const
{ {
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
// Determine offsets of remote data. // Determine offsets of remote data.
labelList minIndex(Pstream::nProcs(), labelMax); labelList minIndex(nProcs, labelMax);
labelList maxIndex(Pstream::nProcs(), labelMin); labelList maxIndex(nProcs, labelMin);
forAll(constructMap_, proci) forAll(constructMap_, proci)
{ {
const labelList& construct = constructMap_[proci]; const labelList& construct = constructMap_[proci];
@ -227,27 +250,27 @@ void Foam::mapDistributeBase::printLayout(Ostream& os) const
} }
label localSize; label localSize;
if (maxIndex[Pstream::myProcNo()] == labelMin) if (maxIndex[myRank] == labelMin)
{ {
localSize = 0; localSize = 0;
} }
else else
{ {
localSize = maxIndex[Pstream::myProcNo()]+1; localSize = maxIndex[myRank]+1;
} }
os << "Layout: (constructSize:" << constructSize_ os << "Layout: (constructSize:" << constructSize_
<< " subHasFlip:" << subHasFlip_ << " subHasFlip:" << subHasFlip_
<< " constructHasFlip:" << constructHasFlip_ << " constructHasFlip:" << constructHasFlip_
<< ")" << endl << ")" << endl
<< "local (processor " << Pstream::myProcNo() << "):" << endl << "local (processor " << myRank << "):" << endl
<< " start : 0" << endl << " start : 0" << endl
<< " size : " << localSize << endl; << " size : " << localSize << endl;
label offset = localSize; label offset = localSize;
forAll(minIndex, proci) forAll(minIndex, proci)
{ {
if (proci != Pstream::myProcNo()) if (proci != myRank)
{ {
if (constructMap_[proci].size() > 0) if (constructMap_[proci].size() > 0)
{ {
@ -279,10 +302,13 @@ void Foam::mapDistributeBase::calcCompactAddressing
List<Map<label>>& compactMap List<Map<label>>& compactMap
) const ) const
{ {
compactMap.setSize(Pstream::nProcs()); 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. // Count all (non-local) elements needed. Just for presizing map.
labelList nNonLocal(Pstream::nProcs(), Zero); labelList nNonLocal(nProcs, Zero);
for (const label globalIdx : elements) for (const label globalIdx : elements)
{ {
@ -296,7 +322,7 @@ void Foam::mapDistributeBase::calcCompactAddressing
forAll(compactMap, proci) forAll(compactMap, proci)
{ {
compactMap[proci].clear(); compactMap[proci].clear();
if (proci != Pstream::myProcNo()) if (proci != myRank)
{ {
compactMap[proci].resize(2*nNonLocal[proci]); compactMap[proci].resize(2*nNonLocal[proci]);
} }
@ -324,10 +350,13 @@ void Foam::mapDistributeBase::calcCompactAddressing
List<Map<label>>& compactMap List<Map<label>>& compactMap
) const ) const
{ {
compactMap.setSize(Pstream::nProcs()); 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. // Count all (non-local) elements needed. Just for presizing map.
labelList nNonLocal(Pstream::nProcs(), Zero); labelList nNonLocal(nProcs, Zero);
for (const labelList& cCells : cellCells) for (const labelList& cCells : cellCells)
{ {
@ -344,7 +373,7 @@ void Foam::mapDistributeBase::calcCompactAddressing
forAll(compactMap, proci) forAll(compactMap, proci)
{ {
compactMap[proci].clear(); compactMap[proci].clear();
if (proci != Pstream::myProcNo()) if (proci != myRank)
{ {
compactMap[proci].resize(2*nNonLocal[proci]); compactMap[proci].resize(2*nNonLocal[proci]);
} }
@ -377,16 +406,19 @@ void Foam::mapDistributeBase::exchangeAddressing
labelList& compactStart labelList& compactStart
) )
{ {
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
// The overall compact addressing is // The overall compact addressing is
// - myProcNo data first (uncompacted) // - myProcNo data first (uncompacted)
// - all other processors consecutively // - all other processors consecutively
compactStart.setSize(Pstream::nProcs()); compactStart.setSize(nProcs);
compactStart[Pstream::myProcNo()] = 0; compactStart[myRank] = 0;
constructSize_ = globalNumbering.localSize(); constructSize_ = globalNumbering.localSize();
forAll(compactStart, proci) forAll(compactStart, proci)
{ {
if (proci != Pstream::myProcNo()) if (proci != myRank)
{ {
compactStart[proci] = constructSize_; compactStart[proci] = constructSize_;
constructSize_ += compactMap[proci].size(); constructSize_ += compactMap[proci].size();
@ -398,12 +430,12 @@ void Foam::mapDistributeBase::exchangeAddressing
// Find out what to receive/send in compact addressing. // Find out what to receive/send in compact addressing.
// What I want to receive is what others have to send // What I want to receive is what others have to send
labelListList wantedRemoteElements(Pstream::nProcs()); labelListList wantedRemoteElements(nProcs);
// Compact addressing for received data // Compact addressing for received data
constructMap_.setSize(Pstream::nProcs()); constructMap_.setSize(nProcs);
forAll(compactMap, proci) forAll(compactMap, proci)
{ {
if (proci == Pstream::myProcNo()) if (proci == myRank)
{ {
// All my own elements are used // All my own elements are used
label nLocal = globalNumbering.localSize(); label nLocal = globalNumbering.localSize();
@ -429,13 +461,13 @@ void Foam::mapDistributeBase::exchangeAddressing
} }
} }
subMap_.setSize(Pstream::nProcs()); subMap_.setSize(nProcs);
Pstream::exchange<labelList, label> Pstream::exchange<labelList, label>
( (
wantedRemoteElements, wantedRemoteElements,
subMap_, subMap_,
tag, tag,
Pstream::worldComm //TBD comm_
); );
// Renumber elements // Renumber elements
@ -455,16 +487,19 @@ void Foam::mapDistributeBase::exchangeAddressing
labelList& compactStart labelList& compactStart
) )
{ {
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
// The overall compact addressing is // The overall compact addressing is
// - myProcNo data first (uncompacted) // - myProcNo data first (uncompacted)
// - all other processors consecutively // - all other processors consecutively
compactStart.setSize(Pstream::nProcs()); compactStart.setSize(nProcs);
compactStart[Pstream::myProcNo()] = 0; compactStart[myRank] = 0;
constructSize_ = globalNumbering.localSize(); constructSize_ = globalNumbering.localSize();
forAll(compactStart, proci) forAll(compactStart, proci)
{ {
if (proci != Pstream::myProcNo()) if (proci != myRank)
{ {
compactStart[proci] = constructSize_; compactStart[proci] = constructSize_;
constructSize_ += compactMap[proci].size(); constructSize_ += compactMap[proci].size();
@ -475,12 +510,12 @@ void Foam::mapDistributeBase::exchangeAddressing
// Find out what to receive/send in compact addressing. // Find out what to receive/send in compact addressing.
// What I want to receive is what others have to send // What I want to receive is what others have to send
labelListList wantedRemoteElements(Pstream::nProcs()); labelListList wantedRemoteElements(nProcs);
// Compact addressing for received data // Compact addressing for received data
constructMap_.setSize(Pstream::nProcs()); constructMap_.setSize(nProcs);
forAll(compactMap, proci) forAll(compactMap, proci)
{ {
if (proci == Pstream::myProcNo()) if (proci == myRank)
{ {
// All my own elements are used // All my own elements are used
label nLocal = globalNumbering.localSize(); label nLocal = globalNumbering.localSize();
@ -506,13 +541,13 @@ void Foam::mapDistributeBase::exchangeAddressing
} }
} }
subMap_.setSize(Pstream::nProcs()); subMap_.setSize(nProcs);
Pstream::exchange<labelList, label> Pstream::exchange<labelList, label>
( (
wantedRemoteElements, wantedRemoteElements,
subMap_, subMap_,
tag, tag,
Pstream::worldComm //TBD comm_
); );
// Renumber elements // Renumber elements
@ -528,11 +563,12 @@ void Foam::mapDistributeBase::exchangeAddressing
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::mapDistributeBase::mapDistributeBase() Foam::mapDistributeBase::mapDistributeBase(const label comm)
: :
constructSize_(0), constructSize_(0),
subHasFlip_(false), subHasFlip_(false),
constructHasFlip_(false), constructHasFlip_(false),
comm_(comm),
schedulePtr_() schedulePtr_()
{} {}
@ -545,6 +581,7 @@ Foam::mapDistributeBase::mapDistributeBase(const mapDistributeBase& map)
constructMap_(map.constructMap_), constructMap_(map.constructMap_),
subHasFlip_(map.subHasFlip_), subHasFlip_(map.subHasFlip_),
constructHasFlip_(map.constructHasFlip_), constructHasFlip_(map.constructHasFlip_),
comm_(map.comm_),
schedulePtr_() schedulePtr_()
{} {}
@ -563,7 +600,8 @@ Foam::mapDistributeBase::mapDistributeBase
labelListList&& subMap, labelListList&& subMap,
labelListList&& constructMap, labelListList&& constructMap,
const bool subHasFlip, const bool subHasFlip,
const bool constructHasFlip const bool constructHasFlip,
const label comm
) )
: :
constructSize_(constructSize), constructSize_(constructSize),
@ -571,6 +609,7 @@ Foam::mapDistributeBase::mapDistributeBase
constructMap_(std::move(constructMap)), constructMap_(std::move(constructMap)),
subHasFlip_(subHasFlip), subHasFlip_(subHasFlip),
constructHasFlip_(constructHasFlip), constructHasFlip_(constructHasFlip),
comm_(comm),
schedulePtr_() schedulePtr_()
{} {}
@ -578,14 +617,19 @@ Foam::mapDistributeBase::mapDistributeBase
Foam::mapDistributeBase::mapDistributeBase Foam::mapDistributeBase::mapDistributeBase
( (
const labelUList& sendProcs, const labelUList& sendProcs,
const labelUList& recvProcs const labelUList& recvProcs,
const label comm
) )
: :
constructSize_(0), constructSize_(0),
subHasFlip_(false), subHasFlip_(false),
constructHasFlip_(false), constructHasFlip_(false),
comm_(comm),
schedulePtr_() schedulePtr_()
{ {
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
if (sendProcs.size() != recvProcs.size()) if (sendProcs.size() != recvProcs.size())
{ {
FatalErrorInFunction FatalErrorInFunction
@ -595,8 +639,8 @@ Foam::mapDistributeBase::mapDistributeBase
} }
// Per processor the number of samples we have to send/receive. // Per processor the number of samples we have to send/receive.
labelList nSend(Pstream::nProcs(), Zero); labelList nSend(nProcs, Zero);
labelList nRecv(Pstream::nProcs(), Zero); labelList nRecv(nProcs, Zero);
forAll(sendProcs, sampleI) forAll(sendProcs, sampleI)
{ {
@ -606,20 +650,20 @@ Foam::mapDistributeBase::mapDistributeBase
// Note that also need to include local communication (both // Note that also need to include local communication (both
// RecvProc and sendProc on local processor) // RecvProc and sendProc on local processor)
if (Pstream::myProcNo() == sendProc) if (myRank == sendProc)
{ {
// I am the sender. Count destination processor. // I am the sender. Count destination processor.
nSend[recvProc]++; nSend[recvProc]++;
} }
if (Pstream::myProcNo() == recvProc) if (myRank == recvProc)
{ {
// I am the receiver. // I am the receiver.
nRecv[sendProc]++; nRecv[sendProc]++;
} }
} }
subMap_.setSize(Pstream::nProcs()); subMap_.setSize(nProcs);
constructMap_.setSize(Pstream::nProcs()); constructMap_.setSize(nProcs);
forAll(nSend, proci) forAll(nSend, proci)
{ {
subMap_[proci].setSize(nSend[proci]); subMap_[proci].setSize(nSend[proci]);
@ -633,12 +677,12 @@ Foam::mapDistributeBase::mapDistributeBase
const label sendProc = sendProcs[sampleI]; const label sendProc = sendProcs[sampleI];
const label recvProc = recvProcs[sampleI]; const label recvProc = recvProcs[sampleI];
if (Pstream::myProcNo() == sendProc) if (myRank == sendProc)
{ {
// I am the sender. Store index I need to send. // I am the sender. Store index I need to send.
subMap_[recvProc][nSend[recvProc]++] = sampleI; subMap_[recvProc][nSend[recvProc]++] = sampleI;
} }
if (Pstream::myProcNo() == recvProc) if (myRank == recvProc)
{ {
// I am the receiver. // I am the receiver.
constructMap_[sendProc][nRecv[sendProc]++] = sampleI; constructMap_[sendProc][nRecv[sendProc]++] = sampleI;
@ -654,12 +698,14 @@ Foam::mapDistributeBase::mapDistributeBase
const globalIndex& globalNumbering, const globalIndex& globalNumbering,
labelList& elements, labelList& elements,
List<Map<label>>& compactMap, List<Map<label>>& compactMap,
const int tag const int tag,
const label comm
) )
: :
constructSize_(0), constructSize_(0),
subHasFlip_(false), subHasFlip_(false),
constructHasFlip_(false), constructHasFlip_(false),
comm_(comm),
schedulePtr_() schedulePtr_()
{ {
// Construct per processor compact addressing of the global elements // Construct per processor compact addressing of the global elements
@ -675,7 +721,7 @@ Foam::mapDistributeBase::mapDistributeBase
//// Sort remote elements needed (not really necessary) //// Sort remote elements needed (not really necessary)
//forAll(compactMap, proci) //forAll(compactMap, proci)
//{ //{
// if (proci != Pstream::myProcNo()) // if (proci != myRank)
// { // {
// Map<label>& globalMap = compactMap[proci]; // Map<label>& globalMap = compactMap[proci];
// //
@ -713,12 +759,14 @@ Foam::mapDistributeBase::mapDistributeBase
const globalIndex& globalNumbering, const globalIndex& globalNumbering,
labelListList& cellCells, labelListList& cellCells,
List<Map<label>>& compactMap, List<Map<label>>& compactMap,
const int tag const int tag,
const label comm
) )
: :
constructSize_(0), constructSize_(0),
subHasFlip_(false), subHasFlip_(false),
constructHasFlip_(false), constructHasFlip_(false),
comm_(comm),
schedulePtr_() schedulePtr_()
{ {
// Construct per processor compact addressing of the global elements // Construct per processor compact addressing of the global elements
@ -734,7 +782,7 @@ Foam::mapDistributeBase::mapDistributeBase
//// Sort remote elements needed (not really necessary) //// Sort remote elements needed (not really necessary)
//forAll(compactMap, proci) //forAll(compactMap, proci)
//{ //{
// if (proci != Pstream::myProcNo()) // if (proci != myRank)
// { // {
// Map<label>& globalMap = compactMap[proci]; // Map<label>& globalMap = compactMap[proci];
// //
@ -771,26 +819,31 @@ Foam::mapDistributeBase::mapDistributeBase
( (
labelListList&& subMap, labelListList&& subMap,
const bool subHasFlip, const bool subHasFlip,
const bool constructHasFlip const bool constructHasFlip,
const label comm
) )
: :
constructSize_(0), constructSize_(0),
subMap_(std::move(subMap)), subMap_(std::move(subMap)),
subHasFlip_(subHasFlip), subHasFlip_(subHasFlip),
constructHasFlip_(constructHasFlip), constructHasFlip_(constructHasFlip),
comm_(comm),
schedulePtr_() schedulePtr_()
{ {
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
// Send over how many i need to receive. // Send over how many i need to receive.
labelList recvSizes; labelList recvSizes;
Pstream::exchangeSizes(subMap_, recvSizes); Pstream::exchangeSizes(subMap_, recvSizes, comm_);
// Determine order of receiving // Determine order of receiving
labelListList constructMap(Pstream::nProcs()); labelListList constructMap(nProcs);
// My local segments first // My local segments first
label nLocal = recvSizes[Pstream::myProcNo()]; label nLocal = recvSizes[myRank];
{ {
labelList& myMap = constructMap[Pstream::myProcNo()]; labelList& myMap = constructMap[myRank];
myMap.setSize(nLocal); myMap.setSize(nLocal);
forAll(myMap, i) forAll(myMap, i)
{ {
@ -801,7 +854,7 @@ Foam::mapDistributeBase::mapDistributeBase
label segmenti = nLocal; label segmenti = nLocal;
forAll(constructMap, proci) forAll(constructMap, proci)
{ {
if (proci != Pstream::myProcNo()) if (proci != myRank)
{ {
// What i need to receive is what other processor is sending to me. // What i need to receive is what other processor is sending to me.
label nRecv = recvSizes[proci]; label nRecv = recvSizes[proci];
@ -840,6 +893,7 @@ void Foam::mapDistributeBase::transfer(mapDistributeBase& rhs)
constructMap_.transfer(rhs.constructMap_); constructMap_.transfer(rhs.constructMap_);
subHasFlip_ = rhs.subHasFlip_; subHasFlip_ = rhs.subHasFlip_;
constructHasFlip_ = rhs.constructHasFlip_; constructHasFlip_ = rhs.constructHasFlip_;
comm_ = rhs.comm_;
schedulePtr_.clear(); schedulePtr_.clear();
rhs.constructSize_ = 0; rhs.constructSize_ = 0;
@ -872,8 +926,15 @@ Foam::label Foam::mapDistributeBase::renumber
} }
void Foam::mapDistributeBase::compact(const boolList& elemIsUsed, const int tag) void Foam::mapDistributeBase::compact
(
const boolList& elemIsUsed,
const int tag
)
{ {
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
// 1. send back to sender. Have sender delete the corresponding element // 1. send back to sender. Have sender delete the corresponding element
// from the submap and do the same to the constructMap locally // from the submap and do the same to the constructMap locally
// (and in same order). // (and in same order).
@ -886,13 +947,13 @@ void Foam::mapDistributeBase::compact(const boolList& elemIsUsed, const int tag)
// Set up receives from neighbours // Set up receives from neighbours
List<boolList> recvFields(Pstream::nProcs()); List<boolList> recvFields(nProcs);
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm_))
{ {
const labelList& map = subMap_[domain]; const labelList& map = subMap_[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
recvFields[domain].setSize(map.size()); recvFields[domain].setSize(map.size());
IPstream::read IPstream::read
@ -901,19 +962,20 @@ void Foam::mapDistributeBase::compact(const boolList& elemIsUsed, const int tag)
domain, domain,
reinterpret_cast<char*>(recvFields[domain].data()), reinterpret_cast<char*>(recvFields[domain].data()),
recvFields[domain].size()*sizeof(bool), recvFields[domain].size()*sizeof(bool),
tag tag,
comm_
); );
} }
} }
List<boolList> sendFields(Pstream::nProcs()); List<boolList> sendFields(nProcs);
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm_))
{ {
const labelList& map = constructMap_[domain]; const labelList& map = constructMap_[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
boolList& subField = sendFields[domain]; boolList& subField = sendFields[domain];
subField.setSize(map.size()); subField.setSize(map.size());
@ -934,7 +996,8 @@ void Foam::mapDistributeBase::compact(const boolList& elemIsUsed, const int tag)
domain, domain,
reinterpret_cast<const char*>(subField.cdata()), reinterpret_cast<const char*>(subField.cdata()),
subField.size()*sizeof(bool), subField.size()*sizeof(bool),
tag tag,
comm_
); );
} }
} }
@ -944,12 +1007,12 @@ void Foam::mapDistributeBase::compact(const boolList& elemIsUsed, const int tag)
// Set up 'send' to myself - write directly into recvFields // Set up 'send' to myself - write directly into recvFields
{ {
const labelList& map = constructMap_[Pstream::myProcNo()]; const labelList& map = constructMap_[myRank];
recvFields[Pstream::myProcNo()].setSize(map.size()); recvFields[myRank].setSize(map.size());
forAll(map, i) forAll(map, i)
{ {
recvFields[Pstream::myProcNo()][i] = accessAndFlip recvFields[myRank][i] = accessAndFlip
( (
elemIsUsed, elemIsUsed,
map[i], map[i],
@ -966,7 +1029,7 @@ void Foam::mapDistributeBase::compact(const boolList& elemIsUsed, const int tag)
// Compact out all submap entries that are referring to unused elements // Compact out all submap entries that are referring to unused elements
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm_))
{ {
const labelList& map = subMap_[domain]; const labelList& map = subMap_[domain];
@ -995,7 +1058,7 @@ void Foam::mapDistributeBase::compact(const boolList& elemIsUsed, const int tag)
label maxConstructIndex = -1; label maxConstructIndex = -1;
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm_))
{ {
const labelList& map = constructMap_[domain]; const labelList& map = constructMap_[domain];
@ -1041,6 +1104,9 @@ void Foam::mapDistributeBase::compact
const int tag const int tag
) )
{ {
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
// 1. send back to sender. Have sender delete the corresponding element // 1. send back to sender. Have sender delete the corresponding element
// from the submap and do the same to the constructMap locally // from the submap and do the same to the constructMap locally
// (and in same order). // (and in same order).
@ -1053,13 +1119,13 @@ void Foam::mapDistributeBase::compact
// Set up receives from neighbours // Set up receives from neighbours
List<boolList> recvFields(Pstream::nProcs()); List<boolList> recvFields(nProcs);
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm_))
{ {
const labelList& map = subMap_[domain]; const labelList& map = subMap_[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
recvFields[domain].setSize(map.size()); recvFields[domain].setSize(map.size());
IPstream::read IPstream::read
@ -1068,19 +1134,20 @@ void Foam::mapDistributeBase::compact
domain, domain,
reinterpret_cast<char*>(recvFields[domain].data()), reinterpret_cast<char*>(recvFields[domain].data()),
recvFields[domain].size()*sizeof(bool), recvFields[domain].size()*sizeof(bool),
tag tag,
comm_
); );
} }
} }
List<boolList> sendFields(Pstream::nProcs()); List<boolList> sendFields(nProcs);
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm_))
{ {
const labelList& map = constructMap_[domain]; const labelList& map = constructMap_[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
boolList& subField = sendFields[domain]; boolList& subField = sendFields[domain];
subField.setSize(map.size()); subField.setSize(map.size());
@ -1100,7 +1167,8 @@ void Foam::mapDistributeBase::compact
domain, domain,
reinterpret_cast<const char*>(subField.cdata()), reinterpret_cast<const char*>(subField.cdata()),
subField.size()*sizeof(bool), subField.size()*sizeof(bool),
tag tag,
comm_
); );
} }
} }
@ -1110,9 +1178,9 @@ void Foam::mapDistributeBase::compact
// Set up 'send' to myself - write directly into recvFields // Set up 'send' to myself - write directly into recvFields
{ {
const labelList& map = constructMap_[Pstream::myProcNo()]; const labelList& map = constructMap_[myRank];
recvFields[Pstream::myProcNo()].setSize(map.size()); recvFields[myRank].setSize(map.size());
forAll(map, i) forAll(map, i)
{ {
label index = map[i]; label index = map[i];
@ -1120,7 +1188,7 @@ void Foam::mapDistributeBase::compact
{ {
index = mag(index)-1; index = mag(index)-1;
} }
recvFields[Pstream::myProcNo()][i] = elemIsUsed[index]; recvFields[myRank][i] = elemIsUsed[index];
} }
} }
@ -1138,7 +1206,7 @@ void Foam::mapDistributeBase::compact
boolList sendElemIsUsed(localSize, false); boolList sendElemIsUsed(localSize, false);
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm_))
{ {
const labelList& map = subMap_[domain]; const labelList& map = subMap_[domain];
forAll(map, i) forAll(map, i)
@ -1167,7 +1235,7 @@ void Foam::mapDistributeBase::compact
// Compact out all submap entries that are referring to unused elements // Compact out all submap entries that are referring to unused elements
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm_))
{ {
const labelList& map = subMap_[domain]; const labelList& map = subMap_[domain];
@ -1217,7 +1285,7 @@ void Foam::mapDistributeBase::compact
} }
} }
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm_))
{ {
const labelList& map = constructMap_[domain]; const labelList& map = constructMap_[domain];
@ -1268,6 +1336,7 @@ void Foam::mapDistributeBase::operator=(const mapDistributeBase& rhs)
constructMap_ = rhs.constructMap_; constructMap_ = rhs.constructMap_;
subHasFlip_ = rhs.subHasFlip_; subHasFlip_ = rhs.subHasFlip_;
constructHasFlip_ = rhs.constructHasFlip_; constructHasFlip_ = rhs.constructHasFlip_;
comm_ = rhs.comm_;
schedulePtr_.clear(); schedulePtr_.clear();
} }
@ -1289,7 +1358,8 @@ Foam::Istream& Foam::operator>>(Istream& is, mapDistributeBase& map)
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
is >> map.constructSize_ >> map.subMap_ >> map.constructMap_ is >> map.constructSize_ >> map.subMap_ >> map.constructMap_
>> map.subHasFlip_ >> map.constructHasFlip_; >> map.subHasFlip_ >> map.constructHasFlip_
>> map.comm_;
return is; return is;
} }
@ -1303,7 +1373,7 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const mapDistributeBase& map)
<< map.subMap_ << token::NL << map.subMap_ << token::NL
<< map.constructMap_ << token::NL << map.constructMap_ << token::NL
<< map.subHasFlip_ << token::SPACE << map.constructHasFlip_ << map.subHasFlip_ << token::SPACE << map.constructHasFlip_
<< token::NL; << token::SPACE << map.comm_ << token::NL;
return os; return os;
} }

View File

@ -122,6 +122,8 @@ protected:
//- Whether constructMap includes flip or not //- Whether constructMap includes flip or not
bool constructHasFlip_; bool constructHasFlip_;
//- Communicator to use for parallel operations
label comm_;
//- Schedule //- Schedule
mutable autoPtr<List<labelPair>> schedulePtr_; mutable autoPtr<List<labelPair>> schedulePtr_;
@ -199,7 +201,7 @@ public:
// Constructors // Constructors
//- Construct null //- Construct null
mapDistributeBase(); mapDistributeBase(const label comm = UPstream::worldComm);
//- Copy construct //- Copy construct
mapDistributeBase(const mapDistributeBase& map); mapDistributeBase(const mapDistributeBase& map);
@ -214,7 +216,8 @@ public:
labelListList&& subMap, labelListList&& subMap,
labelListList&& constructMap, labelListList&& constructMap,
const bool subHasFlip = false, const bool subHasFlip = false,
const bool constructHasFlip = false const bool constructHasFlip = false,
const label comm = UPstream::worldComm
); );
//- Construct from reverse addressing: per data item the send //- Construct from reverse addressing: per data item the send
@ -223,7 +226,8 @@ public:
mapDistributeBase mapDistributeBase
( (
const labelUList& sendProcs, const labelUList& sendProcs,
const labelUList& recvProcs const labelUList& recvProcs,
const label comm = UPstream::worldComm
); );
//- Construct from list of (possibly) remote elements in globalIndex //- Construct from list of (possibly) remote elements in globalIndex
@ -235,7 +239,8 @@ public:
const globalIndex&, const globalIndex&,
labelList& elements, labelList& elements,
List<Map<label>>& compactMap, List<Map<label>>& compactMap,
const int tag = Pstream::msgType() const int tag = Pstream::msgType(),
const label comm = UPstream::worldComm
); );
//- Special variant that works with the info sorted into bins //- Special variant that works with the info sorted into bins
@ -246,7 +251,8 @@ public:
const globalIndex&, const globalIndex&,
labelListList& cellCells, labelListList& cellCells,
List<Map<label>>& compactMap, List<Map<label>>& compactMap,
const int tag = Pstream::msgType() const int tag = Pstream::msgType(),
const label comm = UPstream::worldComm
); );
//- Construct from my elements to send. Assumes layout is my elements //- Construct from my elements to send. Assumes layout is my elements
@ -256,7 +262,8 @@ public:
( (
labelListList&& subMap, labelListList&& subMap,
const bool subHasFlip = false, const bool subHasFlip = false,
const bool constructHasFlip = false const bool constructHasFlip = false,
const label comm = UPstream::worldComm
); );
//- Construct from Istream //- Construct from Istream
@ -327,12 +334,18 @@ public:
return constructHasFlip_; return constructHasFlip_;
} }
label comm() const
{
return comm_;
}
//- Calculate a schedule. See above. //- Calculate a schedule. See above.
static List<labelPair> schedule static List<labelPair> schedule
( (
const labelListList& subMap, const labelListList& subMap,
const labelListList& constructMap, const labelListList& constructMap,
const int tag const int tag,
const label comm = UPstream::worldComm
); );
//- Return a schedule. Demand driven. See above. //- Return a schedule. Demand driven. See above.
@ -389,7 +402,8 @@ public:
const bool constructHasFlip, const bool constructHasFlip,
List<T>&, List<T>&,
const negateOp& negOp, const negateOp& negOp,
const int tag = UPstream::msgType() const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
); );
//- Distribute data. If multiple processors writing to same //- Distribute data. If multiple processors writing to same
@ -405,10 +419,11 @@ public:
const labelListList& constructMap, const labelListList& constructMap,
const bool constructHasFlip, const bool constructHasFlip,
List<T>&, List<T>&,
const T& nullValue,
const CombineOp& cop, const CombineOp& cop,
const negateOp& negOp, const negateOp& negOp,
const T& nullValue, const int tag = UPstream::msgType(),
const int tag = UPstream::msgType() const label comm = UPstream::worldComm
); );
//- Distribute data using default commsType. //- Distribute data using default commsType.

View File

@ -129,14 +129,18 @@ void Foam::mapDistributeBase::distribute
const bool constructHasFlip, const bool constructHasFlip,
List<T>& field, List<T>& field,
const negateOp& negOp, const negateOp& negOp,
const int tag const int tag,
const label comm
) )
{ {
const label myRank = Pstream::myProcNo(comm);
const label nProcs = Pstream::nProcs(comm);
if (!Pstream::parRun()) if (!Pstream::parRun())
{ {
// Do only me to me. // Do only me to me.
const labelList& mySubMap = subMap[Pstream::myProcNo()]; const labelList& mySubMap = subMap[myRank];
List<T> subField(mySubMap.size()); List<T> subField(mySubMap.size());
forAll(mySubMap, i) forAll(mySubMap, i)
@ -145,7 +149,7 @@ void Foam::mapDistributeBase::distribute
} }
// Receive sub field from myself (subField) // Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()]; const labelList& map = constructMap[myRank];
field.setSize(constructSize); field.setSize(constructSize);
@ -168,13 +172,20 @@ void Foam::mapDistributeBase::distribute
// received data. // received data.
// Send sub field to neighbour // Send sub field to neighbour
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm))
{ {
const labelList& map = subMap[domain]; const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
OPstream toNbr(Pstream::commsTypes::blocking, domain, 0, tag); OPstream toNbr
(
Pstream::commsTypes::blocking,
domain,
0,
tag,
comm
);
List<T> subField(map.size()); List<T> subField(map.size());
forAll(subField, i) forAll(subField, i)
@ -192,7 +203,7 @@ void Foam::mapDistributeBase::distribute
} }
// Subset myself // Subset myself
const labelList& mySubMap = subMap[Pstream::myProcNo()]; const labelList& mySubMap = subMap[myRank];
List<T> subField(mySubMap.size()); List<T> subField(mySubMap.size());
forAll(mySubMap, i) forAll(mySubMap, i)
@ -201,7 +212,7 @@ void Foam::mapDistributeBase::distribute
} }
// Receive sub field from myself (subField) // Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()]; const labelList& map = constructMap[myRank];
field.setSize(constructSize); field.setSize(constructSize);
@ -216,13 +227,20 @@ void Foam::mapDistributeBase::distribute
); );
// Receive sub field from neighbour // Receive sub field from neighbour
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm))
{ {
const labelList& map = constructMap[domain]; const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
IPstream fromNbr(Pstream::commsTypes::blocking, domain, 0, tag); IPstream fromNbr
(
Pstream::commsTypes::blocking,
domain,
0,
tag,
comm
);
List<T> subField(fromNbr); List<T> subField(fromNbr);
checkReceivedSize(domain, map.size(), subField.size()); checkReceivedSize(domain, map.size(), subField.size());
@ -248,7 +266,7 @@ void Foam::mapDistributeBase::distribute
// Receive sub field from myself // Receive sub field from myself
{ {
const labelList& mySubMap = subMap[Pstream::myProcNo()]; const labelList& mySubMap = subMap[myRank];
List<T> subField(mySubMap.size()); List<T> subField(mySubMap.size());
forAll(subField, i) forAll(subField, i)
@ -265,7 +283,7 @@ void Foam::mapDistributeBase::distribute
// Receive sub field from myself (subField) // Receive sub field from myself (subField)
flipAndCombine flipAndCombine
( (
constructMap[Pstream::myProcNo()], constructMap[myRank],
constructHasFlip, constructHasFlip,
subField, subField,
eqOp<T>(), eqOp<T>(),
@ -284,7 +302,7 @@ void Foam::mapDistributeBase::distribute
label sendProc = twoProcs[0]; label sendProc = twoProcs[0];
label recvProc = twoProcs[1]; label recvProc = twoProcs[1];
if (Pstream::myProcNo() == sendProc) if (myRank == sendProc)
{ {
// I am send first, receive next // I am send first, receive next
{ {
@ -293,7 +311,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled, Pstream::commsTypes::scheduled,
recvProc, recvProc,
0, 0,
tag tag,
comm
); );
const labelList& map = subMap[recvProc]; const labelList& map = subMap[recvProc];
@ -316,7 +335,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled, Pstream::commsTypes::scheduled,
recvProc, recvProc,
0, 0,
tag tag,
comm
); );
List<T> subField(fromNbr); List<T> subField(fromNbr);
@ -344,7 +364,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled, Pstream::commsTypes::scheduled,
sendProc, sendProc,
0, 0,
tag tag,
comm
); );
List<T> subField(fromNbr); List<T> subField(fromNbr);
@ -368,7 +389,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled, Pstream::commsTypes::scheduled,
sendProc, sendProc,
0, 0,
tag tag,
comm
); );
const labelList& map = subMap[sendProc]; const labelList& map = subMap[sendProc];
@ -395,14 +417,14 @@ void Foam::mapDistributeBase::distribute
if (!is_contiguous<T>::value) if (!is_contiguous<T>::value)
{ {
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking, tag); PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking, tag, comm);
// Stream data into buffer // Stream data into buffer
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm))
{ {
const labelList& map = subMap[domain]; const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
// Put data into send buffer // Put data into send buffer
UOPstream toDomain(domain, pBufs); UOPstream toDomain(domain, pBufs);
@ -427,7 +449,7 @@ void Foam::mapDistributeBase::distribute
{ {
// Set up 'send' to myself // Set up 'send' to myself
const labelList& mySub = subMap[Pstream::myProcNo()]; const labelList& mySub = subMap[myRank];
List<T> mySubField(mySub.size()); List<T> mySubField(mySub.size());
forAll(mySub, i) forAll(mySub, i)
{ {
@ -443,7 +465,7 @@ void Foam::mapDistributeBase::distribute
field.setSize(constructSize); field.setSize(constructSize);
// Receive sub field from myself // Receive sub field from myself
{ {
const labelList& map = constructMap[Pstream::myProcNo()]; const labelList& map = constructMap[myRank];
flipAndCombine flipAndCombine
( (
@ -461,11 +483,11 @@ void Foam::mapDistributeBase::distribute
Pstream::waitRequests(nOutstanding); Pstream::waitRequests(nOutstanding);
// Consume // Consume
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm))
{ {
const labelList& map = constructMap[domain]; const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
UIPstream str(domain, pBufs); UIPstream str(domain, pBufs);
List<T> recvField(str); List<T> recvField(str);
@ -488,13 +510,13 @@ void Foam::mapDistributeBase::distribute
{ {
// Set up sends to neighbours // Set up sends to neighbours
List<List<T>> sendFields(Pstream::nProcs()); List<List<T>> sendFields(nProcs);
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm))
{ {
const labelList& map = subMap[domain]; const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
List<T>& subField = sendFields[domain]; List<T>& subField = sendFields[domain];
subField.setSize(map.size()); subField.setSize(map.size());
@ -515,20 +537,21 @@ void Foam::mapDistributeBase::distribute
domain, domain,
reinterpret_cast<const char*>(subField.cdata()), reinterpret_cast<const char*>(subField.cdata()),
subField.byteSize(), subField.byteSize(),
tag tag,
comm
); );
} }
} }
// Set up receives from neighbours // Set up receives from neighbours
List<List<T>> recvFields(Pstream::nProcs()); List<List<T>> recvFields(nProcs);
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm))
{ {
const labelList& map = constructMap[domain]; const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
recvFields[domain].setSize(map.size()); recvFields[domain].setSize(map.size());
IPstream::read IPstream::read
@ -537,7 +560,8 @@ void Foam::mapDistributeBase::distribute
domain, domain,
reinterpret_cast<char*>(recvFields[domain].data()), reinterpret_cast<char*>(recvFields[domain].data()),
recvFields[domain].byteSize(), recvFields[domain].byteSize(),
tag tag,
comm
); );
} }
} }
@ -546,9 +570,9 @@ void Foam::mapDistributeBase::distribute
// Set up 'send' to myself // Set up 'send' to myself
{ {
const labelList& map = subMap[Pstream::myProcNo()]; const labelList& map = subMap[myRank];
List<T>& subField = sendFields[Pstream::myProcNo()]; List<T>& subField = sendFields[myRank];
subField.setSize(map.size()); subField.setSize(map.size());
forAll(map, i) forAll(map, i)
{ {
@ -568,10 +592,10 @@ void Foam::mapDistributeBase::distribute
field.setSize(constructSize); field.setSize(constructSize);
// Receive sub field from myself (sendFields[Pstream::myProcNo()]) // Receive sub field from myself (sendFields[myRank])
{ {
const labelList& map = constructMap[Pstream::myProcNo()]; const labelList& map = constructMap[myRank];
const List<T>& subField = sendFields[Pstream::myProcNo()]; const List<T>& subField = sendFields[myRank];
flipAndCombine flipAndCombine
( (
@ -592,11 +616,11 @@ void Foam::mapDistributeBase::distribute
// Collect neighbour fields // Collect neighbour fields
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm))
{ {
const labelList& map = constructMap[domain]; const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
const List<T>& subField = recvFields[domain]; const List<T>& subField = recvFields[domain];
@ -636,17 +660,21 @@ void Foam::mapDistributeBase::distribute
const labelListList& constructMap, const labelListList& constructMap,
const bool constructHasFlip, const bool constructHasFlip,
List<T>& field, List<T>& field,
const T& nullValue,
const CombineOp& cop, const CombineOp& cop,
const negateOp& negOp, const negateOp& negOp,
const T& nullValue, const int tag,
const int tag const label comm
) )
{ {
const label myRank = Pstream::myProcNo(comm);
const label nProcs = Pstream::nProcs(comm);
if (!Pstream::parRun()) if (!Pstream::parRun())
{ {
// Do only me to me. // Do only me to me.
const labelList& mySubMap = subMap[Pstream::myProcNo()]; const labelList& mySubMap = subMap[myRank];
List<T> subField(mySubMap.size()); List<T> subField(mySubMap.size());
forAll(mySubMap, i) forAll(mySubMap, i)
@ -655,7 +683,7 @@ void Foam::mapDistributeBase::distribute
} }
// Receive sub field from myself (subField) // Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()]; const labelList& map = constructMap[myRank];
field.setSize(constructSize); field.setSize(constructSize);
field = nullValue; field = nullValue;
@ -671,13 +699,20 @@ void Foam::mapDistributeBase::distribute
// received data. // received data.
// Send sub field to neighbour // Send sub field to neighbour
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm))
{ {
const labelList& map = subMap[domain]; const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
OPstream toNbr(Pstream::commsTypes::blocking, domain, 0, tag); OPstream toNbr
(
Pstream::commsTypes::blocking,
domain,
0,
tag,
comm
);
List<T> subField(map.size()); List<T> subField(map.size());
forAll(subField, i) forAll(subField, i)
{ {
@ -694,7 +729,7 @@ void Foam::mapDistributeBase::distribute
} }
// Subset myself // Subset myself
const labelList& mySubMap = subMap[Pstream::myProcNo()]; const labelList& mySubMap = subMap[myRank];
List<T> subField(mySubMap.size()); List<T> subField(mySubMap.size());
forAll(mySubMap, i) forAll(mySubMap, i)
@ -703,7 +738,7 @@ void Foam::mapDistributeBase::distribute
} }
// Receive sub field from myself (subField) // Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()]; const labelList& map = constructMap[myRank];
field.setSize(constructSize); field.setSize(constructSize);
field = nullValue; field = nullValue;
@ -711,13 +746,20 @@ void Foam::mapDistributeBase::distribute
flipAndCombine(map, constructHasFlip, subField, cop, negOp, field); flipAndCombine(map, constructHasFlip, subField, cop, negOp, field);
// Receive sub field from neighbour // Receive sub field from neighbour
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm))
{ {
const labelList& map = constructMap[domain]; const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
IPstream fromNbr(Pstream::commsTypes::blocking, domain, 0, tag); IPstream fromNbr
(
Pstream::commsTypes::blocking,
domain,
0,
tag,
comm
);
List<T> subField(fromNbr); List<T> subField(fromNbr);
checkReceivedSize(domain, map.size(), subField.size()); checkReceivedSize(domain, map.size(), subField.size());
@ -742,7 +784,7 @@ void Foam::mapDistributeBase::distribute
List<T> newField(constructSize, nullValue); List<T> newField(constructSize, nullValue);
{ {
const labelList& mySubMap = subMap[Pstream::myProcNo()]; const labelList& mySubMap = subMap[myRank];
// Subset myself // Subset myself
List<T> subField(mySubMap.size()); List<T> subField(mySubMap.size());
@ -758,7 +800,7 @@ void Foam::mapDistributeBase::distribute
} }
// Receive sub field from myself (subField) // Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()]; const labelList& map = constructMap[myRank];
flipAndCombine flipAndCombine
( (
@ -782,7 +824,7 @@ void Foam::mapDistributeBase::distribute
label sendProc = twoProcs[0]; label sendProc = twoProcs[0];
label recvProc = twoProcs[1]; label recvProc = twoProcs[1];
if (Pstream::myProcNo() == sendProc) if (myRank == sendProc)
{ {
// I am send first, receive next // I am send first, receive next
{ {
@ -791,7 +833,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled, Pstream::commsTypes::scheduled,
recvProc, recvProc,
0, 0,
tag tag,
comm
); );
const labelList& map = subMap[recvProc]; const labelList& map = subMap[recvProc];
@ -815,7 +858,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled, Pstream::commsTypes::scheduled,
recvProc, recvProc,
0, 0,
tag tag,
comm
); );
List<T> subField(fromNbr); List<T> subField(fromNbr);
const labelList& map = constructMap[recvProc]; const labelList& map = constructMap[recvProc];
@ -842,7 +886,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled, Pstream::commsTypes::scheduled,
sendProc, sendProc,
0, 0,
tag tag,
comm
); );
List<T> subField(fromNbr); List<T> subField(fromNbr);
const labelList& map = constructMap[sendProc]; const labelList& map = constructMap[sendProc];
@ -865,7 +910,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled, Pstream::commsTypes::scheduled,
sendProc, sendProc,
0, 0,
tag tag,
comm
); );
const labelList& map = subMap[sendProc]; const labelList& map = subMap[sendProc];
@ -893,14 +939,14 @@ void Foam::mapDistributeBase::distribute
if (!is_contiguous<T>::value) if (!is_contiguous<T>::value)
{ {
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking, tag); PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking, tag, comm);
// Stream data into buffer // Stream data into buffer
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm))
{ {
const labelList& map = subMap[domain]; const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
// Put data into send buffer // Put data into send buffer
UOPstream toDomain(domain, pBufs); UOPstream toDomain(domain, pBufs);
@ -925,7 +971,7 @@ void Foam::mapDistributeBase::distribute
{ {
// Set up 'send' to myself // Set up 'send' to myself
const labelList& myMap = subMap[Pstream::myProcNo()]; const labelList& myMap = subMap[myRank];
List<T> mySubField(myMap.size()); List<T> mySubField(myMap.size());
forAll(myMap, i) forAll(myMap, i)
@ -944,7 +990,7 @@ void Foam::mapDistributeBase::distribute
field = nullValue; field = nullValue;
// Receive sub field from myself // Receive sub field from myself
{ {
const labelList& map = constructMap[Pstream::myProcNo()]; const labelList& map = constructMap[myRank];
flipAndCombine flipAndCombine
( (
@ -962,11 +1008,11 @@ void Foam::mapDistributeBase::distribute
Pstream::waitRequests(nOutstanding); Pstream::waitRequests(nOutstanding);
// Consume // Consume
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm))
{ {
const labelList& map = constructMap[domain]; const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
UIPstream str(domain, pBufs); UIPstream str(domain, pBufs);
List<T> recvField(str); List<T> recvField(str);
@ -989,13 +1035,13 @@ void Foam::mapDistributeBase::distribute
{ {
// Set up sends to neighbours // Set up sends to neighbours
List<List<T>> sendFields(Pstream::nProcs()); List<List<T>> sendFields(nProcs);
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm))
{ {
const labelList& map = subMap[domain]; const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
List<T>& subField = sendFields[domain]; List<T>& subField = sendFields[domain];
subField.setSize(map.size()); subField.setSize(map.size());
@ -1016,20 +1062,21 @@ void Foam::mapDistributeBase::distribute
domain, domain,
reinterpret_cast<const char*>(subField.cdata()), reinterpret_cast<const char*>(subField.cdata()),
subField.size()*sizeof(T), subField.size()*sizeof(T),
tag tag,
comm
); );
} }
} }
// Set up receives from neighbours // Set up receives from neighbours
List<List<T>> recvFields(Pstream::nProcs()); List<List<T>> recvFields(nProcs);
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm))
{ {
const labelList& map = constructMap[domain]; const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
recvFields[domain].setSize(map.size()); recvFields[domain].setSize(map.size());
UIPstream::read UIPstream::read
@ -1038,7 +1085,8 @@ void Foam::mapDistributeBase::distribute
domain, domain,
reinterpret_cast<char*>(recvFields[domain].data()), reinterpret_cast<char*>(recvFields[domain].data()),
recvFields[domain].size()*sizeof(T), recvFields[domain].size()*sizeof(T),
tag tag,
comm
); );
} }
} }
@ -1046,9 +1094,9 @@ void Foam::mapDistributeBase::distribute
// Set up 'send' to myself // Set up 'send' to myself
{ {
const labelList& map = subMap[Pstream::myProcNo()]; const labelList& map = subMap[myRank];
List<T>& subField = sendFields[Pstream::myProcNo()]; List<T>& subField = sendFields[myRank];
subField.setSize(map.size()); subField.setSize(map.size());
forAll(map, i) forAll(map, i)
{ {
@ -1070,8 +1118,8 @@ void Foam::mapDistributeBase::distribute
// Receive sub field from myself (subField) // Receive sub field from myself (subField)
{ {
const labelList& map = constructMap[Pstream::myProcNo()]; const labelList& map = constructMap[myRank];
const List<T>& subField = sendFields[Pstream::myProcNo()]; const List<T>& subField = sendFields[myRank];
flipAndCombine flipAndCombine
( (
@ -1092,11 +1140,11 @@ void Foam::mapDistributeBase::distribute
// Collect neighbour fields // Collect neighbour fields
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm))
{ {
const labelList& map = constructMap[domain]; const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size()) if (domain != myRank && map.size())
{ {
const List<T>& subField = recvFields[domain]; const List<T>& subField = recvFields[domain];
@ -1129,7 +1177,7 @@ void Foam::mapDistributeBase::send(PstreamBuffers& pBufs, const List<T>& field)
const const
{ {
// Stream data into buffer // Stream data into buffer
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm_))
{ {
const labelList& map = subMap_[domain]; const labelList& map = subMap_[domain];
@ -1165,7 +1213,7 @@ const
// Consume // Consume
field.setSize(constructSize_); field.setSize(constructSize_);
for (const int domain : Pstream::allProcs()) for (const int domain : Pstream::allProcs(comm_))
{ {
const labelList& map = constructMap_[domain]; const labelList& map = constructMap_[domain];
@ -1219,7 +1267,8 @@ void Foam::mapDistributeBase::distribute
constructHasFlip_, constructHasFlip_,
fld, fld,
negOp, negOp,
tag tag,
comm_
); );
} }
else if (Pstream::defaultCommsType == Pstream::commsTypes::scheduled) else if (Pstream::defaultCommsType == Pstream::commsTypes::scheduled)
@ -1235,7 +1284,8 @@ void Foam::mapDistributeBase::distribute
constructHasFlip_, constructHasFlip_,
fld, fld,
negOp, negOp,
tag tag,
comm_
); );
} }
else else
@ -1251,7 +1301,8 @@ void Foam::mapDistributeBase::distribute
constructHasFlip_, constructHasFlip_,
fld, fld,
negOp, negOp,
tag tag,
comm_
); );
} }
} }
@ -1309,7 +1360,8 @@ void Foam::mapDistributeBase::reverseDistribute
subHasFlip_, subHasFlip_,
fld, fld,
flipOp(), flipOp(),
tag tag,
comm_
); );
} }
else if (Pstream::defaultCommsType == Pstream::commsTypes::scheduled) else if (Pstream::defaultCommsType == Pstream::commsTypes::scheduled)
@ -1325,7 +1377,8 @@ void Foam::mapDistributeBase::reverseDistribute
subHasFlip_, subHasFlip_,
fld, fld,
flipOp(), flipOp(),
tag tag,
comm_
); );
} }
else else
@ -1341,7 +1394,8 @@ void Foam::mapDistributeBase::reverseDistribute
subHasFlip_, subHasFlip_,
fld, fld,
flipOp(), flipOp(),
tag tag,
comm_
); );
} }
} }
@ -1371,10 +1425,11 @@ void Foam::mapDistributeBase::reverseDistribute
subMap_, subMap_,
subHasFlip_, subHasFlip_,
fld, fld,
nullValue,
eqOp<T>(), eqOp<T>(),
flipOp(), flipOp(),
nullValue, tag,
tag comm_
); );
} }
else if (Pstream::defaultCommsType == Pstream::commsTypes::scheduled) else if (Pstream::defaultCommsType == Pstream::commsTypes::scheduled)
@ -1389,10 +1444,11 @@ void Foam::mapDistributeBase::reverseDistribute
subMap_, subMap_,
subHasFlip_, subHasFlip_,
fld, fld,
nullValue,
eqOp<T>(), eqOp<T>(),
flipOp(), flipOp(),
nullValue, tag,
tag comm_
); );
} }
else else
@ -1407,10 +1463,11 @@ void Foam::mapDistributeBase::reverseDistribute
subMap_, subMap_,
subHasFlip_, subHasFlip_,
fld, fld,
nullValue,
eqOp<T>(), eqOp<T>(),
flipOp(), flipOp(),
nullValue, tag,
tag comm_
); );
} }
} }

View File

@ -245,16 +245,46 @@ bool Foam::UPstream::init(int& argc, char**& argv, const bool needsThread)
ourMpi = true; ourMpi = true;
} }
// Check argument list for local world
label worldIndex = -1;
word world;
for (int argi = 1; argi < argc; ++argi)
{
if (strcmp(argv[argi], "-world") == 0)
{
worldIndex = argi++;
if (argi >= argc)
{
FatalErrorInFunction
<< "Missing world name to argument \"world\""
<< Foam::abort(FatalError);
}
world = argv[argi];
break;
}
}
// Filter 'world' option
if (worldIndex != -1)
{
for (label i = worldIndex+2; i < argc; i++)
{
argv[i-2] = argv[i];
}
argc -= 2;
}
MPI_Comm_size(MPI_COMM_WORLD, &numprocs); MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myRank); MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
if (debug) if (debug)
{ {
Pout<< "UPstream::init : procs=" << numprocs Pout<< "UPstream::init : procs:" << numprocs
<< " rank:" << myRank << endl; << " rank:" << myRank
<< " world:" << world << endl;
} }
if (numprocs <= 1) if (worldIndex == -1 && numprocs <= 1)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "attempt to run parallel on 1 processor" << "attempt to run parallel on 1 processor"
@ -264,6 +294,85 @@ bool Foam::UPstream::init(int& argc, char**& argv, const bool needsThread)
// Initialise parallel structure // Initialise parallel structure
setParRun(numprocs, provided_thread_support == MPI_THREAD_MULTIPLE); setParRun(numprocs, provided_thread_support == MPI_THREAD_MULTIPLE);
if (worldIndex != -1)
{
wordList worlds(numprocs);
worlds[Pstream::myProcNo()] = world;
Pstream::gatherList(worlds);
Pstream::scatterList(worlds);
// Compact
if (Pstream::master())
{
DynamicList<word> allWorlds(numprocs);
for (const auto& world : worlds)
{
if (!allWorlds.found(world))
{
allWorlds.append(world);
}
}
allWorlds_ = std::move(allWorlds);
worldIDs_.setSize(numprocs);
forAll(worlds, proci)
{
const word& world = worlds[proci];
worldIDs_[proci] = allWorlds_.find(world);
}
}
Pstream::scatter(allWorlds_);
Pstream::scatter(worldIDs_);
DynamicList<label> subRanks;
forAll(worlds, proci)
{
if (worlds[proci] == worlds[Pstream::myProcNo()])
{
subRanks.append(proci);
}
}
// Allocate new communicator 1 with parent 0 (= mpi_world)
const label subComm = allocateCommunicator(0, subRanks, true);
// Override worldComm
UPstream::worldComm = subComm;
// For testing: warn use of non-worldComm
UPstream::warnComm = UPstream::worldComm;
if (debug)
{
// Check
int subNProcs, subRank;
MPI_Comm_size
(
PstreamGlobals::MPICommunicators_[subComm],
&subNProcs
);
MPI_Comm_rank
(
PstreamGlobals::MPICommunicators_[subComm],
&subRank
);
Pout<< "UPstream::init : in world:" << world
<< " using local communicator:" << subComm
<< " with procs:" << subNProcs
<< " and rank:" << subRank
<< endl;
}
// Override Pout prefix (move to setParRun?)
Pout.prefix() = '[' + world + '/' + name(myProcNo(subComm)) + "] ";
Perr.prefix() = '[' + world + '/' + name(myProcNo(subComm)) + "] ";
}
else
{
// All processors use world 0
worldIDs_.setSize(numprocs, 0);
}
attachOurBuffers(); attachOurBuffers();
return true; return true;
@ -357,6 +466,7 @@ void Foam::UPstream::shutdown(int errNo)
} }
else else
{ {
// Abort only locally or world?
MPI_Abort(MPI_COMM_WORLD, errNo); MPI_Abort(MPI_COMM_WORLD, errNo);
} }
} }
@ -443,7 +553,7 @@ void Foam::sumReduce
{ {
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm) if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
{ {
Pout<< "** reducing:" << Value << " with comm:" << communicator Pout<< "** sumReduce:" << Value << " with comm:" << communicator
<< " warnComm:" << UPstream::warnComm << " warnComm:" << UPstream::warnComm
<< endl; << endl;
error::printStack(Pout); error::printStack(Pout);
@ -623,7 +733,18 @@ void Foam::UPstream::allToAll
const label communicator const label communicator
) )
{ {
label np = nProcs(communicator); const label np = nProcs(communicator);
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
{
Pout<< "** allToAll :"
<< " np:" << np
<< " sendData:" << sendData.size()
<< " with comm:" << communicator
<< " warnComm:" << UPstream::warnComm
<< endl;
error::printStack(Pout);
}
if (sendData.size() != np || recvData.size() != np) if (sendData.size() != np || recvData.size() != np)
{ {
@ -683,7 +804,18 @@ void Foam::UPstream::allToAll
const label communicator const label communicator
) )
{ {
label np = nProcs(communicator); const label np = nProcs(communicator);
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
{
Pout<< "** allToAll :"
<< " sendSizes:" << sendSizes
<< " sendOffsets:" << sendOffsets
<< " with comm:" << communicator
<< " warnComm:" << UPstream::warnComm
<< endl;
error::printStack(Pout);
}
if if
( (
@ -757,7 +889,19 @@ void Foam::UPstream::gather
const label communicator const label communicator
) )
{ {
label np = nProcs(communicator); const label np = nProcs(communicator);
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
{
Pout<< "** allToAll :"
<< " np:" << np
<< " recvSizes:" << recvSizes
<< " recvOffsets:" << recvOffsets
<< " with comm:" << communicator
<< " warnComm:" << UPstream::warnComm
<< endl;
error::printStack(Pout);
}
if if
( (
@ -823,7 +967,19 @@ void Foam::UPstream::scatter
const label communicator const label communicator
) )
{ {
label np = nProcs(communicator); const label np = nProcs(communicator);
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
{
Pout<< "** allToAll :"
<< " np:" << np
<< " sendSizes:" << sendSizes
<< " sendOffsets:" << sendOffsets
<< " with comm:" << communicator
<< " warnComm:" << UPstream::warnComm
<< endl;
error::printStack(Pout);
}
if if
( (
@ -976,7 +1132,7 @@ void Foam::UPstream::allocatePstreamCommunicator
void Foam::UPstream::freePstreamCommunicator(const label communicator) void Foam::UPstream::freePstreamCommunicator(const label communicator)
{ {
if (communicator != UPstream::worldComm) if (communicator != 0)
{ {
if (PstreamGlobals::MPICommunicators_[communicator] != MPI_COMM_NULL) if (PstreamGlobals::MPICommunicators_[communicator] != MPI_COMM_NULL)
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd. Copyright (C) 2019-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -57,6 +57,11 @@ turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
"undefined-K", "undefined-K",
"undefined-alpha" "undefined-alpha"
), ),
mappedPatchFieldBase<scalar>
(
mappedPatchFieldBase<scalar>::mapper(p, iF),
*this
),
TnbrName_("undefined-Tnbr"), TnbrName_("undefined-Tnbr"),
thicknessLayers_(0), thicknessLayers_(0),
kappaLayers_(0), kappaLayers_(0),
@ -79,6 +84,12 @@ turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
: :
mixedFvPatchScalarField(ptf, p, iF, mapper), mixedFvPatchScalarField(ptf, p, iF, mapper),
temperatureCoupledBase(patch(), ptf), temperatureCoupledBase(patch(), ptf),
mappedPatchFieldBase<scalar>
(
mappedPatchFieldBase<scalar>::mapper(p, iF),
*this,
ptf
),
TnbrName_(ptf.TnbrName_), TnbrName_(ptf.TnbrName_),
thicknessLayers_(ptf.thicknessLayers_), thicknessLayers_(ptf.thicknessLayers_),
kappaLayers_(ptf.kappaLayers_), kappaLayers_(ptf.kappaLayers_),
@ -96,21 +107,17 @@ turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
: :
mixedFvPatchScalarField(p, iF), mixedFvPatchScalarField(p, iF),
temperatureCoupledBase(patch(), dict), temperatureCoupledBase(patch(), dict),
mappedPatchFieldBase<scalar>
(
mappedPatchFieldBase<scalar>::mapper(p, iF),
*this,
dict
),
TnbrName_(dict.get<word>("Tnbr")), TnbrName_(dict.get<word>("Tnbr")),
thicknessLayers_(0), thicknessLayers_(0),
kappaLayers_(0), kappaLayers_(0),
contactRes_(0.0) contactRes_(0.0)
{ {
if (!isA<mappedPatchBase>(this->patch().patch()))
{
FatalErrorInFunction
<< "' not type '" << mappedPatchBase::typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << internalField().name()
<< " in file " << internalField().objectPath()
<< exit(FatalError);
}
if (dict.readIfPresent("thicknessLayers", thicknessLayers_)) if (dict.readIfPresent("thicknessLayers", thicknessLayers_))
{ {
dict.readEntry("kappaLayers", kappaLayers_); dict.readEntry("kappaLayers", kappaLayers_);
@ -142,6 +149,18 @@ turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
refGrad() = 0.0; refGrad() = 0.0;
valueFraction() = 1.0; valueFraction() = 1.0;
} }
// Store patch value as initial guess when running in database mode
mappedPatchFieldBase<scalar>::initRetrieveField
(
this->internalField().name(),
*this
);
mappedPatchFieldBase<scalar>::initRetrieveField
(
this->internalField().name() + "_weights",
this->patch().deltaCoeffs()
);
} }
@ -154,6 +173,33 @@ turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
: :
mixedFvPatchScalarField(wtcsf, iF), mixedFvPatchScalarField(wtcsf, iF),
temperatureCoupledBase(patch(), wtcsf), temperatureCoupledBase(patch(), wtcsf),
mappedPatchFieldBase<scalar>
(
mappedPatchFieldBase<scalar>::mapper(patch(), iF),
*this,
wtcsf
),
TnbrName_(wtcsf.TnbrName_),
thicknessLayers_(wtcsf.thicknessLayers_),
kappaLayers_(wtcsf.kappaLayers_),
contactRes_(wtcsf.contactRes_)
{}
turbulentTemperatureCoupledBaffleMixedFvPatchScalarField::
turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
(
const turbulentTemperatureCoupledBaffleMixedFvPatchScalarField& wtcsf
)
:
mixedFvPatchScalarField(wtcsf),
temperatureCoupledBase(patch(), wtcsf),
mappedPatchFieldBase<scalar>
(
mappedPatchFieldBase<scalar>::mapper(patch(), wtcsf.internalField()),
*this,
wtcsf
),
TnbrName_(wtcsf.TnbrName_), TnbrName_(wtcsf.TnbrName_),
thicknessLayers_(wtcsf.thicknessLayers_), thicknessLayers_(wtcsf.thicknessLayers_),
kappaLayers_(wtcsf.kappaLayers_), kappaLayers_(wtcsf.kappaLayers_),
@ -172,51 +218,89 @@ void turbulentTemperatureCoupledBaffleMixedFvPatchScalarField::updateCoeffs()
// Since we're inside initEvaluate/evaluate there might be processor // Since we're inside initEvaluate/evaluate there might be processor
// comms underway. Change the tag we use. // comms underway. Change the tag we use.
int oldTag = UPstream::msgType(); const int oldTag = UPstream::msgType();
UPstream::msgType() = oldTag+1; UPstream::msgType() = oldTag+1;
// Get the coupling information from the mappedPatchBase // Get the coupling information from the mappedPatchBase
const mappedPatchBase& mpp = const mappedPatchBase& mpp =
refCast<const mappedPatchBase>(patch().patch()); mappedPatchFieldBase<scalar>::mapper
const polyMesh& nbrMesh = mpp.sampleMesh();
const label samplePatchi = mpp.samplePolyPatch().index();
const fvPatch& nbrPatch =
refCast<const fvMesh>(nbrMesh).boundary()[samplePatchi];
// Calculate the temperature by harmonic averaging
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const turbulentTemperatureCoupledBaffleMixedFvPatchScalarField& nbrField =
refCast
<
const turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
>
(
nbrPatch.lookupPatchField<volScalarField, scalar>
( (
TnbrName_ patch(),
) this->internalField()
); );
// Swap to obtain full local values of neighbour internal field const tmp<scalarField> myKDelta = kappa(*this)*patch().deltaCoeffs();
tmp<scalarField> nbrIntFld(new scalarField(nbrField.size(), Zero)); tmp<scalarField> nbrIntFld;
tmp<scalarField> nbrKDelta(new scalarField(nbrField.size(), Zero)); tmp<scalarField> nbrKDelta;
if (contactRes_ == 0.0) //Pout<< "updateCoeffs() : mpp.sameWorld():" << mpp.sameWorld() << endl;
if (mpp.sameWorld())
{ {
nbrIntFld.ref() = nbrField.patchInternalField(); // Same world so lookup
nbrKDelta.ref() = nbrField.kappa(nbrField)*nbrPatch.deltaCoeffs(); const auto& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
const label nbrPatchID = mpp.samplePolyPatch().index();
const auto& nbrPatch = nbrMesh.boundary()[nbrPatchID];
const turbulentTemperatureCoupledBaffleMixedFvPatchScalarField&
nbrField =
refCast
<
const turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
>
(
nbrPatch.lookupPatchField<volScalarField, scalar>
(
TnbrName_
)
);
if (contactRes_ == 0.0)
{
// Get neighbour internal data in local order. Does all
// comms/reordering already
nbrIntFld = this->mappedInternalField();
// Calculate neighbour weighting (in neighbouring ordering)
nbrKDelta = nbrField.kappa(nbrField)*nbrPatch.deltaCoeffs();
}
else
{
// Get neighbour patch values
nbrIntFld = new scalarField(nbrField);
// Comms/reorder to local
distribute(this->internalField().name(), nbrIntFld.ref());
// Constant neighbour weighting. Reorder/comms below
nbrKDelta = new scalarField(nbrField.size(), contactRes_);
}
} }
else else
{ {
nbrIntFld.ref() = nbrField; // Different world so use my region,patch. Distribution below will
nbrKDelta.ref() = contactRes_; // do the reordering
if (contactRes_ == 0.0)
{
nbrIntFld = this->mappedInternalField();
nbrKDelta = new scalarField(myKDelta());
}
else
{
nbrIntFld = *this;
nbrKDelta = new scalarField(this->size(), contactRes_);
}
} }
mpp.distribute(nbrIntFld.ref());
mpp.distribute(nbrKDelta.ref());
tmp<scalarField> myKDelta = kappa(*this)*patch().deltaCoeffs(); //Pout<< "updateCoeffs() : nbrIntFld:" << flatOutput(nbrIntFld()) << endl;
//Pout<< "updateCoeffs() : nbrKDelta BEFORE:" << flatOutput(nbrKDelta())
// << endl;
distribute(this->internalField().name() + "_weights", nbrKDelta.ref());
//Pout<< "updateCoeffs() : nbrKDelta AFTER:" << flatOutput(nbrKDelta())
// << endl;
//Pout<< "updateCoeffs() : myKDelta:" << flatOutput(myKDelta())
// << endl;
// Both sides agree on // Both sides agree on
@ -247,8 +331,8 @@ void turbulentTemperatureCoupledBaffleMixedFvPatchScalarField::updateCoeffs()
Info<< patch().boundaryMesh().mesh().name() << ':' Info<< patch().boundaryMesh().mesh().name() << ':'
<< patch().name() << ':' << patch().name() << ':'
<< this->internalField().name() << " <- " << this->internalField().name() << " <- "
<< nbrMesh.name() << ':' << mpp.sampleRegion() << ':'
<< nbrPatch.name() << ':' << mpp.samplePatch() << ':'
<< this->internalField().name() << " :" << this->internalField().name() << " :"
<< " heat transfer rate:" << Q << " heat transfer rate:" << Q
<< " walltemperature " << " walltemperature "
@ -274,6 +358,7 @@ void turbulentTemperatureCoupledBaffleMixedFvPatchScalarField::write
kappaLayers_.writeEntry("kappaLayers", os); kappaLayers_.writeEntry("kappaLayers", os);
temperatureCoupledBase::write(os); temperatureCoupledBase::write(os);
mappedPatchFieldBase<scalar>::write(os);
} }

View File

@ -82,6 +82,7 @@ SourceFiles
#include "mixedFvPatchFields.H" #include "mixedFvPatchFields.H"
#include "temperatureCoupledBase.H" #include "temperatureCoupledBase.H"
#include "mappedPatchFieldBase.H"
#include "scalarField.H" #include "scalarField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -98,7 +99,8 @@ namespace compressible
class turbulentTemperatureCoupledBaffleMixedFvPatchScalarField class turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
: :
public mixedFvPatchScalarField, public mixedFvPatchScalarField,
public temperatureCoupledBase public temperatureCoupledBase,
public mappedPatchFieldBase<scalar>
{ {
// Private data // Private data
@ -149,6 +151,12 @@ public:
const fvPatchFieldMapper& const fvPatchFieldMapper&
); );
//- Construct as copy setting internal field reference
turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
(
const turbulentTemperatureCoupledBaffleMixedFvPatchScalarField&
);
//- Construct and return a clone //- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const virtual tmp<fvPatchScalarField> clone() const
{ {

View File

@ -228,8 +228,9 @@ $(derivedFvPatchFields)/plenumPressure/plenumPressureFvPatchScalarField.C
$(derivedFvPatchFields)/interfaceCompression/interfaceCompressionFvPatchScalarField.C $(derivedFvPatchFields)/interfaceCompression/interfaceCompressionFvPatchScalarField.C
$(derivedFvPatchFields)/swirlFanVelocity/swirlFanVelocityFvPatchField.C $(derivedFvPatchFields)/swirlFanVelocity/swirlFanVelocityFvPatchField.C
$(derivedFvPatchFields)/mappedMixed/mappedMixedFvPatchFields.C
$(derivedFvPatchFields)/mappedField/Sampled/makeSampledPatchFunction1s.C $(derivedFvPatchFields)/mappedField/Sampled/makeSampledPatchFunction1s.C
$(derivedFvPatchFields)/mappedField/mappedMixedFieldFvPatchField/mappedMixedFieldFvPatchFields.C
fvsPatchFields = fields/fvsPatchFields fvsPatchFields = fields/fvsPatchFields
$(fvsPatchFields)/fvsPatchField/fvsPatchFields.C $(fvsPatchFields)/fvsPatchField/fvsPatchFields.C

View File

@ -54,7 +54,7 @@ Foam::mappedFieldFvPatchField<Type>::mappedFieldFvPatchField
: :
fixedValueFvPatchField<Type>(p, iF, dict), fixedValueFvPatchField<Type>(p, iF, dict),
mappedPatchBase(p.patch(), dict), mappedPatchBase(p.patch(), dict),
mappedPatchFieldBase<Type>(*this, *this, dict) mappedPatchFieldBase<Type>(*this, *this, dict, *this)
{} {}

View File

@ -0,0 +1,233 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2020 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "mappedMixedFieldFvPatchField.H"
#include "volFields.H"
#include "interpolationCell.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::mappedMixedFieldFvPatchField<Type>::mappedMixedFieldFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
mixedFvPatchField<Type>(p, iF),
mappedPatchBase(p.patch()),
mappedPatchFieldBase<Type>(*this, *this),
weightFieldName_(word::null)
{
this->refValue() = Zero;
this->refGrad() = Zero;
this->valueFraction() = 0.0;
}
template<class Type>
Foam::mappedMixedFieldFvPatchField<Type>::mappedMixedFieldFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
mixedFvPatchField<Type>(p, iF, dict),
mappedPatchBase(p.patch(), dict),
mappedPatchFieldBase<Type>(*this, *this, dict),
weightFieldName_(dict.getOrDefault<word>("weightField", word::null))
{
mixedFvPatchField<Type>::operator=
(
Field<Type>("value", dict, p.size())
);
if (dict.found("refValue"))
{
// Full restart
this->refValue() = Field<Type>("refValue", dict, p.size());
this->refGrad() = Field<Type>("refGradient", dict, p.size());
this->valueFraction() = scalarField("valueFraction", dict, p.size());
}
else
{
// Start from user entered data. Assume fixedValue.
this->refValue() = *this;
this->refGrad() = Zero;
this->valueFraction() = 1.0;
}
// Store patch value as initial guess when running in database mode
mappedPatchFieldBase<Type>::initRetrieveField
(
this->internalField().name(),
*this
);
mappedPatchFieldBase<Type>::initRetrieveField
(
this->internalField().name() + "_weights",
this->patch().deltaCoeffs()
);
}
template<class Type>
Foam::mappedMixedFieldFvPatchField<Type>::mappedMixedFieldFvPatchField
(
const mappedMixedFieldFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
mixedFvPatchField<Type>(ptf, p, iF, mapper),
mappedPatchBase(p.patch(), ptf),
mappedPatchFieldBase<Type>(*this, *this, ptf),
weightFieldName_(ptf.weightFieldName_)
{}
template<class Type>
Foam::mappedMixedFieldFvPatchField<Type>::mappedMixedFieldFvPatchField
(
const mappedMixedFieldFvPatchField<Type>& ptf
)
:
mixedFvPatchField<Type>(ptf),
mappedPatchBase(ptf.patch().patch(), ptf),
mappedPatchFieldBase<Type>(ptf),
weightFieldName_(ptf.weightFieldName_)
{}
template<class Type>
Foam::mappedMixedFieldFvPatchField<Type>::mappedMixedFieldFvPatchField
(
const mappedMixedFieldFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
mixedFvPatchField<Type>(ptf, iF),
mappedPatchBase(ptf.patch().patch(), ptf),
mappedPatchFieldBase<Type>(*this, *this, ptf),
weightFieldName_(ptf.weightFieldName_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::mappedMixedFieldFvPatchField<Type>::autoMap
(
const fvPatchFieldMapper& m
)
{
mixedFvPatchField<Type>::autoMap(m);
mappedPatchBase::clearOut();
}
template<class Type>
void Foam::mappedMixedFieldFvPatchField<Type>::rmap
(
const fvPatchField<Type>& ptf,
const labelList& addr
)
{
mixedFvPatchField<Type>::rmap(ptf, addr);
mappedPatchBase::clearOut();
}
template<class Type>
void Foam::mappedMixedFieldFvPatchField<Type>::updateCoeffs()
{
if (this->updated())
{
return;
}
const tmp<Field<Type>> nbrIntFld(this->mappedInternalField());
//- Unweighted
//const tmp<scalarField> nbrKDelta(this->mappedWeightField());
//- Weighted
tmp<scalarField> myKDelta;
tmp<scalarField> nbrKDelta;
this->mappedWeightField(weightFieldName_, myKDelta, nbrKDelta);
// Both sides agree on
// - temperature : (myKDelta*fld + nbrKDelta*nbrFld)/(myKDelta+nbrKDelta)
// - gradient : (temperature-fld)*delta
// We've got a degree of freedom in how to implement this in a mixed bc.
// (what gradient, what fixedValue and mixing coefficient)
// Two reasonable choices:
// 1. specify above temperature on one side (preferentially the high side)
// and above gradient on the other. So this will switch between pure
// fixedvalue and pure fixedgradient
// 2. specify gradient and temperature such that the equations are the
// same on both sides. This leads to the choice of
// - refGradient = zero gradient
// - refValue = neighbour value
// - mixFraction = nbrKDelta / (nbrKDelta + myKDelta())
this->refValue() = nbrIntFld;
this->refGrad() = Zero;
this->valueFraction() = nbrKDelta()/(nbrKDelta() + myKDelta());
mixedFvPatchField<Type>::updateCoeffs();
if (debug)
{
Info<< this->patch().boundaryMesh().mesh().name() << ':'
<< this->patch().name() << ':'
<< this->internalField().name() << " <- "
<< this->mapper_.sampleRegion() << ':'
<< this->mapper_.samplePatch() << ':'
<< this->fieldName_ << " :"
<< " value "
<< " min:" << gMin(*this)
<< " max:" << gMax(*this)
<< " avg:" << gAverage(*this)
<< endl;
}
}
template<class Type>
void Foam::mappedMixedFieldFvPatchField<Type>::write(Ostream& os) const
{
mappedPatchBase::write(os);
mappedPatchFieldBase<Type>::write(os);
os.writeEntryIfDifferent<word>("weightField", word::null, weightFieldName_);
mixedFvPatchField<Type>::write(os);
}
// ************************************************************************* //

View File

@ -0,0 +1,234 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2020 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 <http://www.gnu.org/licenses/>.
Class
Foam::mappedMixedFieldFvPatchField
Group
grpGenericBoundaryConditions grpCoupledBoundaryConditions
Description
This boundary condition provides a self-contained version of e.g. mapped
boundary conditions
- it expects two-way coupling (so the sampled field needs to run the
same bc)
- it does not use information on the patch; instead it holds the coupling
data locally.
Usage
\table
Property | Description | Required | Default
field | Name of field to be mapped | no | this field name
weightField | Name of field to use as weight | no |
setAverage | Use average value | no | false |
average | Average value to use if \c setAverage = yes | partly |
\endtable
Example of the boundary condition specification:
\verbatim
<patchName>
{
type mappedMixedField;
field T; // optional field name
setAverage no; // apply an average value
average 0; // average to apply if setAverage
value uniform 0; // place holder
}
\endverbatim
Note
Supports multi-world operation:
+----+ +----+
| | | |
| | | |
+----+ +----+
worldA worldB
regionA regionB
patchA patchB
See also
Foam::mappedPatchBase
Foam::mappedPolyPatch
Foam::mappedFvPatch
Foam::mappedFieldFvPatchField
Foam::mixedFvPatchField
SourceFiles
mappedMixedFieldFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef mappedMixedFieldFvPatchField_H
#define mappedMixedFieldFvPatchField_H
#include "mappedPatchBase.H"
#include "mappedPatchFieldBase.H"
#include "mixedFvPatchFields.H"
#include "interpolation.H"
#include "volFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class mappedMixedFieldFvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class mappedMixedFieldFvPatchField
:
public mixedFvPatchField<Type>,
public mappedPatchBase,
public mappedPatchFieldBase<Type>
{
//- Name of weight field to sample
word weightFieldName_;
public:
//- Runtime type information
TypeName("mappedMixedField");
// Constructors
//- Construct from patch and internal field
mappedMixedFieldFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
mappedMixedFieldFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// mappedMixedFieldFvPatchField
// onto a new patch
mappedMixedFieldFvPatchField
(
const mappedMixedFieldFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
mappedMixedFieldFvPatchField
(
const mappedMixedFieldFvPatchField<Type>&
);
//- Construct and return a clone
virtual tmp<fvPatchField<Type>> clone() const
{
return tmp<fvPatchField<Type>>
(
new mappedMixedFieldFvPatchField<Type>
(
*this
)
);
}
//- Construct as copy setting internal field reference
mappedMixedFieldFvPatchField
(
const mappedMixedFieldFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type>> clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type>>
(
new mappedMixedFieldFvPatchField<Type>
(
*this,
iF
)
);
}
// Member functions
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap
(
const fvPatchFieldMapper&
);
//- Reverse map the given fvPatchField onto this fvPatchField
virtual void rmap
(
const fvPatchField<Type>&,
const labelList&
);
// Evaluation functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "mappedMixedFieldFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,44 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "mappedMixedFieldFvPatchFields.H"
#include "volMesh.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
//makeTemplatePatchTypeField(scalar, mappedMixedField);
makePatchFields(mappedMixedField);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef mappedMixedFieldFvPatchFields_H
#define mappedMixedFieldFvPatchFields_H
#include "mappedMixedFieldFvPatchField.H"
#include "fieldTypes.H"
#include "fvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//makePatchTypeFieldTypedef(scalar, mappedMixedField);
makePatchTypeFieldTypedefs(mappedMixedField)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -48,6 +48,174 @@ Type Foam::mappedPatchFieldBase<Type>::getAverage
} }
template<class Type>
template<class T>
void Foam::mappedPatchFieldBase<Type>::storeField
(
const objectRegistry& obr,
const word& region,
const word& patch,
const labelListList& procToMap,
const word& fieldName,
const Field<T>& fld
) const
{
// Store my data onto database
//const label myRank = Pstream::myProcNo(0); // comm_
const label nProcs = Pstream::nProcs(0); // comm_
for (label domain = 0; domain < nProcs; domain++)
{
const labelList& map = procToMap[domain];
if (map.size())
{
const Field<T> subFld(fld, map);
const objectRegistry& subObr = mappedPatchBase::subRegistry
(
obr,
mapper_.sendPath(domain)
/ region
/ patch
);
if (fvPatchField<Type>::debug)
{
Pout<< "*** STORING :"
<< " field:" << fieldName
<< " values:" << flatOutput(subFld)
<< " as:" << subObr.objectPath() << endl;
}
mappedPatchBase::storeField
(
const_cast<objectRegistry&>(subObr),
fieldName,
subFld
);
}
}
}
template<class Type>
template<class T>
void Foam::mappedPatchFieldBase<Type>::retrieveField
(
const bool allowUnset,
const objectRegistry& obr,
const word& region,
const word& patch,
const labelListList& procToMap,
const word& fieldName,
Field<T>& fld
) const
{
// Store my data onto database
//const label myRank = Pstream::myProcNo(0); // comm_
const label nProcs = Pstream::nProcs(0); // comm_
for (label domain = 0; domain < nProcs; domain++)
{
const labelList& map = procToMap[domain];
if (map.size())
{
const objectRegistry& subObr = mappedPatchBase::subRegistry
(
obr,
mapper_.receivePath(domain)
/ region
/ patch
);
//const IOField<T>& subFld = subObr.lookupObject<IOField<T>>
//(
// fieldName
//);
const IOField<T>* subFldPtr = subObr.getObjectPtr<IOField<T>>
(
fieldName
);
if (subFldPtr)
{
UIndirectList<T>(fld, map) = *subFldPtr;
if (fvPatchField<Type>::debug)
{
Pout<< "*** RETRIEVED :"
<< " field:" << fieldName
<< " values:" << flatOutput(fld)
<< " from:" << subObr.objectPath() << endl;
}
}
else if (allowUnset)
{
WarningInFunction << "Not found"
<< " field:" << fieldName
<< " in:" << subObr.objectPath() << endl;
}
else
{
// Not found. Make it fail
(void)subObr.lookupObject<IOField<T>>(fieldName);
}
}
}
}
template<class Type>
template<class T>
void Foam::mappedPatchFieldBase<Type>::initRetrieveField
(
const objectRegistry& obr,
const word& region,
const word& patch,
const mapDistribute& map,
const word& fieldName,
const Field<T>& fld
) const
{
// Store my data onto database
//const label myRank = Pstream::myProcNo(0); // comm_
const label nProcs = Pstream::nProcs(0); // comm_
for (label domain = 0; domain < nProcs; domain++)
{
const labelList& constructMap = map.constructMap()[domain];
if (constructMap.size())
{
const objectRegistry& subObr = mappedPatchBase::subRegistry
(
obr,
mapper_.receivePath(domain)
/ region
/ patch
);
const Field<T> receiveFld(fld, constructMap);
if (fvPatchField<Type>::debug)
{
Pout<< "*** STORING INITIAL :"
<< " field:" << fieldName << " values:"
<< flatOutput(receiveFld)
<< " from:" << flatOutput(fld)
<< " constructMap:" << flatOutput(constructMap)
<< " as:" << subObr.objectPath() << endl;
}
mappedPatchBase::storeField
(
const_cast<objectRegistry&>(subObr),
fieldName,
receiveFld
);
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type> template<class Type>
@ -92,10 +260,60 @@ Foam::mappedPatchFieldBase<Type>::mappedPatchFieldBase
average_(getAverage(dict, setAverage_)), average_(getAverage(dict, setAverage_)),
interpolationScheme_(interpolationCell<Type>::typeName) interpolationScheme_(interpolationCell<Type>::typeName)
{ {
if
(
mapper_.sampleDatabase()
&& mapper_.mode() != mappedPatchBase::NEARESTPATCHFACE
)
{
FatalErrorInFunction
<< "Mapping using the database only supported for "
<< "sampleMode "
<< mappedPatchBase::sampleModeNames_
[
mappedPatchBase::NEARESTPATCHFACE
]
<< exit(FatalError);
}
if (mapper_.mode() == mappedPatchBase::NEARESTCELL) if (mapper_.mode() == mappedPatchBase::NEARESTCELL)
{ {
dict.readEntry("interpolationScheme", interpolationScheme_); dict.readEntry("interpolationScheme", interpolationScheme_);
} }
// Note: in database mode derived boundary conditions need to initialise
// fields
}
template<class Type>
Foam::mappedPatchFieldBase<Type>::mappedPatchFieldBase
(
const mappedPatchBase& mapper,
const fvPatchField<Type>& patchField,
const dictionary& dict,
const Field<Type>& fld
)
:
mappedPatchFieldBase<Type>::mappedPatchFieldBase(mapper, patchField, dict)
{
if
(
mapper_.mode() == mappedPatchBase::NEARESTPATCHFACE
&& mapper_.sampleDatabase()
)
{
// Store my data on receive buffers so we have some initial data
initRetrieveField
(
patchField_.internalField().time(),
patchField_.patch().boundaryMesh().mesh().name(),
patchField_.patch().name(),
mapper_.map(),
patchField_.internalField().name(),
patchField_
);
}
} }
@ -150,14 +368,15 @@ Foam::mappedPatchFieldBase<Type>::mappedPatchFieldBase
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type> template<class Type>
const Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>& template<class Type2>
Foam::mappedPatchFieldBase<Type>::sampleField() const const Foam::GeometricField<Type2, Foam::fvPatchField, Foam::volMesh>&
Foam::mappedPatchFieldBase<Type>::sampleField(const word& fieldName) const
{ {
typedef GeometricField<Type, fvPatchField, volMesh> fieldType; typedef GeometricField<Type2, fvPatchField, volMesh> fieldType;
if (mapper_.sameRegion()) if (mapper_.sameRegion())
{ {
if (fieldName_ == patchField_.internalField().name()) if (fieldName == patchField_.internalField().name())
{ {
// Optimisation: bypass field lookup // Optimisation: bypass field lookup
return return
@ -169,18 +388,70 @@ Foam::mappedPatchFieldBase<Type>::sampleField() const
else else
{ {
const fvMesh& thisMesh = patchField_.patch().boundaryMesh().mesh(); const fvMesh& thisMesh = patchField_.patch().boundaryMesh().mesh();
return thisMesh.template lookupObject<fieldType>(fieldName_); return thisMesh.template lookupObject<fieldType>(fieldName);
} }
} }
const fvMesh& nbrMesh = refCast<const fvMesh>(mapper_.sampleMesh()); const fvMesh& nbrMesh = refCast<const fvMesh>(mapper_.sampleMesh());
return nbrMesh.template lookupObject<fieldType>(fieldName_); return nbrMesh.template lookupObject<fieldType>(fieldName);
} }
template<class Type> template<class Type>
const Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>&
Foam::mappedPatchFieldBase<Type>::sampleField() const
{
return sampleField<Type>(fieldName_);
}
template<class Type>
template<class T>
void Foam::mappedPatchFieldBase<Type>::distribute
(
const word& fieldName,
Field<T>& newValues
) const
{
if (mapper_.sampleDatabase())
{
// Store my data on send buffers
storeField
(
patchField_.internalField().time(),
patchField_.patch().boundaryMesh().mesh().name(),
patchField_.patch().name(),
mapper_.map().subMap(),
fieldName,
newValues
);
// Construct my data from receive buffers
newValues.setSize(mapper_.map().constructSize());
retrieveField
(
true, // allow unset
patchField_.internalField().time(),
mapper_.sampleRegion(),
mapper_.samplePatch(),
mapper_.map().constructMap(),
fieldName,
newValues
);
}
else
{
mapper_.distribute(newValues);
}
}
template<class Type>
//template<class T>
Foam::tmp<Foam::Field<Type>> Foam::tmp<Foam::Field<Type>>
Foam::mappedPatchFieldBase<Type>::mappedField() const Foam::mappedPatchFieldBase<Type>::mappedField
(
// const GeometricField<T, fvPatchField, volMesh>& fld
) const
{ {
typedef GeometricField<Type, fvPatchField, volMesh> fieldType; typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
@ -190,7 +461,6 @@ Foam::mappedPatchFieldBase<Type>::mappedField() const
UPstream::msgType() = oldTag + 1; UPstream::msgType() = oldTag + 1;
const fvMesh& thisMesh = patchField_.patch().boundaryMesh().mesh(); const fvMesh& thisMesh = patchField_.patch().boundaryMesh().mesh();
const fvMesh& nbrMesh = refCast<const fvMesh>(mapper_.sampleMesh());
// Result of obtaining remote values // Result of obtaining remote values
auto tnewValues = tmp<Field<Type>>::New(); auto tnewValues = tmp<Field<Type>>::New();
@ -200,12 +470,25 @@ Foam::mappedPatchFieldBase<Type>::mappedField() const
{ {
case mappedPatchBase::NEARESTCELL: case mappedPatchBase::NEARESTCELL:
{ {
const fieldType& fld = sampleField();
const mapDistribute& distMap = mapper_.map(); const mapDistribute& distMap = mapper_.map();
if (interpolationScheme_ != interpolationCell<Type>::typeName) if (interpolationScheme_ != interpolationCell<Type>::typeName)
{ {
if (!mapper_.sameWorld() || mapper_.sampleDatabase())
{
FatalErrorInFunction
<< "Interpolating cell values from different world"
<< " or database currently not supported"
<< exit(FatalError);
}
const fvMesh& nbrMesh =
refCast<const fvMesh>(mapper_.sampleMesh());
// Send back sample points to the processor that holds the cell // Send back sample points to the processor that holds the cell
vectorField samples(mapper_.samplePoints()); vectorField samples(mapper_.samplePoints());
distMap.reverseDistribute distMap.reverseDistribute
( (
( (
@ -221,7 +504,7 @@ Foam::mappedPatchFieldBase<Type>::mappedField() const
interpolation<Type>::New interpolation<Type>::New
( (
interpolationScheme_, interpolationScheme_,
sampleField() fld
); );
const auto& interp = *interpolator; const auto& interp = *interpolator;
@ -241,52 +524,94 @@ Foam::mappedPatchFieldBase<Type>::mappedField() const
} }
else else
{ {
newValues = sampleField(); newValues = fld;
} }
distMap.distribute(newValues); distribute(fieldName_, newValues);
break; break;
} }
case mappedPatchBase::NEARESTPATCHFACE: case mappedPatchBase::NEARESTPATCHFACE:
case mappedPatchBase::NEARESTPATCHFACEAMI: case mappedPatchBase::NEARESTPATCHFACEAMI:
{ {
const label nbrPatchID = if (mapper_.sameWorld())
nbrMesh.boundaryMesh().findPatchID(mapper_.samplePatch());
if (nbrPatchID < 0)
{ {
FatalErrorInFunction const fvMesh& nbrMesh =
<< "Unable to find sample patch " << mapper_.samplePatch() refCast<const fvMesh>(mapper_.sampleMesh());
<< " in region " << mapper_.sampleRegion() const fieldType& fld = sampleField();
<< " for patch " << patchField_.patch().name() << nl
<< abort(FatalError); const label nbrPatchID =
nbrMesh.boundaryMesh().findPatchID(mapper_.samplePatch());
if (nbrPatchID < 0)
{
FatalErrorInFunction
<< "Unable to find sample patch " << mapper_.samplePatch()
<< " in region " << mapper_.sampleRegion()
<< " for patch " << patchField_.patch().name() << nl
<< abort(FatalError);
}
const auto& nbrField = fld;
newValues = nbrField.boundaryField()[nbrPatchID];
} }
else
const fieldType& nbrField = sampleField(); {
// Start off from my patch values, let distribute function below
newValues = nbrField.boundaryField()[nbrPatchID]; // do all the work
mapper_.distribute(newValues); newValues = patchField_;
}
distribute(fieldName_, newValues);
break; break;
} }
case mappedPatchBase::NEARESTFACE: case mappedPatchBase::NEARESTFACE:
{ {
Field<Type> allValues(nbrMesh.nFaces(), Zero); Field<Type> allValues;
if (mapper_.sameWorld())
const fieldType& nbrField = sampleField();
for (const fvPatchField<Type>& pf : nbrField.boundaryField())
{ {
label faceStart = pf.patch().start(); const fvMesh& nbrMesh =
refCast<const fvMesh>(mapper_.sampleMesh());
const fieldType& fld = sampleField();
forAll(pf, facei) allValues.setSize(nbrMesh.nFaces(), Zero);
const auto& nbrField = fld;
for (const fvPatchField<Type>& pf : nbrField.boundaryField())
{ {
allValues[faceStart++] = pf[facei]; label faceStart = pf.patch().start();
forAll(pf, facei)
{
allValues[faceStart++] = pf[facei];
}
}
}
else
{
// Start off from my patch values. Let distribute function below
// do all the work
allValues.setSize(thisMesh.nFaces(), Zero);
const fieldType& thisFld = dynamic_cast<const fieldType&>
(
patchField_.internalField()
);
for (const fvPatchField<Type>& pf : thisFld.boundaryField())
{
label faceStart = pf.patch().start();
forAll(pf, facei)
{
allValues[faceStart++] = pf[facei];
}
} }
} }
mapper_.distribute(allValues); distribute(fieldName_, allValues);
newValues.transfer(allValues); newValues.transfer(allValues);
break; break;
@ -322,6 +647,197 @@ Foam::mappedPatchFieldBase<Type>::mappedField() const
} }
//template<class Type>
//Foam::tmp<Foam::Field<Type>>
//Foam::mappedPatchFieldBase<Type>::mappedField() const
//{
// const GeometricField<Type, fvPatchField, volMesh>& fld = sampleField();
// return mappedField<Type>(fld);
//}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::mappedPatchFieldBase<Type>::mappedInternalField() const
{
// Swap to obtain full local values of neighbour internal field
tmp<Field<Type>> tnbrIntFld(new Field<Type>());
Field<Type>& nbrIntFld = tnbrIntFld.ref();
if (mapper_.sameWorld())
{
// Same world so lookup
const label nbrPatchID = mapper_.samplePolyPatch().index();
const auto& nbrField = this->sampleField();
nbrIntFld = nbrField.boundaryField()[nbrPatchID].patchInternalField();
}
else
{
// Different world so use my region,patch. Distribution below will
// do the reordering
nbrIntFld = patchField_.patchInternalField();
}
// Since we're inside initEvaluate/evaluate there might be processor
// comms underway. Change the tag we use.
int oldTag = UPstream::msgType();
UPstream::msgType() = oldTag+1;
distribute(fieldName_, nbrIntFld);
// Restore tag
UPstream::msgType() = oldTag;
return tnbrIntFld;
}
template<class Type>
Foam::tmp<Foam::scalarField>
Foam::mappedPatchFieldBase<Type>::mappedWeightField() const
{
// Swap to obtain full local values of neighbour internal field
tmp<scalarField> tnbrKDelta(new scalarField());
scalarField& nbrKDelta = tnbrKDelta.ref();
if (mapper_.sameWorld())
{
// Same world so lookup
const auto& nbrMesh = refCast<const fvMesh>(this->mapper_.sampleMesh());
const label nbrPatchID = mapper_.samplePolyPatch().index();
const auto& nbrPatch = nbrMesh.boundary()[nbrPatchID];
nbrKDelta = nbrPatch.deltaCoeffs();
}
else
{
// Different world so use my region,patch. Distribution below will
// do the reordering
nbrKDelta = patchField_.patch().deltaCoeffs();
}
// Since we're inside initEvaluate/evaluate there might be processor
// comms underway. Change the tag we use.
const int oldTag = UPstream::msgType();
UPstream::msgType() = oldTag+1;
distribute(fieldName_ + "_deltaCoeffs", nbrKDelta);
// Restore tag
UPstream::msgType() = oldTag;
return tnbrKDelta;
}
template<class Type>
void Foam::mappedPatchFieldBase<Type>::mappedWeightField
(
const word& fieldName,
tmp<scalarField>& thisWeights,
tmp<scalarField>& nbrWeights
) const
{
thisWeights = new scalarField(patchField_.patch().deltaCoeffs());
if (!fieldName.empty())
{
thisWeights.ref() *=
patchField_.patch().template lookupPatchField
<
volScalarField,
scalar
>
(
fieldName
).patchInternalField();
}
// Swap to obtain full local values of neighbour internal field
if (mapper_.sameWorld())
{
// Same world so lookup
const auto& nbrMesh = refCast<const fvMesh>(mapper_.sampleMesh());
const label nbrPatchID = mapper_.samplePolyPatch().index();
const auto& nbrPatch = nbrMesh.boundary()[nbrPatchID];
nbrWeights = new scalarField(nbrPatch.deltaCoeffs());
if (!fieldName.empty())
{
// Weightfield is volScalarField
const auto& nbrWeightField =
nbrMesh.template lookupObject<volScalarField>(fieldName);
nbrWeights.ref() *=
nbrWeightField.boundaryField()[nbrPatchID].patchInternalField();
}
}
else
{
// Different world so use my region,patch. Distribution below will
// do the reordering
nbrWeights = new scalarField(thisWeights());
}
// Since we're inside initEvaluate/evaluate there might be processor
// comms underway. Change the tag we use.
int oldTag = UPstream::msgType();
UPstream::msgType() = oldTag+1;
distribute(fieldName_ + "_weights", nbrWeights.ref());
// Restore tag
UPstream::msgType() = oldTag;
}
template<class Type>
const Foam::mappedPatchBase& Foam::mappedPatchFieldBase<Type>::mapper
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
{
if (!isA<mappedPatchBase>(p.patch()))
{
FatalErrorInFunction
<< "Incorrect patch type " << p.patch().type()
<< " for patch " << p.patch().name()
<< " of field " << iF.name()
<< " in file " << iF.objectPath() << nl
<< "Type should be a mappedPatch"
<< exit(FatalError);
}
return refCast<const mappedPatchBase>(p.patch());
}
template<class Type>
template<class T>
void Foam::mappedPatchFieldBase<Type>::initRetrieveField
(
const word& fieldName,
const Field<T>& fld
) const
{
if (mapper_.sampleDatabase())
{
// Store my data on receive buffers (reverse of storeField;
// i.e. retrieveField will obtain patchField)
initRetrieveField
(
patchField_.internalField().time(),
mapper_.sampleRegion(),
mapper_.samplePatch(),
mapper_.map(),
fieldName,
fld
);
}
}
template<class Type> template<class Type>
void Foam::mappedPatchFieldBase<Type>::write(Ostream& os) const void Foam::mappedPatchFieldBase<Type>::write(Ostream& os) const
{ {
@ -333,7 +849,10 @@ void Foam::mappedPatchFieldBase<Type>::write(Ostream& os) const
os.writeEntry("average", average_); os.writeEntry("average", average_);
} }
os.writeEntry("interpolationScheme", interpolationScheme_); if (mapper_.mode() == mappedPatchBase::NEARESTCELL)
{
os.writeEntry("interpolationScheme", interpolationScheme_);
}
} }

View File

@ -67,6 +67,7 @@ namespace Foam
// Forward declarations // Forward declarations
class mappedPatchBase; class mappedPatchBase;
template<class> class interpolation; template<class> class interpolation;
class mapDistribute;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class mappedPatchFieldBase Declaration Class mappedPatchFieldBase Declaration
@ -80,6 +81,7 @@ class mappedPatchFieldBase
//- Selective retrieval of "average" entry from the dictionary //- Selective retrieval of "average" entry from the dictionary
static Type getAverage(const dictionary& dict, bool mandatory); static Type getAverage(const dictionary& dict, bool mandatory);
protected: protected:
// Protected data // Protected data
@ -104,6 +106,21 @@ protected:
word interpolationScheme_; word interpolationScheme_;
// Protected Member Functions
//- Construct field from registered elements
template<class T>
void initRetrieveField
(
const objectRegistry& obr,
const word& region,
const word& patch,
const mapDistribute& map,
const word& fieldName,
const Field<T>& fld
) const;
public: public:
// Constructors // Constructors
@ -127,6 +144,16 @@ public:
const dictionary& dict const dictionary& dict
); );
//- Construct from dictionary and initial field value
// (for when running in database mode)
mappedPatchFieldBase
(
const mappedPatchBase& mapper,
const fvPatchField<Type>& patchField,
const dictionary& dict,
const Field<Type>& fld
);
//- Construct empty //- Construct empty
mappedPatchFieldBase mappedPatchFieldBase
( (
@ -135,7 +162,7 @@ public:
); );
//- Construct copy //- Construct copy
mappedPatchFieldBase explicit mappedPatchFieldBase
( (
const mappedPatchFieldBase<Type>& mapper const mappedPatchFieldBase<Type>& mapper
); );
@ -155,14 +182,84 @@ public:
// Member Functions // Member Functions
//- Field to sample. Either on my or nbr mesh
template<class T>
const GeometricField<T, fvPatchField, volMesh>& sampleField
(
const word& fieldName
) const;
//- Field to sample. Either on my or nbr mesh //- Field to sample. Either on my or nbr mesh
const GeometricField<Type, fvPatchField, volMesh>& sampleField() const; const GeometricField<Type, fvPatchField, volMesh>& sampleField() const;
//- Map sampleField onto *this patch //- Map sampleField onto *this patch
virtual tmp<Field<Type>> mappedField() const; virtual tmp<Field<Type>> mappedField() const;
//- Map internal of sampleField onto *this patch
virtual tmp<Field<Type>> mappedInternalField() const;
//- Map optional weightField onto *this patch. Default is deltaCoeffs
virtual tmp<scalarField> mappedWeightField() const;
//- Map optional weightField (given by name) onto *this patch
virtual void mappedWeightField
(
const word& weightFieldName,
tmp<scalarField>& thisWeights,
tmp<scalarField>& nbrWeights
) const;
//- Write //- Write
virtual void write(Ostream& os) const; virtual void write(Ostream& os) const;
// Helpers
//- Check that patch is of correct type
static const mappedPatchBase& mapper
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
);
//- Initialise field to retrieve (used e.g. when value read from
// dictionary)
template<class T>
void initRetrieveField
(
const word& fieldName,
const Field<T>& fld
) const;
//- Store elements of field onto (sub) registry
template<class T>
void storeField
(
const objectRegistry& obr,
const word& region,
const word& patch,
const labelListList& procToMap,
const word& fieldName,
const Field<T>& fld
) const;
//- Construct field from registered elements
template<class T>
void retrieveField
(
const bool allowUnset,
const objectRegistry& obr,
const word& region,
const word& patch,
const labelListList& procToMap,
const word& fieldName,
Field<T>& fld
) const;
//- Wrapper for mapDistribute::distribute that knows about
//- dabase mapping
template<class T>
void distribute(const word& fieldName, Field<T>& newValues) const;
}; };

View File

@ -38,7 +38,7 @@ Foam::mappedFixedValueFvPatchField<Type>::mappedFixedValueFvPatchField
) )
: :
fixedValueFvPatchField<Type>(p, iF), fixedValueFvPatchField<Type>(p, iF),
mappedPatchFieldBase<Type>(this->mapper(p, iF), *this) mappedPatchFieldBase<Type>(mappedPatchFieldBase<Type>::mapper(p, iF), *this)
{} {}
@ -51,7 +51,13 @@ Foam::mappedFixedValueFvPatchField<Type>::mappedFixedValueFvPatchField
) )
: :
fixedValueFvPatchField<Type>(p, iF, dict), fixedValueFvPatchField<Type>(p, iF, dict),
mappedPatchFieldBase<Type>(this->mapper(p, iF), *this, dict) mappedPatchFieldBase<Type>
(
mappedPatchFieldBase<Type>::mapper(p, iF),
*this,
dict,
*this // initial value for database operation
)
{} {}
@ -65,7 +71,12 @@ Foam::mappedFixedValueFvPatchField<Type>::mappedFixedValueFvPatchField
) )
: :
fixedValueFvPatchField<Type>(ptf, p, iF, mapper), fixedValueFvPatchField<Type>(ptf, p, iF, mapper),
mappedPatchFieldBase<Type>(this->mapper(p, iF), *this, ptf) mappedPatchFieldBase<Type>
(
mappedPatchFieldBase<Type>::mapper(p, iF),
*this,
ptf
)
{} {}
@ -88,32 +99,17 @@ Foam::mappedFixedValueFvPatchField<Type>::mappedFixedValueFvPatchField
) )
: :
fixedValueFvPatchField<Type>(ptf, iF), fixedValueFvPatchField<Type>(ptf, iF),
mappedPatchFieldBase<Type>(this->mapper(this->patch(), iF), *this, ptf) mappedPatchFieldBase<Type>
(
mappedPatchFieldBase<Type>::mapper(this->patch(), iF),
*this,
ptf
)
{} {}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
const Foam::mappedPatchBase& Foam::mappedFixedValueFvPatchField<Type>::mapper
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
{
if (!isA<mappedPatchBase>(p.patch()))
{
FatalErrorInFunction
<< "' not type '" << mappedPatchBase::typeName << "'"
<< "\n for patch " << p.patch().name()
<< " of field " << iF.name()
<< " in file " << iF.objectPath()
<< exit(FatalError);
}
return refCast<const mappedPatchBase>(p.patch());
}
template<class Type> template<class Type>
void Foam::mappedFixedValueFvPatchField<Type>::updateCoeffs() void Foam::mappedFixedValueFvPatchField<Type>::updateCoeffs()
{ {

View File

@ -103,18 +103,6 @@ class mappedFixedValueFvPatchField
public fixedValueFvPatchField<Type>, public fixedValueFvPatchField<Type>,
public mappedPatchFieldBase<Type> public mappedPatchFieldBase<Type>
{ {
protected:
// Protected Member Functions
const mappedPatchBase& mapper
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
);
public: public:
//- Runtime type information //- Runtime type information
@ -190,6 +178,7 @@ public:
//- Update the coefficients associated with the patch field //- Update the coefficients associated with the patch field
virtual void updateCoeffs(); virtual void updateCoeffs();
//- Write //- Write
virtual void write(Ostream&) const; virtual void write(Ostream&) const;
}; };

View File

@ -0,0 +1,242 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "mappedMixedFvPatchField.H"
#include "volFields.H"
#include "interpolationCell.H"
#include "mappedFixedValueFvPatchField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::mappedMixedFvPatchField<Type>::mappedMixedFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
mixedFvPatchField<Type>(p, iF),
mappedPatchFieldBase<Type>
(
mappedFixedValueFvPatchField<Type>::mapper(p, iF),
*this
),
weightFieldName_(word::null)
{
this->refValue() = Zero;
this->refGrad() = Zero;
this->valueFraction() = 0.0;
}
template<class Type>
Foam::mappedMixedFvPatchField<Type>::mappedMixedFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
mixedFvPatchField<Type>(p, iF, dict),
mappedPatchFieldBase<Type>
(
mappedFixedValueFvPatchField<Type>::mapper(p, iF),
*this,
dict
),
weightFieldName_(dict.getOrDefault<word>("weightField", word::null))
{
mixedFvPatchField<Type>::operator=
(
Field<Type>("value", dict, p.size())
);
if (dict.found("refValue"))
{
// Full restart
this->refValue() = Field<Type>("refValue", dict, p.size());
this->refGrad() = Field<Type>("refGradient", dict, p.size());
this->valueFraction() = scalarField("valueFraction", dict, p.size());
}
else
{
// Start from user entered data. Assume fixedValue.
this->refValue() = *this;
this->refGrad() = Zero;
this->valueFraction() = 1.0;
}
// Store patch value as initial guess when running in database mode
mappedPatchFieldBase<Type>::initRetrieveField
(
this->internalField().name(),
*this
);
mappedPatchFieldBase<Type>::initRetrieveField
(
this->internalField().name() + "_weights",
this->patch().deltaCoeffs()
);
}
template<class Type>
Foam::mappedMixedFvPatchField<Type>::mappedMixedFvPatchField
(
const mappedMixedFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
mixedFvPatchField<Type>(ptf, p, iF, mapper),
mappedPatchFieldBase<Type>
(
mappedFixedValueFvPatchField<Type>::mapper(p, iF),
*this,
ptf
),
weightFieldName_(ptf.weightFieldName_)
{}
template<class Type>
Foam::mappedMixedFvPatchField<Type>::mappedMixedFvPatchField
(
const mappedMixedFvPatchField<Type>& ptf
)
:
mixedFvPatchField<Type>(ptf),
mappedPatchFieldBase<Type>(ptf),
weightFieldName_(ptf.weightFieldName_)
{}
template<class Type>
Foam::mappedMixedFvPatchField<Type>::mappedMixedFvPatchField
(
const mappedMixedFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
mixedFvPatchField<Type>(ptf, iF),
mappedPatchFieldBase<Type>
(
mappedFixedValueFvPatchField<Type>::mapper(ptf.patch(), iF),
*this,
ptf
),
weightFieldName_(ptf.weightFieldName_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::mappedMixedFvPatchField<Type>::autoMap(const fvPatchFieldMapper& m)
{
mixedFvPatchField<Type>::autoMap(m);
}
template<class Type>
void Foam::mappedMixedFvPatchField<Type>::rmap
(
const fvPatchField<Type>& ptf,
const labelList& addr
)
{
mixedFvPatchField<Type>::rmap(ptf, addr);
}
template<class Type>
void Foam::mappedMixedFvPatchField<Type>::updateCoeffs()
{
if (this->updated())
{
return;
}
const tmp<Field<Type>> nbrIntFld(this->mappedInternalField());
//- Unweighted
//const tmp<scalarField> nbrKDelta(this->mappedWeightField());
//- Weighted
tmp<scalarField> myKDelta;
tmp<scalarField> nbrKDelta;
this->mappedWeightField(weightFieldName_, myKDelta, nbrKDelta);
// Both sides agree on
// - temperature : (myKDelta*fld + nbrKDelta*nbrFld)/(myKDelta+nbrKDelta)
// - gradient : (temperature-fld)*delta
// We've got a degree of freedom in how to implement this in a mixed bc.
// (what gradient, what fixedValue and mixing coefficient)
// Two reasonable choices:
// 1. specify above temperature on one side (preferentially the high side)
// and above gradient on the other. So this will switch between pure
// fixedvalue and pure fixedgradient
// 2. specify gradient and temperature such that the equations are the
// same on both sides. This leads to the choice of
// - refGradient = zero gradient
// - refValue = neighbour value
// - mixFraction = nbrKDelta / (nbrKDelta + myKDelta())
this->refValue() = nbrIntFld;
this->refGrad() = Zero;
this->valueFraction() = nbrKDelta()/(nbrKDelta() + myKDelta());
mixedFvPatchField<Type>::updateCoeffs();
if (debug)
{
Info<< this->patch().boundaryMesh().mesh().name() << ':'
<< this->patch().name() << ':'
<< this->internalField().name() << " <- "
<< this->mapper_.sampleRegion() << ':'
<< this->mapper_.samplePatch() << ':'
<< this->fieldName_ << " :"
<< " value "
<< " min:" << gMin(*this)
<< " max:" << gMax(*this)
<< " avg:" << gAverage(*this)
<< endl;
}
}
template<class Type>
void Foam::mappedMixedFvPatchField<Type>::write(Ostream& os) const
{
mappedPatchFieldBase<Type>::write(os);
os.writeEntryIfDifferent<word>("weightField", word::null, weightFieldName_);
mixedFvPatchField<Type>::write(os);
}
// ************************************************************************* //

View File

@ -0,0 +1,232 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2020 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 <http://www.gnu.org/licenses/>.
Class
Foam::mappedMixedFvPatchField
Group
grpGenericBoundaryConditions grpCoupledBoundaryConditions
Description
This boundary condition maps the value at a set of cells or patch faces
back to *this.
The sample mode is set by the underlying mapping engine, provided by the
mappedPatchBase class.
Usage
\table
Property | Description | Required | Default
field | Name of field to be mapped | no | this field name
weightField | Name of field to use as weight | no |
setAverage | Use average value | no | false |
average | Average value to use if \c setAverage = yes | partly |
\endtable
Example of the boundary condition specification:
\verbatim
<patchName>
{
type mappedMixed;
field T; // optional field name
value uniform 273.0;
refValue $value;
refGradient uniform 0.0;
valueFraction uniform 1.0;
}
\endverbatim
Note
Supports multi-world operation:
+----+ +----+
| | | |
| | | |
+----+ +----+
worldA worldB
regionA regionB
patchA patchB
See also
Foam::mappedPatchBase
Foam::mappedPolyPatch
Foam::mappedFvPatch
Foam::mappedFieldFvPatchField
Foam::mixedFvPatchField
SourceFiles
mappedMixedFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef mappedMixedFvPatchField_H
#define mappedMixedFvPatchField_H
#include "mappedPatchFieldBase.H"
#include "mixedFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class mappedMixedFvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class mappedMixedFvPatchField
:
public mixedFvPatchField<Type>,
public mappedPatchFieldBase<Type>
{
//- Name of weight field to sample
word weightFieldName_;
public:
//- Runtime type information
TypeName("mappedMixed");
// Constructors
//- Construct from patch and internal field
mappedMixedFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
mappedMixedFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// mappedMixedFvPatchField
// onto a new patch
mappedMixedFvPatchField
(
const mappedMixedFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
mappedMixedFvPatchField
(
const mappedMixedFvPatchField<Type>&
);
//- Construct and return a clone
virtual tmp<fvPatchField<Type>> clone() const
{
return tmp<fvPatchField<Type>>
(
new mappedMixedFvPatchField<Type>
(
*this
)
);
}
//- Construct as copy setting internal field reference
mappedMixedFvPatchField
(
const mappedMixedFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type>> clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type>>
(
new mappedMixedFvPatchField<Type>
(
*this,
iF
)
);
}
// Member functions
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap
(
const fvPatchFieldMapper&
);
//- Reverse map the given fvPatchField onto this fvPatchField
virtual void rmap
(
const fvPatchField<Type>&,
const labelList&
);
// Evaluation functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "mappedMixedFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,44 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2020 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "mappedMixedFvPatchFields.H"
#include "volMesh.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
//makeTemplatePatchTypeField(scalar, mappedMixed);
makePatchFields(mappedMixed);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef mappedMixedFvPatchFields_H
#define mappedMixedFvPatchFields_H
#include "mappedMixedFvPatchField.H"
#include "fieldTypes.H"
#include "fvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//makePatchTypeFieldTypedef(scalar, mappedMixed);
makePatchTypeFieldTypedefs(mappedMixed)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -39,4 +39,6 @@ writeObjects/writeObjects.C
thermoCoupleProbes/thermoCoupleProbes.C thermoCoupleProbes/thermoCoupleProbes.C
syncObjects/syncObjects.C
LIB = $(FOAM_LIBBIN)/libutilityFunctionObjects LIB = $(FOAM_LIBBIN)/libutilityFunctionObjects

View File

@ -0,0 +1,228 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "syncObjects.H"
#include "Time.H"
#include "polyMesh.H"
#include "addToRunTimeSelectionTable.H"
#include "objectRegistry.H"
#include "mappedPatchBase.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
defineTypeNameAndDebug(syncObjects, 0);
addToRunTimeSelectionTable
(
functionObject,
syncObjects,
dictionary
);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::syncObjects::syncObjects
(
const word& name,
const Time& runTime,
const dictionary& dict
)
:
functionObject(name),
obr_
(
//runTime.lookupObject<objectRegistry>
//(
// dict.lookupOrDefault("region", polyMesh::defaultRegion)
//)
runTime
)
{
read(dict);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::functionObjects::syncObjects::sync()
{
if (debug)
{
Pout<< type() << " : sync()"
<< " root:" << root_ << endl;
}
const label oldWarnComm = UPstream::warnComm;
UPstream::warnComm = 0;
if (!Pstream::parRun())
{
return;
}
// Send my data to all other processors
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Note provision of explicit all-world communicator
PstreamBuffers pBufs
(
Pstream::commsTypes::nonBlocking,
UPstream::msgType(),
0
);
const label nProcs = Pstream::nProcs(pBufs.comm());
for (label proci = 0; proci < nProcs; proci++)
{
// Get database to send
const objectRegistry& sendObr = mappedPatchBase::subRegistry
(
obr_,
mappedPatchBase::sendPath(root_, proci)
);
// Pack into dictionary
dictionary sendDataDict;
mappedPatchBase::writeDict(sendObr, sendDataDict);
//Pout<< "** to processor " << proci
// << " sendObr:" << sendObr.objectPath()
// << " sending dictionary:" << sendDataDict << endl;
UOPstream os(proci, pBufs);
os << sendDataDict;
}
// Start sending and receiving and block
pBufs.finishedSends();
for (label proci = 0; proci < nProcs; proci++)
{
// Get database to receive data into
const objectRegistry& receiveObr = mappedPatchBase::subRegistry
(
obr_,
mappedPatchBase::receivePath(root_, proci)
);
//Pout<< "** from processor " << proci
// << " receiveObr:" << receiveObr.objectPath()
// << " receiving dictionary" << endl;
UIPstream is(proci, pBufs);
const dictionary fromProcDict(is);
//Pout<< "** from processor " << proci
// << " received dictionary:" << fromProcDict << endl;
mappedPatchBase::readDict
(
fromProcDict,
const_cast<objectRegistry&>(receiveObr)
);
}
//if (debug)
//{
// dictionary allDict;
// // Add send subdictionary
// dictionary& sendDict = allDict.subDictOrAdd("send");
// mappedPatchBase::writeDict
// (
// mappedPatchBase::subRegistry(obr_, "send"),
// sendDict
// );
// // Add receive subdictionary
// dictionary& receiveDict = allDict.subDictOrAdd("receive");
// mappedPatchBase::writeDict
// (
// mappedPatchBase::subRegistry(obr_, "receive"),
// receiveDict
// );
// Pout<< type() << " : after synchronisation:" << allDict << endl;
//}
UPstream::warnComm = oldWarnComm;
}
bool Foam::functionObjects::syncObjects::read(const dictionary& dict)
{
if (debug)
{
Pout<< type() << " : read(const dictionary&)" << endl;
}
functionObject::read(dict);
root_ = dict.getOrDefault<fileName>("root", fileName::null);
if (debug)
{
Pout<< type() << " : root:" << root_ << endl;
}
// Make sure that at startup we're doing a sync (execute below only gets
// called at end of timeloop)
sync();
return true;
}
bool Foam::functionObjects::syncObjects::execute()
{
if (debug)
{
Pout<< type() << " : execute()" << endl;
}
sync();
return true;
}
bool Foam::functionObjects::syncObjects::write()
{
if (debug)
{
Pout<< type() << " : write()" << endl;
}
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,178 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 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 <http://www.gnu.org/licenses/>.
Class
Foam::functionObjects::syncObjects
Group
grpUtilitiesFunctionObjects
Description
Copies content of local objectRegistry to all processors.
Currently only supports IOFields. It is used to distribute IOFields
from different processors/regions/worlds
when doing loose coupling. To be used in combination with 'mapped'
boundary conditions.
Usage
Example of function object specification:
\verbatim
syncObjects1
{
type syncObjects;
libs ("libutilityFunctionObjects.so");
...
// Where is data located relative to runTime. Given as a filename
// with every '/' indicating a sub-objectRegistry w.r.t. runTime.
// Local data is under <root>/send/processorXXX. After execution
// (potentially remote) data will be under the corresponding
// <root>/receive/processorYYY objectRegistry.
//root "level0/level1/level2";
}
\endverbatim
Where the entries comprise:
\table
Property | Description | Required | Default value
type | type name: syncObjects | yes |
root | relative location of data | no | ""
\endtable
See also
Foam::functionObject
SourceFiles
syncObjects.C
\*---------------------------------------------------------------------------*/
#ifndef functionObjects_syncObjects_H
#define functionObjects_syncObjects_H
#include "token.H"
#include "functionObject.H"
#include "IOField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class objectRegistry;
namespace functionObjects
{
/*---------------------------------------------------------------------------*\
Class functionObjects::syncObjects Declaration
\*---------------------------------------------------------------------------*/
class syncObjects
:
public functionObject
{
private:
// Private data
//- Top-level registry
const objectRegistry& obr_;
//- objectRegistry location relative to top-level
fileName root_;
// Private Member Functions
//- No copy construct
syncObjects(const syncObjects&) = delete;
//- No copy assignment
void operator=(const syncObjects&) = delete;
protected:
//- Do all: synchronise all IOFields and objectRegistry
void sync();
public:
//- Runtime type information
TypeName("syncObjects");
// Constructors
//- Construct from Time and dictionary
syncObjects
(
const word& name,
const Time& runTime,
const dictionary& dict
);
//- Destructor
virtual ~syncObjects() = default;
// Member Functions
const objectRegistry& obr() const
{
return obr_;
}
const fileName& root() const
{
return root_;
}
//- Read the syncObjects data
virtual bool read(const dictionary&);
//- Do nothing
virtual bool execute();
//- Write the registered objects
virtual bool write();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace functionObjects
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,33 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "objectRegistry.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -737,9 +737,9 @@ bool Foam::faceAreaWeightAMI::calculate
extendedTgtMapPtr_->subMap(), extendedTgtMapPtr_->subMap(),
false, // has flip false, // has flip
tgtAddress_, tgtAddress_,
labelList(),
ListOps::appendEqOp<label>(), ListOps::appendEqOp<label>(),
flipOp(), // flip operation flipOp() // flip operation
labelList()
); );
mapDistributeBase::distribute mapDistributeBase::distribute
@ -752,9 +752,9 @@ bool Foam::faceAreaWeightAMI::calculate
extendedTgtMapPtr_->subMap(), extendedTgtMapPtr_->subMap(),
false, false,
tgtWeights_, tgtWeights_,
scalarList(),
ListOps::appendEqOp<scalar>(), ListOps::appendEqOp<scalar>(),
flipOp(), flipOp()
scalarList()
); );
// Note: using patch face areas calculated by the AMI method // Note: using patch face areas calculated by the AMI method

View File

@ -200,9 +200,9 @@ Foam::autoPtr<Foam::mapDistribute> Foam::nearestFaceAMI::calcDistributed
map.subMap(), map.subMap(),
map.subHasFlip(), map.subHasFlip(),
remoteInfo, remoteInfo,
nearestZero,
nearestEqOp(), nearestEqOp(),
noOp(), // no flipping noOp() // no flipping
nearestZero
); );

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,13 @@ Description
If constructed from dictionary: If constructed from dictionary:
\verbatim \verbatim
// Optional world to sample (default is all)
//sampleWorld solidSim;
// Optional explicit coupling (requires functionObject to synchronise
// databases. Default is close coupling (bc to bc)
//sampleDatabase true;
// Region to sample (default is region0) // Region to sample (default is region0)
sampleRegion region0; sampleRegion region0;
@ -184,6 +191,38 @@ public:
}; };
//- nearest + world
// Used to only look at entries from same world
typedef Tuple2<nearInfo, label> nearInfoWorld;
class nearestWorldEqOp
{
public:
void operator()(nearInfoWorld& x, const nearInfoWorld& y) const
{
// Is there a hit and is it sampling the same world
const nearInfo& xi = x.first();
const nearInfo& yi = y.first();
if (yi.first().hit())
{
if (x.second() == y.second())
{
if (!xi.first().hit())
{
x = y;
}
else if (yi.second().first() < xi.second().first())
{
x = y;
}
}
}
}
};
protected: protected:
// Protected data // Protected data
@ -191,6 +230,9 @@ protected:
//- Patch to sample //- Patch to sample
const polyPatch& patch_; const polyPatch& patch_;
//- World to sample
mutable word sampleWorld_;
//- Region to sample //- Region to sample
mutable word sampleRegion_; mutable word sampleRegion_;
@ -203,6 +245,9 @@ protected:
//- PatchGroup (if in sampleMode NEARESTPATCH*) //- PatchGroup (if in sampleMode NEARESTPATCH*)
const coupleGroupIdentifier coupleGroup_; const coupleGroupIdentifier coupleGroup_;
//- Empty or location of database
const autoPtr<fileName> sampleDatabasePtr_;
//- How to obtain samples //- How to obtain samples
offsetMode offsetMode_; offsetMode offsetMode_;
@ -215,6 +260,9 @@ protected:
//- Offset distance (normal) //- Offset distance (normal)
scalar distance_; scalar distance_;
//- Communicator
label comm_;
//- Same region //- Same region
mutable bool sameRegion_; mutable bool sameRegion_;
@ -246,25 +294,59 @@ protected:
// Protected Member Functions // Protected Member Functions
//- Optionally allocate a world-local communicator
static label communicator(const word& sampleWorld);
//- Lookup mesh
const polyMesh& lookupMesh(const word& region) const;
//- Lookup patch
const polyPatch& lookupPatch
(
const word& sampleRegion,
const word& samplePatch
) const;
//- Get the points from face-centre-decomposition face centres //- Get the points from face-centre-decomposition face centres
// and project them onto the face-diagonal-decomposition triangles. // and project them onto the face-diagonal-decomposition triangles.
tmp<pointField> facePoints(const polyPatch&) const; tmp<pointField> facePoints(const polyPatch&) const;
//- Collect single list of samples and originating processor+face. //- Collect single list of samples and originating processor+face +
// wanted world
void collectSamples void collectSamples
( (
const label mySampleWorld, // My wanted sampling world
const pointField& facePoints, const pointField& facePoints,
pointField&, pointField& samples, // Per sample: coordinate
labelList& patchFaceProcs, labelList& patchFaceWorlds, // Per sample: wanted world
labelList& patchFaces, labelList& patchFaceProcs, // Per sample: originating proc
labelList& patchFaces, // Per sample: originating face
pointField& patchFc pointField& patchFc
) const; ) const;
//- Find cells/faces containing samples //- Find (local) cells/faces containing samples
void findLocalSamples
(
const sampleMode mode,
const label sampleWorld, // my world as index
const word& sampleRegion,
const word& samplePatch,
const pointField& samplePoints,
List<nearInfoWorld>& nearest
) const;
//- Find (global) cells/faces containing samples
void findSamples void findSamples
( (
const sampleMode mode, // search mode const sampleMode mode, // search mode
const label myWorldIndex, // my world (in index form)
const pointField&, const pointField&,
const labelList& wantedWorlds,
const labelList& origProcs, // per sample the originating proc
labelList& sampleProcs, // processor containing sample labelList& sampleProcs, // processor containing sample
labelList& sampleIndices, // local index of cell/face labelList& sampleIndices, // local index of cell/face
pointField& sampleLocations // actual representative location pointField& sampleLocations // actual representative location
@ -280,6 +362,38 @@ protected:
void calcAMI() const; void calcAMI() const;
// Database handling
//- Read optional database name from dictionary
static autoPtr<fileName> readDatabase(const dictionary& dict);
//- Lookup (sub)objectRegistry by following names of sub registries.
//- Creates non-existing intermediate ones.
static const objectRegistry& subRegistry
(
const objectRegistry& obr,
const wordList& names,
const label index
);
//- Attempt to detect an IOField<Type> and write to dictionary
template<class Type>
static bool writeIOField
(
const regIOobject& obj,
dictionary& dict
);
//- Attempt to read an IOField<Type> and store on objectRegistry
template<class Type>
static bool constructIOField
(
const word& name,
token& tok,
Istream& is,
objectRegistry& obr
);
public: public:
//- Runtime type information //- Runtime type information
@ -289,7 +403,7 @@ public:
// Constructors // Constructors
//- Construct from patch //- Construct from patch
mappedPatchBase(const polyPatch&); explicit mappedPatchBase(const polyPatch&);
//- Construct with offsetMode=non-uniform //- Construct with offsetMode=non-uniform
mappedPatchBase mappedPatchBase
@ -354,6 +468,9 @@ public:
//- What to sample //- What to sample
inline const sampleMode& mode() const; inline const sampleMode& mode() const;
//- World to sample
inline const word& sampleWorld() const;
//- Region to sample //- Region to sample
inline const word& sampleRegion() const; inline const word& sampleRegion() const;
@ -372,6 +489,12 @@ public:
//- Offset vector (from patch faces to destination mesh objects) //- Offset vector (from patch faces to destination mesh objects)
inline const vectorField& offsets() const; inline const vectorField& offsets() const;
//- Communicator
inline label comm() const;
//- Is world the local world
inline bool sameWorld() const;
//- Cached sampleRegion != mesh.name() //- Cached sampleRegion != mesh.name()
inline bool sameRegion() const; inline bool sameRegion() const;
@ -412,6 +535,60 @@ public:
const polyMesh::cellDecomposition const polyMesh::cellDecomposition
); );
// For database storage
inline const fileName& sampleDatabasePath() const
{
return *sampleDatabasePtr_;
}
inline bool sampleDatabase() const
{
return sampleDatabasePtr_.valid();
}
//- Helper: return path to store data to be sent to processor i
static fileName sendPath(const fileName& root, const label proci);
virtual fileName sendPath(const label proci) const;
//- Helper: return path to store data to be received from
//- processor i
static fileName receivePath
(
const fileName& root,
const label proci
);
virtual fileName receivePath(const label proci) const;
//- Lookup (sub)objectRegistry from '/' separated path (relative to
//- objectRegistry). Creates non-existing intermediate ones.
static const objectRegistry& subRegistry
(
const objectRegistry& obr,
const fileName& path
);
//- Store an IOField on the objectRegistry relative to obr
template<class Type>
static void storeField
(
objectRegistry& obr,
const word& fieldName,
const Field<Type>& values
);
//- Convert objectRegistry contents into dictionary
static void writeDict
(
const objectRegistry& obr,
dictionary& dict
);
//- (recursively) construct and register IOFields from dictionary
static void readDict(const dictionary& d, objectRegistry& obr);
// Distribute // Distribute

View File

@ -33,6 +33,12 @@ Foam::mappedPatchBase::mode() const
} }
inline const Foam::word& Foam::mappedPatchBase::sampleWorld() const
{
return sampleWorld_;
}
inline const Foam::word& Foam::mappedPatchBase::sampleRegion() const inline const Foam::word& Foam::mappedPatchBase::sampleRegion() const
{ {
if (sampleRegion_.empty()) if (sampleRegion_.empty())
@ -138,6 +144,20 @@ inline const Foam::vectorField& Foam::mappedPatchBase::offsets() const
} }
inline Foam::label Foam::mappedPatchBase::comm() const
{
return comm_;
}
inline bool Foam::mappedPatchBase::sameWorld() const
{
return
UPstream::allWorlds().size() == 1
|| UPstream::myWorld() == sampleWorld_;
}
inline bool Foam::mappedPatchBase::sameRegion() const inline bool Foam::mappedPatchBase::sameRegion() const
{ {
return sameRegion_; return sameRegion_;
@ -147,7 +167,9 @@ inline bool Foam::mappedPatchBase::sameRegion() const
inline const Foam::mapDistribute& Foam::mappedPatchBase::map() const inline const Foam::mapDistribute& Foam::mappedPatchBase::map() const
{ {
const polyMesh& thisMesh = patch_.boundaryMesh().mesh(); const polyMesh& thisMesh = patch_.boundaryMesh().mesh();
bool topoChange = sampleMesh().topoChanging() || thisMesh.topoChanging(); bool topoChange =
(sameWorld() && sampleMesh().topoChanging())
|| thisMesh.topoChanging();
if (topoChange) if (topoChange)
{ {
@ -169,7 +191,9 @@ inline const Foam::AMIPatchToPatchInterpolation& Foam::mappedPatchBase::AMI
) const ) const
{ {
const polyMesh& thisMesh = patch_.boundaryMesh().mesh(); const polyMesh& thisMesh = patch_.boundaryMesh().mesh();
bool topoChange = sampleMesh().topoChanging() || thisMesh.topoChanging(); bool topoChange =
(sameWorld() && sampleMesh().topoChanging())
|| thisMesh.topoChanging();
if (topoChange || forceUpdate) if (topoChange || forceUpdate)
{ {

View File

@ -28,11 +28,16 @@ License
template<class Type> template<class Type>
void Foam::mappedPatchBase::distribute(List<Type>& lst) const void Foam::mappedPatchBase::distribute(List<Type>& lst) const
{ {
const label oldComm(Pstream::warnComm);
Pstream::warnComm = map().comm();
switch (mode_) switch (mode_)
{ {
case NEARESTPATCHFACEAMI: case NEARESTPATCHFACEAMI:
{ {
const label oldWorldComm = Pstream::worldComm;
Pstream::worldComm = comm_;
lst = AMI().interpolateToSource(Field<Type>(std::move(lst))); lst = AMI().interpolateToSource(Field<Type>(std::move(lst)));
Pstream::worldComm = oldWorldComm;
break; break;
} }
default: default:
@ -40,6 +45,7 @@ void Foam::mappedPatchBase::distribute(List<Type>& lst) const
map().distribute(lst); map().distribute(lst);
} }
} }
Pstream::warnComm = oldComm;
} }
@ -50,11 +56,16 @@ void Foam::mappedPatchBase::distribute
const CombineOp& cop const CombineOp& cop
) const ) const
{ {
const label oldComm(Pstream::warnComm);
Pstream::warnComm = comm_;
switch (mode_) switch (mode_)
{ {
case NEARESTPATCHFACEAMI: case NEARESTPATCHFACEAMI:
{ {
const label oldWorldComm = Pstream::worldComm;
Pstream::worldComm = comm_;
lst = AMI().interpolateToSource(Field<Type>(std::move(lst)), cop); lst = AMI().interpolateToSource(Field<Type>(std::move(lst)), cop);
Pstream::worldComm = oldWorldComm;
break; break;
} }
default: default:
@ -69,23 +80,31 @@ void Foam::mappedPatchBase::distribute
map().constructMap(), map().constructMap(),
false, false,
lst, lst,
Type(Zero),
cop, cop,
flipOp(), flipOp(),
Type(Zero) UPstream::msgType(),
comm_
); );
} }
} }
Pstream::warnComm = oldComm;
} }
template<class Type> template<class Type>
void Foam::mappedPatchBase::reverseDistribute(List<Type>& lst) const void Foam::mappedPatchBase::reverseDistribute(List<Type>& lst) const
{ {
const label oldComm(Pstream::warnComm);
Pstream::warnComm = map().comm();
switch (mode_) switch (mode_)
{ {
case NEARESTPATCHFACEAMI: case NEARESTPATCHFACEAMI:
{ {
const label oldWorldComm = Pstream::worldComm;
Pstream::worldComm = comm_;
lst = AMI().interpolateToTarget(Field<Type>(std::move(lst))); lst = AMI().interpolateToTarget(Field<Type>(std::move(lst)));
Pstream::worldComm = oldWorldComm;
break; break;
} }
default: default:
@ -94,6 +113,7 @@ void Foam::mappedPatchBase::reverseDistribute(List<Type>& lst) const
break; break;
} }
} }
Pstream::warnComm = oldComm;
} }
@ -104,11 +124,16 @@ void Foam::mappedPatchBase::reverseDistribute
const CombineOp& cop const CombineOp& cop
) const ) const
{ {
const label oldComm(Pstream::warnComm);
Pstream::warnComm = map().comm();
switch (mode_) switch (mode_)
{ {
case NEARESTPATCHFACEAMI: case NEARESTPATCHFACEAMI:
{ {
const label oldWorldComm = Pstream::worldComm;
Pstream::worldComm = comm_;
lst = AMI().interpolateToTarget(Field<Type>(std::move(lst)), cop); lst = AMI().interpolateToTarget(Field<Type>(std::move(lst)), cop);
Pstream::worldComm = oldWorldComm;
break; break;
} }
default: default:
@ -124,13 +149,137 @@ void Foam::mappedPatchBase::reverseDistribute
map().subMap(), map().subMap(),
false, false,
lst, lst,
Type(Zero),
cop, cop,
flipOp(), flipOp(),
Type(Zero) UPstream::msgType(),
comm_
); );
break; break;
} }
} }
Pstream::warnComm = oldComm;
}
template<class Type>
bool Foam::mappedPatchBase::writeIOField
(
const regIOobject& obj,
dictionary& dict
)
{
const auto* fldPtr = isA<IOField<Type>>(obj);
if (fldPtr)
{
const auto& fld = *fldPtr;
token tok;
tok = new token::Compound<List<Type>>(fld);
primitiveEntry* pePtr = new primitiveEntry
(
fld.name(),
tokenList
(
one(),
std::move(tok)
)
);
dict.set(pePtr);
return true;
}
else
{
return false;
}
}
template<class Type>
bool Foam::mappedPatchBase::constructIOField
(
const word& name,
token& tok,
Istream& is,
objectRegistry& obr
)
{
const word tag = "List<" + word(pTraits<Type>::typeName) + '>';
if (tok.isCompound() && tok.compoundToken().type() == tag)
{
IOField<Type>* fldPtr = obr.findObject<IOField<Type>>(name);
if (fldPtr)
{
fldPtr->transfer
(
dynamicCast<token::Compound<List<Type>>>
(
tok.transferCompoundToken(is)
)
);
}
else
{
IOField<Type>* fldPtr = new IOField<Type>
(
IOobject
(
name,
obr,
IOobject::NO_READ,
IOobject::NO_WRITE
),
0
);
fldPtr->transfer
(
dynamicCast<token::Compound<List<Type>>>
(
tok.transferCompoundToken(is)
)
);
objectRegistry::store(fldPtr);
}
return true;
}
else
{
return false;
}
}
template<class Type>
void Foam::mappedPatchBase::storeField
(
objectRegistry& obr,
const word& fieldName,
const Field<Type>& values
)
{
IOField<Type>* fldPtr = obr.findObject<IOField<Type>>(fieldName);
if (fldPtr)
{
*fldPtr = values;
}
else
{
fldPtr = new IOField<Type>
(
IOobject
(
fieldName,
obr,
IOobject::NO_READ,
IOobject::NO_WRITE
),
values
);
objectRegistry::store(fldPtr);
}
} }

View File

@ -1552,9 +1552,11 @@ void Foam::cellCellStencils::inverseDistance::createStencil
cellInterpolationMap().subMap(), cellInterpolationMap().subMap(),
false, false,
samples, samples,
greatPoint, // nullValue
minMagSqrEqOp<point>(), minMagSqrEqOp<point>(),
flipOp(), // negateOp flipOp(), // negateOp
greatPoint // nullValue UPstream::msgType(),
cellInterpolationMap().comm()
); );
// All the donor cells will now have a valid cell centre. Construct a // All the donor cells will now have a valid cell centre. Construct a

View File

@ -1392,9 +1392,11 @@ void Foam::distributedTriSurfaceMesh::surfaceSide
map.subMap(), map.subMap(),
map.subHasFlip(), map.subHasFlip(),
volType, volType,
zero,
volumeCombineOp(), volumeCombineOp(),
noOp(), // no flipping noOp(), // no flipping
zero UPstream::msgType(),
map.comm()
); );
if (debug) if (debug)
@ -3193,9 +3195,11 @@ void Foam::distributedTriSurfaceMesh::findNearest
map1.subMap(), map1.subMap(),
map1.subHasFlip(), map1.subHasFlip(),
nearestInfo, nearestInfo,
nearestZero,
nearestEqOp(), nearestEqOp(),
noOp(), // no flipping noOp(), // no flipping
nearestZero UPstream::msgType(),
map1.comm()
); );
@ -3351,9 +3355,11 @@ void Foam::distributedTriSurfaceMesh::findNearest
map2.subMap(), map2.subMap(),
map2.subHasFlip(), map2.subHasFlip(),
localBest, localBest,
nearestZero,
nearestEqOp(), nearestEqOp(),
noOp(), // no flipping noOp(), // no flipping
nearestZero UPstream::msgType(),
map2.comm()
); );
// Combine with nearestInfo // Combine with nearestInfo
@ -4183,9 +4189,11 @@ void Foam::distributedTriSurfaceMesh::getVolumeType
map.subMap(), map.subMap(),
map.subHasFlip(), map.subHasFlip(),
volType, volType,
zero,
volumeCombineOp(), volumeCombineOp(),
noOp(), // no flipping noOp(), // no flipping
zero UPstream::msgType(),
map.comm()
); );

View File

@ -556,9 +556,11 @@ void Foam::meshToMesh::calculate(const word& methodName, const bool normalise)
map.subMap(), map.subMap(),
false, false,
tgtToSrcCellAddr_, tgtToSrcCellAddr_,
labelList(),
ListOps::appendEqOp<label>(), ListOps::appendEqOp<label>(),
flipOp(), flipOp(),
labelList() UPstream::msgType(),
map.comm()
); );
// Set up as a reverse distribute // Set up as a reverse distribute
@ -572,9 +574,11 @@ void Foam::meshToMesh::calculate(const word& methodName, const bool normalise)
map.subMap(), map.subMap(),
false, false,
tgtToSrcCellWght_, tgtToSrcCellWght_,
scalarList(),
ListOps::appendEqOp<scalar>(), ListOps::appendEqOp<scalar>(),
flipOp(), flipOp(),
scalarList() UPstream::msgType(),
map.comm()
); );
// weights normalisation // weights normalisation

View File

@ -74,6 +74,11 @@ inline Foam::scalar Foam::species::thermo<Thermo, Type>::T
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Maximum number of iterations exceeded: " << maxIter_ << "Maximum number of iterations exceeded: " << maxIter_
<< " when starting from T0:" << T0
<< " old T:" << Test << " new T:" << Tnew
<< " f:" << f
<< " p:" << p
<< " tol:" << Ttol
<< abort(FatalError); << abort(FatalError);
} }