Merge branch 'pstream-cleanups' into 'develop'

various cleanup and add support for non-worldComm reduction of DimensionedField, GeometricField

See merge request Development/openfoam!728
This commit is contained in:
Kutalmış Berçin 2025-02-24 12:38:40 +00:00
commit d41c644a49
48 changed files with 1326 additions and 991 deletions

View File

@ -1,3 +1,3 @@
Test-minMax1.C
Test-minMax1.cxx
EXE = $(FOAM_USER_APPBIN)/Test-minMax1

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -170,8 +170,19 @@ int main(int argc, char *argv[])
values1 *= (Pstream::myProcNo()+1);
Pout<<"min-max of " << flatOutput(values1) << " = "
<< minMax(values1) << endl;
{
auto limits = minMax(values1);
Pout<<"min-max of " << flatOutput(values1) << " = "
<< limits << endl;
// add in some more values
limits.add(-100, 10, 1000, 500, 800);
limits.add(-120, 1200);
Pout<<"with more values: " << limits << endl;
}
// Construct from values
MinMax<scalar> minmax1(values1);
@ -182,10 +193,7 @@ int main(int argc, char *argv[])
minmax1 += values1;
Pout<<"range: " << minmax1 << endl;
Info<< "Reduced: "<< returnReduce(minmax1, plusOp<scalarMinMax>()) << nl;
Info<< "Reduced: "<< returnReduce(minmax1, minMaxOp<scalar>()) << nl;
// Info<< "gMinMax: "<< gMinMax(values1v) << nl;

View File

@ -1,3 +1,3 @@
Test-minMax2.C
Test-minMax2.cxx
EXE = $(FOAM_USER_APPBIN)/Test-minMax2

View File

@ -85,7 +85,8 @@ int main(int argc, char *argv[])
if (UPstream::parRun() && optPrintTree)
{
Info<< "comms: " << UPstream::whichCommunication() << endl;
Info<< "comms: "
<< UPstream::whichCommunication(UPstream::worldComm) << nl;
UPstream::printCommTree(UPstream::commWorld());
}

View File

@ -123,7 +123,7 @@ void Foam::printMeshStats(const polyMesh& mesh, const bool allTopology)
{
// Number of global patches and min-max range of total patches
Info<< mesh.boundaryMesh().nNonProcessor() << ' '
<< returnReduce(labelMinMax(nPatches), minMaxOp<label>()) << nl;
<< returnReduce(labelMinMax(nPatches), sumOp<labelMinMax>{}) << nl;
}
else
{

View File

@ -124,8 +124,8 @@ void Foam::PDRutils::one_d_overlap
}
// Ensure search is within the (point) bounds
xmin = grid.clip(xmin);
xmax = grid.clip(xmax);
xmin = grid.clamp(xmin);
xmax = grid.clamp(xmax);
// The begin/end of the obstacle
*cmin = grid.findCell(xmin);

View File

@ -126,6 +126,19 @@ public:
// Gather/scatter : single value
//- Implementation: gather (reduce) single element data onto
//- UPstream::masterNo()
template<class T, class BinaryOp, bool InplaceMode>
static void gather_algorithm
(
const UPstream::commsStructList& comms, //!< Communication order
//! [in,out]
T& value,
const BinaryOp& bop,
const int tag,
const int communicator
);
//- Gather (reduce) data, applying \c bop to combine \c value
//- from different processors. The basis for Foam::reduce().
// A no-op for non-parallel.
@ -208,12 +221,25 @@ public:
const label comm = UPstream::worldComm
)
{
Pstream::listCombineReduce(value, cop, tag, comm);
Pstream::combineReduce(value, cop, tag, comm);
}
// Gather/combine variants working on entire List
//- Implementation: gather (reduce) list element data onto
//- UPstream::masterNo()
template<class T, class BinaryOp, bool InplaceMode>
static void listGather_algorithm
(
const UPstream::commsStructList& comms, //!< Communication order
//! [in,out]
UList<T>& values,
const BinaryOp& bop,
const int tag,
const int communicator
);
//- Gather (reduce) list elements,
//- applying \c bop to each list element
//
@ -240,27 +266,27 @@ public:
const label comm = UPstream::worldComm
);
//- Gather (reduce) list elements,
//- applying \c bop to combine each list element.
//- Reduce list elements (list must be equal size on all ranks),
//- applying \c bop to each list element.
//
// \tparam InplaceMode indicates that the binary operator
// modifies values in-place, not using assignment
template<class T, class BinaryOp, bool InplaceMode=false>
static void listGatherReduce
static void listReduce
(
//! [in,out] the result is consistent on all ranks
List<T>& values,
UList<T>& values,
const BinaryOp& bop,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
//- Forwards to Pstream::listGatherReduce with an \em in-place \c cop
//- Forwards to Pstream::listReduce with an \em in-place \c cop
template<class T, class CombineOp>
static void listCombineReduce
(
//! [in,out] the result is consistent on all ranks
List<T>& values,
UList<T>& values,
const CombineOp& cop,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
@ -271,7 +297,7 @@ public:
static void listCombineAllGather
(
//! [in,out] the result is consistent on all ranks
List<T>& values,
UList<T>& values,
const CombineOp& cop,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
@ -283,6 +309,18 @@ public:
// Gather/combine variants working on Map/HashTable containers
//- Implementation: gather (reduce) Map/HashTable containers onto
//- UPstream::masterNo()
template<class Container, class BinaryOp, bool InplaceMode>
static void mapGather_algorithm
(
const UPstream::commsStructList& comms, //!< Communication order
Container& values,
const BinaryOp& bop,
const int tag,
const int communicator
);
//- Gather (reduce) Map/HashTable containers,
//- applying \c bop to combine entries from different processors.
//
@ -316,7 +354,7 @@ public:
//
// Wraps mapCombineGather/broadcast (may change in the future).
template<class Container, class BinaryOp, bool InplaceMode=false>
static void mapGatherReduce
static void mapReduce
(
//! [in,out] the result is consistent on all ranks
Container& values,
@ -325,7 +363,7 @@ public:
const label comm = UPstream::worldComm
);
//- Forwards to Pstream::mapGatherReduce with an \em in-place \c cop
//- Forwards to Pstream::mapReduce with an \em in-place \c cop
template<class Container, class CombineOp>
static void mapCombineReduce
(
@ -351,37 +389,33 @@ public:
}
private:
// Private implementations
//- Gather data, but keep individual values separate.
template<class T>
static void gatherList_tree_algorithm
(
//! [in,out]
UList<T>& values,
const int tag,
const label communicator
);
//- Inverse of gatherList_tree_algorithm
template<class T>
static void scatterList_tree_algorithm
(
//! [in,out]
UList<T>& values,
const int tag,
const label communicator
);
public:
// Gather/scatter keeping the individual processor data separate.
// The values is a List of size UPstream::nProcs() where
// values[UPstream::myProcNo()] is the data for the current processor.
//- Implementation: gather data, keeping individual values separate.
//- Output is only valid (consistent) on UPstream::masterNo()
template<class T>
static void gatherList_algorithm
(
const UPstream::commsStructList& comms, //!< Communication order
//! [in,out]
UList<T>& values,
const int tag,
const int communicator
);
//- Implementation: inverse of gatherList_algorithm
template<class T>
static void scatterList_algorithm
(
const UPstream::commsStructList& comms, //!< Communication order
//! [in,out]
UList<T>& values,
const int tag,
const int communicator
);
//- Gather data, but keep individual values separate.
template<class T>
static void gatherList

View File

@ -49,12 +49,13 @@ Note
// Single value variants
template<class T, class BinaryOp, bool InplaceMode>
void Foam::Pstream::gather
void Foam::Pstream::gather_algorithm
(
const UPstream::commsStructList& comms, // Communication order
T& value,
const BinaryOp& bop,
const int tag,
const label communicator
const int communicator
)
{
if (!UPstream::is_parallel(communicator))
@ -64,12 +65,12 @@ void Foam::Pstream::gather
}
else
{
// Communication order
const auto& comms = UPstream::whichCommunication(communicator);
// if (comms.empty()) return; // extra safety?
const auto& myComm = comms[UPstream::myProcNo(communicator)];
const label myProci = UPstream::myProcNo(communicator);
const auto& myComm = comms[myProci];
const auto& below = myComm.below();
// Receive from my downstairs neighbours
for (const auto proci : below)
{
@ -146,6 +147,37 @@ void Foam::Pstream::gather
}
template<class T, class BinaryOp, bool InplaceMode>
void Foam::Pstream::gather
(
T& value,
const BinaryOp& bop,
const int tag,
const label communicator
)
{
if (!UPstream::is_parallel(communicator))
{
// Nothing to do
return;
}
else
{
// Communication order
const auto& commOrder = UPstream::whichCommunication(communicator);
Pstream::gather_algorithm<T, BinaryOp, InplaceMode>
(
commOrder,
value,
bop,
tag,
communicator
);
}
}
template<class T, class CombineOp>
void Foam::Pstream::combineGather
(
@ -183,12 +215,13 @@ void Foam::Pstream::combineReduce
// List variants
template<class T, class BinaryOp, bool InplaceMode>
void Foam::Pstream::listGather
void Foam::Pstream::listGather_algorithm
(
const UPstream::commsStructList& comms, // Communication order
UList<T>& values,
const BinaryOp& bop,
const int tag,
const label communicator
const int communicator
)
{
if (!UPstream::is_parallel(communicator) || values.empty())
@ -198,10 +231,9 @@ void Foam::Pstream::listGather
}
else
{
// Communication order
const auto& comms = UPstream::whichCommunication(communicator);
// if (comms.empty()) return; // extra safety?
const auto& myComm = comms[UPstream::myProcNo(communicator)];
const label myProci = UPstream::myProcNo(communicator);
const auto& myComm = comms[myProci];
const auto& below = myComm.below();
// Same length on all ranks
@ -295,17 +327,70 @@ void Foam::Pstream::listGather
template<class T, class BinaryOp, bool InplaceMode>
void Foam::Pstream::listGatherReduce
void Foam::Pstream::listGather
(
List<T>& values,
UList<T>& values,
const BinaryOp& bop,
const int tag,
const label communicator
)
{
if (!UPstream::is_parallel(communicator) || values.empty())
{
// Nothing to do
return;
}
else if (values.size() == 1)
{
// Single value - optimized version
Pstream::gather<T, BinaryOp, InplaceMode>
(
values[0],
bop,
tag,
communicator
);
}
else
{
// Communication order
const auto& commOrder = UPstream::whichCommunication(communicator);
Pstream::listGather_algorithm<T, BinaryOp, InplaceMode>
(
commOrder,
values,
bop,
tag,
communicator
);
}
}
template<class T, class BinaryOp, bool InplaceMode>
void Foam::Pstream::listReduce
(
UList<T>& values,
const BinaryOp& bop,
const int tag,
const label comm
)
{
Pstream::listGather<T, BinaryOp, InplaceMode>(values, bop, tag, comm);
if (!values.empty())
if (!UPstream::is_parallel(comm) || values.empty())
{
// Nothing to do
}
else if (values.size() == 1)
{
// Single value - optimized version
Pstream::gather<T, BinaryOp, InplaceMode>(values[0], bop, tag, comm);
Pstream::broadcast(values[0], comm);
}
else
{
// Multiple values
Pstream::listGather<T, BinaryOp, InplaceMode>(values, bop, tag, comm);
Pstream::broadcast(values, comm);
}
}
@ -328,14 +413,14 @@ void Foam::Pstream::listCombineGather
template<class T, class CombineOp>
void Foam::Pstream::listCombineReduce
(
List<T>& values,
UList<T>& values,
const CombineOp& cop,
const int tag,
const label comm
)
{
// In-place binary operation
Pstream::listGatherReduce<T, CombineOp, true>(values, cop, tag, comm);
Pstream::listReduce<T, CombineOp, true>(values, cop, tag, comm);
}
@ -344,12 +429,13 @@ void Foam::Pstream::listCombineReduce
// Map variants
template<class Container, class BinaryOp, bool InplaceMode>
void Foam::Pstream::mapGather
void Foam::Pstream::mapGather_algorithm
(
const UPstream::commsStructList& comms, // Communication order
Container& values,
const BinaryOp& bop,
const int tag,
const label communicator
const int communicator
)
{
if (!UPstream::is_parallel(communicator))
@ -359,12 +445,12 @@ void Foam::Pstream::mapGather
}
else
{
// Communication order
const auto& comms = UPstream::whichCommunication(communicator);
// if (comms.empty()) return; // extra safety?
const auto& myComm = comms[UPstream::myProcNo(communicator)];
const label myProci = UPstream::myProcNo(communicator);
const auto& myComm = comms[myProci];
const auto& below = myComm.below();
// Receive from my downstairs neighbours
for (const auto proci : below)
{
@ -430,7 +516,38 @@ void Foam::Pstream::mapGather
template<class Container, class BinaryOp, bool InplaceMode>
void Foam::Pstream::mapGatherReduce
void Foam::Pstream::mapGather
(
Container& values,
const BinaryOp& bop,
const int tag,
const label communicator
)
{
if (!UPstream::is_parallel(communicator))
{
// Nothing to do
return;
}
else
{
// Communication order
const auto& commOrder = UPstream::whichCommunication(communicator);
Pstream::mapGather_algorithm<Container, BinaryOp, InplaceMode>
(
commOrder,
values,
bop,
tag,
communicator
);
}
}
template<class Container, class BinaryOp, bool InplaceMode>
void Foam::Pstream::mapReduce
(
Container& values,
const BinaryOp& bop,
@ -473,7 +590,7 @@ void Foam::Pstream::mapCombineReduce
)
{
// In-place binary operation
Pstream::mapGatherReduce<Container, CombineOp, true>
Pstream::mapReduce<Container, CombineOp, true>
(
values, cop, tag, comm
);

View File

@ -43,11 +43,12 @@ Description
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
void Foam::Pstream::gatherList_tree_algorithm
void Foam::Pstream::gatherList_algorithm
(
const UPstream::commsStructList& comms, // Communication order
UList<T>& values,
const int tag,
const label communicator
const int communicator
)
{
if (FOAM_UNLIKELY(!UPstream::is_parallel(communicator)))
@ -65,11 +66,8 @@ void Foam::Pstream::gatherList_tree_algorithm
<< Foam::abort(FatalError);
}
const label myProci = UPstream::myProcNo(communicator);
// Communication order
const auto& comms = UPstream::whichCommunication(communicator);
// if (comms.empty()) return; // extra safety?
const label myProci = UPstream::myProcNo(communicator);
const auto& myComm = comms[myProci];
@ -253,11 +251,12 @@ void Foam::Pstream::gatherList_tree_algorithm
template<class T>
void Foam::Pstream::scatterList_tree_algorithm
void Foam::Pstream::scatterList_algorithm
(
const UPstream::commsStructList& comms, // Communication order
UList<T>& values,
const int tag,
const label communicator
const int communicator
)
{
if (FOAM_UNLIKELY(!UPstream::is_parallel(communicator)))
@ -279,11 +278,8 @@ void Foam::Pstream::scatterList_tree_algorithm
<< Foam::abort(FatalError);
}
const label myProci = UPstream::myProcNo(communicator);
// Communication order
const auto& comms = UPstream::whichCommunication(communicator);
// if (comms.empty()) return; // extra safety?
const label myProci = UPstream::myProcNo(communicator);
const auto& myComm = comms[myProci];
@ -448,7 +444,10 @@ void Foam::Pstream::gatherList
}
else
{
Pstream::gatherList_tree_algorithm(values, tag, communicator);
// Communication order
const auto& commOrder = UPstream::whichCommunication(communicator);
Pstream::gatherList_algorithm(commOrder, values, tag, communicator);
}
}
@ -479,7 +478,10 @@ void Foam::Pstream::scatterList
}
else
{
Pstream::scatterList_tree_algorithm(values, tag, communicator);
// Communication order
const auto& commOrder = UPstream::whichCommunication(communicator);
Pstream::scatterList_algorithm(commOrder, values, tag, communicator);
}
}
@ -511,8 +513,11 @@ void Foam::Pstream::allGatherList
}
else
{
Pstream::gatherList(values, tag, comm);
Pstream::scatterList(values, tag, comm);
// Communication order
const auto& commOrder = UPstream::whichCommunication(comm);
Pstream::gatherList_algorithm(commOrder, values, tag, comm);
Pstream::scatterList_algorithm(commOrder, values, tag, comm);
}
}

View File

@ -100,21 +100,6 @@ void reduce
NotImplemented;
}
//- Non-blocking reduce inplace (cf. MPI Iallreduce)
//- single value. Sets request.
template<class T, class BinaryOp>
void reduce
(
T& Value,
const BinaryOp&,
const int tag,
const label comm,
label& request
)
{
NotImplemented;
}
//- Non-blocking reduce inplace (cf. MPI Iallreduce)
//- of multiple values (same size on all ranks!). Sets request.
template<class T, class BinaryOp>
@ -131,22 +116,6 @@ void reduce
NotImplemented;
}
//- Non-blocking reduce inplace (cf. MPI Iallreduce)
//- of multiple values (same size on all ranks!). Sets request.
template<class T, class BinaryOp>
void reduce
(
T values[],
const int size,
const BinaryOp&,
const int tag,
const label comm,
label& request
)
{
NotImplemented;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -295,18 +264,6 @@ void reduce \
UPstream::Request& req /*!< [out] request information */ \
); \
\
/*! \brief Non-blocking reduce (sum) multiple Native values. Sets request */ \
/*! \deprecated prefer version with UPstream::Request */ \
void reduce \
( \
Native values[], \
const int size, \
const sumOp<Native>&, \
const int tag, /*!< (ignored) */ \
const label comm, \
label& requestID \
); \
\
/*! \brief Non-blocking reduce (sum) single Native value. Sets request */ \
void reduce \
( \
@ -315,17 +272,6 @@ void reduce \
const int tag, /*!< (ignored) */ \
const label comm, \
UPstream::Request& req /*!< [out] request information */ \
); \
\
/*! \brief Non-blocking reduce (sum) single Native value. Sets request */ \
/*! \deprecated prefer version with UPstream::Request */ \
void reduce \
( \
Native& value, \
const sumOp<Native>&, \
const int tag, /*!< (ignored) */ \
const label comm, \
label& requestID \
);

View File

@ -58,6 +58,58 @@ Foam::UPstream::commsTypeNames
});
// * * * * * * * * * * * * * Controls Information * * * * * * * * * * * * * //
void Foam::UPstream::printNodeCommsControl(Ostream& os)
{
if (UPstream::nodeCommsControl_ > 0)
{
if (UPstream::usingNodeComms(UPstream::worldComm))
{
os << "on [";
}
else
{
os << "off [";
}
if (UPstream::nodeCommsMin_ > 2)
{
os << "min=" << UPstream::nodeCommsMin_ << ",";
}
os << "type=";
// 1: split by hostname [default]
// 2: split by shared
// >=4: (debug/manual) split with given number per node
if (UPstream::nodeCommsControl_ >= 4)
{
os << UPstream::nodeCommsControl_;
}
else if (UPstream::nodeCommsControl_ == 2)
{
os << "shared";
}
else
{
os << "host";
}
os << "]";
}
else
{
os << "disabled";
}
os << " (" << UPstream::nProcs(UPstream::worldComm) << " ranks, "
<< UPstream::numNodes() << " nodes)";
}
void Foam::UPstream::printTopoControl(Ostream& os)
{
os << "none";
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::UPstream::setParRun(const label nProcs, const bool haveThreads)
@ -187,6 +239,10 @@ Foam::label Foam::UPstream::getAvailableCommIndex(const label parentIndex)
treeCommunication_.emplace_back(index);
}
// Set the communication pattern
linearCommunication_[index].linear(true);
treeCommunication_[index].linear(false);
return index;
}
@ -617,32 +673,50 @@ Foam::label Foam::UPstream::procNo
const Foam::UPstream::commsStructList&
Foam::UPstream::linearCommunication(const label communicator)
Foam::UPstream::linearCommunication(int communicator)
{
// linear = true
if (linearCommunication_[communicator].empty())
{
linearCommunication_[communicator].init(communicator);
linearCommunication_[communicator].init(communicator, true);
}
// Probably not needed
// else
// {
// linearCommunication_[communicator].linear(true);
// }
return linearCommunication_[communicator];
}
const Foam::UPstream::commsStructList&
Foam::UPstream::treeCommunication(const label communicator)
Foam::UPstream::treeCommunication(int communicator)
{
// linear = false
if (treeCommunication_[communicator].empty())
{
treeCommunication_[communicator].init(communicator);
treeCommunication_[communicator].init(communicator, false);
}
// Probably not needed
// else
// {
// treeCommunication_[communicator].linear(false);
// }
return treeCommunication_[communicator];
}
void Foam::UPstream::printCommTree(int communicator)
void Foam::UPstream::printCommTree
(
int communicator,
bool linear
)
{
const auto& comms = UPstream::whichCommunication(communicator);
const auto& comms = UPstream::whichCommunication(communicator, linear);
if (UPstream::master(communicator))
{
@ -789,6 +863,17 @@ registerOptSwitch
);
int Foam::UPstream::topologyControl_
(
Foam::debug::optimisationSwitch("topoControl", 0)
);
registerOptSwitch
(
"topoControl",
int,
Foam::UPstream::topologyControl_
);
bool Foam::UPstream::floatTransfer
(
Foam::debug::optimisationSwitch("floatTransfer", 0)

View File

@ -179,7 +179,14 @@ public:
//- Reset to default constructed state
void reset();
//- Reset (automatic linear/tree selection),
//- Reset to linear (flat) communication
void reset_linear
(
const int myProci,
const int numProcs
);
//- Reset to tree selection (linear when very small),
//- possibly with communicator-specific adjustments
void reset
(
@ -205,6 +212,9 @@ public:
//- The communicator index
int comm_;
//- Linear (flat) communication instead of tree communication
bool flat_;
//- The communication tree
List<commsStruct> tree_;
@ -213,10 +223,18 @@ public:
// Constructors
//- Construct empty with invalid communicator
commsStructList() noexcept : comm_(-1) {}
commsStructList() noexcept
:
comm_(-1),
flat_(false)
{}
//- Construct empty with given communicator
explicit commsStructList(int comm) noexcept : comm_(comm) {}
explicit commsStructList(int comm, bool flat=false) noexcept
:
comm_(comm),
flat_(flat)
{}
// Static Functions
@ -233,6 +251,13 @@ public:
//- The communicator internal index
int comm() const noexcept { return comm_; }
//- Linear (flat) communication instead of tree communication
bool linear() const noexcept { return flat_; }
//- Change communication type (linear vs tree communication).
//- Resets existing structure.
void linear(bool on);
//- Clear the list
void clear() { return tree_.clear(); }
@ -245,9 +270,17 @@ public:
//- Reset communicator index, fill tree with empty entries
void init(int communicator);
//- Reset communicator index, fill tree with empty entries.
//- Specify flat vs tree communication.
void init(int communicator, bool flat);
//- Reset communicator index, clear tree entries
void reset(int communicator);
//- Reset communicator index, clear tree entries.
//- Specify flat vs tree communication.
void reset(int communicator, bool flat);
//- Get existing or create (demand-driven) entry
const UPstream::commsStruct& get(int proci) const;
@ -404,6 +437,15 @@ public:
// >= 3 : when there are more than N nodes
static int nodeCommsMin_;
//- Selection of topology-aware routines
static int topologyControl_;
//- Test for selection of given topology-aware routine (bitmask)
static bool usingTopoControl(int routine = 0) noexcept
{
return static_cast<bool>(topologyControl_ & routine);
}
//- Should compact transfer be used in which floats replace doubles
//- reducing the bandwidth requirement at the expense of some loss
//- in accuracy
@ -481,7 +523,7 @@ public:
static label nComms() noexcept { return parentComm_.size(); }
//- Debugging: print the communication tree
static void printCommTree(const label communicator);
static void printCommTree(int communicator, bool linear = false);
// Host Communicators
@ -757,6 +799,15 @@ public:
);
// Information
//- Report the node-communication settings
static void printNodeCommsControl(Ostream& os);
//- Report the topology routines settings
static void printTopoControl(Ostream& os);
// Requests (non-blocking comms).
// Pending requests are usually handled as an internal (global) list,
// since this simplifies the overall tracking and provides a convenient
@ -771,8 +822,9 @@ public:
// A no-op for out-of-range values.
static void resetRequests(const label n);
//- Transfer the (wrapped) MPI request to the internal global list.
// A no-op for non-parallel. No special treatment for null requests.
//- Transfer the (wrapped) MPI request to the internal global list
//- and invalidate the parameter (ignores null requests)
// A no-op for non-parallel,
static void addRequest(UPstream::Request& req);
//- Non-blocking comms: cancel and free outstanding request.
@ -784,7 +836,7 @@ public:
//- Non-blocking comms: cancel and free outstanding request.
//- Corresponds to MPI_Cancel() + MPI_Request_free()
// A no-op if parRun() == false
// A no-op for non-parallel
static void cancelRequest(UPstream::Request& req);
//- Non-blocking comms: cancel and free outstanding requests.
@ -1081,38 +1133,34 @@ public:
static const List<int>& interNode_offsets();
//- Communication schedule for linear all-to-master (proc 0)
static const commsStructList& linearCommunication
(
const label communicator = worldComm
);
//- Linear communication schedule (special case) for given communicator
static const commsStructList& linearCommunication(int communicator);
//- Communication schedule for tree all-to-master (proc 0)
static const commsStructList& treeCommunication
(
const label communicator = worldComm
);
//- Tree communication schedule (standard case) for given communicator
static const commsStructList& treeCommunication(int communicator);
//- Communication schedule for all-to-master (proc 0) as
//- linear/tree/none with switching based on UPstream::nProcsSimpleSum
//- and the is_parallel() state
//- and the is_parallel() state and the optional \c linear parameter.
static const commsStructList& whichCommunication
(
const label communicator = worldComm
const int communicator,
//! optionally select linear schedule only
bool linear = false
)
{
const label np
(
parRun_ && is_rank(communicator) // cf. is_parallel()
? nProcs(communicator)
: 0
: label(0)
);
return
(
np <= 1
? commsStructList::null()
: (np <= 2 || np < UPstream::nProcsSimpleSum)
: (linear || np < UPstream::nProcsSimpleSum)
? linearCommunication(communicator)
: treeCommunication(communicator)
);

View File

@ -338,6 +338,32 @@ void Foam::UPstream::commsStruct::reset()
}
void Foam::UPstream::commsStruct::reset_linear
(
const int myProci,
const int numProcs
)
{
reset();
// Linear (flat) communication pattern
int above(-1);
List<int> below;
if (myProci == 0)
{
below.resize(numProcs-1);
std::iota(below.begin(), below.end(), 1);
}
else
{
above = 0;
}
*this = UPstream::commsStruct(numProcs, myProci, above, below, below);
}
void Foam::UPstream::commsStruct::reset
(
const int myProci,
@ -345,52 +371,28 @@ void Foam::UPstream::commsStruct::reset
const int communicator
)
{
reset();
// Linear (flat) communication pattern
if
(
// Trivially small domains
(numProcs <= 2 || numProcs < UPstream::nProcsSimpleSum)
// local-node: assume that the local communication is low-latency
|| (
UPstream::commLocalNode() == communicator
&& UPstream::commLocalNode() > UPstream::commConstWorld()
)
// inter-node: presumably relatively few nodes and/or
// higher latency with larger messages being sent
|| (
UPstream::commInterNode() == communicator
&& UPstream::commInterNode() > UPstream::commConstWorld()
)
)
// Trivially small domains
if (numProcs <= 2)
{
// Linear communication pattern
int above(-1);
List<int> below;
if (myProci == 0)
{
below.resize(numProcs-1);
std::iota(below.begin(), below.end(), 1);
}
else
{
above = 0;
}
*this = UPstream::commsStruct(numProcs, myProci, above, below, below);
reset_linear(myProci, numProcs);
return;
}
reset();
int above(-1);
DynamicList<int> below;
DynamicList<int> allBelow;
if (UPstream::usingNodeComms(communicator))
{
// Additional treatment...
}
// Simple tree communication pattern
int above = simpleTree
above = simpleTree
(
myProci,
numProcs,
@ -420,6 +422,38 @@ Foam::UPstream::commsStructList::null()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::UPstream::commsStructList::linear(bool on)
{
if (flat_ != on)
{
// Current size
const auto len = tree_.size();
flat_ = on;
tree_.clear();
if (len > 0)
{
tree_.resize(len);
}
}
}
void Foam::UPstream::commsStructList::reset(int communicator)
{
comm_ = communicator;
tree_.clear();
}
void Foam::UPstream::commsStructList::reset(int communicator, bool flat)
{
comm_ = communicator;
tree_.clear();
flat_ = flat;
}
void Foam::UPstream::commsStructList::init(int communicator)
{
comm_ = communicator;
@ -431,10 +465,10 @@ void Foam::UPstream::commsStructList::init(int communicator)
}
void Foam::UPstream::commsStructList::reset(int communicator)
void Foam::UPstream::commsStructList::init(int communicator, bool flat)
{
comm_ = communicator;
tree_.clear();
init(communicator);
flat_ = flat;
}
@ -454,8 +488,17 @@ Foam::UPstream::commsStructList::get(int proci) const
if (entry.nProcs() != numProcs)
{
// Create/update
const_cast<UPstream::commsStruct&>(entry)
.reset(proci, numProcs, comm_);
if (flat_)
{
const_cast<UPstream::commsStruct&>(entry)
.reset_linear(proci, numProcs);
}
else
{
const_cast<UPstream::commsStruct&>(entry)
.reset(proci, numProcs, comm_);
}
}
return entry;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -275,24 +275,26 @@ cmptAv(const tmp<DimensionedField<Type, GeoMesh>>& tf1)
template<class Type, class GeoMesh> \
dimensioned<ReturnType> Func \
( \
const DimensionedField<Type, GeoMesh>& f1 \
const DimensionedField<Type, GeoMesh>& f1, \
const label comm \
) \
{ \
return dimensioned<ReturnType> \
( \
#Func "(" + f1.name() + ')', \
f1.dimensions(), \
gFunc(f1.field()) \
gFunc(f1.field(), comm) \
); \
} \
\
template<class Type, class GeoMesh> \
dimensioned<ReturnType> Func \
( \
const tmp<DimensionedField<Type, GeoMesh>>& tf1 \
const tmp<DimensionedField<Type, GeoMesh>>& tf1, \
const label comm \
) \
{ \
dimensioned<ReturnType> res = Func(tf1()); \
dimensioned<ReturnType> res = Func(tf1(), comm); \
tf1.clear(); \
return res; \
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -107,12 +107,14 @@ cmptAv(const tmp<DimensionedField<Type, GeoMesh>>& tf1);
template<class Type, class GeoMesh> \
dimensioned<ReturnType> Func \
( \
const DimensionedField<Type, GeoMesh>& f1 \
const DimensionedField<Type, GeoMesh>& f1, \
const label comm = UPstream::worldComm \
); \
template<class Type, class GeoMesh> \
dimensioned<ReturnType> Func \
( \
const tmp<DimensionedField<Type, GeoMesh>>& tf1 \
const tmp<DimensionedField<Type, GeoMesh>>& tf1, \
const label comm = UPstream::worldComm \
);
UNARY_REDUCTION_FUNCTION(Type, max, gMax)

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2024 OpenCFD Ltd.
Copyright (C) 2015-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -1132,10 +1132,11 @@ Foam::word Foam::GeometricField<Type, PatchField, GeoMesh>::select
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::writeMinMax
(
Ostream& os
Ostream& os,
label comm
) const
{
MinMax<Type> range = Foam::minMax(*this).value();
MinMax<Type> range = Foam::minMax(*this, comm).value();
os << "min/max(" << this->name() << ") = "
<< range.min() << ", " << range.max() << endl;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2024 OpenCFD Ltd.
Copyright (C) 2015-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -906,8 +906,9 @@ public:
//- otherwise the standard parameters by returning the field name
word select(bool final) const;
//- Helper function to write the min and max to an Ostream
void writeMinMax(Ostream& os) const;
//- Helper function to write the min and max to an Ostream.
// Uses the specified communicator for reductions
void writeMinMax(Ostream& os, label comm = UPstream::worldComm) const;
// Member Function *this Operators
@ -1037,6 +1038,7 @@ public:
//- Clamp field values (in-place) to the specified range.
// \deprecated(2023-01) prefer clamp_range() naming
FOAM_DEPRECATED_FOR(2023-01, "clamp_range() method")
void clip(const dimensioned<MinMax<Type>>& range)
{
this->clamp_range(range);
@ -1044,6 +1046,7 @@ public:
//- Clamp field values (in-place) to the specified range.
// \deprecated(2023-01) prefer clamp_range() naming
FOAM_DEPRECATED_FOR(2023-01, "clamp_range() method")
void clip(const dimensioned<Type>& lo, const dimensioned<Type>& hi)
{
this->clamp_range(lo.value(), hi.value());
@ -1076,13 +1079,12 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "GeometricFieldI.H"
#include "GeometricFieldFunctions.H"
#ifdef NoRepository
#include "GeometricField.C"
#endif
#include "GeometricFieldFunctions.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -429,7 +429,8 @@ cmptAv(const tmp<GeometricField<Type, PatchField, GeoMesh>>& tf1)
template<class Type, template<class> class PatchField, class GeoMesh> \
dimensioned<ReturnType> Func \
( \
const GeometricField<Type, PatchField, GeoMesh>& f1 \
const GeometricField<Type, PatchField, GeoMesh>& f1, \
const label comm \
) \
{ \
return dimensioned<ReturnType> \
@ -443,7 +444,9 @@ dimensioned<ReturnType> Func \
Foam::Func(f1.primitiveField()), \
Foam::Func(f1.boundaryField()) \
), \
BinaryOp<ReturnType>() \
BinaryOp<ReturnType>(), \
UPstream::msgType(), \
comm \
) \
); \
} \
@ -451,52 +454,52 @@ dimensioned<ReturnType> Func \
template<class Type, template<class> class PatchField, class GeoMesh> \
dimensioned<ReturnType> Func \
( \
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tf1 \
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tf1, \
const label comm \
) \
{ \
dimensioned<ReturnType> res = Func(tf1()); \
dimensioned<ReturnType> res = Func(tf1(), comm); \
tf1.clear(); \
return res; \
}
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(Type, max, maxOp)
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(Type, min, minOp)
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(MinMax<Type>, minMax, minMaxOp)
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(scalarMinMax, minMaxMag, minMaxMagOp)
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(MinMax<Type>, minMax, plusOp)
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(scalarMinMax, minMaxMag, plusOp)
#undef UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY
#define UNARY_REDUCTION_FUNCTION(ReturnType, Func, gFunc) \
// Forward to DimensionedField directly (same name)
#define UNARY_REDUCTION_FUNCTION(ReturnType, Func) \
\
template<class Type, template<class> class PatchField, class GeoMesh> \
dimensioned<ReturnType> Func \
( \
const GeometricField<Type, PatchField, GeoMesh>& f1 \
const GeometricField<Type, PatchField, GeoMesh>& f1, \
const label comm \
) \
{ \
return dimensioned<ReturnType> \
( \
#Func "(" + f1.name() + ')', \
f1.dimensions(), \
gFunc(f1.primitiveField()) \
); \
return Func(f1.internalField(), comm); \
} \
\
template<class Type, template<class> class PatchField, class GeoMesh> \
dimensioned<ReturnType> Func \
( \
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tf1 \
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tf1, \
const label comm \
) \
{ \
dimensioned<ReturnType> res = Func(tf1()); \
auto result = Func(tf1(), comm); \
tf1.clear(); \
return res; \
return result; \
}
UNARY_REDUCTION_FUNCTION(Type, sum, gSum)
UNARY_REDUCTION_FUNCTION(Type, average, gAverage)
UNARY_REDUCTION_FUNCTION(typename typeOfMag<Type>::type, sumMag, gSumMag)
UNARY_REDUCTION_FUNCTION(Type, sum)
UNARY_REDUCTION_FUNCTION(Type, average)
UNARY_REDUCTION_FUNCTION(typename typeOfMag<Type>::type, sumMag)
#undef UNARY_REDUCTION_FUNCTION

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -225,40 +225,45 @@ cmptAv(const tmp<GeometricField<Type, PatchField, GeoMesh>>& tf1);
template<class Type, template<class> class PatchField, class GeoMesh> \
dimensioned<ReturnType> Func \
( \
const GeometricField<Type, PatchField, GeoMesh>& f1 \
const GeometricField<Type, PatchField, GeoMesh>& f1, \
const label comm = UPstream::worldComm \
); \
\
template<class Type, template<class> class PatchField, class GeoMesh> \
dimensioned<ReturnType> Func \
( \
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tf1 \
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tf1, \
const label comm = UPstream::worldComm \
);
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(Type, max, maxOp)
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(Type, min, minOp)
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(MinMax<Type>, minMax, minMaxOp)
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(scalarMinMax, minMaxMag, minMaxMagOp)
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(MinMax<Type>, minMax, plusOp)
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(scalarMinMax, minMaxMag, plusOp)
#undef UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY
#define UNARY_REDUCTION_FUNCTION(ReturnType, Func, gFunc) \
#define UNARY_REDUCTION_FUNCTION(ReturnType, Func) \
\
/*! \brief Forwards to Func on internalField */ \
template<class Type, template<class> class PatchField, class GeoMesh> \
dimensioned<ReturnType> Func \
( \
const GeometricField<Type, PatchField, GeoMesh>& f1 \
const GeometricField<Type, PatchField, GeoMesh>& f1, \
const label comm = UPstream::worldComm \
); \
\
template<class Type, template<class> class PatchField, class GeoMesh> \
dimensioned<ReturnType> Func \
( \
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tf1 \
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tf1, \
const label comm = UPstream::worldComm \
);
UNARY_REDUCTION_FUNCTION(Type, sum, gSum)
UNARY_REDUCTION_FUNCTION(Type, average, gAverage)
UNARY_REDUCTION_FUNCTION(typename typeOfMag<Type>::type, sumMag, gSumMag)
UNARY_REDUCTION_FUNCTION(Type, sum)
UNARY_REDUCTION_FUNCTION(Type, average)
UNARY_REDUCTION_FUNCTION(typename typeOfMag<Type>::type, sumMag)
#undef UNARY_REDUCTION_FUNCTION

View File

@ -2094,21 +2094,17 @@ void Foam::argList::parse
}
}
Info<< "Pstream initialized with:" << nl
<< " node communication : ";
if (UPstream::nodeCommsControl_ > 0)
Info<< "Pstream initialized with:" << nl;
{
Info<< Switch::name(UPstream::usingNodeComms())
<< " [min=" << UPstream::nodeCommsMin_
<< ", type=" << UPstream::nodeCommsControl_
<< "]";
Info<< " node communication : ";
UPstream::printNodeCommsControl(Info);
Info<< nl;
}
else
{
Info<< "disabled";
Info<< " topology controls : ";
UPstream::printTopoControl(Info);
Info<< nl;
}
Info<< " (" << UPstream::nProcs() << " ranks, "
<< UPstream::numNodes() << " nodes)" << nl;
if (UPstream::floatTransfer)
{
@ -2128,7 +2124,7 @@ void Foam::argList::parse
const auto& commsType =
UPstream::commsTypeNames[UPstream::defaultCommsType];
Info<< " nonBlockingExchange: "
Info<< " consensus exchange : "
<< UPstream::nProcsNonblockingExchange
<< " (tuning: " << UPstream::tuning_NBX_ << ')' << nl
<< " exchange algorithm : "

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -110,9 +110,15 @@ typedef MinMax<scalar> scalarMinMax; //!< A scalar min/max range
template<class T>
class MinMax
:
public Tuple2<T,T>
{
// Private Data
//- Min value
T min_;
//- Max value
T max_;
public:
// Typedefs
@ -126,23 +132,26 @@ public:
// Constructors
//- Construct inverted range
//- Default construct: an inverted range
inline MinMax();
//- Copy construct from components
//- Construct from min/max limits
inline MinMax(const T& minVal, const T& maxVal);
//- Copy construct from components
//- Implicit construct from min/max limits
inline MinMax(const std::pair<T,T>& range);
//- Copy construct from components
//- Implicit construct from min/max limits
inline MinMax(const Pair<T>& range);
//- Implicit construct from min/max limits
inline MinMax(const Tuple2<T,T>& range);
//- Construct with a single zero value
inline explicit MinMax(const Foam::zero);
inline explicit MinMax(Foam::zero);
//- Implicit construct from zero_one as 0-1 range (pTraits zero, one)
inline MinMax(const Foam::zero_one);
inline MinMax(Foam::zero_one);
//- Construct with a single initial value
inline explicit MinMax(const T& val);
@ -167,25 +176,25 @@ public:
// Access
//- The min value (first)
inline const T& min() const noexcept;
//- The min value
const T& min() const noexcept { return min_; }
//- The min value (first)
inline T& min() noexcept;
//- The min value
T& min() noexcept { return min_; }
//- The max value (second)
inline const T& max() const noexcept;
//- The max value
const T& max() const noexcept { return max_; }
//- The max value (second)
inline T& max() noexcept;
//- The max value
T& max() noexcept { return max_; }
//- The min/max average value
inline T centre() const;
//- The min to max span. Zero if the range is invalid.
//- The min to max span. Zero for invalid range.
inline T span() const;
//- The magnitude of the min to max span. Zero if the range is invalid.
//- The magnitude of the min to max span. Zero for invalid range.
inline scalar mag() const;
//- Range is empty if it is inverted
@ -194,9 +203,6 @@ public:
//- Range is non-inverted
inline bool good() const;
//- Range is non-inverted
bool valid() const { return good(); }
//- Reset to an inverted (invalid) range
inline void reset();
@ -244,6 +250,11 @@ public:
//- Include the values into the range
inline MinMax<T>& add(const UList<T>& vals);
//- Include two or more values into the range.
// All values must be similar types
template<class... Args>
inline MinMax<T>& add(const T& val0, const T& val1, Args&&... values);
// Member Operators
@ -264,23 +275,33 @@ public:
inline MinMax<T>& operator+=(const UList<T>& vals);
//- Multiply range by scalar factor
inline MinMax<T>& operator*=(const scalar& s);
inline MinMax<T>& operator*=(scalar s);
//- Divide range by scalar factor
inline MinMax<T>& operator/=(const scalar& s);
inline MinMax<T>& operator/=(scalar s);
// Housekeeping
//- Range is non-inverted. Same as good (2022-10)
bool valid() const { return good(); }
//- Old method name. Same as clamp (2023-01)
T clip(const T& val) const { return this->clamp(val); }
//- Old method (2023-01)
void inplaceClip(T& val) const { val = this->clamp(val); }
};
// Global Functions
// * * * * * * * * * * * * * * * * * Traits * * * * * * * * * * * * * * * * //
//- Declare MinMax as non-contiguous (similar to Tuple2).
// Output remains separate (even in binary) and, since the defined
// \c operator+ is somewhat non-standard, also avoid false matching with
// any MPI intrinsic operation.
template<class T>
struct is_contiguous<MinMax<T>> : std::false_type {};
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
//- Min/max range as a string
template<class T>
@ -289,6 +310,30 @@ word name(const MinMax<T>& range)
return '(' + Foam::name(range.min()) + ',' + Foam::name(range.max()) + ')';
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
//- Read min/max range as (min max) tuple from Istream
template<class T>
inline Istream& operator>>(Istream& is, MinMax<T>& range)
{
is.readBegin("min.max");
is >> range.min() >> range.max();
is.readEnd("min.max");
is.check(FUNCTION_NAME);
return is;
}
//- Write min/max range as (min max) tuple to Ostream
template<class T>
inline Ostream& operator<<(Ostream& os, const MinMax<T>& range)
{
os << token::BEGIN_LIST
<< range.min() << token::SPACE << range.max()
<< token::END_LIST;
return os;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -53,49 +53,65 @@ inline Foam::MinMax<T> Foam::MinMax<T>::zero_one()
template<class T>
inline Foam::MinMax<T>::MinMax()
:
Tuple2<T,T>(pTraits<T>::max, pTraits<T>::min)
// An inverted range
min_(pTraits<T>::max),
max_(pTraits<T>::min)
{}
template<class T>
inline Foam::MinMax<T>::MinMax(const T& minVal, const T& maxVal)
:
Tuple2<T,T>(minVal, maxVal)
min_(minVal),
max_(maxVal)
{}
template<class T>
inline Foam::MinMax<T>::MinMax(const std::pair<T,T>& range)
:
Tuple2<T,T>(range.first, range.second)
min_(range.first),
max_(range.second)
{}
template<class T>
inline Foam::MinMax<T>::MinMax(const Pair<T>& range)
:
Tuple2<T,T>(range.first(), range.second())
min_(range.first()),
max_(range.second())
{}
template<class T>
inline Foam::MinMax<T>::MinMax(const Foam::zero)
inline Foam::MinMax<T>::MinMax(const Tuple2<T,T>& range)
:
Tuple2<T,T>(pTraits<T>::zero, pTraits<T>::zero)
min_(range.first()),
max_(range.second())
{}
template<class T>
inline Foam::MinMax<T>::MinMax(const Foam::zero_one)
inline Foam::MinMax<T>::MinMax(Foam::zero)
:
Tuple2<T,T>(pTraits<T>::zero, pTraits<T>::one)
min_(pTraits<T>::zero),
max_(pTraits<T>::zero)
{}
template<class T>
inline Foam::MinMax<T>::MinMax(Foam::zero_one)
:
min_(pTraits<T>::zero),
max_(pTraits<T>::one)
{}
template<class T>
inline Foam::MinMax<T>::MinMax(const T& val)
:
Tuple2<T,T>(val, val)
min_(val),
max_(val)
{}
@ -110,34 +126,6 @@ inline Foam::MinMax<T>::MinMax(const UList<T>& vals)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
inline const T& Foam::MinMax<T>::min() const noexcept
{
return this->first();
}
template<class T>
inline T& Foam::MinMax<T>::min() noexcept
{
return this->first();
}
template<class T>
inline const T& Foam::MinMax<T>::max() const noexcept
{
return this->second();
}
template<class T>
inline T& Foam::MinMax<T>::max() noexcept
{
return this->second();
}
template<class T>
inline T Foam::MinMax<T>::centre() const
{
@ -156,7 +144,7 @@ inline T Foam::MinMax<T>::span() const
template<class T>
inline Foam::scalar Foam::MinMax<T>::mag() const
{
return ::Foam::mag(span());
return (empty() ? scalar(0) : ::Foam::mag(max() - min()));
}
@ -171,31 +159,32 @@ inline bool Foam::MinMax<T>::empty() const
template<class T>
inline bool Foam::MinMax<T>::good() const
{
return !empty();
return !(max() < min());
}
template<class T>
inline void Foam::MinMax<T>::reset()
{
min() = pTraits<T>::max;
max() = pTraits<T>::min;
// An inverted range
min_ = pTraits<T>::max;
max_ = pTraits<T>::min;
}
template<class T>
inline void Foam::MinMax<T>::reset(const T& val)
{
min() = val;
max() = val;
min_ = val;
max_ = val;
}
template<class T>
inline void Foam::MinMax<T>::reset(const T& minVal, const T& maxVal)
{
min() = minVal;
max() = maxVal;
min_ = minVal;
max_ = maxVal;
}
@ -246,6 +235,7 @@ inline T Foam::MinMax<T>::clamp(const T& val) const
{
if (good())
{
// Uses Foam::min/Foam::max for component-wise handling
return Foam::min(Foam::max(val, min()), max());
}
@ -256,6 +246,7 @@ inline T Foam::MinMax<T>::clamp(const T& val) const
template<class T>
inline Foam::MinMax<T>& Foam::MinMax<T>::add(const MinMax& other)
{
// Uses Foam::min/Foam::max for component-wise handling
min() = Foam::min(min(), other.min());
max() = Foam::max(max(), other.max());
return *this;
@ -265,6 +256,7 @@ inline Foam::MinMax<T>& Foam::MinMax<T>::add(const MinMax& other)
template<class T>
inline Foam::MinMax<T>& Foam::MinMax<T>::add(const T& val)
{
// Uses Foam::min/Foam::max for component-wise handling
min() = Foam::min(min(), val);
max() = Foam::max(max(), val);
return *this;
@ -282,6 +274,25 @@ inline Foam::MinMax<T>& Foam::MinMax<T>::add(const UList<T>& vals)
}
template<class T>
template<class... Args>
inline Foam::MinMax<T>& Foam::MinMax<T>::add
(
const T& val0,
const T& val1,
Args&&... values
)
{
add(val0);
add(val1);
// Add multiple values via fold expression
((*this += std::forward<Args>(values)), ...);
return *this;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T>
@ -325,6 +336,7 @@ inline bool Foam::MinMax<T>::operator()(const T& val) const
template<class T>
inline Foam::MinMax<T>& Foam::MinMax<T>::operator&=(const MinMax<T>& b)
{
// Uses Foam::min/Foam::max for component-wise handling
min() = ::Foam::max(min(), b.min());
max() = ::Foam::min(max(), b.max());
@ -354,7 +366,7 @@ inline Foam::MinMax<T>& Foam::MinMax<T>::operator+=(const UList<T>& vals)
template<class T>
inline Foam::MinMax<T>& Foam::MinMax<T>::operator*=(const scalar& s)
inline Foam::MinMax<T>& Foam::MinMax<T>::operator*=(scalar s)
{
min() *= s;
max() *= s;
@ -363,7 +375,7 @@ inline Foam::MinMax<T>& Foam::MinMax<T>::operator*=(const scalar& s)
template<class T>
inline Foam::MinMax<T>& Foam::MinMax<T>::operator/=(const scalar& s)
inline Foam::MinMax<T>& Foam::MinMax<T>::operator/=(scalar s)
{
min() /= s;
max() /= s;

View File

@ -44,7 +44,7 @@ Description
namespace Foam
{
// Global Functions
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
//- The mag() function for min/max range
template<class T>
@ -134,53 +134,6 @@ inline MinMax<T> minMax(const MinMax<T>& x, const MinMax<T>& y)
}
//- Combine values and/or MinMax ranges
template<class T>
struct minMaxOp
{
MinMax<T> operator()(const T& x, const T& y) const
{
return MinMax<T>(x).add(y);
}
MinMax<T> operator()(const MinMax<T>& x, const T& y) const
{
return MinMax<T>(x).add(y);
}
MinMax<T> operator()(const T& x, const MinMax<T>& y) const
{
return MinMax<T>(y).add(x);
}
MinMax<T> operator()(const MinMax<T>& x, const MinMax<T>& y) const
{
return MinMax<T>(x).add(y); // Same as (x + y)
}
};
//- Combine assignment for MinMax range
template<class T>
struct minMaxEqOp
{
MinMax<T>& operator()(MinMax<T>& x, const T& y) const
{
return x.add(y);
}
MinMax<T>& operator()(MinMax<T>& x, const UList<T>& y) const
{
return x.add(y);
}
MinMax<T>& operator()(MinMax<T>& x, const MinMax<T>& y) const
{
return x.add(y);
}
};
//- The magnitude of a single value.
inline scalarMinMax minMaxMag(const scalar val)
{
@ -203,7 +156,7 @@ inline scalarMinMax minMaxMag(const UList<T>& vals)
scalarMinMax result;
for (const T& val : vals)
{
result += Foam::mag(val);
result.add(Foam::mag(val));
}
return result;
@ -221,92 +174,109 @@ inline scalarMinMax minMaxMag(const MinMax<T>& range)
}
//- Combine the magitude of two values to create a min/max range.
//- Order is unimportant.
template<class T>
inline scalarMinMax minMaxMag(const T& x, const T& y)
//- Combine the magitude of two values (similar or dissimilar types)
//- to create a min/max range. Order is unimportant.
template<class T1, class T2>
inline scalarMinMax minMaxMag(const T1& x, const T2& y)
{
return minMaxMag(x).add(Foam::mag(y));
}
//- Scalar combine two MinMax ranges of same type
template<class T>
inline scalarMinMax minMaxMag(const MinMax<T>& x, const MinMax<T>& y)
{
return
(
minMaxMag(x)
.add(Foam::mag(y.min()))
.add(Foam::mag(y.max()))
);
}
//- Scalar combine two MinMax ranges of dissimilar types
//- Scalar combine two MinMax ranges (same or dissimilar types)
template<class T1, class T2>
inline scalarMinMax minMaxMag(const MinMax<T1>& x, const MinMax<T2>& y)
{
return
(
minMaxMag(x)
.add(Foam::mag(y.min()))
.add(Foam::mag(y.max()))
);
return minMaxMag(x).add(Foam::mag(y.min()), Foam::mag(y.max()));
}
//- Scalar combine the magitude of a value.
template<class T>
struct minMaxMagOp
{
scalarMinMax operator()(const scalarMinMax& x, const T& y) const
{
return minMaxMag(x).add(Foam::mag(y));
}
template<class T1, class T2>
scalarMinMax operator()(const MinMax<T1>& x, const MinMax<T2>& y) const
{
return minMaxMag(x, y);
}
};
//- Combine assignment for MinMax range
template<class T>
struct minMaxMagEqOp
{
scalarMinMax& operator()(scalarMinMax& x, const T& y) const
{
x = minMaxMag(x);
return x.add(Foam::mag(y));
}
scalarMinMax& operator()(scalarMinMax& x, const MinMax<T>& y) const
{
x = minMaxMag(x);
return
(
x
.add(Foam::mag(y.min()))
.add(Foam::mag(y.max()))
);
}
scalarMinMax& operator()(scalarMinMax& x, const UList<T>& y) const
{
x = minMaxMag(x);
for (const T& val : y)
{
x.add(Foam::mag(val));
}
return x;
}
};
// Mark as unused (2025-02)
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// //- Combine values and/or MinMax ranges
// template<class T>
// struct minMaxOp
// {
// MinMax<T> operator()(const T& x, const T& y) const
// {
// return MinMax<T>(x).add(y);
// }
//
// MinMax<T> operator()(const MinMax<T>& x, const T& y) const
// {
// return MinMax<T>(x).add(y);
// }
//
// MinMax<T> operator()(const T& x, const MinMax<T>& y) const
// {
// return MinMax<T>(y).add(x);
// }
// };
//
//
// //- Combine assignment for MinMax range
// template<class T>
// struct minMaxEqOp
// {
// MinMax<T>& operator()(MinMax<T>& x, const T& y) const
// {
// return x.add(y);
// }
//
// MinMax<T>& operator()(MinMax<T>& x, const UList<T>& y) const
// {
// return x.add(y);
// }
// };
//
//
// //- Scalar combine the magitude of a value.
// template<class T>
// struct minMaxMagOp
// {
// scalarMinMax operator()(const scalarMinMax& x, const T& y) const
// {
// return minMaxMag(x).add(Foam::mag(y));
// }
//
// template<class T1, class T2>
// scalarMinMax operator()(const MinMax<T1>& x, const MinMax<T2>& y) const
// {
// return minMaxMag(x).add(Foam::mag(y.min()), Foam::mag(y.max()));
// }
// };
//
//
// //- Combine assignment for MinMax range
// template<class T>
// struct minMaxMagEqOp
// {
// scalarMinMax& operator()(scalarMinMax& x, const T& y) const
// {
// x = minMaxMag(x);
// return x.add(Foam::mag(y));
// }
//
// scalarMinMax& operator()(scalarMinMax& x, const MinMax<T>& y) const
// {
// x = minMaxMag(x);
//
// return x.add(Foam::mag(y.min()), Foam::mag(y.max()));
// }
//
// scalarMinMax& operator()(scalarMinMax& x, const UList<T>& y) const
// {
// x = minMaxMag(x);
//
// for (const T& val : y)
// {
// x.add(Foam::mag(val));
// }
//
// return x;
// }
// };
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
@ -321,7 +291,7 @@ inline MinMax<T> operator+(const MinMax<T>& x, const MinMax<T>& y)
//- Multiply range by scalar factor
template<class T>
inline MinMax<T> operator*(const MinMax<T>& x, const scalar& s)
inline MinMax<T> operator*(const MinMax<T>& x, scalar s)
{
return MinMax<T>(x.min()*s, x.max()*s);
}
@ -329,7 +299,7 @@ inline MinMax<T> operator*(const MinMax<T>& x, const scalar& s)
//- Divide range by scalar factor
template<class T>
inline MinMax<T> operator/(const MinMax<T>& x, const scalar& s)
inline MinMax<T> operator/(const MinMax<T>& x, scalar s)
{
return MinMax<T>(x.min()/s, x.max()/s);
}

View File

@ -141,18 +141,6 @@ void Foam::reduce \
const label comm, \
UPstream::Request& req \
) \
{} \
\
/* Deprecated: prefer version with UPstream::Request */ \
void Foam::reduce \
( \
Native values[], \
const int size, \
const sumOp<Native>&, \
const int tag, \
const label comm, \
label& requestID \
) \
{} \
\
void Foam::reduce \
@ -163,17 +151,6 @@ void Foam::reduce \
const label comm, \
UPstream::Request& req \
) \
{} \
\
/* Deprecated: prefer version with UPstream::Request */ \
void Foam::reduce \
( \
Native& value, \
const sumOp<Native>&, \
const int tag, \
const label comm, \
label& requestID \
) \
{} \
\
void Foam::sumReduce \

View File

@ -82,50 +82,40 @@ inline void checkCommunicator(int comm, int rank)
}
}
//- True if warn communicator is active and not equal to given communicator
inline bool warnCommunicator(int comm) noexcept
{
return (UPstream::warnComm >= 0 && comm != UPstream::warnComm);
}
// * * * * * * * * * * * * * * * * Requests * * * * * * * * * * * * * * * * //
//- Reset UPstream::Request to null and/or the index of the outstanding
//- request to -1.
// Does not affect the stack of outstanding requests.
inline void reset_request
(
UPstream::Request* requestPtr,
label* requestIdx = nullptr
)
//- Reset UPstream::Request to MPI_REQUEST_NULL
// Does not affect the stack of outstanding requests
inline void reset_request(UPstream::Request* req) noexcept
{
if (requestPtr) *requestPtr = UPstream::Request(MPI_REQUEST_NULL);
if (requestIdx) *requestIdx = -1;
if (req) *req = UPstream::Request(MPI_REQUEST_NULL);
}
//- Transcribe MPI_Request to UPstream::Request
//- (does not affect the stack of outstanding requests)
//- or else push onto list of outstanding requests
//- and (optionally) record its location
inline void push_request
(
MPI_Request request,
UPstream::Request* requestPtr = nullptr,
label* requestIdx = nullptr
UPstream::Request* req = nullptr
)
{
if (requestPtr)
if (req)
{
// Transcribe as UPstream::Request
*requestPtr = UPstream::Request(request);
// Not on stack of outstanding requests
if (requestIdx) *requestIdx = -1;
*req = UPstream::Request(request);
}
else
{
if (requestIdx)
{
// Its index into outstanding requests
*requestIdx = PstreamGlobals::outstandingRequests_.size();
}
// Push onto list of requests
PstreamGlobals::outstandingRequests_.push_back(request);
}
}

View File

@ -66,7 +66,7 @@ static std::streamsize UPstream_mpi_receive
}
#endif
if (UPstream::warnComm >= 0 && communicator != UPstream::warnComm)
if (FOAM_UNLIKELY(PstreamGlobals::warnCommunicator(communicator)))
{
Perr<< "UIPstream::read : starting read from:" << fromProcNo
<< " size:" << label(bufSize)
@ -76,7 +76,7 @@ static std::streamsize UPstream_mpi_receive
<< Foam::endl;
error::printStack(Perr);
}
else if (UPstream::debug)
else if (FOAM_UNLIKELY(UPstream::debug))
{
Perr<< "UIPstream::read : starting read from:" << fromProcNo
<< " size:" << label(bufSize)
@ -121,7 +121,7 @@ static std::streamsize UPstream_mpi_receive
<< Foam::abort(FatalError);
return 0;
}
else if (UPstream::debug)
else if (FOAM_UNLIKELY(UPstream::debug))
{
Perr<< "UIPstream::read : finished recv from:"
<< fromProcNo
@ -196,7 +196,7 @@ static std::streamsize UPstream_mpi_receive
profilingPstream::addRequestTime();
if (UPstream::debug)
if (FOAM_UNLIKELY(UPstream::debug))
{
Perr<< "UIPstream::read : started non-blocking recv from:"
<< fromProcNo
@ -223,7 +223,7 @@ static std::streamsize UPstream_mpi_receive
void Foam::UIPstream::bufferIPCrecv()
{
// Called by constructor
if (UPstream::debug)
if (FOAM_UNLIKELY(UPstream::debug))
{
Perr<< "UIPstream IPC read buffer :"
<< " from:" << fromProcNo_
@ -289,7 +289,7 @@ void Foam::UIPstream::bufferIPCrecv()
<< Foam::abort(FatalError);
}
if (UPstream::debug)
if (FOAM_UNLIKELY(UPstream::debug))
{
Perr<< "UIPstream::UIPstream : probed size:"
<< label(count) << Foam::endl;

View File

@ -72,7 +72,7 @@ bool Foam::UOPstream::write
}
#endif
if (UPstream::warnComm >= 0 && communicator != UPstream::warnComm)
if (FOAM_UNLIKELY(PstreamGlobals::warnCommunicator(communicator)))
{
Perr<< "UOPstream::write : starting write to:" << toProcNo
<< " size:" << label(bufSize)
@ -82,7 +82,7 @@ bool Foam::UOPstream::write
<< Foam::endl;
error::printStack(Perr);
}
else if (UPstream::debug)
else if (FOAM_UNLIKELY(UPstream::debug))
{
Perr<< "UOPstream::write : starting write to:" << toProcNo
<< " size:" << label(bufSize)
@ -112,7 +112,7 @@ bool Foam::UOPstream::write
// Assume these are from scatters ...
profilingPstream::addScatterTime();
if (UPstream::debug)
if (FOAM_UNLIKELY(UPstream::debug))
{
Perr<< "UOPstream::write : finished buffered send to:"
<< toProcNo
@ -150,7 +150,7 @@ bool Foam::UOPstream::write
// Assume these are from scatters ...
profilingPstream::addScatterTime();
if (UPstream::debug)
if (FOAM_UNLIKELY(UPstream::debug))
{
Perr<< "UOPstream::write : finished send to:"
<< toProcNo
@ -189,7 +189,7 @@ bool Foam::UOPstream::write
);
}
if (UPstream::debug)
if (FOAM_UNLIKELY(UPstream::debug))
{
Perr<< "UOPstream::write : started non-blocking send to:"
<< toProcNo

View File

@ -39,8 +39,6 @@ License
#include <numeric>
#include <string>
#undef Pstream_use_MPI_Get_count
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// The min value and default for MPI buffer length
@ -1178,33 +1176,28 @@ Foam::UPstream::probeMessage
// Unlikely to be used with large amounts of data,
// but use MPI_Get_elements_x() instead of MPI_Count() anyhow
#ifdef Pstream_use_MPI_Get_count
int count(0);
MPI_Get_count(&status, MPI_BYTE, &count);
#else
MPI_Count count(0);
MPI_Get_elements_x(&status, MPI_BYTE, &count);
#endif
MPI_Count num_recv(0);
MPI_Get_elements_x(&status, MPI_BYTE, &num_recv);
// Errors
if (count == MPI_UNDEFINED || int64_t(count) < 0)
if (num_recv == MPI_UNDEFINED || int64_t(num_recv) < 0)
{
FatalErrorInFunction
<< "MPI_Get_count() or MPI_Get_elements_x() : "
<< "MPI_Get_elements_x() : "
"returned undefined or negative value"
<< Foam::abort(FatalError);
}
else if (int64_t(count) > int64_t(INT_MAX))
else if (int64_t(num_recv) > int64_t(INT_MAX))
{
FatalErrorInFunction
<< "MPI_Get_count() or MPI_Get_elements_x() : "
"count is larger than INI_MAX bytes"
<< "MPI_Get_elements_x() : "
"count is larger than INT_MAX bytes"
<< Foam::abort(FatalError);
}
result.first = status.MPI_SOURCE;
result.second = int64_t(count);
result.second = int64_t(num_recv);
}
return result;

View File

@ -47,7 +47,7 @@ bool Foam::UPstream::broadcast
//Needed? PstreamGlobals::checkCommunicator(comm, rootProcNo);
if (UPstream::warnComm >= 0 && comm != UPstream::warnComm)
if (FOAM_UNLIKELY(PstreamGlobals::warnCommunicator(comm)))
{
Perr<< "UPstream::broadcast : root:" << rootProcNo
<< " comm:" << comm
@ -56,7 +56,7 @@ bool Foam::UPstream::broadcast
<< Foam::endl;
error::printStack(Perr);
}
else if (UPstream::debug)
else if (FOAM_UNLIKELY(UPstream::debug))
{
Perr<< "UPstream::broadcast : root:" << rootProcNo
<< " comm:" << comm

View File

@ -187,24 +187,7 @@ void Foam::reduce \
{ \
PstreamDetail::allReduce<Native> \
( \
values, size, TaggedType, MPI_SUM, comm, &req, nullptr \
); \
} \
\
/* Deprecated: prefer version with UPstream::Request */ \
void Foam::reduce \
( \
Native values[], \
const int size, \
const sumOp<Native>&, \
const int tag, /* (unused) */ \
const label comm, \
label& requestID \
) \
{ \
PstreamDetail::allReduce<Native> \
( \
values, size, TaggedType, MPI_SUM, comm, nullptr, &requestID \
values, size, TaggedType, MPI_SUM, comm, &req \
); \
} \
\
@ -219,23 +202,7 @@ void Foam::reduce \
{ \
PstreamDetail::allReduce<Native> \
( \
&value, 1, TaggedType, MPI_SUM, comm, &req, nullptr \
); \
} \
\
/* Deprecated: prefer version with UPstream::Request */ \
void Foam::reduce \
( \
Native& value, \
const sumOp<Native>&, \
const int tag, /* (unused) */ \
const label comm, \
label& requestID \
) \
{ \
PstreamDetail::allReduce<Native> \
( \
&value, 1, TaggedType, MPI_SUM, comm, nullptr, &requestID \
&value, 1, TaggedType, MPI_SUM, comm, &req \
); \
} \
\

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2023 OpenCFD Ltd.
Copyright (C) 2023-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -65,7 +65,7 @@ void Foam::UPstream::Request::reset() noexcept
// << PstreamGlobals::outstandingRequests_.size()
// << ')' << endl;
//
// return UPstream::Communicator(MPI_REQUEST_NULL);
// return UPstream::Request(MPI_REQUEST_NULL);
// }
//
// return UPstream::Request(PstreamGlobals::outstandingRequests_[req]);
@ -97,11 +97,13 @@ void Foam::UPstream::addRequest(UPstream::Request& req)
return;
}
// Transcribe as a MPI_Request
PstreamGlobals::outstandingRequests_.push_back
(
PstreamUtils::Cast::to_mpi(req)
);
{
MPI_Request request = PstreamUtils::Cast::to_mpi(req);
if (MPI_REQUEST_NULL != request)
{
PstreamGlobals::outstandingRequests_.push_back(request);
}
}
// Invalidate parameter
req = UPstream::Request(MPI_REQUEST_NULL);

View File

@ -48,13 +48,14 @@ namespace PstreamDetail
{
// MPI_Bcast, using root=0
// No fail/abort handling
template<class Type>
void broadcast0
bool broadcast0
(
Type* values,
int count,
MPI_Datatype datatype,
const label comm
const int communicator
);
// MPI_Reduce, using root=0
@ -65,7 +66,8 @@ void reduce0
int count,
MPI_Datatype datatype,
MPI_Op optype,
const label comm
const int communicator, // Communicator
UPstream::Request* req = nullptr // Non-null for non-blocking
);
// MPI_Allreduce or MPI_Iallreduce
@ -76,9 +78,8 @@ void allReduce
int count,
MPI_Datatype datatype,
MPI_Op optype,
const label comm, // Communicator
UPstream::Request* req = nullptr, // Non-null for non-blocking
label* requestID = nullptr // (alternative to UPstream::Request)
const int communicator, // Communicator
UPstream::Request* req = nullptr // Non-null for non-blocking
);
@ -89,9 +90,8 @@ void allToAll
const UList<Type>& sendData,
UList<Type>& recvData,
MPI_Datatype datatype,
const label comm, // Communicator
UPstream::Request* req = nullptr, // Non-null for non-blocking
label* requestID = nullptr // (alternative to UPstream::Request)
const int communicator, // Communicator
UPstream::Request* req = nullptr // Non-null for non-blocking
);
@ -108,9 +108,8 @@ void allToAllv
const UList<int>& recvOffsets,
MPI_Datatype datatype,
const label comm, // Communicator
UPstream::Request* req = nullptr, // Non-null for non-blocking
label* requestID = nullptr // (alternative to UPstream::Request)
const int communicator, // Communicator
UPstream::Request* req = nullptr // Non-null for non-blocking
);
@ -122,7 +121,7 @@ void allToAllConsensus
UList<Type>& recvData,
MPI_Datatype datatype,
const int tag, // Message tag
const label comm // Communicator
const int communicator // Communicator
);
@ -134,7 +133,7 @@ void allToAllConsensus
Map<Type>& recvData,
MPI_Datatype datatype,
const int tag, // Message tag
const label comm // Communicator
const int communicator // Communicator
);
@ -147,9 +146,8 @@ void gather
Type* recvData, // On master: recv buffer. Ignored elsewhere
int count, // Per rank send/recv count. Globally consistent!
MPI_Datatype datatype, // The send/recv data type
const label comm, // Communicator
UPstream::Request* req = nullptr, // Non-null for non-blocking
label* requestID = nullptr // (alternative to UPstream::Request)
const int communicator, // Communicator
UPstream::Request* req = nullptr // Non-null for non-blocking
);
@ -162,9 +160,8 @@ void scatter
Type* recvData, // Local recv value
int count, // Per rank send/recv count. Globally consistent!
MPI_Datatype datatype, // The send/recv data type
const label comm, // Communicator
UPstream::Request* req = nullptr, // Non-null for non-blocking
label* requestID = nullptr // (alternative to UPstream::Request)
const int communicator, // Communicator
UPstream::Request* req = nullptr // Non-null for non-blocking
);
@ -180,9 +177,8 @@ void gatherv
const UList<int>& recvOffsets, // Ignored on non-root rank
MPI_Datatype datatype, // The send/recv data type
const label comm, // Communicator
UPstream::Request* req = nullptr, // Non-null for non-blocking
label* requestID = nullptr // (alternative to UPstream::Request)
const int communicator, // Communicator
UPstream::Request* req = nullptr // Non-null for non-blocking
);
@ -198,9 +194,8 @@ void scatterv
int recvCount,
MPI_Datatype datatype, // The send/recv data type
const label comm, // Communicator
UPstream::Request* req = nullptr, // Non-null for non-blocking
label* requestID = nullptr // (alternative to UPstream::Request)
const int communicator, // Communicator
UPstream::Request* req = nullptr // Non-null for non-blocking
);
@ -212,9 +207,8 @@ void allGather
int count, // The send/recv count per element
MPI_Datatype datatype, // The send/recv data type
const label comm, // Communicator
UPstream::Request* req = nullptr, // Non-null for non-blocking
label* requestID = nullptr // (alternative to UPstream::Request)
const int communicator, // Communicator
UPstream::Request* req = nullptr // Non-null for non-blocking
);

File diff suppressed because it is too large Load Diff

View File

@ -199,7 +199,7 @@ bool Foam::displacementPointSmoothingMotionSolver::relax()
);
// Synchronise completion
reduce(complete, andOp<bool>());
UPstream::reduceAnd(complete);
}
// Check for convergence
@ -222,7 +222,7 @@ bool Foam::displacementPointSmoothingMotionSolver::relax()
}
// Syncronise convergence
reduce(converged, andOp<bool>());
UPstream::reduceAnd(converged);
//if (converged)
//{

View File

@ -245,7 +245,7 @@ bool Foam::displacementSmartPointSmoothingMotionSolver::relax()
);
// Synchronise completion
reduce(complete, andOp<bool>());
UPstream::reduceAnd(complete);
}
// Check for convergence
@ -266,7 +266,7 @@ bool Foam::displacementSmartPointSmoothingMotionSolver::relax()
}
// Syncronise convergence
reduce(converged, andOp<bool>());
UPstream::reduceAnd(converged);
//if (converged)
//{

View File

@ -405,7 +405,7 @@ bool Foam::hexMeshSmootherMotionSolver::relax
// Synchronise convergence
reduce(complete, andOp<bool>());
UPstream::reduceAnd(complete);
// Synchronise relaxation levels
syncTools::syncPointList

View File

@ -161,14 +161,14 @@ void Foam::faMeshTools::printMeshChecks
scalarMinMax limit(minMax(mesh.magLe().primitiveField()));
// Include processor boundaries into 'internal' edges
if (Pstream::parRun())
if (UPstream::parRun())
{
for (label patchi = nNonProcessor; patchi < nPatches; ++patchi)
{
limit.add(minMax(mesh.magLe().boundaryField()[patchi]));
}
reduce(limit, minMaxOp<scalar>());
reduce(limit, plusOp<scalarMinMax>{});
}
Info<< "Edge length (internal):" << nl
@ -181,9 +181,9 @@ void Foam::faMeshTools::printMeshChecks
limit.add(minMax(mesh.magLe().boundaryField()[patchi]));
}
if (Pstream::parRun())
if (UPstream::parRun())
{
reduce(limit, minMaxOp<scalar>());
reduce(limit, plusOp<scalarMinMax>{});
}
Info<< "Edge length:" << nl

View File

@ -87,7 +87,7 @@ Foam::pressureControl::pressureControl
}
}
reduce(rhoLimits, andOp<bool>());
UPstream::reduceAnd(rhoLimits);
if (rhoLimits)
{
reduce(pMax, maxOp<scalar>());

View File

@ -372,7 +372,7 @@ void Foam::turbulentDFSEMInletFvPatchVectorField::initialiseEddies()
}
// else eddy on remote processor
reduce(search, andOp<bool>());
UPstream::reduceAnd(search);
}

View File

@ -75,7 +75,7 @@ void Foam::binModels::singleDirectionUniformBin::initialise()
}
// Globally consistent
reduce(geomLimits, minMaxOp<scalar>());
reduce(geomLimits, sumOp<scalarMinMax>());
if (!geomLimits.good())
{

View File

@ -58,9 +58,7 @@ void Foam::binModels::uniformBin::initialise()
);
MinMax<vector> limits(pts);
geomLimits.add(limits.min());
geomLimits.add(limits.max());
geomLimits.add(limits.min(), limits.max());
}
for (const label zonei : cellZoneIDs_)
@ -72,9 +70,7 @@ void Foam::binModels::uniformBin::initialise()
);
MinMax<vector> limits(pts);
geomLimits.add(limits.min());
geomLimits.add(limits.max());
geomLimits.add(limits.min(), limits.max());
}
// Globally consistent

View File

@ -175,10 +175,12 @@ public:
// within bounds, but not aligned with a grid point.
label findIndex(const scalar p, const scalar tol) const;
//- If out of range, return the respective min/max limits,
//- otherwise return the value itself.
//- Return value clamped to min/max limits.
// If the range is invalid, always return the value.
inline const scalar& clip(const scalar& val) const;
inline const scalar& clamp(const scalar& val) const;
//- Return value clamped to min/max limits.
const scalar& clip(const scalar& val) const { return clamp(val); }
};

View File

@ -124,7 +124,7 @@ inline Foam::scalar Foam::PDRblock::location::C(const label i) const
inline const Foam::scalar&
Foam::PDRblock::location::clip(const scalar& val) const
Foam::PDRblock::location::clamp(const scalar& val) const
{
if (scalarList::size())
{

View File

@ -180,8 +180,7 @@ Foam::cyclicAMIGAMGInterface::cyclicAMIGAMGInterface
const auto& AMI = amiPtr_();
if (debug & 2)
{
const auto oldWarnComm = UPstream::warnComm;
UPstream::warnComm = AMI.comm();
const auto oldWarnComm = UPstream::commWarn(AMI.comm());
const label myRank = UPstream::myProcNo(AMI.comm());
Pout<< "At level:" << fineLevelIndex
@ -297,7 +296,7 @@ Foam::cyclicAMIGAMGInterface::cyclicAMIGAMGInterface
}
Pout<< "DONE agglomerating at level:" << fineLevelIndex << endl;
UPstream::warnComm = oldWarnComm;
UPstream::commWarn(oldWarnComm);
}
}
}
@ -820,8 +819,7 @@ Foam::cyclicAMIGAMGInterface::cyclicAMIGAMGInterface
{
const auto& AMI = amiPtr_();
const auto oldWarnComm = UPstream::warnComm;
UPstream::warnComm = AMI.comm();
const auto oldWarnComm = UPstream::commWarn(AMI.comm());
const label myRank = UPstream::myProcNo(AMI.comm());
Pout<< "PROCAGGLOMERATED :"
@ -930,7 +928,7 @@ Foam::cyclicAMIGAMGInterface::cyclicAMIGAMGInterface
}
}
Pout<< "DONE PROCAGGLOMERATED" << endl;
UPstream::warnComm = oldWarnComm;
UPstream::commWarn(oldWarnComm);
}
}
}

View File

@ -1030,7 +1030,7 @@ Foam::nullSpace::nullSpace
}
if (globalSum_)
{
reduce(existsNonBoundVar, orOp<bool>());
UPstream::reduceOr(existsNonBoundVar);
}
if (!existsNonBoundVar)
{

View File

@ -476,7 +476,7 @@ void Foam::NURBS3DVolume::confineInertControlPoints()
break;
}
}
reduce(foundParamPt, orOp<bool>());
UPstream::reduceOr(foundParamPt);
if (!foundParamPt)
{
activeControlPoints_[cpI] = false;

View File

@ -498,7 +498,7 @@ void Foam::cellCellStencil::walkFront
bitSet isFrontWork(isFront);
label nCurrLayer = currLayer;
while (nCurrLayer > 1 && returnReduce(isFrontWork.any(), orOp<bool>()))
while (nCurrLayer > 1 && returnReduceOr(isFrontWork.any()))
{
bitSet newIsFront(mesh_.nFaces());
forAll(isFrontWork, facei)
@ -575,7 +575,7 @@ void Foam::cellCellStencil::walkFront
scalarField allWeightWork(allCellTypes.size(), Zero);
bitSet nHoles(allCellTypes.size());
while (returnReduce(isFront.any(), orOp<bool>()))
while (returnReduceOr(isFront.any()))
{
// Interpolate cells on front
bitSet newIsFront(mesh_.nFaces());