ENH: Update redistribute clouds with readOnProc/writeOnProc

- when reading, detect all clouds on all processors and uses this when
  reading fields. Similarly, when writing it uses writeOnProc to skip
  clouds that are empty on any particular processor.

Co-authored-by: Mark Olesen <>
This commit is contained in:
mattijs
2023-05-12 18:43:32 +02:00
committed by Andrew Heather
parent eea72282ab
commit bcd873ccfe
5 changed files with 309 additions and 262 deletions

View File

@ -52,7 +52,7 @@ Foam::parLagrangianDistributor::parLagrangianDistributor
const mapDistribute& cellMap = distMap_.cellMap(); const mapDistribute& cellMap = distMap_.cellMap();
// Get destination processors and cells // Get destination processors and cells
destinationProcID_ = labelList(tgtMesh_.nCells(), Pstream::myProcNo()); destinationProcID_ = labelList(tgtMesh_.nCells(), UPstream::myProcNo());
cellMap.reverseDistribute(nSrcCells, destinationProcID_); cellMap.reverseDistribute(nSrcCells, destinationProcID_);
destinationCell_ = identity(tgtMesh_.nCells()); destinationCell_ = identity(tgtMesh_.nCells());
@ -67,21 +67,39 @@ Foam::parLagrangianDistributor::parLagrangianDistributor
void Foam::parLagrangianDistributor::findClouds void Foam::parLagrangianDistributor::findClouds
( (
const fvMesh& mesh, const fvMesh& mesh,
wordList& cloudNames, wordList& cloudNames, // All cloud names on any processor
List<wordList>& objectNames boolList& haveClouds, // Per cloud name, whether my processor has it
List<wordList>& objectNames // Per cloud name, the field name
) )
{ {
fileNameList localCloudDirs const IOobject io
( (
readDir cloud::prefix,
mesh.time().timeName(),
mesh,
IOobjectOption::MUST_READ,
IOobjectOption::NO_WRITE
);
// Using the fileHandler:
// - use fileHandler to synthesise correct processor directory
// - cannot use readObjects since assumes all processors have same
// files (i.e. it only checks processor0)
const fileNameList localCloudDirs
(
fileHandler().readDir
( (
mesh.time().timePath() fileHandler().objectPath
/ mesh.dbDir() (
/ cloud::prefix, io,
word::null // typeName: not used currently
),
fileName::DIRECTORY fileName::DIRECTORY
) )
); );
// Copy out the local cloud names (and fileName -> word)
cloudNames.resize_nocopy(localCloudDirs.size()); cloudNames.resize_nocopy(localCloudDirs.size());
forAll(localCloudDirs, i) forAll(localCloudDirs, i)
{ {
@ -92,18 +110,34 @@ void Foam::parLagrangianDistributor::findClouds
Pstream::combineReduce(cloudNames, ListOps::uniqueEqOp<word>()); Pstream::combineReduce(cloudNames, ListOps::uniqueEqOp<word>());
Foam::sort(cloudNames); // Consistent order Foam::sort(cloudNames); // Consistent order
objectNames.clear();
// See which of the global cloudNames I have
haveClouds.resize_nocopy(cloudNames.size());
haveClouds = false;
for (const fileName& localCloudName : localCloudDirs)
{
const label cloudi = cloudNames.find(localCloudName);
if (cloudi >= 0)
{
haveClouds[cloudi] = true;
}
}
// Collect fields per cloud
objectNames.resize(cloudNames.size()); objectNames.resize(cloudNames.size());
for (const fileName& localCloudName : localCloudDirs) for (const fileName& localCloudName : localCloudDirs)
{ {
// Do local scan for valid cloud objects // Do local scan for valid cloud objects
const bool oldParRun = UPstream::parRun(false);
IOobjectList localObjs IOobjectList localObjs
( (
mesh, mesh,
mesh.time().timeName(), mesh.time().timeName(),
cloud::prefix/localCloudName cloud::prefix/localCloudName
); );
UPstream::parRun(oldParRun);
bool isCloud = false; bool isCloud = false;
if (localObjs.erase("coordinates")) if (localObjs.erase("coordinates"))
@ -141,8 +175,7 @@ Foam::parLagrangianDistributor::distributeLagrangianPositions
) const ) const
{ {
//Debug(lpi.size()); //Debug(lpi.size());
//const label oldLpi = lpi.size();
const label oldLpi = lpi.size();
labelListList sendMap; labelListList sendMap;
@ -154,7 +187,7 @@ Foam::parLagrangianDistributor::distributeLagrangianPositions
// neighbour processors // neighbour processors
List<IDLList<passivePositionParticle>> particleTransferLists List<IDLList<passivePositionParticle>> particleTransferLists
( (
Pstream::nProcs() UPstream::nProcs()
); );
// Per particle the destination processor // Per particle the destination processor
@ -233,13 +266,15 @@ Foam::parLagrangianDistributor::distributeLagrangianPositions
} }
} }
if (lagrangianPositions.size()) const bool writeOnProc = lagrangianPositions.size();
//if (writeOnProc)
{ {
// Write coordinates file // Write coordinates file
IOPosition<passivePositionParticleCloud> IOPosition<passivePositionParticleCloud>
( (
lagrangianPositions lagrangianPositions
).write(); ).write(writeOnProc);
// Optionally write positions file in v1706 format and earlier // Optionally write positions file in v1706 format and earlier
if (particle::writeLagrangianPositions) if (particle::writeLagrangianPositions)
@ -248,35 +283,33 @@ Foam::parLagrangianDistributor::distributeLagrangianPositions
( (
lagrangianPositions, lagrangianPositions,
cloud::geometryType::POSITIONS cloud::geometryType::POSITIONS
).write(); ).write(writeOnProc);
} }
} }
else if (oldLpi) //else if (!writeOnProc && oldLpi)
{ //{
// When running with -overwrite it should also delete the old // // When running with -overwrite it should also delete the old
// files. Below works but is not optimal. // // files. Below works but is not optimal.
//
// Remove any existing coordinates // // Remove any existing coordinates
const fileName oldCoords // Foam::rm
( // (
IOPosition<passivePositionParticleCloud> // IOPosition<passivePositionParticleCloud>
( // (
lagrangianPositions // lagrangianPositions
).objectPath() // ).objectPath()
); // );
Foam::rm(oldCoords); //
// // Remove any existing positions
// Remove any existing positions // Foam::rm
const fileName oldPos // (
( // IOPosition<passivePositionParticleCloud>
IOPosition<passivePositionParticleCloud> // (
( // lagrangianPositions,
lagrangianPositions, // cloud::geometryType::POSITIONS
cloud::geometryType::POSITIONS // ).objectPath()
).objectPath() // );
); //}
Foam::rm(oldPos);
}
// Restore cloud name // Restore cloud name
lpi.rename(cloudName); lpi.rename(cloudName);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015 OpenFOAM Foundation Copyright (C) 2015 OpenFOAM Foundation
Copyright (C) 2018-2022 OpenCFD Ltd. Copyright (C) 2018-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -114,7 +114,14 @@ public:
static void findClouds static void findClouds
( (
const fvMesh&, const fvMesh&,
//! All cloud names on any processor
wordList& cloudNames, wordList& cloudNames,
//! Per cloud name, whether my processor has it
boolList& haveClouds,
//! Per cloud nmae, the field names
List<wordList>& objectNames List<wordList>& objectNames
); );
@ -131,6 +138,7 @@ public:
static label readFields static label readFields
( (
const passivePositionParticleCloud& cloud, const passivePositionParticleCloud& cloud,
const bool haveCloud,
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields = wordRes() const wordRes& selectedFields = wordRes()
); );
@ -139,18 +147,11 @@ public:
static label readAllFields static label readAllFields
( (
const passivePositionParticleCloud& cloud, const passivePositionParticleCloud& cloud,
const bool haveCloud,
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields = wordRes() const wordRes& selectedFields = wordRes()
); );
//- Read and store all fields for known cloud field types
// Uses the current cloud instance to obtain the IOobjectList
static label readAllFields
(
const passivePositionParticleCloud& cloud,
const wordRes& selectedFields = wordRes()
);
// Member Functions // Member Functions
@ -171,6 +172,7 @@ public:
( (
const mapDistributeBase& lagrangianMap, const mapDistributeBase& lagrangianMap,
const word& cloudName, const word& cloudName,
const bool haveCloud,
const IOobjectList& cloudObjs, const IOobjectList& cloudObjs,
const wordRes& selectedFields const wordRes& selectedFields
) const; ) const;
@ -189,6 +191,7 @@ public:
( (
const mapDistributeBase& map, const mapDistributeBase& map,
const word& cloudName, const word& cloudName,
const bool haveCloud,
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields = wordRes() const wordRes& selectedFields = wordRes()
) const; ) const;
@ -199,11 +202,14 @@ public:
( (
const mapDistributeBase& map, const mapDistributeBase& map,
const word& cloudName, const word& cloudName,
const bool haveCloud,
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields = wordRes() const wordRes& selectedFields = wordRes()
) const; ) const;
//- Redistribute and write stored lagrangian fields //- Redistribute and write stored lagrangian fields.
// Note: does no reading so no need to check for existence
// of lagrangian files
template<class Container> template<class Container>
label distributeStoredFields label distributeStoredFields
( (

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd. Copyright (C) 2022-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -33,6 +33,7 @@ License
Foam::label Foam::parLagrangianDistributor::readAllFields Foam::label Foam::parLagrangianDistributor::readAllFields
( (
const passivePositionParticleCloud& cloud, const passivePositionParticleCloud& cloud,
const bool haveCloud,
const IOobjectList& cloudObjs, const IOobjectList& cloudObjs,
const wordRes& selectedFields const wordRes& selectedFields
) )
@ -48,6 +49,7 @@ Foam::label Foam::parLagrangianDistributor::readAllFields
<IOField<Type>> \ <IOField<Type>> \
( \ ( \
cloud, \ cloud, \
haveCloud, \
cloudObjs, \ cloudObjs, \
selectedFields \ selectedFields \
); \ ); \
@ -56,6 +58,7 @@ Foam::label Foam::parLagrangianDistributor::readAllFields
<IOField<Field<Type>>> \ <IOField<Field<Type>>> \
( \ ( \
cloud, \ cloud, \
haveCloud, \
cloudObjs, \ cloudObjs, \
selectedFields \ selectedFields \
); \ ); \
@ -64,6 +67,7 @@ Foam::label Foam::parLagrangianDistributor::readAllFields
<CompactIOField<Field<Type>, Type>> \ <CompactIOField<Field<Type>, Type>> \
( \ ( \
cloud, \ cloud, \
haveCloud, \
cloudObjs, \ cloudObjs, \
selectedFields \ selectedFields \
); \ ); \
@ -84,21 +88,22 @@ Foam::label Foam::parLagrangianDistributor::readAllFields
} }
Foam::label Foam::parLagrangianDistributor::readAllFields //Foam::label Foam::parLagrangianDistributor::readAllFields
( //(
const passivePositionParticleCloud& cloud, // const passivePositionParticleCloud& cloud,
const wordRes& selectedFields // const wordRes& selectedFields
) //)
{ //{
IOobjectList cloudObjs(cloud, cloud.time().timeName()); // IOobjectList cloudObjs(cloud, cloud.time().timeName());
return readAllFields(cloud, cloudObjs, selectedFields); // return readAllFields(cloud, cloudObjs, selectedFields);
} //}
Foam::label Foam::parLagrangianDistributor::distributeAllFields Foam::label Foam::parLagrangianDistributor::distributeAllFields
( (
const mapDistributeBase& lagrangianMap, const mapDistributeBase& lagrangianMap,
const word& cloudName, const word& cloudName,
const bool haveCloud,
const IOobjectList& cloudObjs, const IOobjectList& cloudObjs,
const wordRes& selectedFields const wordRes& selectedFields
) const ) const
@ -114,6 +119,7 @@ Foam::label Foam::parLagrangianDistributor::distributeAllFields
( \ ( \
lagrangianMap, \ lagrangianMap, \
cloudName, \ cloudName, \
haveCloud, \
cloudObjs, \ cloudObjs, \
selectedFields \ selectedFields \
); \ ); \
@ -122,6 +128,7 @@ Foam::label Foam::parLagrangianDistributor::distributeAllFields
( \ ( \
lagrangianMap, \ lagrangianMap, \
cloudName, \ cloudName, \
haveCloud, \
cloudObjs, \ cloudObjs, \
selectedFields \ selectedFields \
); \ ); \

View File

@ -64,91 +64,85 @@ Foam::label Foam::parLagrangianDistributor::distributeFields
( (
const mapDistributeBase& map, const mapDistributeBase& map,
const word& cloudName, const word& cloudName,
const bool haveCloud,
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields const wordRes& selectedFields
) const ) const
{ {
typedef IOField<Type> fieldType; typedef IOField<Type> Container;
const wordList fieldNames const wordList fieldNames
( (
filterObjects<fieldType> filterObjects<IOField<Type>>
( (
objects, objects,
selectedFields selectedFields
) )
); );
// Read if present
IOobject srcIOobject
(
"none",
srcMesh_.time().timeName(),
cloud::prefix/cloudName,
srcMesh_,
IOobjectOption::LAZY_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::NO_REGISTER
);
bool reconstruct = false; IOobject tgtIOobject
(
"none",
tgtMesh_.time().timeName(),
cloud::prefix/cloudName,
tgtMesh_,
IOobjectOption::NO_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::NO_REGISTER
);
label nFields = 0; //bool reconstruct = false;
for (const word& objectName : fieldNames)
if (verbose_ && fieldNames.size())
{ {
if (!nFields) Info<< " Distributing lagrangian "
{ << Container::typeName << "s\n" << nl;
// Performing an all-to-one (reconstruct)?
reconstruct =
returnReduceAnd(!map.constructSize() || Pstream::master());
}
if (verbose_)
{
if (!nFields)
{
Info<< " Distributing lagrangian "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << objectName << nl;
}
++nFields;
// Read if present
IOField<Type> field
(
IOobject
(
objectName,
srcMesh_.time().timeName(),
cloud::prefix/cloudName,
srcMesh_,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
label(0)
);
map.distribute(field);
const IOobject fieldIO
(
objectName,
tgtMesh_.time().timeName(),
cloud::prefix/cloudName,
tgtMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
);
if (field.size())
{
IOField<Type>(fieldIO, std::move(field)).write();
}
else if (!reconstruct)
{
// When running with -overwrite it should also delete the old
// files. Below works but is not optimal.
const fileName fldName(fieldIO.objectPath());
Foam::rm(fldName);
}
} }
if (nFields && verbose_) Info<< endl; for (const word& objectName : fieldNames)
return nFields; {
if (verbose_)
{
Info<< " " << objectName << nl;
}
srcIOobject.resetHeader(objectName);
tgtIOobject.resetHeader(objectName);
// Read if present (ie, haveCloud means readOnProc)
Container field(srcIOobject, haveCloud);
// Distribute
map.distribute(field);
const bool writeOnProc = field.size();
// Write
Container(tgtIOobject, std::move(field)).write(writeOnProc);
//if (!writeOnProc && !reconstruct)
//{
// // When running with -overwrite it should also delete the old
// // files. Below works but is not optimal.
//
// Foam::rm(tgtIOobject.objectPath());
//}
}
if (verbose_ && fieldNames.size()) Info<< endl;
return fieldNames.size();
} }
@ -157,25 +151,27 @@ Foam::label Foam::parLagrangianDistributor::distributeFieldFields
( (
const mapDistributeBase& map, const mapDistributeBase& map,
const word& cloudName, const word& cloudName,
const bool haveCloud,
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields const wordRes& selectedFields
) const ) const
{ {
typedef CompactIOField<Field<Type>, Type> fieldType; typedef CompactIOField<Field<Type>, Type> Container;
DynamicList<word> fieldNames; DynamicList<word> fieldNames;
fieldNames.append // CompactIOField Field names
fieldNames.push_back
( (
filterObjects<fieldType> filterObjects<CompactIOField<Field<Type>, Type>>
( (
objects, objects,
selectedFields selectedFields
) )
); );
// Append IOField Field names // IOField Field names
fieldNames.append fieldNames.push_back
( (
filterObjects<IOField<Field<Type>>> filterObjects<IOField<Field<Type>>>
( (
@ -184,80 +180,69 @@ Foam::label Foam::parLagrangianDistributor::distributeFieldFields
) )
); );
bool reconstruct = false; // Read if present
IOobject srcIOobject
(
"none",
srcMesh_.time().timeName(),
cloud::prefix/cloudName,
srcMesh_,
IOobjectOption::LAZY_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::NO_REGISTER
);
IOobject tgtIOobject
(
"none",
tgtMesh_.time().timeName(),
cloud::prefix/cloudName,
tgtMesh_,
IOobjectOption::NO_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::NO_REGISTER
);
//bool reconstruct = false;
if (verbose_ && fieldNames.size())
{
Info<< " Distributing lagrangian "
<< Container::typeName << "s\n" << nl;
}
label nFields = 0;
for (const word& objectName : fieldNames) for (const word& objectName : fieldNames)
{ {
if (!nFields)
{
// Performing an all-to-one (reconstruct)?
reconstruct =
returnReduceAnd(!map.constructSize() || Pstream::master());
}
if (verbose_) if (verbose_)
{ {
if (!nFields)
{
Info<< " Distributing lagrangian "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << objectName << nl; Info<< " " << objectName << nl;
} }
++nFields;
// Read if present srcIOobject.resetHeader(objectName);
CompactIOField<Field<Type>, Type> field tgtIOobject.resetHeader(objectName);
(
IOobject // Read if present (ie, haveCloud means readOnProc)
( Container field(srcIOobject, haveCloud);
objectName,
srcMesh_.time().timeName(),
cloud::prefix/cloudName,
srcMesh_,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
label(0)
);
// Distribute // Distribute
map.distribute(field); map.distribute(field);
const bool writeOnProc = field.size();
// Write // Write
const IOobject fieldIO Container(tgtIOobject, std::move(field)).write(writeOnProc);
(
objectName,
tgtMesh_.time().timeName(),
cloud::prefix/cloudName,
tgtMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
);
if (field.size()) //if (!writeOnProc && !reconstruct)
{ //{
CompactIOField<Field<Type>, Type> // // When running with -overwrite it should also delete the old
( // // files. Below works but is not optimal.
fieldIO, //
std::move(field) // Foam::rm(tgtIOobject.objectPath());
).write(); //}
}
else if (!reconstruct)
{
// When running with -overwrite it should also delete the old
// files. Below works but is not optimal.
const fileName fldName(fieldIO.objectPath());
Foam::rm(fldName);
}
} }
if (nFields && verbose_) Info<< endl; if (verbose_ && fieldNames.size()) Info<< endl;
return nFields; return fieldNames.size();
} }
@ -265,12 +250,11 @@ template<class Container>
Foam::label Foam::parLagrangianDistributor::readFields Foam::label Foam::parLagrangianDistributor::readFields
( (
const passivePositionParticleCloud& cloud, const passivePositionParticleCloud& cloud,
const bool haveCloud,
const IOobjectList& objects, const IOobjectList& objects,
const wordRes& selectedFields const wordRes& selectedFields
) )
{ {
const word fieldClassName(Container::typeName);
const wordList fieldNames const wordList fieldNames
( (
filterObjects<Container> filterObjects<Container>
@ -280,40 +264,40 @@ Foam::label Foam::parLagrangianDistributor::readFields
) )
); );
label nFields = 0; // Read if present
IOobject readIO
(
"none",
cloud.time().timeName(),
cloud,
IOobjectOption::LAZY_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::REGISTER
);
if (verbose_ && fieldNames.size())
{
Info<< " Reading lagrangian "
<< Container::typeName << "s\n" << nl;
}
for (const word& objectName : fieldNames) for (const word& objectName : fieldNames)
{ {
if (verbose_) if (verbose_)
{ {
if (!nFields)
{
Info<< " Reading lagrangian "
<< Container::typeName << "s\n" << nl;
}
Info<< " " << objectName << nl; Info<< " " << objectName << nl;
} }
++nFields;
// Read if present readIO.resetHeader(objectName);
Container* fieldPtr = new Container
( // Read if present (ie, haveCloud means readOnProc)
IOobject Container* fieldPtr = new Container(readIO, haveCloud);
(
objectName,
cloud.time().timeName(),
cloud,
IOobject::LAZY_READ,
IOobject::NO_WRITE,
IOobject::REGISTER
),
label(0)
);
fieldPtr->store(); fieldPtr->store();
} }
if (nFields && verbose_) Info<< endl; if (verbose_ && fieldNames.size()) Info<< endl;
return nFields; return fieldNames.size();
} }
@ -324,58 +308,55 @@ Foam::label Foam::parLagrangianDistributor::distributeStoredFields
passivePositionParticleCloud& cloud passivePositionParticleCloud& cloud
) const ) const
{ {
bool reconstruct = false; // Parallel-consistent
label nFields = 0; UPtrList<Container> fields(cloud.sorted<Container>());
for (Container& field : cloud.sorted<Container>()) IOobject writeIO
(
"none",
tgtMesh_.time().timeName(),
cloud::prefix/cloud.name(),
tgtMesh_,
IOobjectOption::NO_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::NO_REGISTER
);
//bool reconstruct = false;
if (verbose_ && fields.size())
{ {
if (!nFields) Info<< " Distributing lagrangian "
{ << Container::typeName << "s\n" << nl;
// Performing an all-to-one (reconstruct)? }
reconstruct =
returnReduceAnd(!map.constructSize() || Pstream::master());
}
for (Container& field : fields)
{
if (verbose_) if (verbose_)
{ {
if (!nFields)
{
Info<< " Distributing lagrangian "
<< Container::typeName << "s\n" << nl;
}
Info<< " " << field.name() << nl; Info<< " " << field.name() << nl;
} }
++nFields;
map.distribute(field); map.distribute(field);
const IOobject fieldIO writeIO.resetHeader(field.name());
(
field.name(),
tgtMesh_.time().timeName(),
cloud::prefix/cloud.name(),
tgtMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
);
if (field.size()) const bool writeOnProc = field.size();
{
Container(fieldIO, std::move(field)).write();
}
else if (!reconstruct)
{
// When running with -overwrite it should also delete the old
// files. Below works but is not optimal.
const fileName fldName(fieldIO.objectPath()); // Write
Foam::rm(fldName); Container(writeIO, std::move(field)).write(writeOnProc);
}
//if (!writeOnProc && !reconstruct)
//{
// // When running with -overwrite it should also delete the old
// // files. Below works but is not optimal.
//
// Foam::rm(writeIO.objectPath());
//}
} }
if (nFields && verbose_) Info<< endl; if (verbose_ && fields.size()) Info<< endl;
return nFields; return fields.size();
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2022 OpenCFD Ltd. Copyright (C) 2015-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -48,6 +48,7 @@ readLagrangian
( (
const fvMesh& mesh, const fvMesh& mesh,
const wordList& cloudNames, const wordList& cloudNames,
const boolUList& haveClouds,
const wordRes& selectedFields const wordRes& selectedFields
) )
{ {
@ -78,11 +79,10 @@ readLagrangian
IOobjectList cloudObjs(clouds[i], clouds[i].time().timeName()); IOobjectList cloudObjs(clouds[i], clouds[i].time().timeName());
//Pout<< "Found cloud objects:" << cloudObjs.names() << endl;
parLagrangianDistributor::readAllFields parLagrangianDistributor::readAllFields
( (
clouds[i], clouds[i],
haveClouds[i],
cloudObjs, cloudObjs,
selectedFields selectedFields
); );
@ -101,11 +101,19 @@ readLagrangian
) )
{ {
wordList cloudNames; wordList cloudNames;
boolList haveClouds;
List<wordList> fieldNames; List<wordList> fieldNames;
// Find all cloudNames on all processors
parLagrangianDistributor::findClouds(mesh, cloudNames, fieldNames);
return readLagrangian(mesh, cloudNames, selectedFields); // Find all cloudNames on all processors
parLagrangianDistributor::findClouds
(
mesh,
cloudNames,
haveClouds,
fieldNames
);
return readLagrangian(mesh, cloudNames, haveClouds, selectedFields);
} }
@ -121,9 +129,17 @@ void reconstructLagrangian
// Clouds (note: might not be present on all processors) // Clouds (note: might not be present on all processors)
wordList cloudNames; wordList cloudNames;
boolList haveClouds;
List<wordList> fieldNames; List<wordList> fieldNames;
// Find all cloudNames on all processors // Find all cloudNames on all processors
parLagrangianDistributor::findClouds(mesh, cloudNames, fieldNames); parLagrangianDistributor::findClouds
(
mesh,
cloudNames,
haveClouds,
fieldNames
);
if (cloudNames.empty()) if (cloudNames.empty())
{ {
@ -142,13 +158,16 @@ void reconstructLagrangian
baseMesh, baseMesh,
mesh.nCells(), // range of cell indices in clouds mesh.nCells(), // range of cell indices in clouds
distMap distMap
//writeHandler // Which processors to write
) )
); );
} }
const auto& distributor = *distributorPtr; const auto& distributor = *distributorPtr;
for (const word& cloudName : cloudNames) forAll(cloudNames, cloudi)
{ {
const word& cloudName = cloudNames[cloudi];
Info<< "Reconstructing lagrangian fields for cloud " Info<< "Reconstructing lagrangian fields for cloud "
<< cloudName << nl << endl; << cloudName << nl << endl;
@ -169,6 +188,7 @@ void reconstructLagrangian
( (
lagrangianMapPtr(), lagrangianMapPtr(),
cloudName, cloudName,
haveClouds[cloudi],
cloudObjs, cloudObjs,
selectedFields selectedFields
); );