mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
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:
@ -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
|
||||||
(
|
(
|
||||||
mesh.time().timePath()
|
fileHandler().readDir
|
||||||
/ mesh.dbDir()
|
(
|
||||||
/ cloud::prefix,
|
fileHandler().objectPath
|
||||||
|
(
|
||||||
|
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);
|
||||||
|
|||||||
@ -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
|
||||||
(
|
(
|
||||||
|
|||||||
@ -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 \
|
||||||
); \
|
); \
|
||||||
|
|||||||
@ -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
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
bool reconstruct = false;
|
|
||||||
|
|
||||||
label nFields = 0;
|
|
||||||
for (const word& objectName : fieldNames)
|
|
||||||
{
|
|
||||||
if (!nFields)
|
|
||||||
{
|
|
||||||
// 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
|
// Read if present
|
||||||
IOField<Type> field
|
IOobject srcIOobject
|
||||||
(
|
(
|
||||||
IOobject
|
"none",
|
||||||
(
|
|
||||||
objectName,
|
|
||||||
srcMesh_.time().timeName(),
|
srcMesh_.time().timeName(),
|
||||||
cloud::prefix/cloudName,
|
cloud::prefix/cloudName,
|
||||||
srcMesh_,
|
srcMesh_,
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobjectOption::LAZY_READ,
|
||||||
IOobject::NO_WRITE,
|
IOobjectOption::NO_WRITE,
|
||||||
IOobject::NO_REGISTER
|
IOobjectOption::NO_REGISTER
|
||||||
),
|
|
||||||
label(0)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
map.distribute(field);
|
IOobject tgtIOobject
|
||||||
|
|
||||||
|
|
||||||
const IOobject fieldIO
|
|
||||||
(
|
(
|
||||||
objectName,
|
"none",
|
||||||
tgtMesh_.time().timeName(),
|
tgtMesh_.time().timeName(),
|
||||||
cloud::prefix/cloudName,
|
cloud::prefix/cloudName,
|
||||||
tgtMesh_,
|
tgtMesh_,
|
||||||
IOobject::NO_READ,
|
IOobjectOption::NO_READ,
|
||||||
IOobject::NO_WRITE,
|
IOobjectOption::NO_WRITE,
|
||||||
IOobject::NO_REGISTER
|
IOobjectOption::NO_REGISTER
|
||||||
);
|
);
|
||||||
|
|
||||||
if (field.size())
|
//bool reconstruct = false;
|
||||||
{
|
|
||||||
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());
|
if (verbose_ && fieldNames.size())
|
||||||
Foam::rm(fldName);
|
{
|
||||||
}
|
Info<< " Distributing lagrangian "
|
||||||
|
<< Container::typeName << "s\n" << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
label nFields = 0;
|
|
||||||
for (const word& objectName : fieldNames)
|
|
||||||
{
|
|
||||||
if (!nFields)
|
|
||||||
{
|
|
||||||
// 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
|
// Read if present
|
||||||
CompactIOField<Field<Type>, Type> field
|
IOobject srcIOobject
|
||||||
(
|
(
|
||||||
IOobject
|
"none",
|
||||||
(
|
|
||||||
objectName,
|
|
||||||
srcMesh_.time().timeName(),
|
srcMesh_.time().timeName(),
|
||||||
cloud::prefix/cloudName,
|
cloud::prefix/cloudName,
|
||||||
srcMesh_,
|
srcMesh_,
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobjectOption::LAZY_READ,
|
||||||
IOobject::NO_WRITE,
|
IOobjectOption::NO_WRITE,
|
||||||
IOobject::NO_REGISTER
|
IOobjectOption::NO_REGISTER
|
||||||
),
|
|
||||||
label(0)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const word& objectName : fieldNames)
|
||||||
|
{
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< " " << objectName << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
srcIOobject.resetHeader(objectName);
|
||||||
|
tgtIOobject.resetHeader(objectName);
|
||||||
|
|
||||||
|
// Read if present (ie, haveCloud means readOnProc)
|
||||||
|
Container field(srcIOobject, haveCloud);
|
||||||
|
|
||||||
// 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
|
||||||
for (const word& objectName : fieldNames)
|
IOobject readIO
|
||||||
{
|
(
|
||||||
if (verbose_)
|
"none",
|
||||||
{
|
cloud.time().timeName(),
|
||||||
if (!nFields)
|
cloud,
|
||||||
|
IOobjectOption::LAZY_READ,
|
||||||
|
IOobjectOption::NO_WRITE,
|
||||||
|
IOobjectOption::REGISTER
|
||||||
|
);
|
||||||
|
|
||||||
|
if (verbose_ && fieldNames.size())
|
||||||
{
|
{
|
||||||
Info<< " Reading lagrangian "
|
Info<< " Reading lagrangian "
|
||||||
<< Container::typeName << "s\n" << nl;
|
<< Container::typeName << "s\n" << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const word& objectName : fieldNames)
|
||||||
|
{
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
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
|
||||||
{
|
(
|
||||||
if (!nFields)
|
"none",
|
||||||
{
|
tgtMesh_.time().timeName(),
|
||||||
// Performing an all-to-one (reconstruct)?
|
cloud::prefix/cloud.name(),
|
||||||
reconstruct =
|
tgtMesh_,
|
||||||
returnReduceAnd(!map.constructSize() || Pstream::master());
|
IOobjectOption::NO_READ,
|
||||||
}
|
IOobjectOption::NO_WRITE,
|
||||||
|
IOobjectOption::NO_REGISTER
|
||||||
|
);
|
||||||
|
|
||||||
if (verbose_)
|
//bool reconstruct = false;
|
||||||
{
|
|
||||||
if (!nFields)
|
if (verbose_ && fields.size())
|
||||||
{
|
{
|
||||||
Info<< " Distributing lagrangian "
|
Info<< " Distributing lagrangian "
|
||||||
<< Container::typeName << "s\n" << nl;
|
<< Container::typeName << "s\n" << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Container& field : fields)
|
||||||
|
{
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user