52 a(iter.key()) |= iter.val();
58 static void printDOT(Ostream&
os,
const EdgeMap<unsigned>& connections)
60 os <<
nl <<
"// Multiworld communication graph:" <<
nl;
68 os << worldi <<
" [xlabel=" << worldi
69 <<
",label=\"" << worldName <<
"\"]" <<
nl;
76 for (
const edge& connect : connections.sortedToc())
79 os << connect.first() <<
" -- " << connect.second();
82 if (connections.lookup(connect, 0u) != 3u)
84 os <<
" [style=dashed] // mismatched?";
91 os <<
"// end graph" <<
nl;
99 Foam::edge Foam::multiWorldConnections::worldPair(
const label otherWorld)
103 Perr<<
"ignore: no world or non-parallel" <<
endl;
108 Perr<<
"ignore: invalid world: " << otherWorld <<
endl;
115 return edge(thisWorldID, otherWorld,
true);
119 Foam::edge Foam::multiWorldConnections::worldPair(
const word& otherWorld)
123 Perr<<
"ignore: no world or non-parallel" <<
endl;
130 if (otherWorldID < 0)
133 <<
"Cannot find world " << otherWorld
139 return edge(thisWorldID, otherWorldID,
true);
143 Foam::label Foam::multiWorldConnections::createCommunicator(
const edge& worlds)
155 DynamicList<label> subRanks(worldIDs.size());
158 if (worlds.found(worldIDs[proci]))
160 subRanks.push_back(proci);
169 Pout<<
"multiWorld::communicator :" 172 <<
" sub-ranks: " << subRanks
173 <<
" comm:" << comm <<
endl;
207 return table_.empty();
213 return table_.size();
226 const edge& connect = iter.key();
231 (connect.
first() == thisWorldID ? 1u : 2u)
246 label brokenConnections = 0;
251 if (iter.val() != 3u)
257 if (brokenConnections)
264 <<
"Has " << brokenConnections
265 <<
" broken world-world connections";
276 for (
const edge& connect : allConnections.
sortedToc())
281 auto iter = table_.find(connect);
282 if (iter.good() && iter.val() == -1)
284 iter.val() = createCommunicator(connect);
303 edge worlds(worldPair(otherWorld));
310 const bool added = table_.insert(worlds, -1);
312 Pout<< (added ?
"Add" :
"Existing") <<
" connection from " 322 edge worlds(worldPair(otherWorld));
329 const bool added = table_.insert(worlds, -1);
331 Pout<< (added ?
"Add" :
"Existing") <<
" connection from " 340 const label otherWorldID
347 edge worlds(worldPair(otherWorldID));
354 const auto iter = table_.cfind(worlds);
359 <<
"No connection registered for worlds " << worlds
369 const_cast<multiWorldConnections&
>(*this).createComms();
381 const word& otherWorld
388 edge worlds(worldPair(otherWorld));
395 const auto iter = table_.cfind(worlds);
400 <<
"No connection registered for worlds " << worlds
410 const_cast<multiWorldConnections&
>(*this).createComms();
433 if (iter.val() == -1)
436 const_cast<multiWorldConnections&
>(*this).createComms();
446 list[i] = iter.val();
static const word & myWorld()
My world.
label getCommById(const label otherWorld) const
Get communicator for myWorld to other world connection by ID.
prefixOSstream Perr
OSstream wrapped stderr (std::cerr) with parallel prefix.
const T & first() const noexcept
Access the first element.
void operator()(EdgeMap< unsigned > &a, const EdgeMap< unsigned > &b) const
static const labelList & worldIDs() noexcept
The indices into allWorlds for all processes.
static void printDOT(Ostream &os, const EdgeMap< unsigned > &connections)
errorManipArg< error, int > exit(error &err, const int errNo=1)
bool valid() const noexcept
Same as good()
void resize(const label len)
Adjust allocated size of list.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
label find(const T &val, label pos=0) const
Find index of the first occurrence of the value.
Centralized handling of multi-world MPI connections.
constexpr char nl
The newline '\n' character (0x0a)
static const multiWorldConnections & New(const Time &runTime)
Access mesh object.
Ostream & endl(Ostream &os)
Add newline and flush stream.
static bool & parRun() noexcept
Test if this a parallel run.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
labelList comms() const
Get communicators used for myWorld to other worlds in sorted order.
virtual void indent()
Add indentation characters.
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
#define forAll(list, i)
Loop across all elements in list.
bool insert(const edge &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
bool empty() const noexcept
True if no world-to-world connections are defined.
static label commWarn(const label communicator) noexcept
Alter communicator debugging setting. Warns for use of any communicator differing from specified...
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
A class for handling words, derived from Foam::string.
void sort(UList< T > &list)
Sort the list.
virtual Ostream & endBlock()
Write end block group.
multiWorldConnections(const Time &runTime)
Construct.
static void combineReduce(const List< commsStruct > &comms, T &value, const CombineOp &cop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) applying cop to inplace combine value from different processors...
~multiWorldConnections()
Destructor.
label getCommByName(const word &otherWorld) const
Get communicator for myWorld to other world connection by NAME.
int debug
Static debugging option.
Map from edge (expressed as its endpoints) to value. Hashing (and ==) on an edge is symmetric...
OBJstream os(runTime.globalPath()/outputName)
defineTypeNameAndDebug(combustionModel, 0)
static label commWorld() noexcept
Communicator for all ranks (respecting any local worlds)
label size() const noexcept
Number of world-to-world connections defined.
bool addConnectionByName(const word &otherWorld)
Define a connection from myWorld to other world by NAME.
List< edge > sortedToc() const
The table of contents (the keys) in sorted order.
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
void createComms()
Create all communicators. Low-level, not normally called directly.
List< label > labelList
A List of labels.
static const wordList & allWorlds() noexcept
All worlds.
bool addConnectionById(const label otherWorld)
Define a connection from myWorld to other world by ID.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
static label allocateCommunicator(const label parent, const labelRange &subRanks, const bool withComponents=true)
Allocate new communicator with contiguous sub-ranks on the parent communicator.
forAllConstIters(mixture.phases(), phase)
static label myWorldID()
My worldID.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
static constexpr label commGlobal() noexcept
Communicator for all ranks, irrespective of any local worlds.