Compare commits

..

5 Commits

Author SHA1 Message Date
11964a4731 ENH: reduce overhead and clearer data ownership for OFstreamCollator
- local data to be written is now transferable into the
  OFstreamCollator. This avoids making a full copy when threading is
  active.

- use plain lists for managing proc data
  * storage: List<List<char>> instead of PtrList<List<char>>
  * views:   List<stdFoam::span<char>> instead of PtrList<SubList<char>>

- use gather/write (unthreaded) as backstop if the output is too big
  to fit in the buffer size. Emit warning instead of FatalError
2024-01-23 17:16:02 +01:00
c82facdc8e ENH: reduce overhead of decomposedBlockData IO
- OCharStream for serializing
- skip intermediate blocks without reading
- support character spans
- read and distribute with direct non-blocking send/recv
  instead of PstreamBuffers or with IPstream/OPstream streaming
  operators.
- non-blocking gather/write when using intermediate buffer space
2024-01-23 17:16:02 +01:00
da560be4df ENH: reduce overhead of masterOFstream
- use OCharStream instead of OStringStream to avoid copying char data.

- direct non-blocking send/recv with probing instead of PstreamBuffers
  to avoid serialization/de-serialization of char data and reduce the
  memory footprint somewhat.

- polling dispatch to write file content as it becomes available,
  which should improve communication and IO overlap
2024-01-23 17:16:02 +01:00
cf6e3a1acf CONFIG: adjust compile-time value of maxThreadFileBufferSize to 0
- consistent with etc/controlDict default

STYLE: update banner message for collated
2024-01-23 17:16:02 +01:00
0a51a4848c TEST: add standalone test application: Test-checkIOspeed 2024-01-23 17:16:02 +01:00
216 changed files with 3886 additions and 18950 deletions

View File

@ -1,15 +1,10 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude
-I$(LIB_SRC)/sampling/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfvOptions \
-lmeshTools \
-ldynamicMesh \
-ldynamicFvMesh \
-ltopoChangerFvMesh \
-lsampling

View File

@ -56,7 +56,6 @@ Description
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "dynamicFvMesh.H"
#include "fvOptions.H"
#include "simpleControl.H"
@ -72,7 +71,7 @@ int main(int argc, char *argv[])
#include "addCheckCaseOptions.H"
#include "setRootCaseLists.H"
#include "createTime.H"
#include "createDynamicFvMesh.H"
#include "createMesh.H"
simpleControl simple(mesh);
@ -88,16 +87,6 @@ int main(int argc, char *argv[])
{
Info<< "Time = " << runTime.timeName() << nl << endl;
// Do any mesh changes
mesh.controlledUpdate();
if (mesh.changing())
{
// Calculate absolute flux
// from the mapped surface velocity
phi = mesh.Sf() & fvc::interpolate(U);
}
while (simple.correctNonOrthogonal())
{
fvScalarMatrix TEqn

View File

@ -135,14 +135,14 @@ public:
virtual volScalarField& he()
{
NotImplemented;
return const_cast<volScalarField&>(volScalarField::null());
return thermo1_->he();
}
//- Enthalpy/Internal energy [J/kg]
virtual const volScalarField& he() const
{
NotImplemented;
return volScalarField::null();
return thermo1_->he();
}
//- Enthalpy/Internal energy
@ -213,7 +213,7 @@ public:
) const
{
NotImplemented;
return nullptr;
return tmp<scalarField>::New(p);
}
//- Heat capacity at constant volume [J/kg/K]
@ -236,7 +236,7 @@ public:
) const
{
NotImplemented;
return nullptr;
return tmp<scalarField>::New(p);
}
//- Gamma = Cp/Cv []

View File

@ -243,14 +243,14 @@ public:
virtual volScalarField& he()
{
NotImplemented;
return const_cast<volScalarField&>(volScalarField::null());
return phases_[0].thermo().he();
}
//- Enthalpy/Internal energy [J/kg]
virtual const volScalarField& he() const
{
NotImplemented;
return volScalarField::null();
return phases_[0].thermo().he();
}
//- Enthalpy/Internal energy
@ -327,7 +327,7 @@ public:
) const
{
NotImplemented;
return nullptr;
return tmp<scalarField>::New(p);
}
//- Heat capacity at constant volume [J/kg/K]
@ -350,7 +350,7 @@ public:
) const
{
NotImplemented;
return nullptr;
return tmp<scalarField>::New(p);
}
//- Gamma = Cp/Cv []

View File

@ -86,14 +86,14 @@ public:
virtual volScalarField& he()
{
NotImplemented;
return const_cast<volScalarField&>(volScalarField::null());
return p();
}
//- Return access to the internal energy field [J/Kg]
virtual const volScalarField& he() const
{
NotImplemented;
return volScalarField::null();
return p();
}
//- Enthalpy/Internal energy
@ -182,7 +182,7 @@ public:
) const
{
NotImplemented;
return nullptr;
return tmp<scalarField>::New(p);
}
//- Return Cv of the mixture
@ -205,7 +205,7 @@ public:
) const
{
NotImplemented;
return nullptr;
return tmp<scalarField>::New(p);
}
//- Gamma = Cp/Cv []

View File

@ -64,7 +64,6 @@ int main(int argc, char *argv[])
// Add some more entries
{
label idx = 0;
dictionary subdict;
subdict.add("key", 100);
@ -73,30 +72,23 @@ int main(int argc, char *argv[])
subdict.add
(
new formattingEntry(++idx, "// comment - without newline.")
new formattingEntry(10, "// comment - without newline.")
);
subdict.add
(
// NB newline must be part of the content!
new formattingEntry(++idx, "// some comment - with newline?\n")
new formattingEntry(11, "// some comment - with newline?\n")
);
subdict.add
(
// NB newline must be part of the content!
new formattingEntry(++idx, "/* other comment */\n")
new formattingEntry(12, "/* other comment */\n")
);
// Other - invisible
subdict.add(new formattingEntry(++idx, token(123), false));
// Other - visible (probably not what anyone wants!)
subdict.add(new formattingEntry(++idx, token(456)));
subdict.add("val", 42);
Info<< "subdict keys:" << flatOutput(subdict.toc()) << nl;
dict.add("subdict", std::move(subdict));
}

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021-2024 OpenCFD Ltd.
Copyright (C) 2021-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -52,7 +52,7 @@ int main(int argc, char *argv[])
const labelList localValues
(
identity(2 *(UPstream::myProcNo()+1), -5*UPstream::myProcNo())
identity(2 *(Pstream::myProcNo()+1), -5*Pstream::myProcNo())
);
// Test resize
@ -76,8 +76,8 @@ int main(int argc, char *argv[])
// One-sided sizing! master only
const globalIndex allProcAddr
(
globalIndex::gatherOnly{},
sendData.size()
sendData.size(),
globalIndex::gatherOnly{}
);
Pout<< "listGather sizes: " << flatOutput(allProcAddr.sizes()) << nl;
@ -98,8 +98,8 @@ int main(int argc, char *argv[])
// One-sided sizing! master only
const globalIndex allProcAddr
(
globalIndex::gatherOnly{},
sendData.size()
sendData.size(),
globalIndex::gatherOnly{}
);
Pout<< "listGather sizes: " << flatOutput(allProcAddr.sizes()) << nl;
@ -116,7 +116,7 @@ int main(int argc, char *argv[])
{
const labelList::subList& sendData =
(
UPstream::master()
Pstream::master()
? SubList<label>(localValues, 0) // exclude
: SubList<label>(localValues)
);
@ -147,11 +147,11 @@ int main(int argc, char *argv[])
<< UPstream::listScatterValues(subProcAddr.offsets()) << nl;
Pout<< endl << "local list [" << UPstream::myProcNo() << "] "
Pout<< endl << "local list [" << Pstream::myProcNo() << "] "
<< flatOutput(localValues) << nl;
Pout<< endl << "local send [" << UPstream::myProcNo() << "] "
Pout<< endl << "local send [" << Pstream::myProcNo() << "] "
<< sendSize << nl;
@ -163,7 +163,7 @@ int main(int argc, char *argv[])
Pout<< "off-proc: " << allValues << endl;
if (UPstream::master())
if (Pstream::master())
{
Info<< "master: " << flatOutput(localValues) << nl;
@ -196,7 +196,7 @@ int main(int argc, char *argv[])
{
globalIndex glob
(
globalIndex::gatherNone{},
globalIndex:gatherNone{},
labelList(Foam::one{}, 0)
);
Info<< "single:" << nl;
@ -208,37 +208,35 @@ int main(int argc, char *argv[])
}
}
// Non-contiguous gather - use Pstream, not UPstream!
// This will likely fail - not declared as is_contiguous
// Cannot even catch since it triggers an abort()
#if 0
{
typedef std::pair<label,vector> valueType;
std::pair<label,vector> sendData(Pstream::myProcNo(), vector::one);
valueType sendData(UPstream::myProcNo(), vector::one);
const bool oldThrowingError = FatalError.throwing(true);
List<valueType> countValues
(
Pstream::listGatherValues(sendData)
);
Pout<< "listGather: " << flatOutput(countValues) << nl;
}
// Non-contiguous scatter - use Pstream, not UPstream!
{
List<fileName> allValues;
if (UPstream::master())
try
{
allValues.resize(UPstream::nProcs());
forAll(allValues, proci)
{
allValues[proci] = "processor" + Foam::name(proci);
}
List<std::pair<label,vector>> countValues
(
UPstream::listGatherValues<std::pair<label, vector>>
(
sendData
)
);
Pout<< "listGather: " << flatOutput(countValues) << nl;
}
catch (const Foam::error& err)
{
Info<< err.message().c_str() << nl;
}
fileName procName = Pstream::listScatterValues(allValues);
Pout<< "listScatter: " << procName << nl;
FatalError.throwing(oldThrowingError);
}
#endif
Info<< "\nEnd\n" << endl;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2014 OpenFOAM Foundation
Copyright (C) 2019-2024 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -48,7 +48,7 @@ class SimpleClass
public:
//- Default construct
SimpleClass() = default;
SimpleClass() {}
};
@ -73,8 +73,9 @@ void printInfo(const UList<T>& list)
int main()
{
// Test pointer and reference to a class
auto ptrToClass = autoPtr<SimpleClass>::New();
auto& refToClass = ptrToClass.ref();
SimpleClass* ptrToClass = new SimpleClass;
SimpleClass& refToClass(*ptrToClass);
std::cout
<< "nullObject addr=" << name(&(nullObjectPtr)) << nl
@ -88,13 +89,13 @@ int main()
<< " pointer:" << name(nullObjectPtr->pointer()) << nl
<< " value:" << nullObjectPtr->value() << nl << nl;
if (notNull(ptrToClass.get()))
if (notNull(ptrToClass))
{
Info<< "Pass: ptrToClass is not null" << nl;
}
else
{
Info<< "FAIL: ptrToClass is null" << nl;
Info<< "FAIL: refToClass is null" << nl;
}
if (notNull(refToClass))
@ -109,8 +110,8 @@ int main()
// Test pointer and reference to the nullObject
const SimpleClass* ptrToNull = NullObjectPtr<SimpleClass>();
const SimpleClass& refToNull = (*ptrToNull);
const SimpleClass* ptrToNull(NullObjectPtr<SimpleClass>());
const SimpleClass& refToNull(*ptrToNull);
if (isNull(ptrToNull))
{
@ -130,6 +131,9 @@ int main()
Info<< "FAIL: refToNull is not null" << nl;
}
// Clean-up
delete ptrToClass;
// Test List casting
{
@ -148,7 +152,7 @@ int main()
// Looks pretty ugly though!
NullObject::nullObject = "hello world";
NullObject::nullObject = Foam::identity(5);
NullObject::nullObject = labelList({1, 2, 3});
Info<< nl;

View File

@ -50,37 +50,37 @@ scalar sumReduce
)
{
scalar sum = 0;
if (UPstream::parRun())
if (Pstream::parRun())
{
if (UPstream::master(comm))
{
// Add master value and all sub-procs
// Add master value and all slaves
sum = localValue;
for (const int proci : UPstream::subProcs(comm))
for (const int slave : UPstream::subProcs(comm))
{
scalar procValue;
scalar slaveValue;
UIPstream::read
(
UPstream::commsTypes::blocking,
proci,
reinterpret_cast<char*>(&procValue),
Pstream::commsTypes::blocking,
slave,
reinterpret_cast<char*>(&slaveValue),
sizeof(scalar),
UPstream::msgType(), // tag
comm // communicator
);
sum += procValue;
sum += slaveValue;
}
// Send back
// Send back to slaves
for (const int proci : UPstream::subProcs(comm))
for (const int slave : UPstream::subProcs(comm))
{
UOPstream::write
(
UPstream::commsTypes::blocking,
proci,
slave,
reinterpret_cast<const char*>(&sum),
sizeof(scalar),
UPstream::msgType(), // tag

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2024 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -52,27 +52,27 @@ void testMapDistribute()
// Generate random data.
List<Tuple2<label, List<scalar>>> complexData(100);
for (auto& data : complexData)
forAll(complexData, i)
{
data.first() = rndGen.position(0, UPstream::nProcs()-1);
data.second().resize(3);
data.second()[0] = 1;
data.second()[1] = 2;
data.second()[2] = 3;
complexData[i].first() = rndGen.position(0, Pstream::nProcs()-1);
complexData[i].second().setSize(3);
complexData[i].second()[0] = 1;
complexData[i].second()[1] = 2;
complexData[i].second()[2] = 3;
}
// Send all ones to processor indicated by .first()
// Count how many to send
labelList nSend(UPstream::nProcs(), Foam::zero{});
for (const auto& data : complexData)
labelList nSend(Pstream::nProcs(), Zero);
forAll(complexData, i)
{
const label proci = data.first();
const label proci = complexData[i].first();
nSend[proci]++;
}
// Collect items to be sent
labelListList sendMap(UPstream::nProcs());
labelListList sendMap(Pstream::nProcs());
forAll(sendMap, proci)
{
sendMap[proci].resize_nocopy(nSend[proci]);
@ -116,31 +116,40 @@ void testTransfer(const T& input)
{
T data = input;
if (UPstream::master())
if (Pstream::master())
{
Perr<<"test transfer (" << (typeid(T).name()) << "): ";
perrInfo(data) << nl << endl;
}
for (const int proci : UPstream::subProcs())
if (Pstream::master())
{
for (const int slave : Pstream::subProcs())
{
Perr<< "master receiving from proc:" << proci << endl;
IPstream::recv(data, proci);
Perr<< "master receiving from slave " << slave << endl;
IPstream fromSlave(Pstream::commsTypes::blocking, slave);
fromSlave >> data;
perrInfo(data) << endl;
}
for (const int proci : UPstream::subProcs())
for (const int slave : Pstream::subProcs())
{
Perr<< "master sending to proc:" << proci << endl;
OPstream::bsend(data, proci);
Perr<< "master sending to slave " << slave << endl;
OPstream toSlave(Pstream::commsTypes::blocking, slave);
toSlave << data;
}
}
else
{
Perr<< "proc sending to master" << endl;
OPstream::bsend(data, UPstream::masterNo());
{
Perr<< "slave sending to master " << Pstream::masterNo() << endl;
OPstream toMaster(Pstream::commsTypes::blocking, Pstream::masterNo());
toMaster << data;
}
Perr<< "proc receiving from master" << endl;
IPstream::recv(data, UPstream::masterNo());
Perr<< "slave receiving from master " << Pstream::masterNo() << endl;
IPstream fromMaster(Pstream::commsTypes::blocking, Pstream::masterNo());
fromMaster >> data;
perrInfo(data) << endl;
}
}
@ -151,31 +160,49 @@ void testTokenized(const T& data)
{
token tok;
if (UPstream::master())
if (Pstream::master())
{
Perr<< "test tokenized \"" << data << "\"" << nl << endl;
Perr<<"test tokenized \"" << data << "\"" << nl << endl;
}
for (const int proci : UPstream::subProcs())
if (Pstream::master())
{
for (const int slave : Pstream::subProcs())
{
Perr<< "master receiving from proc:" << proci << endl;
IPstream::recv(tok, proci);
Perr<< "master receiving from slave " << slave << endl;
IPstream fromSlave(Pstream::commsTypes::blocking, slave);
fromSlave >> tok;
Perr<< tok.info() << endl;
}
for (const int proci : UPstream::subProcs())
for (const int slave : Pstream::subProcs())
{
Perr<< "master sending to proc:" << proci << endl;
OPstream::bsend(tok, proci);
Perr<< "master sending to slave " << slave << endl;
OPstream toSlave(Pstream::commsTypes::blocking, slave);
toSlave << data;
}
}
else
{
Perr<< "proc sending to master" << endl;
OPstream::bsend(tok, UPstream::masterNo());
{
Perr<< "slave sending to master " << Pstream::masterNo() << endl;
OPstream toMaster
(
Pstream::commsTypes::blocking,
Pstream::masterNo()
);
Perr<< "proc receiving from master" << endl;
IPstream::recv(tok, UPstream::masterNo());
toMaster << data;
}
Perr<< "slave receiving from master " << Pstream::masterNo() << endl;
IPstream fromMaster
(
Pstream::commsTypes::blocking,
Pstream::masterNo()
);
fromMaster >> tok;
Perr<< tok.info() << endl;
}
}
@ -185,14 +212,12 @@ void testTokenized(const T& data)
int main(int argc, char *argv[])
{
argList::noCheckProcessorDirectories();
#include "setRootCase.H"
#include "createTime.H"
testMapDistribute();
if (!UPstream::parRun())
if (!Pstream::parRun())
{
Info<< "\nWarning: not parallel - skipping further tests\n" << endl;
return 0;

View File

@ -51,7 +51,7 @@ void printConnection(Ostream& os, const label proci, const labelUList& below)
// The number of receives - as per gatherList (v2112)
void printRecvCount_gatherList
(
const UList<UPstream::commsStruct>& comms,
const List<UPstream::commsStruct>& comms,
const label comm = UPstream::worldComm
)
{
@ -91,7 +91,7 @@ void printRecvCount_gatherList
// The number of sends - as per scatterList (v2112)
void printSendCount_scatterList
(
const UList<UPstream::commsStruct>& comms,
const List<UPstream::commsStruct>& comms,
const label comm = UPstream::worldComm
)
{
@ -131,7 +131,7 @@ void printSendCount_scatterList
// Transmission widths (contiguous data)
void printWidths
(
const UList<UPstream::commsStruct>& comms,
const List<UPstream::commsStruct>& comms,
const label comm = UPstream::worldComm
)
{

View File

@ -43,7 +43,6 @@ Description
#include "argList.H"
#include "Time.H"
#include "polyTopoChange.H"
#include "batchPolyTopoChange.H"
#include "polyTopoChanger.H"
#include "edgeCollapser.H"
#include "perfectInterface.H"
@ -1060,8 +1059,7 @@ int main(int argc, char *argv[])
);
// Topo change container
//polyTopoChange meshMod(mesh);
batchPolyTopoChange meshMod(mesh);
polyTopoChange meshMod(mesh);
perfectStitcher.setRefinement
(
@ -1087,9 +1085,7 @@ int main(int argc, char *argv[])
);
// Construct new mesh from polyTopoChange.
//autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
polyTopoChanger XXX (mesh, IOobject::NO_READ);
autoPtr<mapPolyMesh> map = XXX.changeMesh(mesh, meshMod);
autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
// Update fields
mesh.updateMesh(map());

View File

@ -579,8 +579,8 @@ inline bool CGAL::indexedCell<Gt, Cb>::potentialCoplanarCell() const
if (nMasters == 2 && nSlaves == 2)
{
Foam::vector vp0(Foam::zero{});
Foam::vector vp1(Foam::zero{});
Foam::vector vp0(Foam::Zero);
Foam::vector vp1(Foam::Zero);
if
(

View File

@ -622,7 +622,7 @@ int main(int argc, char *argv[])
}
// Execute all polyMeshModifiers
autoPtr<mapPolyMesh> morphMap = stitcher.changeMesh();
autoPtr<mapPolyMesh> morphMap = stitcher.changeMesh(true);
mesh.movePoints(morphMap->preMotionPoints());

View File

@ -75,7 +75,7 @@ wmake $targetType lagrangian/distributionModels
parallel/Allwmake $targetType $*
wmake $targetType dynamicFvMesh
#HJ wmake $targetType topoChangerFvMesh
wmake $targetType topoChangerFvMesh
wmake $targetType sampling
transportModels/Allwmake $targetType $*
@ -130,9 +130,6 @@ wmake $targetType rigidBodyMeshMotion
wmake $targetType atmosphericModels
wmake $targetType optimisation/adjointOptimisation/adjoint
# Moved by HJ
wmake $targetType topoChangerFvMesh
# interfaceTracking libs
dynamicFaMesh/Allwmake $targetType $*

View File

@ -120,11 +120,8 @@ public:
// Static Member Functions
//- Return a null bitSet (reference to a nullObject).
static const bitSet& null() noexcept
{
return NullObjectRef<bitSet>();
}
//- Return a null bitSet reference
inline static const bitSet& null();
//- Declare type-name (with debug switch)

View File

@ -405,6 +405,12 @@ inline Foam::label Foam::bitSet::find_next(label pos) const
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::bitSet& Foam::bitSet::null()
{
return NullObjectRef<bitSet>();
}
inline bool Foam::bitSet::all() const
{
if (empty()) return true; // SIC. boost convention

View File

@ -81,7 +81,7 @@ Foam::CompactListList<T> Foam::CompactListList<T>::pack_impl
if (len)
{
newOffsets.resize(len+1, Foam::zero{});
newOffsets.resize(len+1, Zero);
for (label i = 0; i < len; ++i)
{

View File

@ -138,11 +138,8 @@ public:
// Static Member Functions
//- Return a null CompactListList (reference to a nullObject).
static const CompactListList<T>& null() noexcept
{
return NullObjectRef<CompactListList<T>>();
}
//- Return a CompactListList reference to a nullObject
inline static const CompactListList<T>& null();
//- Construct by packing together the list of lists
template<class SubListType = List<T>>

View File

@ -29,6 +29,15 @@ License
#include "ListOps.H"
#include "SubList.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class T>
inline const Foam::CompactListList<T>& Foam::CompactListList<T>::null()
{
return NullObjectRef<CompactListList<T>>();
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class T>
@ -89,7 +98,7 @@ inline Foam::CompactListList<T>::CompactListList
const label nVals
)
:
offsets_(mRows+1, Foam::zero{}),
offsets_(mRows+1, Zero),
values_(nVals)
{
// Optionally: enforceSizeSanity();
@ -104,8 +113,8 @@ inline Foam::CompactListList<T>::CompactListList
const Foam::zero
)
:
offsets_(mRows+1, Foam::zero{}),
values_(nVals, Foam::zero{})
offsets_(mRows+1, Zero),
values_(nVals, Zero)
{
// Optionally: enforceSizeSanity();
}
@ -119,7 +128,7 @@ inline Foam::CompactListList<T>::CompactListList
const T& val
)
:
offsets_(mRows+1, Foam::zero{}),
offsets_(mRows+1, Zero),
values_(nVals, val)
{
// Optionally: enforceSizeSanity();
@ -378,7 +387,7 @@ inline void Foam::CompactListList<T>::resize
}
else
{
offsets_.resize(mRows+1, Foam::zero{});
offsets_.resize(mRows+1, Zero);
values_.resize(nVals);
}
}
@ -399,7 +408,7 @@ inline void Foam::CompactListList<T>::resize_nocopy
}
else
{
offsets_.resize(mRows+1, Foam::zero{});
offsets_.resize(mRows+1, Zero);
values_.resize_nocopy(nVals);
}
}
@ -421,7 +430,7 @@ inline void Foam::CompactListList<T>::resize
}
else
{
offsets_.resize(mRows+1, Foam::zero{});
offsets_.resize(mRows+1, Zero);
values_.resize(nVals, val);
}
}

View File

@ -46,10 +46,9 @@ SourceFiles
#include "zero.H"
#include "contiguous.H"
#include "stdFoam.H"
#include "nullObject.H"
#include "autoPtr.H"
#include "Hash.H"
#include "ListPolicy.H"
#include "autoPtr.H"
// <algorithm> already included by stdFoam.H
#include <iterator>
@ -140,12 +139,8 @@ public:
// Static Functions
//- Return a null FixedList (reference to a nullObject).
//- Read/write access is questionable
static const FixedList<T, N>& null() noexcept
{
return NullObjectRef<FixedList<T, N>>();
}
//- Return a null FixedList
inline static const FixedList<T, N>& null();
// Constructors

View File

@ -28,6 +28,15 @@ License
#include "UList.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class T, unsigned N>
inline const Foam::FixedList<T, N>& Foam::FixedList<T, N>::null()
{
return NullObjectRef<FixedList<T, N>>();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T, unsigned N>

View File

@ -129,12 +129,8 @@ public:
// Static Member Functions
//- Return a null List (reference to a nullObject).
//- Behaves like an empty List.
static const List<T>& null() noexcept
{
return NullObjectRef<List<T>>();
}
//- Return a null List
inline static const List<T>& null();
// Constructors

View File

@ -133,6 +133,13 @@ inline Foam::autoPtr<Foam::List<T>> Foam::List<T>::clone() const
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
inline const Foam::List<T>& Foam::List<T>::null()
{
return NullObjectRef<List<T>>();
}
template<class T>
inline void Foam::List<T>::clear()
{

View File

@ -73,12 +73,8 @@ public:
// Static Functions
//- Return a null SubList (reference to a nullObject).
//- Behaves like an empty SubList.
static const SubList<T>& null() noexcept
{
return NullObjectRef<SubList<T>>();
}
//- Return a null SubList
inline static const SubList<T>& null();
// Generated Methods

View File

@ -28,6 +28,15 @@ License
#include "FixedList.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class T>
inline const Foam::SubList<T>& Foam::SubList<T>::null()
{
return NullObjectRef<SubList<T>>();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T>
@ -115,7 +124,7 @@ inline Foam::SubList<T>::SubList
template<class T>
inline Foam::UList<T>& Foam::SubList<T>::reset(std::nullptr_t) noexcept
{
UList<T>::shallowCopy(nullptr);
UList<T>::shallowCopy(nullptr, 0);
return *this;
}

View File

@ -183,12 +183,8 @@ public:
// Static Functions
//- Return a null UList (reference to a nullObject).
//- Behaves like an empty UList.
static const UList<T>& null() noexcept
{
return NullObjectRef<UList<T>>();
}
//- Return a UList reference to a nullObject
inline static const UList<T>& null();
// Public Classes
@ -371,9 +367,6 @@ public:
//- Copy the pointer and size
inline void shallowCopy(T* __restrict__ ptr, const label len) noexcept;
//- Copy nullptr and zero size
inline void shallowCopy(std::nullptr_t) noexcept;
//- Copy the pointer and size held by the given UList
inline void shallowCopy(const UList<T>& list) noexcept;

View File

@ -93,6 +93,13 @@ inline void Foam::UList<T>::fill_uniform(const Foam::zero)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
inline const Foam::UList<T>& Foam::UList<T>::null()
{
return NullObjectRef<UList<T>>();
}
template<class T>
inline Foam::label Foam::UList<T>::fcIndex(const label i) const noexcept
{
@ -323,14 +330,6 @@ inline void Foam::UList<T>::shallowCopy
}
template<class T>
inline void Foam::UList<T>::shallowCopy(std::nullptr_t) noexcept
{
size_ = 0;
v_ = nullptr;
}
template<class T>
inline void Foam::UList<T>::shallowCopy(const UList<T>& list) noexcept
{

View File

@ -116,7 +116,7 @@ Foam::labelListList Foam::invertOneToMany
const labelUList& map
)
{
labelList sizes(len, Foam::zero{});
labelList sizes(len, Zero);
for (const label newIdx : map)
{

View File

@ -707,7 +707,7 @@ void Foam::invertManyToMany
)
{
// The output list sizes
labelList sizes(len, Foam::zero{});
labelList sizes(len, Zero);
for (const InputIntListType& sublist : input)
{

View File

@ -135,23 +135,15 @@ protected:
// Protected Member Functions
//- Helper: determine number of processors whose recvSizes fits
//- into maxBufferSize
static label calcNumProcs
(
const label comm,
const off_t maxBufferSize,
const labelUList& recvSizes,
const label startProci
);
//- Read data into *this. ISstream is only valid on master.
//- Read data (on master) and transmit.
static bool readBlocks
(
const label comm,
// [in] The input stream (only valid on master)
autoPtr<ISstream>& isPtr,
List<char>& contentChars,
const UPstream::commsTypes commsType
// [out] The processor local data
List<char>& localData,
const UPstream::commsTypes commsType /* unused */
);
//- Helper: skip a block of (binary) character data
@ -277,6 +269,19 @@ public:
}
//- Helper: write block of (binary) character content
// Housekeeping
static std::streamoff writeBlockEntry
(
OSstream& os,
const label blocki,
const stdFoam::span<char>& s
)
{
return writeBlockEntry(os, blocki, s.data(), s.size());
}
//- Helper: write block of (binary) character content
// Housekeeping
static std::streamoff writeBlockEntry
(
OSstream& os,
@ -307,41 +312,37 @@ public:
);
//- Read master header information (into headerIO) and return
//- data in stream. Note: isPtr is only valid on master.
//- data in stream.
static autoPtr<ISstream> readBlocks
(
const label comm,
const fileName& fName,
//! [in] The input stream (only valid on master)
autoPtr<ISstream>& isPtr,
//! [out] header information
IOobject& headerIO,
const UPstream::commsTypes commsType
const UPstream::commsTypes commsType /* unused */
);
//- Helper: gather single label. Note: using native Pstream.
// datas sized with num procs but undefined contents on
// slaves
static void gather
(
const label comm,
const label data,
labelList& datas
);
//- Helper: gather data from (subset of) slaves.
//- Helper: gather data from (subset of) sub-ranks.
// In non-blocking mode it sets up send/recv for non-empty content.
// In blocking/scheduled mode it uses MPI_Gatherv to collect data.
//
// Returns:
// - recvData : received data
// - recvData : the received data
// - recvOffsets : offset in data. recvOffsets is nProcs+1
static void gatherSlaveData
static void gatherProcData
(
const label comm,
const UList<char>& data,
const labelUList& recvSizes,
const UList<char>& localData, //!< [in] required on all procs
const labelUList& recvSizes, //!< [in] only required on master
const labelRange& fromProcs,
const labelRange& whichProcs, //!< [in] required on all procs
List<int>& recvOffsets,
DynamicList<char>& recvData
List<int>& recvOffsets, //!< [out] only relevant on master
DynamicList<char>& recvData, //!< [out] only relevant on master
const UPstream::commsTypes commsType
);
//- Write *this. Ostream only valid on master.
@ -349,19 +350,98 @@ public:
static bool writeBlocks
(
const label comm,
//! [in] output stream (relevant on master)
autoPtr<OSstream>& osPtr,
//! [out] start offsets to each block (relevant on master),
//! ignored if List::null() type
List<std::streamoff>& blockOffset,
const UList<char>& masterData,
const UList<char>& localData, //!< [in] required on all procs
const labelUList& recvSizes, //!< [in] only required on master
const labelUList& recvSizes,
// Optional slave data (on master)
const UPtrList<SubList<char>>& slaveData,
//! Optional proc data (only written on master)
//! but \b must also be symmetrically defined (empty/non-empty)
//! on all ranks
const UList<stdFoam::span<char>>& procData,
const UPstream::commsTypes commsType,
const bool syncReturnState = true
);
// Housekeeping
//- Write *this. Ostream only valid on master.
// Returns offsets of processor blocks in blockOffset
FOAM_DEPRECATED_FOR(2023-09, "write with char span instead")
static bool writeBlocks
(
const label comm,
autoPtr<OSstream>& osPtr,
List<std::streamoff>& blockOffset,
const UList<char>& localData, // [in] required on all procs
const labelUList& recvSizes, // [in] only required on master
// Optional proc data (only written on master)
// but \b must also be symmetrically defined (empty/non-empty)
// on all ranks
const UPtrList<SubList<char>>& procData,
const UPstream::commsTypes commsType,
const bool syncReturnState = true
)
{
// Transcribe to span<char>
List<stdFoam::span<char>> spans(procData.size());
forAll(procData, proci)
{
if (procData.test(proci))
{
spans[proci] = stdFoam::span<char>
(
const_cast<char*>(procData[proci].cdata()),
procData[proci].size()
);
}
}
return decomposedBlockData::writeBlocks
(
comm,
osPtr,
blockOffset,
localData,
recvSizes,
spans,
commsType,
syncReturnState
);
}
//- Deprecated(2023-09) - consider UPstream::listGatherValue
// The only difference is that this gather also resizes the output
// on the non-master procs
// \deprecated(2023-09) - consider UPstream::listGatherValue
FOAM_DEPRECATED_FOR(2023-09, "consider UPstream::listGatherValue()")
static void gather
(
const label comm,
const label localValue,
labelList& allValues
)
{
allValues.resize_nocopy(UPstream::nProcs(comm));
UPstream::mpiGather
(
reinterpret_cast<const char*>(&localValue),
allValues.data_bytes(),
sizeof(label), // The send/recv size per rank
comm
);
}
};

View File

@ -29,7 +29,7 @@ License
#include "masterOFstream.H"
#include "OFstream.H"
#include "OSspecific.H"
#include "PstreamBuffers.H"
#include "Pstream.H"
#include "masterUncollatedFileOperation.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -38,10 +38,10 @@ void Foam::masterOFstream::checkWrite
(
const fileName& fName,
const char* str,
std::streamsize len
const std::streamsize len
)
{
if (!len)
if (!str || !len)
{
// Can probably skip all of this if there is nothing to write
return;
@ -63,9 +63,7 @@ void Foam::masterOFstream::checkWrite
<< exit(FatalIOError);
}
// Use writeRaw() instead of writeQuoted(string,false) to output
// characters directly.
// Write characters directly to std::ostream
os.writeRaw(str, len);
if (!os.good())
@ -77,97 +75,159 @@ void Foam::masterOFstream::checkWrite
}
void Foam::masterOFstream::checkWrite
(
const fileName& fName,
const std::string& s
)
{
checkWrite(fName, s.data(), s.length());
}
void Foam::masterOFstream::commit()
{
// Take ownership of serialized content, without copying or reallocation
DynamicList<char> charData(OCharStream::release());
if (UPstream::parRun())
{
// Ignore content if not writing (reduces communication)
if (!writeOnProc_)
{
charData.clear();
}
List<fileName> filePaths(UPstream::nProcs(comm_));
filePaths[UPstream::myProcNo(comm_)] = pathName_;
Pstream::gatherList(filePaths, UPstream::msgType(), comm_);
// Test for identical output paths
bool uniform =
(
UPstream::master(comm_)
&& fileOperation::uniformFile(filePaths)
? fileOperation::uniformFile(filePaths)
: true
);
Pstream::broadcast(uniform, comm_);
if (uniform)
{
// Identical file paths - write on master
if (UPstream::master(comm_) && writeOnProc_)
{
checkWrite(pathName_, this->str());
checkWrite(pathName_, charData);
}
this->reset();
return;
}
// Different files
PstreamBuffers pBufs(comm_, UPstream::commsTypes::nonBlocking);
// ---------------
// Current strategy is to setup all non-blocking send/recv
// using the probed message size to establish the recv size
// (to avoid an additional communication of the sizes).
//
// For ranks with writeOnProc=false, the message size is 0.
if (!UPstream::master(comm_))
// An alternative approach would be to gather recv sizes
// to avoid zero-sized messages and/or use double buffering
// to recv into a buffer and write.
//
// const labelList recvSizes
// (
// UPstream::listGatherValues<label>
// (
// (UPstream::is_subrank(comm_) ? charData.size() : label(0)),
// comm_
// )
// );
const label startOfRequests = UPstream::nRequests();
// Some unique tag for this read/write/probe grouping
const int messageTag = UPstream::msgType() + 256;
if (UPstream::is_subrank(comm_))
{
if (writeOnProc_)
{
// Send buffer to master
string s(this->str());
UOPstream os(UPstream::masterNo(), pBufs);
os.write(s.data(), s.length());
}
this->reset(); // Done with contents
// Send to master. When (!writeOnProc_) it is zero-sized.
UOPstream::write
(
UPstream::commsTypes::nonBlocking,
UPstream::masterNo(),
charData.cdata_bytes(),
charData.size_bytes(),
messageTag,
comm_
);
}
pBufs.finishedGathers();
if (UPstream::master(comm_))
else if (UPstream::master(comm_))
{
// The receive slots
List<List<char>> procBuffers(UPstream::nProcs(comm_));
const auto recvProcs = UPstream::subProcs(comm_);
for (const int proci : recvProcs)
{
auto& procSlice = procBuffers[proci];
// Probe the message size
std::pair<int, int> probed =
UPstream::probeMessage
(
UPstream::commsTypes::blocking,
proci,
messageTag,
comm_
);
procSlice.resize_nocopy(probed.second);
// Receive content (can also be zero-sized)
UIPstream::read
(
UPstream::commsTypes::nonBlocking,
proci,
procSlice.data_bytes(),
procSlice.size_bytes(),
messageTag,
comm_
);
}
if (writeOnProc_)
{
// Write master data
checkWrite(filePaths[UPstream::masterNo()], this->str());
// Write non-empty master data
checkWrite(pathName_, charData);
}
this->reset(); // Done with contents
// Allocate large enough to read without resizing
List<char> buf(pBufs.maxRecvCount());
for (const int proci : UPstream::subProcs(comm_))
// Poll for completed receive requests and dispatch
DynamicList<int> indices(recvProcs.size());
while
(
UPstream::waitSomeRequests
(
startOfRequests,
recvProcs.size(),
&indices
)
)
{
const std::streamsize count(pBufs.recvDataCount(proci));
if (count)
for (const int idx : indices)
{
UIPstream is(proci, pBufs);
const int proci = recvProcs[idx];
auto& procSlice = procBuffers[proci];
is.read(buf.data(), count);
checkWrite(filePaths[proci], buf.cdata(), count);
if (!procSlice.empty())
{
// Write non-empty sub-proc data
checkWrite(filePaths[proci], procSlice);
}
// Eager cleanup?
// TBD: procSlice.clear();
}
}
}
UPstream::waitRequests(startOfRequests);
}
else
{
checkWrite(pathName_, this->str());
this->reset();
// Write (non-empty) data
checkWrite(pathName_, charData);
}
// This method is only called once (internally)
// so no need to clear/flush old buffered data
}
@ -183,7 +243,7 @@ Foam::masterOFstream::masterOFstream
const bool writeOnProc
)
:
OStringStream(streamOpt),
OCharStream(streamOpt),
pathName_(pathName),
atomic_(atomic),
compression_(streamOpt.compression()),

View File

@ -41,7 +41,7 @@ SourceFiles
#ifndef Foam_masterOFstream_H
#define Foam_masterOFstream_H
#include "StringStream.H"
#include "SpanStream.H"
#include "UPstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -55,7 +55,7 @@ namespace Foam
class masterOFstream
:
public OStringStream
public OCharStream
{
// Private Data
@ -85,13 +85,20 @@ class masterOFstream
(
const fileName& fName,
const char* str,
std::streamsize len
const std::streamsize len
);
//- Open file with checking and write append contents
void checkWrite(const fileName& fName, const std::string& s);
void checkWrite
(
const fileName& fName,
const UList<char>& charData
)
{
checkWrite(fName, charData.cdata(), charData.size_bytes());
}
//- Commit buffered information, including parallel gather as required
//- Commit buffered information, including communication as required
void commit();

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2013 OpenFOAM Foundation
Copyright (C) 2021-2024 OpenCFD Ltd.
Copyright (C) 2021-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -71,33 +71,6 @@ public:
const label comm = UPstream::worldComm,
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
);
// Static Functions
//- Receive and deserialize a value.
//- Uses \c operator>> for de-serialization
template<class Type>
static void recv
(
Type& value,
const int fromProcNo,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm,
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
)
{
IPstream is
(
UPstream::commsTypes::scheduled,
fromProcNo,
0, // bufSize
tag,
comm,
fmt
);
is >> value;
}
};

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2013 OpenFOAM Foundation
Copyright (C) 2021-2024 OpenCFD Ltd.
Copyright (C) 2021-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -71,73 +71,6 @@ public:
const label comm = UPstream::worldComm,
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
);
// Static Functions
//- Serialize a value and send (buffered/blocking or standard mode).
//- Uses \c operator<< for serialization
template<class Type>
static void send
(
const Type& value,
//! blocking or scheduled only!
const UPstream::commsTypes commsType,
const int toProcNo,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm,
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
)
{
OPstream os(commsType, toProcNo, 0, tag, comm, fmt);
os << value;
}
//- Serialize a value and send (buffered/blocking mode).
//- Uses \c operator<< for serialization
template<class Type>
static void bsend
(
const Type& value,
const int toProcNo,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm,
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
)
{
OPstream::send
(
value,
UPstream::commsTypes::blocking,
toProcNo,
tag,
comm,
fmt
);
}
//- Serialize a value and send (standard mode).
//- Uses \c operator<< for serialization
template<class Type>
static void send
(
const Type& value,
const int toProcNo,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm,
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
)
{
OPstream::send
(
value,
UPstream::commsTypes::scheduled,
toProcNo,
tag,
comm,
fmt
);
}
};

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2024 OpenCFD Ltd.
Copyright (C) 2016-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -47,6 +47,9 @@ SourceFiles
#include "UPstream.H"
#include "DynamicList.H"
// Legacy
// #define Foam_Pstream_scatter_nobroadcast
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -127,9 +130,22 @@ public:
// Gather
//- Gather (reduce) data, appyling \c bop to combine \c value
//- from different processors. The basis for Foam::reduce().
// Uses the specified communication schedule.
template<class T, class BinaryOp>
static void gather
(
const List<commsStruct>& comms,
T& value,
const BinaryOp& bop,
const int tag,
const label comm
);
//- Gather (reduce) data, applying \c bop to combine \c value
//- from different processors. The basis for Foam::reduce().
// Uses linear/tree communication (with parallel guard).
// Uses linear/tree communication.
template<class T, class BinaryOp>
static void gather
(
@ -139,46 +155,46 @@ public:
const label comm = UPstream::worldComm
);
//- Gather individual values into list locations.
// On master list length == nProcs, otherwise zero length.
// \n
// For \b non-parallel :
// the returned list length is 1 with localValue.
template<class T>
static List<T> listGatherValues
(
const T& localValue,
const label comm = UPstream::worldComm,
//! Only used for non-contiguous types
const int tag = UPstream::msgType()
);
//- Scatter individual values from list locations.
// On master input list length == nProcs, ignored on other procs.
// \n
// For \b non-parallel :
// returns the first list element (or default initialized).
template<class T>
static T listScatterValues
(
const UList<T>& allValues,
const label comm = UPstream::worldComm,
//! Only used for non-contiguous types
const int tag = UPstream::msgType()
);
// Gather/combine data
// Inplace combine values from processors.
// (Uses construct from Istream instead of \c << operator)
// (Uses construct from Istream instead of <<)
//- Gather data, applying \c cop to inplace combine \c value
//- from different processors.
// Uses linear/tree communication (with parallel guard).
// Uses the specified communication schedule.
template<class T, class CombineOp>
static void combineGather
(
//! [in,out]
const List<commsStruct>& comms,
T& value,
const CombineOp& cop,
const int tag,
const label comm
);
//- Gather data, applying \c cop to inplace combine \c value
//- from different processors.
// Uses linear/tree communication.
template<class T, class CombineOp>
static void combineGather
(
T& value,
const CombineOp& cop,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
//- Reduce inplace (cf. MPI Allreduce)
//- applying \c cop to inplace combine \c value
//- from different processors.
//- After completion all processors have the same data.
// Uses the specified communication schedule.
// Wraps combineGather/broadcast (may change in the future).
template<class T, class CombineOp>
static void combineReduce
(
const List<commsStruct>& comms,
T& value,
const CombineOp& cop,
const int tag = UPstream::msgType(),
@ -194,7 +210,6 @@ public:
template<class T, class CombineOp>
static void combineReduce
(
//! [in,out]
T& value,
const CombineOp& cop,
const int tag = UPstream::msgType(),
@ -217,25 +232,30 @@ public:
// Combine variants working on whole List at a time.
//- Combines List elements.
// Uses linear/tree communication (with parallel guard).
template<class T, class CombineOp>
static void listCombineGather
(
//! [in,out]
UList<T>& values,
const List<commsStruct>& comms,
List<T>& values,
const CombineOp& cop,
const int tag,
const label comm
);
//- Like above but switches between linear/tree communication
template<class T, class CombineOp>
static void listCombineGather
(
List<T>& values,
const CombineOp& cop,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
//- Combines List elements.
//- After completion all processors have the same data.
// Uses linear/tree communication (with parallel guard).
template<class T, class CombineOp>
static void listCombineReduce
(
//! [in,out] - List (not UList) due to broadcast()
List<T>& values,
const CombineOp& cop,
const int tag = UPstream::msgType(),
@ -246,7 +266,6 @@ public:
template<class T, class CombineOp>
static void listCombineAllGather
(
//! [in,out] - List (not UList) due to broadcast()
List<T>& values,
const CombineOp& cop,
const int tag = UPstream::msgType(),
@ -260,8 +279,17 @@ public:
// Combine variants working on whole map at a time.
// Container needs iterators, find() and insert methods defined.
//- Combine Map elements.
// Uses linear/tree communication (with parallel guard).
template<class Container, class CombineOp>
static void mapCombineGather
(
const List<commsStruct>& comms,
Container& values,
const CombineOp& cop,
const int tag,
const label comm
);
//- Like above but switches between linear/tree communication
template<class Container, class CombineOp>
static void mapCombineGather
(
@ -310,9 +338,8 @@ public:
template<class T>
static void gatherList
(
const UList<commsStruct>& comms,
//! [in,out]
UList<T>& values,
const List<commsStruct>& comms,
List<T>& values,
const int tag,
const label comm
);
@ -322,48 +349,133 @@ public:
template<class T>
static void gatherList
(
//! [in,out]
UList<T>& values,
List<T>& values,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
//- Gather data, but keep individual values separate.
//- Uses MPI_Allgather or manual linear/tree communication.
//- Uses linear/tree communication.
// After completion all processors have the same data.
// Wraps gatherList/scatterList (may change in the future).
template<class T>
static void allGatherList
(
//! [in,out]
UList<T>& values,
List<T>& values,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
// Scatter
// Scatter
//- Inverse of gatherList.
//- Uses the specified communication schedule.
template<class T>
static void scatterList
(
const UList<commsStruct>& comms,
UList<T>& values,
const int tag,
const label comm
);
//- Broadcast data: Distribute without modification.
// \note comms and tag parameters only used when
// Foam_Pstream_scatter_nobroadcast is defined
template<class T>
static void scatter
(
const List<commsStruct>& comms,
T& value,
const int tag,
const label comm
);
//- Inverse of gatherList.
//- Uses linear/tree communication.
template<class T>
static void scatterList
(
UList<T>& values,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
//- Broadcast data: Distribute without modification.
// \note tag parameter only used when
// Foam_Pstream_scatter_nobroadcast is defined
template<class T>
static void scatter
(
T& value,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
//- Broadcast data: Distribute without modification.
// \note tag parameter only used when
// Foam_Pstream_scatter_nobroadcast is defined
template<class T>
static void combineScatter
(
const List<commsStruct>& comms,
T& value,
const int tag,
const label comm
);
//- Broadcast data: Distribute without modification.
// \note tag parameter only used when
// Foam_Pstream_scatter_nobroadcast is defined
template<class T>
static void combineScatter
(
T& value,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
//- Broadcast data: Distribute without modification.
// \note comms and tag parameters only used when
// Foam_Pstream_scatter_nobroadcast is defined
template<class T>
static void listCombineScatter
(
const List<commsStruct>& comms,
List<T>& value,
const int tag,
const label comm
);
//- Broadcast data: Distribute without modification.
// \note comms and tag parameters only used when
// Foam_Pstream_scatter_nobroadcast is defined
template<class T>
static void listCombineScatter
(
List<T>& value,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
//- Broadcast data: Distribute without modification.
template<class Container>
static void mapCombineScatter
(
const List<commsStruct>& comms,
Container& values,
const int tag,
const label comm
);
//- Like above but switches between linear/tree communication
template<class Container>
static void mapCombineScatter
(
Container& values,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
//- Scatter data. Reverse of gatherList
template<class T>
static void scatterList
(
const List<commsStruct>& comms,
List<T>& values,
const int tag,
const label comm
);
//- Like above but switches between linear/tree communication
template<class T>
static void scatterList
(
List<T>& values,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
// Exchange
@ -542,61 +654,6 @@ public:
const label comm,
const bool wait = true //!< (ignored)
);
// Housekeeping
//- \deprecated(2024-01) Broadcast data
template<class T>
FOAM_DEPRECATED_FOR(2024-01, "Pstream::broadcast()")
static void scatter
(
T& value,
const int tag = UPstream::msgType(), //!< ignored
const label comm = UPstream::worldComm
)
{
Pstream::broadcast(value, comm);
}
//- \deprecated(2024-01) Broadcast data
template<class T>
FOAM_DEPRECATED_FOR(2024-01, "Pstream::broadcast()")
static void combineScatter
(
T& value,
const int tag = UPstream::msgType(), //!< ignored
const label comm = UPstream::worldComm
)
{
Pstream::broadcast(value, comm);
}
//- \deprecated(2024-01) Broadcast data
template<class T>
FOAM_DEPRECATED_FOR(2024-01, "Pstream::broadcast()")
static void listCombineScatter
(
List<T>& value,
const int tag = UPstream::msgType(), //!< ignored
const label comm = UPstream::worldComm
)
{
Pstream::broadcast(value, comm);
}
//- \deprecated(2024-01) Broadcast data
template<class Container>
FOAM_DEPRECATED_FOR(2024-01, "Pstream::broadcast()")
static void mapCombineScatter
(
Container& values,
const int tag = UPstream::msgType(), //!< ignored
const label comm = UPstream::worldComm
)
{
Pstream::broadcast(values, comm);
}
};

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022-2024 OpenCFD Ltd.
Copyright (C) 2022-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -137,32 +137,4 @@ void Foam::Pstream::broadcastList(ListType& list, const label comm)
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Convenience wrappers - defined after all specialisations are known
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Return a broadcasted value (uses a copy internally)
template<class Type>
Type returnBroadcast
(
const Type& value,
const label comm = UPstream::worldComm
)
{
Type work(value);
Pstream::broadcast(work, comm);
return work;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019-2024 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,7 +25,7 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
Variant of gather.
Variant of gather, scatter.
Normal gather uses:
- default construct and read (>>) from Istream
- binary operator and assignment operator to combine values
@ -46,6 +46,7 @@ Description
template<class T, class CombineOp>
void Foam::Pstream::combineGather
(
const List<UPstream::commsStruct>& comms,
T& value,
const CombineOp& cop,
const int tag,
@ -54,10 +55,8 @@ void Foam::Pstream::combineGather
{
if (UPstream::is_parallel(comm))
{
// Communication order
const auto& comms = UPstream::whichCommunication(comm);
// if (comms.empty()) return; // extra safety?
const auto& myComm = comms[UPstream::myProcNo(comm)];
// My communication order
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
// Receive from my downstairs neighbours
for (const label belowID : myComm.below())
@ -90,7 +89,7 @@ void Foam::Pstream::combineGather
(
UPstream::commsTypes::scheduled,
belowID,
0, // bufsize
0,
tag,
comm
);
@ -107,7 +106,7 @@ void Foam::Pstream::combineGather
}
// Send up value
if (myComm.above() >= 0)
if (myComm.above() != -1)
{
if (debug & 2)
{
@ -133,7 +132,7 @@ void Foam::Pstream::combineGather
(
UPstream::commsTypes::scheduled,
myComm.above(),
0, // bufsize
0,
tag,
comm
);
@ -144,6 +143,144 @@ void Foam::Pstream::combineGather
}
template<class T>
void Foam::Pstream::combineScatter
(
const List<UPstream::commsStruct>& comms,
T& value,
const int tag,
const label comm
)
{
#ifndef Foam_Pstream_scatter_nobroadcast
Pstream::broadcast(value, comm);
#else
if (UPstream::is_parallel(comm))
{
// My communication order
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo(comm)];
// Receive from up
if (myComm.above() != -1)
{
if (is_contiguous<T>::value)
{
UIPstream::read
(
UPstream::commsTypes::scheduled,
myComm.above(),
reinterpret_cast<char*>(&value),
sizeof(T),
tag,
comm
);
}
else
{
IPstream fromAbove
(
UPstream::commsTypes::scheduled,
myComm.above(),
0,
tag,
comm
);
value = T(fromAbove);
}
}
// Send to my downstairs neighbours
forAllReverse(myComm.below(), belowI)
{
const label belowID = myComm.below()[belowI];
if (is_contiguous<T>::value)
{
UOPstream::write
(
UPstream::commsTypes::scheduled,
belowID,
reinterpret_cast<const char*>(&value),
sizeof(T),
tag,
comm
);
}
else
{
OPstream toBelow
(
UPstream::commsTypes::scheduled,
belowID,
0,
tag,
comm
);
toBelow << value;
}
}
}
#endif
}
template<class T, class CombineOp>
void Foam::Pstream::combineGather
(
T& value,
const CombineOp& cop,
const int tag,
const label comm
)
{
Pstream::combineGather
(
UPstream::whichCommunication(comm),
value,
cop,
tag,
comm
);
}
template<class T>
void Foam::Pstream::combineScatter
(
T& value,
const int tag,
const label comm
)
{
#ifndef Foam_Pstream_scatter_nobroadcast
Pstream::broadcast(value, comm);
#else
Pstream::combineScatter
(
UPstream::whichCommunication(comm),
value,
tag,
comm
);
#endif
}
template<class T, class CombineOp>
void Foam::Pstream::combineReduce
(
const List<UPstream::commsStruct>& comms,
T& value,
const CombineOp& cop,
const int tag,
const label comm
)
{
Pstream::combineGather(comms, value, cop, tag, comm);
Pstream::broadcast(value, comm);
}
template<class T, class CombineOp>
void Foam::Pstream::combineReduce
(
@ -155,7 +292,9 @@ void Foam::Pstream::combineReduce
{
if (UPstream::is_parallel(comm))
{
Pstream::combineGather(value, cop, tag, comm);
const auto& comms = UPstream::whichCommunication(comm);
Pstream::combineGather(comms, value, cop, tag, comm);
Pstream::broadcast(value, comm);
}
}
@ -166,7 +305,8 @@ void Foam::Pstream::combineReduce
template<class T, class CombineOp>
void Foam::Pstream::listCombineGather
(
UList<T>& values,
const List<UPstream::commsStruct>& comms,
List<T>& values,
const CombineOp& cop,
const int tag,
const label comm
@ -174,10 +314,8 @@ void Foam::Pstream::listCombineGather
{
if (UPstream::is_parallel(comm))
{
// Communication order
const auto& comms = UPstream::whichCommunication(comm);
// if (comms.empty()) return; // extra safety?
const auto& myComm = comms[UPstream::myProcNo(comm)];
// My communication order
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
// Receive from my downstairs neighbours
for (const label belowID : myComm.below())
@ -213,7 +351,7 @@ void Foam::Pstream::listCombineGather
(
UPstream::commsTypes::scheduled,
belowID,
0, // bufsize
0,
tag,
comm
);
@ -233,7 +371,7 @@ void Foam::Pstream::listCombineGather
}
// Send up values
if (myComm.above() >= 0)
if (myComm.above() != -1)
{
if (debug & 2)
{
@ -259,7 +397,7 @@ void Foam::Pstream::listCombineGather
(
UPstream::commsTypes::scheduled,
myComm.above(),
0, // bufsize
0,
tag,
comm
);
@ -270,6 +408,129 @@ void Foam::Pstream::listCombineGather
}
template<class T>
void Foam::Pstream::listCombineScatter
(
const List<UPstream::commsStruct>& comms,
List<T>& values,
const int tag,
const label comm
)
{
#ifndef Foam_Pstream_scatter_nobroadcast
Pstream::broadcast(values, comm);
#else
if (UPstream::is_parallel(comm))
{
// My communication order
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo(comm)];
// Receive from up
if (myComm.above() != -1)
{
if (is_contiguous<T>::value)
{
UIPstream::read
(
UPstream::commsTypes::scheduled,
myComm.above(),
values.data_bytes(),
values.size_bytes(),
tag,
comm
);
}
else
{
IPstream fromAbove
(
UPstream::commsTypes::scheduled,
myComm.above(),
0,
tag,
comm
);
fromAbove >> values;
}
}
// Send to my downstairs neighbours
forAllReverse(myComm.below(), belowI)
{
const label belowID = myComm.below()[belowI];
if (is_contiguous<T>::value)
{
UOPstream::write
(
UPstream::commsTypes::scheduled,
belowID,
values.cdata_bytes(),
values.size_bytes(),
tag,
comm
);
}
else
{
OPstream toBelow
(
UPstream::commsTypes::scheduled,
belowID,
0,
tag,
comm
);
toBelow << values;
}
}
}
#endif
}
template<class T, class CombineOp>
void Foam::Pstream::listCombineGather
(
List<T>& values,
const CombineOp& cop,
const int tag,
const label comm
)
{
Pstream::listCombineGather
(
UPstream::whichCommunication(comm),
values,
cop,
tag,
comm
);
}
template<class T>
void Foam::Pstream::listCombineScatter
(
List<T>& values,
const int tag,
const label comm
)
{
#ifndef Foam_Pstream_scatter_nobroadcast
Pstream::broadcast(values, comm);
#else
Pstream::listCombineScatter
(
UPstream::whichCommunication(comm),
values,
tag,
comm
);
#endif
}
template<class T, class CombineOp>
void Foam::Pstream::listCombineReduce
(
@ -281,7 +542,9 @@ void Foam::Pstream::listCombineReduce
{
if (UPstream::is_parallel(comm))
{
Pstream::listCombineGather(values, cop, tag, comm);
const auto& comms = UPstream::whichCommunication(comm);
Pstream::listCombineGather(comms, values, cop, tag, comm);
Pstream::broadcast(values, comm);
}
}
@ -292,6 +555,7 @@ void Foam::Pstream::listCombineReduce
template<class Container, class CombineOp>
void Foam::Pstream::mapCombineGather
(
const List<UPstream::commsStruct>& comms,
Container& values,
const CombineOp& cop,
const int tag,
@ -300,10 +564,8 @@ void Foam::Pstream::mapCombineGather
{
if (UPstream::is_parallel(comm))
{
// Communication order
const auto& comms = UPstream::whichCommunication(comm);
// if (comms.empty()) return; // extra safety?
const auto& myComm = comms[UPstream::myProcNo(comm)];
// My communication order
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
// Receive from my downstairs neighbours
for (const label belowID : myComm.below())
@ -314,7 +576,7 @@ void Foam::Pstream::mapCombineGather
(
UPstream::commsTypes::scheduled,
belowID,
0, // bufsize
0,
tag,
comm
);
@ -349,7 +611,7 @@ void Foam::Pstream::mapCombineGather
}
// Send up values
if (myComm.above() >= 0)
if (myComm.above() != -1)
{
if (debug & 2)
{
@ -361,7 +623,7 @@ void Foam::Pstream::mapCombineGather
(
UPstream::commsTypes::scheduled,
myComm.above(),
0, // bufsize
0,
tag,
comm
);
@ -371,6 +633,110 @@ void Foam::Pstream::mapCombineGather
}
template<class Container>
void Foam::Pstream::mapCombineScatter
(
const List<UPstream::commsStruct>& comms,
Container& values,
const int tag,
const label comm
)
{
#ifndef Foam_Pstream_scatter_nobroadcast
Pstream::broadcast(values, comm);
#else
if (UPstream::is_parallel(comm))
{
// My communication order
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo(comm)];
// Receive from up
if (myComm.above() != -1)
{
IPstream fromAbove
(
UPstream::commsTypes::scheduled,
myComm.above(),
0,
tag,
comm
);
fromAbove >> values;
if (debug & 2)
{
Pout<< " received from "
<< myComm.above() << " data:" << values << endl;
}
}
// Send to my downstairs neighbours
forAllReverse(myComm.below(), belowI)
{
const label belowID = myComm.below()[belowI];
if (debug & 2)
{
Pout<< " sending to " << belowID << " data:" << values << endl;
}
OPstream toBelow
(
UPstream::commsTypes::scheduled,
belowID,
0,
tag,
comm
);
toBelow << values;
}
}
#endif
}
template<class Container, class CombineOp>
void Foam::Pstream::mapCombineGather
(
Container& values,
const CombineOp& cop,
const int tag,
const label comm
)
{
Pstream::mapCombineGather
(
UPstream::whichCommunication(comm),
values,
cop,
tag,
comm
);
}
template<class Container>
void Foam::Pstream::mapCombineScatter
(
Container& values,
const int tag,
const label comm
)
{
#ifndef Foam_Pstream_scatter_nobroadcast
Pstream::broadcast(values, comm);
#else
Pstream::mapCombineScatter
(
UPstream::whichCommunication(comm),
values,
tag,
comm
);
#endif
}
template<class Container, class CombineOp>
void Foam::Pstream::mapCombineReduce
(
@ -382,7 +748,9 @@ void Foam::Pstream::mapCombineReduce
{
if (UPstream::is_parallel(comm))
{
Pstream::mapCombineGather(values, cop, tag, comm);
const auto& comms = UPstream::whichCommunication(comm);
Pstream::mapCombineGather(comms, values, cop, tag, comm);
Pstream::broadcast(values, comm);
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019-2024 OpenCFD Ltd.
Copyright (C) 2019-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -26,7 +26,7 @@ License
Description
Gather data from all processors onto single processor according to some
communication schedule (usually tree-to-master).
communication schedule (usually linear-to-master or tree-to-master).
The gathered data will be a single value constructed from the values
on individual processors using a user-specified operator.
@ -41,6 +41,7 @@ Description
template<class T, class BinaryOp>
void Foam::Pstream::gather
(
const List<UPstream::commsStruct>& comms,
T& value,
const BinaryOp& bop,
const int tag,
@ -49,10 +50,8 @@ void Foam::Pstream::gather
{
if (UPstream::is_parallel(comm))
{
// Communication order
const auto& comms = UPstream::whichCommunication(comm);
// if (comms.empty()) return; // extra safety?
const auto& myComm = comms[UPstream::myProcNo(comm)];
// My communication order
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
// Receive from my downstairs neighbours
for (const label belowID : myComm.below())
@ -77,7 +76,7 @@ void Foam::Pstream::gather
(
UPstream::commsTypes::scheduled,
belowID,
0, // bufsize
0,
tag,
comm
);
@ -88,7 +87,7 @@ void Foam::Pstream::gather
}
// Send up value
if (myComm.above() >= 0)
if (myComm.above() != -1)
{
if (is_contiguous<T>::value)
{
@ -108,7 +107,7 @@ void Foam::Pstream::gather
(
UPstream::commsTypes::scheduled,
myComm.above(),
0, // bufsize
0,
tag,
comm
);
@ -120,181 +119,110 @@ void Foam::Pstream::gather
template<class T>
Foam::List<T> Foam::Pstream::listGatherValues
void Foam::Pstream::scatter
(
const T& localValue,
const label comm,
const int tag
const List<UPstream::commsStruct>& comms,
T& value,
const int tag,
const label comm
)
{
// OR
// if (is_contiguous<T>::value)
// {
// return UPstream::listGatherValues(localValue, comm);
// }
List<T> allValues;
#ifndef Foam_Pstream_scatter_nobroadcast
Pstream::broadcast(value, comm);
#else
if (UPstream::is_parallel(comm))
{
const label numProc = UPstream::nProcs(comm);
// My communication order
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
if (UPstream::master(comm))
// Receive from up
if (myComm.above() != -1)
{
allValues.resize(numProc);
}
if (is_contiguous<T>::value)
{
UPstream::mpiGather
(
reinterpret_cast<const char*>(&localValue),
allValues.data_bytes(),
sizeof(T), // The send/recv size per rank
comm
);
}
else
{
if (UPstream::master(comm))
if (is_contiguous<T>::value)
{
// Non-trivial to manage non-blocking gather without a
// PEX/NBX approach (eg, PstreamBuffers) but leave with
// with simple exchange for now
allValues[0] = localValue;
for (int proci = 1; proci < numProc; ++proci)
{
IPstream fromProc
(
UPstream::commsTypes::scheduled,
proci,
0, // bufsize
tag,
comm
);
fromProc >> allValues[proci];
}
}
else if (UPstream::is_rank(comm))
{
OPstream toProc
UIPstream::read
(
UPstream::commsTypes::scheduled,
UPstream::masterNo(),
0, // bufsize
myComm.above(),
reinterpret_cast<char*>(&value),
sizeof(T),
tag,
comm
);
toProc << localValue;
}
else
{
IPstream fromAbove
(
UPstream::commsTypes::scheduled,
myComm.above(),
0,
tag,
comm
);
fromAbove >> value;
}
}
// Send to my downstairs neighbours. Note reverse order (compared to
// receiving). This is to make sure to send to the critical path
// (only when using a tree schedule!) first.
forAllReverse(myComm.below(), belowI)
{
const label belowID = myComm.below()[belowI];
if (is_contiguous<T>::value)
{
UOPstream::write
(
UPstream::commsTypes::scheduled,
belowID,
reinterpret_cast<const char*>(&value),
sizeof(T),
tag,
comm
);
}
else
{
OPstream toBelow
(
UPstream::commsTypes::scheduled,
belowID,
0,
tag,
comm
);
toBelow << value;
}
}
}
else
{
// non-parallel: return own value
// TBD: only when UPstream::is_rank(comm) as well?
allValues.resize(1);
allValues[0] = localValue;
}
#endif
}
return allValues;
template<class T, class BinaryOp>
void Foam::Pstream::gather
(
T& value,
const BinaryOp& bop,
const int tag,
const label comm
)
{
Pstream::gather(UPstream::whichCommunication(comm), value, bop, tag, comm);
}
template<class T>
T Foam::Pstream::listScatterValues
(
const UList<T>& allValues,
const label comm,
const int tag
)
void Foam::Pstream::scatter(T& value, const int tag, const label comm)
{
// OR
// if (is_contiguous<T>::value)
// {
// return UPstream::listScatterValues(allValues, comm);
// }
T localValue{};
if (UPstream::is_parallel(comm))
{
const label numProc = UPstream::nProcs(comm);
if (UPstream::master(comm) && allValues.size() < numProc)
{
FatalErrorInFunction
<< "Attempting to send " << allValues.size()
<< " values to " << numProc << " processors" << endl
<< Foam::abort(FatalError);
}
if (is_contiguous<T>::value)
{
UPstream::mpiScatter
(
allValues.cdata_bytes(),
reinterpret_cast<char*>(&localValue),
sizeof(T), // The send/recv size per rank
comm
);
}
else
{
if (UPstream::master(comm))
{
const label startOfRequests = UPstream::nRequests();
List<DynamicList<char>> sendBuffers(numProc);
for (int proci = 1; proci < numProc; ++proci)
{
UOPstream toProc
(
UPstream::commsTypes::nonBlocking,
proci,
sendBuffers[proci],
tag,
comm
);
toProc << allValues[proci];
}
// Wait for outstanding requests
UPstream::waitRequests(startOfRequests);
return allValues[0];
}
else if (UPstream::is_rank(comm))
{
IPstream fromProc
(
UPstream::commsTypes::scheduled,
UPstream::masterNo(),
0, // bufsize
tag,
comm
);
fromProc >> localValue;
}
}
}
else
{
// non-parallel: return first value
// TBD: only when UPstream::is_rank(comm) as well?
if (!allValues.empty())
{
return allValues[0];
}
}
return localValue;
#ifndef Foam_Pstream_scatter_nobroadcast
Pstream::broadcast(value, comm);
#else
Pstream::scatter(UPstream::whichCommunication(comm), value, tag, comm);
#endif
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2024 OpenCFD Ltd.
Copyright (C) 2015-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -26,7 +26,7 @@ License
Description
Gather data from all processors onto single processor according to some
communication schedule (usually tree-to-master).
communication schedule (usually linear-to-master or tree-to-master).
The gathered data will be a list with element procID the data from processor
procID. Before calling every processor should insert its value into
values[UPstream::myProcNo(comm)].
@ -45,27 +45,24 @@ Description
template<class T>
void Foam::Pstream::gatherList
(
const UList<UPstream::commsStruct>& comms,
UList<T>& values,
const List<UPstream::commsStruct>& comms,
List<T>& values,
const int tag,
const label comm
)
{
if (!comms.empty() && UPstream::is_parallel(comm))
if (UPstream::is_parallel(comm))
{
const label myProci = UPstream::myProcNo(comm);
const label numProc = UPstream::nProcs(comm);
if (values.size() < numProc)
if (values.size() < UPstream::nProcs(comm))
{
FatalErrorInFunction
<< "List of values:" << values.size()
<< " < numProcs:" << numProc << nl
<< "List of values is too small:" << values.size()
<< " vs numProcs:" << UPstream::nProcs(comm) << nl
<< Foam::abort(FatalError);
}
// My communication order
const auto& myComm = comms[myProci];
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
// Receive from my downstairs neighbours
for (const label belowID : myComm.below())
@ -130,21 +127,21 @@ void Foam::Pstream::gatherList
// Send up from values:
// - my own value first
// - all belowLeaves next
if (myComm.above() >= 0)
if (myComm.above() != -1)
{
const labelList& belowLeaves = myComm.allBelow();
if (debug & 2)
{
Pout<< " sending to " << myComm.above()
<< " data from me:" << myProci
<< " data:" << values[myProci] << endl;
<< " data from me:" << UPstream::myProcNo(comm)
<< " data:" << values[UPstream::myProcNo(comm)] << endl;
}
if (is_contiguous<T>::value)
{
List<T> sending(belowLeaves.size() + 1);
sending[0] = values[myProci];
sending[0] = values[UPstream::myProcNo(comm)];
forAll(belowLeaves, leafI)
{
@ -171,7 +168,7 @@ void Foam::Pstream::gatherList
tag,
comm
);
toAbove << values[myProci];
toAbove << values[UPstream::myProcNo(comm)];
for (const label leafID : belowLeaves)
{
@ -192,8 +189,8 @@ void Foam::Pstream::gatherList
template<class T>
void Foam::Pstream::scatterList
(
const UList<UPstream::commsStruct>& comms,
UList<T>& values,
const List<UPstream::commsStruct>& comms,
List<T>& values,
const int tag,
const label comm
)
@ -202,24 +199,21 @@ void Foam::Pstream::scatterList
// between scatterList() and using broadcast(List<T>&) or a regular
// scatter(List<T>&) is that processor-local data is skipped.
if (!comms.empty() && UPstream::is_parallel(comm))
if (UPstream::is_parallel(comm))
{
const label myProci = UPstream::myProcNo(comm);
const label numProc = UPstream::nProcs(comm);
if (values.size() < numProc)
if (values.size() < UPstream::nProcs(comm))
{
FatalErrorInFunction
<< "List of values:" << values.size()
<< " < numProcs:" << numProc << nl
<< "List of values is too small:" << values.size()
<< " vs numProcs:" << UPstream::nProcs(comm) << nl
<< Foam::abort(FatalError);
}
// My communication order
const auto& myComm = comms[myProci];
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
// Receive from up
if (myComm.above() >= 0)
if (myComm.above() != -1)
{
const labelList& notBelowLeaves = myComm.allNotBelow();
@ -324,18 +318,12 @@ void Foam::Pstream::scatterList
template<class T>
void Foam::Pstream::gatherList
(
UList<T>& values,
List<T>& values,
const int tag,
const label comm
)
{
Pstream::gatherList
(
UPstream::whichCommunication(comm),
values,
tag,
comm
);
Pstream::gatherList(UPstream::whichCommunication(comm), values, tag, comm);
}
@ -343,25 +331,19 @@ void Foam::Pstream::gatherList
template<class T>
void Foam::Pstream::scatterList
(
UList<T>& values,
List<T>& values,
const int tag,
const label comm
)
{
Pstream::scatterList
(
UPstream::whichCommunication(comm),
values,
tag,
comm
);
Pstream::scatterList(UPstream::whichCommunication(comm), values, tag, comm);
}
template<class T>
void Foam::Pstream::allGatherList
(
UList<T>& values,
List<T>& values,
const int tag,
const label comm
)

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2024 OpenCFD Ltd.
Copyright (C) 2016-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -46,6 +46,28 @@ namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Reduce inplace (cf. MPI Allreduce)
//- using specified communication schedule.
template<class T, class BinaryOp>
void reduce
(
const List<UPstream::commsStruct>& comms,
T& value,
const BinaryOp& bop,
const int tag,
const label comm
)
{
if (UPstream::warnComm >= 0 && comm != UPstream::warnComm)
{
Pout<< "** reducing:" << value << " with comm:" << comm << endl;
error::printStack(Pout);
}
Pstream::gather(comms, value, bop, tag, comm);
Pstream::broadcast(value, comm);
}
//- Reduce inplace (cf. MPI Allreduce)
//- using linear/tree communication schedule
template<class T, class BinaryOp>
@ -59,13 +81,7 @@ void reduce
{
if (UPstream::is_parallel(comm))
{
if (UPstream::warnComm >= 0 && comm != UPstream::warnComm)
{
Pout<< "** reducing:" << value << " with comm:" << comm << endl;
error::printStack(Pout);
}
Pstream::gather(value, bop, tag, comm);
Pstream::broadcast(value, comm);
Foam::reduce(UPstream::whichCommunication(comm), value, bop, tag, comm);
}
}
@ -420,7 +436,8 @@ Pstream_SumReduce(double);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Convenience wrappers - defined after all specialisations are known
// Convenience wrappers for some reduction operations
// - defined after all specialisations are known
//- Perform reduction on a copy, using specified binary operation
// \return the resulting value

View File

@ -52,7 +52,6 @@ Foam::UPstream::commsTypeNames
({
{ commsTypes::blocking, "blocking" },
{ commsTypes::scheduled, "scheduled" },
// { commsTypes::nonBlocking, "non-blocking" },
{ commsTypes::nonBlocking, "nonBlocking" },
});

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2024 OpenCFD Ltd.
Copyright (C) 2015-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -895,32 +895,21 @@ public:
);
//- Communication schedule for tree all-to-master (proc 0)
static const List<commsStruct>&
treeCommunication
static const List<commsStruct>& treeCommunication
(
const label communicator = worldComm
);
//- Communication schedule for all-to-master (proc 0) as
//- linear/tree/none with switching based on UPstream::nProcsSimpleSum
//- and the is_parallel() state
//- Communication schedule for linear/tree all-to-master (proc 0).
//- Chooses based on the value of UPstream::nProcsSimpleSum
static const List<commsStruct>& whichCommunication
(
const label communicator = worldComm
)
{
const label np
(
parRun_ && is_rank(communicator) // cf. is_parallel()
? nProcs(communicator)
: 0
);
return
(
np <= 1
? List<commsStruct>::null()
: np < nProcsSimpleSum
nProcs(communicator) < nProcsSimpleSum
? linearCommunication(communicator)
: treeCommunication(communicator)
);
@ -1149,7 +1138,7 @@ public:
// On master input list length == nProcs, ignored on other procs.
// \n
// For \b non-parallel :
// returns the first list element (or default initialized).
// returns the first list element (or zero).
template<class T>
static T listScatterValues
(
@ -1202,7 +1191,6 @@ public:
//- Process index of first sub-process
// \deprecated(2020-09) use subProcs() method instead
FOAM_DEPRECATED_FOR(2020-09, "subProcs() method")
static constexpr int firstSlave() noexcept
{
return 1;
@ -1210,7 +1198,6 @@ public:
//- Process index of last sub-process
// \deprecated(2020-09) use subProcs() method instead
FOAM_DEPRECATED_FOR(2020-09, "subProcs() or allProcs() method")
static int lastSlave(const label communicator = worldComm)
{
return nProcs(communicator) - 1;

View File

@ -34,6 +34,14 @@ Foam::List<T> Foam::UPstream::allGatherValues
const label comm
)
{
if (!is_contiguous<T>::value)
{
FatalErrorInFunction
<< "Cannot all-gather values for non-contiguous types" << endl
<< Foam::abort(FatalError);
}
List<T> allValues;
if (UPstream::is_parallel(comm))
@ -41,17 +49,7 @@ Foam::List<T> Foam::UPstream::allGatherValues
allValues.resize(UPstream::nProcs(comm));
allValues[UPstream::myProcNo(comm)] = localValue;
if (is_contiguous<T>::value)
{
UPstream::mpiAllGather(allValues.data_bytes(), sizeof(T), comm);
}
else
{
FatalErrorInFunction
<< "Cannot all-gather values for non-contiguous types"
" - consider Pstream variant instead" << endl
<< Foam::abort(FatalError);
}
UPstream::mpiAllGather(allValues.data_bytes(), sizeof(T), comm);
}
else
{
@ -72,6 +70,14 @@ Foam::List<T> Foam::UPstream::listGatherValues
const label comm
)
{
if (!is_contiguous<T>::value)
{
FatalErrorInFunction
<< "Cannot gather values for non-contiguous types" << endl
<< Foam::abort(FatalError);
}
List<T> allValues;
if (UPstream::is_parallel(comm))
@ -81,23 +87,13 @@ Foam::List<T> Foam::UPstream::listGatherValues
allValues.resize(UPstream::nProcs(comm));
}
if (is_contiguous<T>::value)
{
UPstream::mpiGather
(
reinterpret_cast<const char*>(&localValue),
allValues.data_bytes(),
sizeof(T), // The send/recv size per rank
comm
);
}
else
{
FatalErrorInFunction
<< "Cannot gather values for non-contiguous types"
" - consider Pstream variant instead" << endl
<< Foam::abort(FatalError);
}
UPstream::mpiGather
(
reinterpret_cast<const char*>(&localValue),
allValues.data_bytes(),
sizeof(T), // The send/recv size per rank
comm
);
}
else
{
@ -118,46 +114,47 @@ T Foam::UPstream::listScatterValues
const label comm
)
{
T localValue{};
if (!is_contiguous<T>::value)
{
FatalErrorInFunction
<< "Cannot scatter values for non-contiguous types" << endl
<< Foam::abort(FatalError);
}
T localValue;
if (UPstream::is_parallel(comm))
{
const label numProc = UPstream::nProcs(comm);
const label nproc = UPstream::nProcs(comm);
if (UPstream::master(comm) && allValues.size() < numProc)
if (UPstream::master(comm) && allValues.size() < nproc)
{
FatalErrorInFunction
<< "Attempting to send " << allValues.size()
<< " values to " << numProc << " processors" << endl
<< " values to " << nproc << " processors" << endl
<< Foam::abort(FatalError);
}
if (is_contiguous<T>::value)
{
UPstream::mpiScatter
(
allValues.cdata_bytes(),
reinterpret_cast<char*>(&localValue),
sizeof(T), // The send/recv size per rank
comm
);
}
else
{
FatalErrorInFunction
<< "Cannot scatter values for non-contiguous types"
" - consider Pstream variant instead" << endl
<< Foam::abort(FatalError);
}
UPstream::mpiScatter
(
allValues.cdata_bytes(),
reinterpret_cast<char*>(&localValue),
sizeof(T), // The send/recv size per rank
comm
);
}
else
{
// non-parallel: return first value
// TBD: only when UPstream::is_rank(comm) as well?
// non-parallel: return local value
if (!allValues.empty())
if (UPstream::is_rank(comm) && !allValues.empty())
{
return allValues[0];
localValue = allValues[0];
}
else
{
localValue = Zero;
}
}

View File

@ -541,7 +541,7 @@ public:
// No character stripping
inline explicit token(tokenType typ, const std::string&, label line=0);
//- Move construct word/string token with the specified variant.
//- Copy construct word/string token with the specified variant.
// A invalid word/string variant type is silently treated as STRING.
// No character stripping
inline explicit token(tokenType typ, std::string&&, label line=0);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2023 Sergey Lesnik
Copyright (C) 2023-2024 OpenCFD Ltd.
Copyright (C) 2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -35,7 +35,7 @@ namespace Foam
{
// Write tokens without keyword, suppress/ignore bad tokens.
// Mostly like primitiveEntry::write(os, true);
// Mostly like primitiveEntry::write(os, false);
static void writeTokens(Ostream& os, const tokenList& toks)
{
@ -56,11 +56,11 @@ static void writeTokens(Ostream& os, const tokenList& toks)
started = true;
}
// Token output via direct handling in Ostream(s),
// or normal '<<' output operator
// Output token with direct handling in Ostream(s),
// or use normal '<<' output operator
if (!os.write(tok))
{
os << tok;
os << tok;
}
if (tok.isCharData())
@ -73,10 +73,18 @@ static void writeTokens(Ostream& os, const tokenList& toks)
if (s.starts_with("//") && !s.ends_with('\n'))
{
os << '\n';
started = false; // Does not need further space separator
started = false; // already have newline as separator
}
}
}
// Always finish up with a newline?
// eg,
//
// if (started)
// {
// os << nl;
// }
}
} // End namespace Foam
@ -133,10 +141,7 @@ Foam::formattingEntry::formattingEntry
void Foam::formattingEntry::write(Ostream& os) const
{
if (active_)
{
writeTokens(os, *this);
}
writeTokens(os, *this);
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2023 Sergey Lesnik
Copyright (C) 2023-2024 OpenCFD Ltd.
Copyright (C) 2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -51,17 +51,12 @@ class formattingEntry
:
public primitiveEntry
{
// Private Data
//- The output visibility
bool active_ = true;
public:
// Static Member Functions
//- Generate an entry keyword: "__format-entry__NNN".
//- The generated names are unlikely to collide with user dictionaries
//- Generate a default entry keyword: "__format-entry__NNN"
// The generated names are unlikely to collide with user dictionaries
static keyType defaultName(label n)
{
return keyType
@ -104,12 +99,6 @@ public:
formattingEntry(defaultName(n), std::move(content))
{}
//- Construct with token data, using a generated keyword
formattingEntry(const label n, token&& tok, bool visible=true)
:
primitiveEntry(defaultName(n), std::move(tok)),
active_(visible)
{}
//- Clone the entry
virtual autoPtr<entry> clone(const dictionary&) const
@ -123,21 +112,6 @@ public:
// Member Functions
//- Set output visibility on/off.
// \return the previous value
bool active(bool on) noexcept
{
bool old(active_);
active_ = on;
return old;
}
//- Get the output visibility
bool active() const noexcept
{
return active_;
}
//- Write content without the keyword.
// Special properties:
// - ignores any bad tokens on output.

View File

@ -115,7 +115,7 @@ Type Foam::Function1Types::Function1Expression<Type>::integrate
) const
{
NotImplemented;
return Type();
return Zero;
}

View File

@ -7,7 +7,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2024 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -163,7 +163,7 @@ operator_precedence()
svalue (lhs) ::= NUMBER (tok) . { lhs = (tok).scalarValue; } // scanToken
svalue (lhs) ::= ZERO . { lhs = Foam::zero{}; }
svalue (lhs) ::= ZERO . { lhs = Foam::Zero; }
svalue (lhs) ::= PI LPAREN RPAREN . { lhs = Foam::constant::mathematical::pi; }
svalue (lhs) ::= DEG_TO_RAD LPAREN RPAREN . { lhs = Foam::degToRad(); }
svalue (lhs) ::= RAD_TO_DEG LPAREN RPAREN . { lhs = Foam::radToDeg(); }

View File

@ -137,11 +137,8 @@ public:
// Static Member Functions
//- Return a null DimensionedField (reference to a nullObject).
static const DimensionedField<Type, GeoMesh>& null() noexcept
{
return NullObjectRef<DimensionedField<Type, GeoMesh>>();
}
//- Return a NullObjectRef DimensionedField
inline static const DimensionedField<Type, GeoMesh>& null();
// Constructors

View File

@ -28,6 +28,14 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type, class GeoMesh>
inline const Foam::DimensionedField<Type, GeoMesh>&
Foam::DimensionedField<Type, GeoMesh>::null()
{
return NullObjectRef<DimensionedField<Type, GeoMesh>>();
}
template<class Type, class GeoMesh>
inline const typename GeoMesh::Mesh&
Foam::DimensionedField<Type, GeoMesh>::mesh() const noexcept

View File

@ -85,7 +85,7 @@ public:
~SlicedDimensionedField()
{
// Set internalField to nullptr to avoid deletion of underlying field
UList<Type>::shallowCopy(nullptr);
UList<Type>::shallowCopy(UList<Type>());
}
};

View File

@ -97,8 +97,8 @@ public:
// Static Member Functions
//- Return a null DynamicField (reference to a nullObject).
static const DynamicField<T, SizeMin>& null() noexcept
//- Return a null field
inline static const DynamicField<T, SizeMin>& null()
{
return NullObjectRef<DynamicField<T, SizeMin>>();
}

View File

@ -122,12 +122,8 @@ public:
// Static Member Functions
//- Return a null Field (reference to a nullObject).
//- Behaves like an empty Field.
static const Field<Type>& null() noexcept
{
return NullObjectRef<Field<Type>>();
}
//- Return nullObject reference Field
inline static const Field<Type>& null();
// Constructors

View File

@ -25,6 +25,15 @@ License
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class Type>
inline const Foam::Field<Type>& Foam::Field<Type>::null()
{
return NullObjectRef<Field<Type>>();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>

View File

@ -69,12 +69,8 @@ public:
// Static Member Functions
//- Return a null SubField (reference to a nullObject).
//- Behaves like an empty SubField.
static const SubField<Type>& null() noexcept
{
return NullObjectRef<SubField<Type>>();
}
//- Return nullObject reference SubField
inline static const SubField<Type>& null();
// Constructors

View File

@ -26,6 +26,15 @@ License
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class Type>
inline const Foam::SubField<Type>& Foam::SubField<Type>::null()
{
return NullObjectRef<SubField<Type>>();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>

View File

@ -154,11 +154,8 @@ public:
// Static Member Functions
//- Return a null GeometricField (reference to a nullObject).
static const GeometricField<Type, PatchField, GeoMesh>& null() noexcept
{
return NullObjectRef<GeometricField<Type, PatchField, GeoMesh>>();
}
//- Return a null geometric field
inline static const GeometricField<Type, PatchField, GeoMesh>& null();
// Constructors

View File

@ -28,6 +28,14 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>
inline const Foam::GeometricField<Type, PatchField, GeoMesh>&
Foam::GeometricField<Type, PatchField, GeoMesh>::null()
{
return NullObjectRef<GeometricField<Type, PatchField, GeoMesh>>();
}
template<class Type, template<class> class PatchField, class GeoMesh>
inline const typename
Foam::GeometricField<Type, PatchField, GeoMesh>::Internal&

View File

@ -176,11 +176,10 @@ makeBoundary
new SlicedPatchField<Type>
(
p,
DimensionedField<Type, GeoMesh>::null()
DimensionedField<Type, GeoMesh>::null(),
bField[patchi]
)
);
bf[patchi].UList<Type>::shallowCopy(bField[patchi]);
}
}
@ -369,7 +368,7 @@ Foam::SlicedGeometricField<Type, PatchField, SlicedPatchField, GeoMesh>::
~SlicedGeometricField()
{
// Set internalField to nullptr to avoid deletion of underlying field
UList<Type>::shallowCopy(nullptr);
UList<Type>::shallowCopy(UList<Type>());
}

View File

@ -47,9 +47,9 @@ bool Foam::OFstreamCollator::writeFile
const label comm,
const word& objectType,
const fileName& fName,
const string& masterData,
const UList<char>& localData,
const labelUList& recvSizes,
const UPtrList<SubList<char>>& slaveData, // optional slave data
const UList<stdFoam::span<char>>& procData, // optional proc data
IOstreamOption streamOpt,
IOstreamOption::atomicType atomic,
IOstreamOption::appendType append,
@ -58,18 +58,14 @@ bool Foam::OFstreamCollator::writeFile
{
if (debug)
{
Pout<< "OFstreamCollator : Writing master " << label(masterData.size())
Pout<< "OFstreamCollator : Writing local " << localData.size()
<< " bytes to " << fName << " using comm " << comm
<< " and " << slaveData.size() << " sub-ranks" << endl;
<< " and " << procData.size() << " sub-ranks" << endl;
forAll(slaveData, proci)
forAll(procData, proci)
{
if (slaveData.set(proci))
{
Pout<< " " << proci
<< " size:" << slaveData[proci].size()
<< endl;
}
Pout<< " " << proci << " size:"
<< label(procData[proci].size()) << nl;
}
}
@ -104,32 +100,27 @@ bool Foam::OFstreamCollator::writeFile
// for some mpi so default is non-blocking.
const UPstream::commsTypes myCommsType
(
mag
(
fileOperations::masterUncollatedFileOperation::
maxMasterFileBufferSize == 0
)
maxMasterFileBufferSize
) < 1
? UPstream::commsTypes::scheduled
: UPstream::commsTypes::nonBlocking
);
UList<char> slice
(
const_cast<char*>(masterData.data()),
label(masterData.size())
);
List<std::streamoff> blockOffset;
List<std::streamoff> blockOffsets; // Optional
decomposedBlockData::writeBlocks
(
comm,
osPtr,
blockOffset,
slice,
blockOffsets, // or List<std::streamoff>::null()
localData,
recvSizes,
slaveData,
procData,
myCommsType,
false // do not reduce return state
false // do not sync return state
);
if (osPtr && !osPtr->good())
@ -140,17 +131,18 @@ bool Foam::OFstreamCollator::writeFile
if (debug)
{
Pout<< "OFstreamCollator : Finished writing " << masterData.size()
<< " bytes";
Pout<< "OFstreamCollator : Finished writing "
<< localData.size() << " bytes";
if (UPstream::master(comm))
{
off_t sum = 0;
off_t total = 0;
for (const label recv : recvSizes)
{
sum += recv;
total += recv;
}
// Use std::to_string to display long int
Pout<< " (overall " << std::to_string(sum) << ')';
Pout<< " (overall " << std::to_string(total) << ')';
}
Pout<< " to " << fName
<< " using comm " << comm << endl;
@ -167,13 +159,16 @@ void* Foam::OFstreamCollator::writeAll(void *threadarg)
// Consume stack
while (true)
{
writeData* ptr = nullptr;
std::unique_ptr<writeData> ptr;
{
std::lock_guard<std::mutex> guard(handler.mutex_);
if (handler.objects_.size())
{
ptr = handler.objects_.pop();
// FIFO
ptr.reset(handler.objects_.front());
handler.objects_.pop_front();
}
}
@ -181,51 +176,39 @@ void* Foam::OFstreamCollator::writeAll(void *threadarg)
{
break;
}
else
writeData& obj = *ptr;
// Obtain spans from storage
List<stdFoam::span<char>> procData(obj.procData_.size());
forAll(procData, proci)
{
// Convert storage to pointers
PtrList<SubList<char>> slaveData;
if (ptr->slaveData_.size())
{
slaveData.resize(ptr->slaveData_.size());
forAll(slaveData, proci)
{
if (ptr->slaveData_.set(proci))
{
slaveData.set
(
proci,
new SubList<char>
(
ptr->slaveData_[proci],
ptr->sizes_[proci]
)
);
}
}
}
bool ok = writeFile
procData[proci] = stdFoam::span<char>
(
ptr->comm_,
ptr->objectType_,
ptr->pathName_,
ptr->data_,
ptr->sizes_,
slaveData,
ptr->streamOpt_,
ptr->atomic_,
ptr->append_,
ptr->headerEntries_
const_cast<char*>(obj.procData_[proci].cdata()),
obj.procData_[proci].size()
);
if (!ok)
{
FatalIOErrorInFunction(ptr->pathName_)
<< "Failed writing " << ptr->pathName_
<< exit(FatalIOError);
}
}
delete ptr;
bool ok = writeFile
(
obj.comm_,
obj.objectType_,
obj.pathName_,
obj.localData_,
obj.sizes_,
procData,
obj.streamOpt_,
obj.atomic_,
obj.append_,
obj.headerEntries_
);
if (!ok)
{
FatalIOErrorInFunction(obj.pathName_)
<< "Failed writing " << obj.pathName_
<< exit(FatalIOError);
}
//sleep(1);
}
@ -248,14 +231,14 @@ void Foam::OFstreamCollator::waitForBufferSpace(const off_t wantedSize) const
{
while (true)
{
// Count files to be written
// The pending output size(s)
off_t totalSize = 0;
{
std::lock_guard<std::mutex> guard(mutex_);
forAllConstIters(objects_, iter)
for (const writeData* ptr : objects_)
{
totalSize += iter()->size();
if (ptr) totalSize += ptr->size();
}
}
@ -287,17 +270,7 @@ void Foam::OFstreamCollator::waitForBufferSpace(const off_t wantedSize) const
Foam::OFstreamCollator::OFstreamCollator(const off_t maxBufferSize)
:
maxBufferSize_(maxBufferSize),
threadRunning_(false),
localComm_(UPstream::worldComm),
threadComm_
(
UPstream::allocateCommunicator
(
localComm_,
labelRange(UPstream::nProcs(localComm_))
)
)
OFstreamCollator(maxBufferSize, UPstream::worldComm)
{}
@ -312,6 +285,7 @@ Foam::OFstreamCollator::OFstreamCollator
localComm_(comm),
threadComm_
(
// dupComm
UPstream::allocateCommunicator
(
localComm_,
@ -345,7 +319,7 @@ bool Foam::OFstreamCollator::write
(
const word& objectType,
const fileName& fName,
const string& data,
DynamicList<char>&& localData,
IOstreamOption streamOpt,
IOstreamOption::atomicType atomic,
IOstreamOption::appendType append,
@ -355,78 +329,109 @@ bool Foam::OFstreamCollator::write
{
// Determine (on master) sizes to receive. Note: do NOT use thread
// communicator
labelList recvSizes;
decomposedBlockData::gather(localComm_, label(data.size()), recvSizes);
const labelList recvSizes
(
UPstream::listGatherValues<label>(localData.size(), localComm_)
);
off_t totalSize = 0;
label maxLocalSize = 0;
if (UPstream::master(localComm_))
{
if (UPstream::master(localComm_))
for (const label recvSize : recvSizes)
{
for (const label recvSize : recvSizes)
{
totalSize += recvSize;
maxLocalSize = max(maxLocalSize, recvSize);
}
totalSize += recvSize;
maxLocalSize = max(maxLocalSize, recvSize);
}
Pstream::broadcasts(localComm_, totalSize, maxLocalSize);
}
Pstream::broadcasts(localComm_, totalSize, maxLocalSize);
// Determine how things will be gathered and written...
enum class dispatchModes { GATHER_WRITE, PREFETCH_THREADED, FULL_THREADED };
dispatchModes dispatch(dispatchModes::GATHER_WRITE);
if (!useThread || maxBufferSize_ == 0 || maxLocalSize > maxBufferSize_)
{
dispatch = dispatchModes::GATHER_WRITE;
}
else if (totalSize <= maxBufferSize_)
{
// Total size can be stored locally
// - gather all data now and only do the writing in the thread
dispatch = dispatchModes::PREFETCH_THREADED;
}
else
{
// Gather data and write in the thread
dispatch = dispatchModes::FULL_THREADED;
if (!UPstream::haveThreads())
{
WarningInFunction
<< "MPI not initialized with thread support." << nl
<< " maxThreadFileBufferSize = 0 to disable threading" << nl
<< " or maxThreadFileBufferSize > " << totalSize
<< " to collate before threaded writing." << nl << nl;
dispatch = dispatchModes::GATHER_WRITE;
}
}
// -----------
// Dispatching
// -----------
if (dispatch == dispatchModes::GATHER_WRITE)
{
if (debug)
{
Pout<< "OFstreamCollator : non-thread gather and write of " << fName
<< " using local comm " << localComm_ << endl;
Pout<< "OFstreamCollator : non-thread gather/write "
<< "(local comm: " << localComm_ << ") of "
<< fName << endl;
}
// Direct collating and writing (so master blocks until all written!)
const PtrList<SubList<char>> dummySlaveData;
return writeFile
(
localComm_,
objectType,
fName,
data,
localData,
recvSizes,
dummySlaveData,
UList<stdFoam::span<char>>(), // dummy proc data
streamOpt,
atomic,
append,
headerEntries
);
}
else if (totalSize <= maxBufferSize_)
else if (dispatch == dispatchModes::PREFETCH_THREADED)
{
// Total size can be stored locally so receive all data now and only
// do the writing in the thread
if (debug)
{
Pout<< "OFstreamCollator : non-thread gather; thread write of "
<< fName << endl;
}
if (Pstream::master(localComm_))
if (UPstream::master(localComm_))
{
waitForBufferSpace(totalSize);
}
// Receive in chunks of labelMax (2^31-1) since this is the maximum
// size that a List can be
autoPtr<writeData> fileAndDataPtr
std::unique_ptr<writeData> fileAndDataPtr
(
new writeData
(
threadComm_, // Note: comm not actually used anymore
objectType,
fName,
(
Pstream::master(localComm_)
? data // Only used on master
: string::null
),
recvSizes,
streamOpt,
atomic,
@ -434,63 +439,81 @@ bool Foam::OFstreamCollator::write
headerEntries
)
);
writeData& fileAndData = fileAndDataPtr();
auto& fileAndData = *fileAndDataPtr;
PtrList<List<char>>& slaveData = fileAndData.slaveData_;
List<List<char>>& procData = fileAndData.procData_;
if (UPstream::master(localComm_))
{
// Move in local data (master only!)
fileAndData.transfer(localData);
UList<char> slice(const_cast<char*>(data.data()), label(data.size()));
// Storage for receive data
procData.resize(UPstream::nProcs(localComm_));
for (const int proci : UPstream::subProcs(localComm_))
{
procData[proci].resize(recvSizes[proci]);
}
}
else if (UPstream::is_subrank(localComm_))
{
// Requires a size for decomposedBlockData::writeBlocks() logic
procData.resize(UPstream::nProcs(localComm_));
}
slaveData.setSize(recvSizes.size());
// Gather all data onto master. Is done in local communicator since
// not in write thread. Note that we do not store in contiguous
// buffer since that would limit to 2G chars.
// not in write thread.
const label startOfRequests = UPstream::nRequests();
if (Pstream::master(localComm_))
if (UPstream::master(localComm_))
{
for (label proci = 1; proci < slaveData.size(); proci++)
for (const int proci : UPstream::subProcs(localComm_))
{
slaveData.set(proci, new List<char>(recvSizes[proci]));
List<char>& procSlice = procData[proci];
if (procSlice.empty()) continue;
UIPstream::read
(
UPstream::commsTypes::nonBlocking,
proci,
slaveData[proci].data(),
slaveData[proci].size_bytes(),
Pstream::msgType(),
procSlice.data_bytes(),
procSlice.size_bytes(),
UPstream::msgType(),
localComm_
);
}
}
else
else if (UPstream::is_subrank(localComm_) && !localData.empty())
{
if
(
!UOPstream::write
(
UPstream::commsTypes::nonBlocking,
0,
slice.cdata(),
slice.size_bytes(),
Pstream::msgType(),
UPstream::masterNo(),
localData.cdata_bytes(),
localData.size_bytes(),
UPstream::msgType(),
localComm_
)
)
{
FatalErrorInFunction
<< "Cannot send outgoing message. "
<< "to:" << 0 << " nBytes:"
<< label(slice.size_bytes())
<< "Cannot send outgoing message (size: "
<< localData.size() << ") to master" << nl
<< Foam::abort(FatalError);
}
}
UPstream::waitRequests(startOfRequests);
// The localData has been moved (master) or communicated
localData.clearStorage();
{
std::lock_guard<std::mutex> guard(mutex_);
// Append to thread buffer
objects_.push(fileAndDataPtr.ptr());
// Append to thread buffer (as FIFO), take ownership
objects_.push_back(fileAndDataPtr.release());
// Start thread if not running
if (!threadRunning_)
@ -517,49 +540,46 @@ bool Foam::OFstreamCollator::write
return true;
}
else
else if (dispatch == dispatchModes::FULL_THREADED)
{
if (debug)
{
Pout<< "OFstreamCollator : thread gather and write of " << fName
<< " using communicator " << threadComm_ << endl;
Pout<< "OFstreamCollator : thread gather and write "
<< "(thread comm: " << threadComm_
<< ") of " << fName << endl;
}
if (!UPstream::haveThreads())
if (UPstream::master(localComm_))
{
FatalErrorInFunction
<< "mpi does not seem to have thread support."
<< " Make sure to set buffer size 'maxThreadFileBufferSize'"
<< " to at least " << totalSize
<< " to be able to do the collating before threading."
<< exit(FatalError);
waitForBufferSpace(localData.size());
}
if (Pstream::master(localComm_))
{
waitForBufferSpace(data.size());
}
std::unique_ptr<writeData> fileAndDataPtr
(
new writeData
(
threadComm_,
objectType,
fName,
recvSizes,
streamOpt,
atomic,
append,
headerEntries
)
);
// Move in local data (all procs)
fileAndDataPtr->transfer(localData);
{
std::lock_guard<std::mutex> guard(mutex_);
// Push all file info on buffer. Note that no slave data provided
// Append to thread buffer (as FIFO), take ownership
objects_.push_back(fileAndDataPtr.release());
// Note: no proc data provided
// so it will trigger communication inside the thread
objects_.push
(
new writeData
(
threadComm_,
objectType,
fName,
data,
recvSizes,
streamOpt,
atomic,
append,
headerEntries
)
);
if (!threadRunning_)
{
@ -584,6 +604,12 @@ bool Foam::OFstreamCollator::write
return true;
}
FatalErrorInFunction
<< "Unknown dispatch mode: " << int(dispatch)
<< " - programming error?" << abort(FatalError);
return false;
}
@ -591,7 +617,7 @@ void Foam::OFstreamCollator::waitAll()
{
// Wait for all buffer space to be available i.e. wait for all jobs
// to finish
if (Pstream::master(localComm_))
if (UPstream::master(localComm_))
{
if (debug)
{

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2018 OpenFOAM Foundation
Copyright (C) 2021-2022 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -51,14 +51,14 @@ SourceFiles
#ifndef Foam_OFstreamCollator_H
#define Foam_OFstreamCollator_H
#include <thread>
#include <mutex>
#include "IOstream.H"
#include "labelList.H"
#include "FIFOStack.H"
#include "SubList.H"
#include "List.H"
#include "CircularBuffer.H" // As FIFO
#include "dictionary.H"
#include <mutex>
#include <thread>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -72,26 +72,33 @@ class OFstreamCollator
{
// Private Class
//- Holds data to be written
struct writeData
{
const label comm_;
const word objectType_;
const fileName pathName_;
const string data_;
DynamicList<char> localData_;
const labelList sizes_;
PtrList<List<char>> slaveData_;
List<List<char>> procData_;
const IOstreamOption streamOpt_;
IOstreamOption::atomicType atomic_;
IOstreamOption::appendType append_;
const dictionary headerEntries_;
writeData() = delete; // No default construct
writeData(const writeData&) = delete; // No copy construct
writeData(writeData&&) = delete; // No move construct
void operator=(const writeData&) = delete; // No copy assign
void operator=(writeData&&) = delete; // No move assign
//- Construct without local data
writeData
(
const label comm,
const word& objectType,
const fileName& pathName,
const string& data,
const labelList& sizes,
const labelUList& sizes,
IOstreamOption streamOpt,
IOstreamOption::atomicType atomic,
IOstreamOption::appendType append,
@ -101,27 +108,30 @@ class OFstreamCollator
comm_(comm),
objectType_(objectType),
pathName_(pathName),
data_(data),
localData_(),
sizes_(sizes),
slaveData_(),
procData_(),
streamOpt_(streamOpt),
atomic_(atomic),
append_(append),
headerEntries_(headerEntries)
{}
//- The (approximate) size of master + any optional slave data
//- Move reset local data
void transfer(DynamicList<char>& localData)
{
localData_.transfer(localData);
}
//- The (approximate) size of local + any optional proc data
off_t size() const
{
off_t totalSize = data_.size();
forAll(slaveData_, i)
off_t total = localData_.size();
for (const auto& data : procData_)
{
if (slaveData_.set(i))
{
totalSize += slaveData_[i].size();
}
total += data.size();
}
return totalSize;
return total;
}
};
@ -135,8 +145,8 @@ class OFstreamCollator
std::unique_ptr<std::thread> thread_;
//- Stack of files to write + contents
FIFOStack<writeData*> objects_;
//- FIFO of files to write and their contents
CircularBuffer<writeData*> objects_;
//- Whether thread is running (and not exited)
bool threadRunning_;
@ -156,9 +166,9 @@ class OFstreamCollator
const label comm,
const word& objectType,
const fileName& fName,
const string& masterData,
const UList<char>& localData,
const labelUList& recvSizes,
const UPtrList<SubList<char>>& slaveData,
const UList<stdFoam::span<char>>& procData,
IOstreamOption streamOpt,
IOstreamOption::atomicType atomic,
IOstreamOption::appendType append,
@ -181,7 +191,8 @@ public:
// Constructors
//- Construct from buffer size. 0 = do not use thread
//- Construct from buffer size (0 = do not use thread)
//- and with worldComm
explicit OFstreamCollator(const off_t maxBufferSize);
//- Construct from buffer size (0 = do not use thread)
@ -195,14 +206,15 @@ public:
// Member Functions
//- Write file with contents.
// Blocks until writethread has space available
//- Write file with contents, possibly taking ownership of the
//- content.
// Blocks until write-thread has space available
// (total file sizes < maxBufferSize)
bool write
(
const word& objectType,
const fileName&,
const string& data,
const fileName& fName,
DynamicList<char>&& localData,
IOstreamOption streamOpt,
IOstreamOption::atomicType atomic,
IOstreamOption::appendType append,
@ -210,6 +222,37 @@ public:
const dictionary& headerEntries = dictionary::null
);
//- Write file with contents.
FOAM_DEPRECATED_FOR(2023-09, "use write with movable content")
bool write
(
const word& objectType,
const fileName& fName,
const std::string& s,
IOstreamOption streamOpt,
IOstreamOption::atomicType atomic,
IOstreamOption::appendType append,
const bool useThread = true,
const dictionary& headerEntries = dictionary::null
)
{
DynamicList<char> charData;
charData.setCapacity(s.size());
std::copy(s.begin(), s.end(), charData.begin());
return write
(
objectType,
fName,
std::move(charData),
streamOpt,
atomic,
append,
useThread,
headerEntries
);
}
//- Wait for all thread actions to have finished
void waitAll();
};

View File

@ -116,7 +116,7 @@ void Foam::fileOperations::collatedFileOperation::printBanner
{
DetailInfo
<< " With non-blocking transfer,"
" buffer-size = " << maxMasterFileBufferSize << nl;
" buffer-size = " << maxMasterFileBufferSize << nl;
}
else
{

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2018 OpenFOAM Foundation
Copyright (C) 2020-2022 OpenCFD Ltd.
Copyright (C) 2020-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -41,7 +41,7 @@ Foam::threadedCollatedOFstream::threadedCollatedOFstream
const bool useThread
)
:
OStringStream(streamOpt),
OCharStream(streamOpt),
writer_(writer),
pathName_(pathName),
atomic_(atomic),
@ -74,11 +74,22 @@ Foam::threadedCollatedOFstream::threadedCollatedOFstream
Foam::threadedCollatedOFstream::~threadedCollatedOFstream()
{
commit();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::threadedCollatedOFstream::commit()
{
// Take ownership of serialized content, without copying or reallocation
DynamicList<char> charData(OCharStream::release());
writer_.write
(
decomposedBlockData::typeName,
pathName_,
str(),
std::move(charData),
IOstreamOption(IOstreamOption::BINARY, version(), compression_),
atomic_,
IOstreamOption::NON_APPEND,

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2018 OpenFOAM Foundation
Copyright (C) 2021-2022 OpenCFD Ltd.
Copyright (C) 2021-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -39,7 +39,7 @@ SourceFiles
#define Foam_threadedCollatedOFstream_H
#include "dictionary.H"
#include "StringStream.H"
#include "SpanStream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -55,7 +55,7 @@ class OFstreamCollator;
class threadedCollatedOFstream
:
public OStringStream
public OCharStream
{
// Private Data
@ -78,6 +78,11 @@ class threadedCollatedOFstream
dictionary headerEntries_;
// Private Member Functions
//- Commit buffered information
void commit();
public:
// Constructors
@ -102,12 +107,14 @@ public:
);
//- Destructor
//- Destructor - commits buffered information to file
~threadedCollatedOFstream();
// Member Functions
// -> using OCharStream::rewind
//- Define the header entries for the data block(s)
void setHeaderEntries(const dictionary& dict);
};

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2018 OpenFOAM Foundation
Copyright (C) 2019-2024 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -875,11 +875,11 @@ bool Foam::fileOperations::masterUncollatedFileOperation::mkDir
mode_t mode
) const
{
return masterOp<bool>
return masterOp<mode_t>
(
dir,
mkDirOp(mode),
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -891,11 +891,11 @@ bool Foam::fileOperations::masterUncollatedFileOperation::chMod
mode_t mode
) const
{
return masterOp<bool>
return masterOp<mode_t>
(
fName,
chModOp(mode),
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -911,7 +911,7 @@ mode_t Foam::fileOperations::masterUncollatedFileOperation::mode
(
fName,
modeOp(followLink),
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -925,11 +925,11 @@ Foam::fileName::Type Foam::fileOperations::masterUncollatedFileOperation::type
{
return fileName::Type
(
masterOp<int>
masterOp<label>
(
fName,
typeOp(followLink),
UPstream::msgType(),
Pstream::msgType(),
comm_
)
);
@ -947,7 +947,7 @@ bool Foam::fileOperations::masterUncollatedFileOperation::exists
(
fName,
existsOp(checkGzip, followLink),
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -963,7 +963,7 @@ bool Foam::fileOperations::masterUncollatedFileOperation::isDir
(
fName,
isDirOp(followLink),
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -980,7 +980,7 @@ bool Foam::fileOperations::masterUncollatedFileOperation::isFile
(
fName,
isFileOp(checkGzip, followLink),
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -996,7 +996,7 @@ off_t Foam::fileOperations::masterUncollatedFileOperation::fileSize
(
fName,
fileSizeOp(followLink),
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -1012,7 +1012,7 @@ time_t Foam::fileOperations::masterUncollatedFileOperation::lastModified
(
fName,
lastModifiedOp(followLink),
UPstream::msgType(),
Pstream::msgType(),
UPstream::worldComm
);
}
@ -1028,7 +1028,7 @@ double Foam::fileOperations::masterUncollatedFileOperation::highResLastModified
(
fName,
highResLastModifiedOp(followLink),
UPstream::msgType(),
Pstream::msgType(),
UPstream::worldComm
);
}
@ -1044,7 +1044,7 @@ bool Foam::fileOperations::masterUncollatedFileOperation::mvBak
(
fName,
mvBakOp(ext),
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -1059,7 +1059,7 @@ bool Foam::fileOperations::masterUncollatedFileOperation::rm
(
fName,
rmOp(),
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -1076,7 +1076,7 @@ bool Foam::fileOperations::masterUncollatedFileOperation::rmDir
(
dir,
rmDirOp(silent, emptyOnly),
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -1094,7 +1094,7 @@ Foam::fileNameList Foam::fileOperations::masterUncollatedFileOperation::readDir
(
dir,
readDirOp(type, filtergz, followLink),
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -1112,7 +1112,7 @@ bool Foam::fileOperations::masterUncollatedFileOperation::cp
src,
dst,
cpOp(followLink),
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -1129,7 +1129,7 @@ bool Foam::fileOperations::masterUncollatedFileOperation::ln
src,
dst,
lnOp(),
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -1147,7 +1147,7 @@ bool Foam::fileOperations::masterUncollatedFileOperation::mv
src,
dst,
mvOp(followLink),
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -1293,7 +1293,7 @@ Foam::fileName Foam::fileOperations::masterUncollatedFileOperation::filePath
(
io.objectPath(),
fileOrNullOp(true), // isFile=true
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}
@ -1451,7 +1451,7 @@ Foam::fileName Foam::fileOperations::masterUncollatedFileOperation::dirPath
(
io.objectPath(),
fileOrNullOp(false), // isFile=false
UPstream::msgType(),
Pstream::msgType(),
comm_
);
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenFOAM Foundation
Copyright (C) 2019-2024 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -162,8 +162,8 @@ protected:
followLink_(followLink)
{}
// Returns int (for reductions) instead of fileName::Type
int operator()(const fileName& f) const
// Returns label not fileName::Type for reductions
label operator()(const fileName& f) const
{
return Foam::type(f, followLink_);
}
@ -390,6 +390,9 @@ protected:
// Private Member Functions
template<class Type>
Type scatterList(const UList<Type>&, const int, const label comm) const;
template<class Type, class FileOp>
Type masterOp
(

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2018 OpenFOAM Foundation
Copyright (C) 2020-2024 OpenCFD Ltd.
Copyright (C) 2020-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,6 +31,41 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Type Foam::fileOperations::masterUncollatedFileOperation::scatterList
(
const UList<Type>& allValues,
const int tag,
const label comm
) const
{
// TBD: more efficient scatter
PstreamBuffers pBufs(UPstream::commsTypes::nonBlocking, tag, comm);
if (Pstream::master(comm))
{
for (const int proci : Pstream::subProcs(comm))
{
UOPstream os(proci, pBufs);
os << allValues[proci];
}
}
pBufs.finishedScatters();
Type value;
if (Pstream::master(comm))
{
value = allValues[0];
}
else
{
UIPstream is(Pstream::masterNo(), pBufs);
is >> value;
}
return value;
}
template<class Type, class FileOp>
Type Foam::fileOperations::masterUncollatedFileOperation::masterOp
(
@ -46,24 +81,17 @@ Type Foam::fileOperations::masterUncollatedFileOperation::masterOp
<< typeid(FileOp).name()
<< " on " << fName << endl;
}
if (UPstream::is_parallel(comm))
if (Pstream::parRun())
{
const label myProci = UPstream::myProcNo(comm);
const label numProc = UPstream::nProcs(comm);
List<fileName> filePaths(numProc);
filePaths[myProci] = fName;
List<fileName> filePaths(Pstream::nProcs(comm));
filePaths[Pstream::myProcNo(comm)] = fName;
Pstream::gatherList(filePaths, tag, comm);
// OR filePaths = Pstream::listGatherValues(fName, comm, tag)
List<Type> result;
if (UPstream::master(comm))
List<Type> result(filePaths.size());
if (Pstream::master(comm))
{
result.resize(numProc);
result = fop(filePaths[0]);
for (label i = 1; i < numProc; ++i)
for (label i = 1; i < filePaths.size(); i++)
{
if (filePaths[i] != filePaths[0])
{
@ -72,10 +100,12 @@ Type Foam::fileOperations::masterUncollatedFileOperation::masterOp
}
}
return Pstream::listScatterValues(result, comm, tag);
return scatterList(result, tag, comm);
}
else
{
return fop(fName);
}
return fop(fName);
}
@ -94,41 +124,35 @@ Type Foam::fileOperations::masterUncollatedFileOperation::masterOp
Pout<< "masterUncollatedFileOperation : Operation on src:" << src
<< " dest:" << dest << endl;
}
if (UPstream::is_parallel(comm))
if (Pstream::parRun())
{
const label myProci = UPstream::myProcNo(comm);
const label numProc = UPstream::nProcs(comm);
List<fileName> srcs(Pstream::nProcs(comm));
srcs[Pstream::myProcNo(comm)] = src;
Pstream::gatherList(srcs, tag, comm);
List<Pair<fileName>> filePaths(numProc);
filePaths[myProci].first() = src;
filePaths[myProci].second() = dest;
Pstream::gatherList(filePaths, tag, comm);
// OR
// Pair<fileName> tup(src, dest);
// filePaths = Pstream::listGatherValues(tup, comm, tag)
List<fileName> dests(srcs.size());
dests[Pstream::myProcNo(comm)] = dest;
Pstream::gatherList(dests, tag, comm);
List<Type> result;
if (UPstream::master(comm))
List<Type> result(Pstream::nProcs(comm));
if (Pstream::master(comm))
{
result.resize(numProc);
result = fop(filePaths[0].first(), filePaths[0].second());
for (label i = 1; i < numProc; ++i)
result = fop(srcs[0], dests[0]);
for (label i = 1; i < srcs.size(); i++)
{
// TBD: also check second() ?
if (filePaths[i].first() != filePaths[0].first())
if (srcs[i] != srcs[0])
{
result[i] =
fop(filePaths[i].first(), filePaths[i].second());
result[i] = fop(srcs[i], dests[i]);
}
}
}
return Pstream::listScatterValues(result, comm, tag);
return scatterList(result, tag, comm);
}
else
{
return fop(src, dest);
}
return fop(src, dest);
}

View File

@ -114,12 +114,8 @@ public:
// Static Member Functions
//- Return a null Matrix (reference to a nullObject).
//- Behaves like a empty Matrix.
static const Matrix<Form, Type>& null() noexcept
{
return NullObjectRef<Matrix<Form, Type>>();
}
//- Return a null Matrix
inline static const Matrix<Form, Type>& null();
// Iterators

View File

@ -85,6 +85,13 @@ Foam::Matrix<Form, Type>::clone() const
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Form, class Type>
inline const Foam::Matrix<Form, Type>& Foam::Matrix<Form, Type>::null()
{
return NullObjectRef<Matrix<Form, Type>>();
}
template<class Form, class Type>
inline Foam::label Foam::Matrix<Form, Type>::size() const
{

View File

@ -102,7 +102,7 @@ public:
) const
{
NotImplemented;
return nullptr;
return autoPtr<GAMGInterfaceField>(nullptr);
}

View File

@ -42,7 +42,8 @@ namespace Foam
const Foam::objectRegistry& Foam::lduMesh::thisDb() const
{
NotImplemented;
return NullObjectRef<objectRegistry>();
const objectRegistry* orPtr_ = nullptr;
return *orPtr_;
}

View File

@ -395,7 +395,7 @@ public:
// Face splitting utilities
//- Number of triangles after splitting
inline label nTriangles() const noexcept;
inline label nTriangles() const;
//- Number of triangles after splitting
label nTriangles(const UList<point>& unused) const;

View File

@ -199,9 +199,9 @@ inline Foam::label Foam::face::prevLabel(const label i) const
}
inline Foam::label Foam::face::nTriangles() const noexcept
inline Foam::label Foam::face::nTriangles() const
{
return labelList::size() - 2;
return size() - 2;
}

View File

@ -93,7 +93,7 @@ public:
//- Construct from an initializer list of three vertex labels
inline explicit triFace(std::initializer_list<label> list);
//- Copy construct from a list of three vertex labels.
//- Copy construct from a list of three vertex labels.
inline explicit triFace(const labelUList& list);
//- Copy construct from a subset of vertex labels

View File

@ -123,13 +123,13 @@ bool Foam::polyMesh::checkFaceOrthogonality
reduce(severeNonOrth, sumOp<label>());
reduce(errorNonOrth, sumOp<label>());
const scalar maxNonOrth = radToDeg(::acos(clamp(minDDotS, -1, 1)));
const scalar aveNonOrth = radToDeg(::acos(clamp(sumDDotS/nSummed, -1, 1)));
dictionary& meshDict = const_cast<dictionary&>(data().meshDict());
if (nSummed > 0)
{
scalar maxNonOrth = radToDeg(::acos(clamp(minDDotS, -1, 1)));
scalar aveNonOrth = radToDeg(::acos(clamp(sumDDotS/nSummed, -1, 1)));
meshDict.set("maxNonOrth", maxNonOrth);
meshDict.set("aveNonOrth", aveNonOrth);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2024 OpenCFD Ltd.
Copyright (C) 2018-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -110,15 +110,6 @@ public:
const FixedList<label, 3>& indices
);
//- Copy construct from subset of points
inline triPoints
(
const UList<point>& points,
const label p0,
const label p1,
const label p2
);
// Member Functions
@ -284,7 +275,7 @@ public:
//- Construct from three points
inline triangle(const FixedList<Point, 3>& pts);
//- Construct from three points out of the list of points
//- Construct from three points in the list of points
// The indices could be from triFace etc.
inline triangle
(
@ -292,15 +283,6 @@ public:
const FixedList<label, 3>& indices
);
//- Construct from three points out of the list of points
inline triangle
(
const UList<Point>& points,
const label p0,
const label p1,
const label p2
);
//- Construct from Istream
inline explicit triangle(Istream& is);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2024 OpenCFD Ltd.
Copyright (C) 2018-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -69,20 +69,6 @@ inline Foam::triPoints::triPoints
{}
inline Foam::triPoints::triPoints
(
const UList<point>& points,
const label p0,
const label p1,
const label p2
)
{
a() = points[p0];
b() = points[p1];
c() = points[p2];
}
template<class Point, class PointRef>
inline Foam::triangle<Point, PointRef>::triangle
(
@ -122,21 +108,6 @@ inline Foam::triangle<Point, PointRef>::triangle
{}
template<class Point, class PointRef>
inline Foam::triangle<Point, PointRef>::triangle
(
const UList<Point>& points,
const label p0,
const label p1,
const label p2
)
:
a_(points[p0]),
b_(points[p1]),
c_(points[p2])
{}
template<class Point, class PointRef>
inline Foam::triangle<Point, PointRef>::triangle(Istream& is)
{

View File

@ -290,7 +290,7 @@ Foam::globalIndex::bin
if (!globalIds.empty())
{
labelList& binOffsets = bins.offsets();
binOffsets.resize(offsets.size(), Foam::zero{});
binOffsets.resize(offsets.size(), Zero);
labelList& binValues = bins.values();
binValues = UIndirectList<label>(globalIds, order);
@ -372,7 +372,7 @@ void Foam::globalIndex::reset
// TBD: check for (proci >= 0) ?
const auto proci = UPstream::myProcNo(comm);
counts.resize(len, Foam::zero{});
counts.resize(len, Zero);
counts[proci] = localSize;
}

View File

@ -83,14 +83,6 @@ class globalIndex
DynamicList<label>& validBins
);
// Cannot use non-blocking for non-contiguous data.
// template<class Type>
// inline static UPstream::commsTypes getCommsType
// (
// const UPstream::commsTypes preferred
// = UPstream::commsTypes::nonBlocking
// );
//- Report overflow at specified (non-negative) index
static void reportOverflowAndExit
(
@ -195,7 +187,7 @@ public:
inline label length() const noexcept;
//- Global sum of localSizes. Same as totalSize()
FOAM_DEPRECATED_STRICT(2022-10, "totalSize() - unambiguous")
FOAM_DEPRECATED_STRICT(2022-10, "totalSize() - less ambiguous")
inline label size() const;
//- The span size covered by the offsets, zero if empty
@ -730,11 +722,10 @@ public:
//- Inplace collect data in processor order on master
//- (in serial: a no-op).
// Communication with default/specified communicator, message tag.
// After the gather, the field is zero-sized on non-master.
// After the gather, the field is zero-sized on the slaves.
template<class Type>
void gatherInplace
(
//! [in,out]
List<Type>& fld,
const int tag = UPstream::msgType(),
const UPstream::commsTypes = UPstream::commsTypes::nonBlocking,
@ -746,11 +737,12 @@ public:
// Communication with default/specified communicator.
// \attention The nProcs for globalIndex and communicator
// must match!!
//
// The allData is output (master), zero-sized on non-master
template<class Type, class OutputContainer = List<Type>>
void mpiGather
(
const UList<Type>& sendData,
//! [out] output on master, zero-sized on non-master
OutputContainer& allData,
const label comm = UPstream::worldComm, //!< communicator
@ -788,7 +780,6 @@ public:
template<class Type>
void mpiGatherInplace
(
//! [in,out]
List<Type>& fld,
const label comm = UPstream::worldComm, //!< communicator
@ -842,7 +833,6 @@ public:
template<class Type>
static void mpiGatherInplaceOp
(
//! [in,out]
List<Type>& fld,
const label comm = UPstream::worldComm, //!< communicator
@ -854,11 +844,12 @@ public:
//- Collect data in processor order on master
//- (in serial: performs a simple copy).
// Communication with default/specified communicator, message tag.
//
// The allFld is output (master), zero-sized on non-master
template<class Type>
static void gatherOp
(
const UList<Type>& sendData,
//! [out] output on master, zero-sized on non-master
List<Type>& allData,
const int tag = UPstream::msgType(),
const UPstream::commsTypes = UPstream::commsTypes::nonBlocking,
@ -868,11 +859,12 @@ public:
//- Collect data in processor order on master
//- (in serial: performs a simple copy).
// Communication with default/specified communicator, message tag.
//
// The allFld is output (master), zero-sized on non-master
template<class Type, class Addr>
static void gatherOp
(
const IndirectListBase<Type, Addr>& sendData,
//! [out] output on master, zero-sized on non-master
List<Type>& allData,
const int tag = UPstream::msgType(),
const UPstream::commsTypes = UPstream::commsTypes::nonBlocking,
@ -911,11 +903,10 @@ public:
//- (in serial: a no-op).
// Communication with default/specified communicator, message tag.
//
// After the gather, the field is zero-sized on non-master.
// After the gather, the field is zero-sized on the slaves.
template<class Type>
static void gatherInplaceOp
(
//! [in,out]
List<Type>& fld,
const int tag = UPstream::msgType(),
const UPstream::commsTypes = UPstream::commsTypes::nonBlocking,

View File

@ -30,25 +30,6 @@ License
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
// Cannot use non-blocking for non-contiguous data.
// template<class Type>
// inline Foam::UPstream::commsTypes getCommsType
// (
// const UPstream::commsTypes preferred
// )
// {
// return
// (
// (
// !is_contiguous<Type>::value
// && UPstream::commsTypes::nonBlocking == preferred
// )
// ? UPstream::commsTypes::scheduled
// : preferred
// );
// }
template<class Addr>
Foam::labelList
Foam::globalIndex::calcOffsets
@ -134,7 +115,8 @@ void Foam::globalIndex::gatherValues
{
// low-level: no parRun guard
// Cannot use non-blocking for non-contiguous data.
// Automatically change from nonBlocking to scheduled for
// non-contiguous data.
const UPstream::commsTypes commsType =
(
(
@ -220,7 +202,8 @@ void Foam::globalIndex::gather
{
// low-level: no parRun guard
// Cannot use non-blocking for non-contiguous data.
// Automatically change from nonBlocking to scheduled for
// non-contiguous data.
const UPstream::commsTypes commsType =
(
(
@ -339,7 +322,8 @@ void Foam::globalIndex::gather
return;
}
// Cannot use non-blocking for non-contiguous data.
// Automatically change from nonBlocking to scheduled for
// non-contiguous data.
const UPstream::commsTypes commsType =
(
(
@ -923,7 +907,8 @@ void Foam::globalIndex::scatter
{
// low-level: no parRun guard
// Cannot use non-blocking for non-contiguous data.
// Automatically change from nonBlocking to scheduled for
// non-contiguous data.
const UPstream::commsTypes commsType =
(
(

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2014 OpenFOAM Foundation
Copyright (C) 2017-2024 OpenCFD Ltd.
Copyright (C) 2017-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -158,7 +158,7 @@ extern const NullObject* nullObjectPtr;
// IOstream Operators
//- Read from Istream consumes no content, does not change NullObject
//- Read from Istream consumes no content
inline Istream& operator>>(Istream& is, const NullObject&) noexcept
{
return is;
@ -173,48 +173,31 @@ inline Ostream& operator<<(Ostream& os, const NullObject&) noexcept
// Global Functions
//- Const pointer (of type T) to the nullObject
//- Pointer (of type T) to the nullObject
template<class T>
inline const T* NullObjectPtr() noexcept
inline const T* NullObjectPtr()
{
return reinterpret_cast<const T*>(nullObjectPtr);
}
//- Non-const pointer (of type T) to the nullObject.
//- Only use when nothing will be written into it!
//- Reference (of type T) to the nullObject
template<class T>
inline T* NullObjectPtr_constCast() noexcept
{
return reinterpret_cast<T*>(const_cast<NullObject*>(nullObjectPtr));
}
//- Const reference (of type T) to the nullObject
template<class T>
inline const T& NullObjectRef() noexcept
inline const T& NullObjectRef()
{
return *reinterpret_cast<const T*>(nullObjectPtr);
}
//- Non-const reference (of type T) to the nullObject
//- Only use when nothing will be written into it!
template<class T>
inline T& NullObjectRef_constCast() noexcept
{
return *reinterpret_cast<T*>(const_cast<NullObject*>(nullObjectPtr));
}
//- True if ptr is a pointer (of type T) to the nullObject
template<class T>
inline bool isNull(const T* ptr) noexcept
inline bool isNull(const T* ptr)
{
return ptr == NullObjectPtr<T>();
}
//- True if obj is a reference (of type T) to the nullObject
template<class T>
inline bool isNull(const T& obj) noexcept
inline bool isNull(const T& obj)
{
return &obj == NullObjectPtr<T>();
}
@ -222,14 +205,14 @@ inline bool isNull(const T& obj) noexcept
//- True if ptr is not a pointer (of type T) to the nullObject
template<class T>
inline bool notNull(const T* ptr) noexcept
inline bool notNull(const T* ptr)
{
return ptr != NullObjectPtr<T>();
}
//- True if obj is not a reference (of type T) to the nullObject
template<class T>
inline bool notNull(const T& obj) noexcept
inline bool notNull(const T& obj)
{
return &obj != NullObjectPtr<T>();
}

View File

@ -86,12 +86,8 @@ public:
// Static Data / Methods
//- Return a null wordRes (reference to a nullObject).
//- Behaves like a empty wordRes.
static const wordRes& null() noexcept
{
return NullObjectRef<wordRes>();
}
//- Return a null wordRes - a reference to the NullObject
inline static const wordRes& null();
//- Return a wordRes with duplicate entries filtered out.
// No distinction made between literals and regular expressions.

View File

@ -27,6 +27,12 @@ License
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
inline const Foam::wordRes& Foam::wordRes::null()
{
return NullObjectRef<wordRes>();
}
inline Foam::label Foam::wordRes::first_match
(
const UList<wordRe>& selectors,

View File

@ -22,7 +22,6 @@ $(polyMeshModifier)/polyMeshModifier.C
$(polyMeshModifier)/polyMeshModifierNew.C
polyTopoChange/polyTopoChanger/polyTopoChanger.C
polyTopoChange/polyTopoChanger/polyTopoChangerChangeMesh.C
polyTopoChange/polyTopoChange/addPatchCellLayer.C
polyTopoChange/polyTopoChange/pointEdgeCollapse/pointEdgeCollapse.C
polyTopoChange/polyTopoChange/edgeCollapser.C
@ -77,10 +76,6 @@ meshCut/refineCell/refineCell.C
meshCut/wallLayerCells/wallLayerCells.C
meshCut/wallLayerCells/wallNormalInfo/wallNormalInfo.C
refinement/refinement/refinement.C
refinement/polyhedralRefinement/polyhedralRefinement.C
refinement/prismatic2DRefinement/prismatic2DRefinement.C
polyTopoChange/attachPolyTopoChanger/attachPolyTopoChanger.C
polyTopoChange/repatchPolyTopoChanger/repatchPolyTopoChanger.C

View File

@ -31,7 +31,7 @@ License
#include "polyMesh.H"
#include "Time.H"
#include "primitiveMesh.H"
#include "batchPolyTopoChange.H"
#include "polyTopoChange.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -365,7 +365,7 @@ bool Foam::attachDetach::changeTopology() const
}
void Foam::attachDetach::setRefinement(batchPolyTopoChange& ref) const
void Foam::attachDetach::setRefinement(polyTopoChange& ref) const
{
// Insert the attach/detach instructions into the topological change

View File

@ -122,10 +122,10 @@ class attachDetach
// Topological changes
//- Attach interface
void attachInterface(batchPolyTopoChange&) const;
void attachInterface(polyTopoChange&) const;
//- Detach interface
void detachInterface(batchPolyTopoChange&) const;
void detachInterface(polyTopoChange&) const;
//- Calculate point match addressing
void calcPointMatchMap() const;
@ -215,7 +215,7 @@ public:
//- Insert the layer addition/removal instructions
// into the topological change
virtual void setRefinement(batchPolyTopoChange&) const;
virtual void setRefinement(polyTopoChange&) const;
//- Modify motion points to comply with the topological change
virtual void modifyMotionPoints(pointField& motionPoints) const;

View File

@ -29,7 +29,7 @@ License
#include "attachDetach.H"
#include "polyMesh.H"
#include "primitiveMesh.H"
#include "batchPolyTopoChange.H"
#include "polyTopoChange.H"
#include "polyTopoChanger.H"
#include "polyRemovePoint.H"
#include "polyRemoveFace.H"
@ -43,7 +43,7 @@ const Foam::scalar Foam::attachDetach::positionDifference_ = 1e-8;
void Foam::attachDetach::attachInterface
(
batchPolyTopoChange& ref
polyTopoChange& ref
) const
{
// Algorithm:
@ -62,7 +62,7 @@ void Foam::attachDetach::attachInterface
if (debug)
{
Pout<< "void attachDetach::attachInterface("
<< "batchPolyTopoChange& ref) const "
<< "polyTopoChange& ref) const "
<< " for object " << name() << " : "
<< "Attaching interface" << endl;
}
@ -266,7 +266,7 @@ void Foam::attachDetach::attachInterface
if (debug)
{
Pout<< "void attachDetach::attachInterface("
<< "batchPolyTopoChange& ref) const "
<< "polyTopoChange& ref) const "
<< " for object " << name() << " : "
<< "Finished attaching interface" << endl;
}

View File

@ -28,7 +28,7 @@ License
#include "attachDetach.H"
#include "polyMesh.H"
#include "primitiveMesh.H"
#include "batchPolyTopoChange.H"
#include "polyTopoChange.H"
#include "polyTopoChanger.H"
#include "polyAddPoint.H"
#include "polyModifyFace.H"
@ -38,7 +38,7 @@ License
void Foam::attachDetach::detachInterface
(
batchPolyTopoChange& ref
polyTopoChange& ref
) const
{
// Algorithm:
@ -66,7 +66,7 @@ void Foam::attachDetach::detachInterface
if (debug)
{
Pout<< "void attachDetach::detachInterface("
<< "batchPolyTopoChange& ref) const "
<< "polyTopoChange& ref) const "
<< " for object " << name() << " : "
<< "Detaching interface" << endl;
}
@ -75,7 +75,7 @@ void Foam::attachDetach::detachInterface
const faceZoneMesh& zoneMesh = mesh.faceZones();
// Check that zone is in increasing order (needed since adding faces
// in same order - otherwise batchPolyTopoChange face ordering will mess up
// in same order - otherwise polyTopoChange face ordering will mess up
// correspondence)
if (debug)
{
@ -467,7 +467,7 @@ void Foam::attachDetach::detachInterface
if (debug)
{
Pout<< "void attachDetach::detachInterface("
<< "batchPolyTopoChange& ref) const "
<< "polyTopoChange& ref) const "
<< " for object " << name() << " : "
<< "Finished detaching interface" << endl;
}

View File

@ -29,7 +29,7 @@ License
#include "layerAdditionRemoval.H"
#include "polyMesh.H"
#include "primitiveMesh.H"
#include "batchPolyTopoChange.H"
#include "polyTopoChange.H"
#include "polyTopoChanger.H"
#include "polyAddPoint.H"
#include "polyAddCell.H"
@ -88,7 +88,7 @@ Foam::tmp<Foam::vectorField> Foam::layerAdditionRemoval::extrusionDir() const
void Foam::layerAdditionRemoval::addCellLayer
(
batchPolyTopoChange& ref
polyTopoChange& ref
) const
{
// Insert the layer addition instructions into the topological change
@ -108,7 +108,7 @@ void Foam::layerAdditionRemoval::addCellLayer
if (debug)
{
Pout<< "void layerAdditionRemoval::addCellLayer("
<< "batchPolyTopoChange& ref) const for object " << name() << " : "
<< "polyTopoChange& ref) const for object " << name() << " : "
<< "Adding cell layer" << endl;
}
@ -682,7 +682,7 @@ void Foam::layerAdditionRemoval::addCellLayer
if (debug)
{
Pout<< "void layerAdditionRemoval::addCellLayer(batchPolyTopoChange&) const "
Pout<< "void layerAdditionRemoval::addCellLayer(polyTopoChange&) const "
<< " for object " << name() << ": "
<< "Finished adding cell layer" << endl;
}

View File

@ -355,7 +355,7 @@ bool Foam::layerAdditionRemoval::changeTopology() const
}
void Foam::layerAdditionRemoval::setRefinement(batchPolyTopoChange& ref) const
void Foam::layerAdditionRemoval::setRefinement(polyTopoChange& ref) const
{
// Insert the layer addition/removal instructions
// into the topological change
@ -367,7 +367,7 @@ void Foam::layerAdditionRemoval::setRefinement(batchPolyTopoChange& ref) const
// Clear addressing. This also resets the addition/removal data
if (debug)
{
Pout<< "layerAdditionRemoval::setRefinement(batchPolyTopoChange&) "
Pout<< "layerAdditionRemoval::setRefinement(polyTopoChange&) "
<< "for object " << name() << " : "
<< "Clearing addressing after layer removal" << endl;
}
@ -383,7 +383,7 @@ void Foam::layerAdditionRemoval::setRefinement(batchPolyTopoChange& ref) const
// Clear addressing. This also resets the addition/removal data
if (debug)
{
Pout<< "layerAdditionRemoval::setRefinement(batchPolyTopoChange&) "
Pout<< "layerAdditionRemoval::setRefinement(polyTopoChange&) "
<< "for object " << name() << " : "
<< "Clearing addressing after layer addition" << endl;
}

View File

@ -119,10 +119,10 @@ class layerAdditionRemoval
tmp<vectorField> extrusionDir() const;
//- Add a layer of cells
void addCellLayer(batchPolyTopoChange&) const;
void addCellLayer(polyTopoChange&) const;
//- Remove a layer of cells
void removeCellLayer(batchPolyTopoChange&) const;
void removeCellLayer(polyTopoChange&) const;
//- Clear addressing
void clearAddressing() const;
@ -179,7 +179,7 @@ public:
//- Insert the layer addition/removal instructions
// into the topological change
virtual void setRefinement(batchPolyTopoChange&) const;
virtual void setRefinement(polyTopoChange&) const;
//- Modify motion points to comply with the topological change
virtual void modifyMotionPoints(pointField& motionPoints) const;

View File

@ -29,7 +29,7 @@ License
#include "layerAdditionRemoval.H"
#include "polyMesh.H"
#include "primitiveMesh.H"
#include "batchPolyTopoChange.H"
#include "polyTopoChange.H"
#include "oppositeFace.H"
#include "polyTopoChanger.H"
#include "polyRemoveCell.H"
@ -83,7 +83,7 @@ bool Foam::layerAdditionRemoval::validCollapse() const
void Foam::layerAdditionRemoval::removeCellLayer
(
batchPolyTopoChange& ref
polyTopoChange& ref
) const
{
// Algorithm for layer removal. Second phase: topological change

View File

@ -33,7 +33,7 @@ Description
#include "perfectInterface.H"
#include "polyTopoChanger.H"
#include "polyMesh.H"
#include "batchPolyTopoChange.H"
#include "polyTopoChange.H"
#include "addToRunTimeSelectionTable.H"
#include "mapPolyMesh.H"
#include "matchPoints.H"
@ -154,7 +154,7 @@ void Foam::perfectInterface::setRefinement
(
const indirectPrimitivePatch& pp0,
const indirectPrimitivePatch& pp1,
batchPolyTopoChange& ref
polyTopoChange& ref
) const
{
const polyMesh& mesh = topoChanger().mesh();
@ -423,11 +423,11 @@ void Foam::perfectInterface::setRefinement
}
void Foam::perfectInterface::setRefinement(batchPolyTopoChange& ref) const
void Foam::perfectInterface::setRefinement(polyTopoChange& ref) const
{
if (debug)
{
Pout<< "bool perfectInterface::setRefinement(batchPolyTopoChange&) const : "
Pout<< "bool perfectInterface::setRefinement(polyTopoChange&) const : "
<< "for object " << name() << " : "
<< "masterPatchID_:" << masterPatchID_
<< " slavePatchID_:" << slavePatchID_

View File

@ -129,7 +129,7 @@ public:
//- Insert the layer addition/removal instructions
// into the topological change
virtual void setRefinement(batchPolyTopoChange&) const;
virtual void setRefinement(polyTopoChange&) const;
//- Insert the layer addition/removal instructions
// into the topological change. Uses only mesh, not any of the
@ -139,7 +139,7 @@ public:
(
const indirectPrimitivePatch& pp0,
const indirectPrimitivePatch& pp1,
batchPolyTopoChange&
polyTopoChange&
) const;
//- Modify motion points to comply with the topological change

View File

@ -65,10 +65,7 @@ void Foam::attachPolyTopoChanger::attach(const bool removeEmptyPatches)
const fileName oldInst = mesh_.facesInstance();
// Execute all polyMeshModifiers
// DISABLED - this functionality is lost
// Bad rewrite by Mattijs Janssens - completely misunderstood the interface
// Needs to use polyTopoChange, and not changer.
// changeMesh(false); // no inflation
changeMesh(false); // no inflation
const pointField p = mesh_.oldPoints();

View File

@ -55,7 +55,7 @@ namespace Foam
// Forward Declarations
class polyTopoChanger;
class batchPolyTopoChange;
class polyTopoChange;
class mapPolyMesh;
class polyMeshModifier;
@ -166,7 +166,7 @@ public:
virtual bool changeTopology() const = 0;
//- Insert the topological change instructions
virtual void setRefinement(batchPolyTopoChange&) const = 0;
virtual void setRefinement(polyTopoChange&) const = 0;
//- Modify motion points to comply with the topological change
virtual void modifyMotionPoints(pointField& motionPoints) const = 0;

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More