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:
commit
d41c644a49
@ -1,3 +1,3 @@
|
||||
Test-minMax1.C
|
||||
Test-minMax1.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-minMax1
|
||||
|
@ -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;
|
||||
|
@ -1,3 +1,3 @@
|
||||
Test-minMax2.C
|
||||
Test-minMax2.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-minMax2
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 \
|
||||
);
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
);
|
||||
|
@ -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;
|
||||
|
@ -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; \
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 : "
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
); \
|
||||
} \
|
||||
\
|
||||
|
@ -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);
|
||||
|
@ -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
@ -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)
|
||||
//{
|
||||
|
@ -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)
|
||||
//{
|
||||
|
@ -405,7 +405,7 @@ bool Foam::hexMeshSmootherMotionSolver::relax
|
||||
|
||||
|
||||
// Synchronise convergence
|
||||
reduce(complete, andOp<bool>());
|
||||
UPstream::reduceAnd(complete);
|
||||
|
||||
// Synchronise relaxation levels
|
||||
syncTools::syncPointList
|
||||
|
@ -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
|
||||
|
@ -87,7 +87,7 @@ Foam::pressureControl::pressureControl
|
||||
}
|
||||
}
|
||||
|
||||
reduce(rhoLimits, andOp<bool>());
|
||||
UPstream::reduceAnd(rhoLimits);
|
||||
if (rhoLimits)
|
||||
{
|
||||
reduce(pMax, maxOp<scalar>());
|
||||
|
@ -372,7 +372,7 @@ void Foam::turbulentDFSEMInletFvPatchVectorField::initialiseEddies()
|
||||
}
|
||||
// else eddy on remote processor
|
||||
|
||||
reduce(search, andOp<bool>());
|
||||
UPstream::reduceAnd(search);
|
||||
}
|
||||
|
||||
|
||||
|
@ -75,7 +75,7 @@ void Foam::binModels::singleDirectionUniformBin::initialise()
|
||||
}
|
||||
|
||||
// Globally consistent
|
||||
reduce(geomLimits, minMaxOp<scalar>());
|
||||
reduce(geomLimits, sumOp<scalarMinMax>());
|
||||
|
||||
if (!geomLimits.good())
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -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())
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1030,7 +1030,7 @@ Foam::nullSpace::nullSpace
|
||||
}
|
||||
if (globalSum_)
|
||||
{
|
||||
reduce(existsNonBoundVar, orOp<bool>());
|
||||
UPstream::reduceOr(existsNonBoundVar);
|
||||
}
|
||||
if (!existsNonBoundVar)
|
||||
{
|
||||
|
@ -476,7 +476,7 @@ void Foam::NURBS3DVolume::confineInertControlPoints()
|
||||
break;
|
||||
}
|
||||
}
|
||||
reduce(foundParamPt, orOp<bool>());
|
||||
UPstream::reduceOr(foundParamPt);
|
||||
if (!foundParamPt)
|
||||
{
|
||||
activeControlPoints_[cpI] = false;
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user