mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: extend ensightCloud write-measured support
- related to issue #3095
This commit is contained in:
@ -43,7 +43,7 @@ static inline void writeMeasured_binary
|
||||
const UList<floatVector>& points
|
||||
)
|
||||
{
|
||||
for (const floatVector& p : points)
|
||||
for (const auto& p : points)
|
||||
{
|
||||
os.write(p.x());
|
||||
os.write(p.y());
|
||||
@ -59,7 +59,7 @@ static inline label writeMeasured_ascii
|
||||
const UList<floatVector>& points
|
||||
)
|
||||
{
|
||||
for (const floatVector& p : points)
|
||||
for (const auto& p : points)
|
||||
{
|
||||
os.writeInt(++pointId, 8); // 1-index and an unusual width
|
||||
os.write(p.x());
|
||||
@ -79,75 +79,24 @@ static inline label writeMeasured_ascii
|
||||
bool Foam::ensightOutput::writeCloudPositions
|
||||
(
|
||||
ensightFile& os,
|
||||
const fvMesh& mesh,
|
||||
const word& cloudName,
|
||||
bool exists
|
||||
DynamicList<floatVector>& positions,
|
||||
const globalIndex& procAddr
|
||||
)
|
||||
{
|
||||
label nLocalParcels(0);
|
||||
autoPtr<Cloud<passiveParticle>> parcelsPtr;
|
||||
// Total number of parcels across all ranks
|
||||
const label nTotParcels = procAddr.totalSize();
|
||||
|
||||
if (exists)
|
||||
{
|
||||
parcelsPtr.reset(new Cloud<passiveParticle>(mesh, cloudName, false));
|
||||
nLocalParcels = parcelsPtr().size();
|
||||
}
|
||||
|
||||
// Total number of parcels on all processes
|
||||
const label nTotParcels = returnReduce(nLocalParcels, sumOp<label>());
|
||||
bool noCloud(!procAddr.totalSize());
|
||||
Pstream::broadcast(noCloud);
|
||||
|
||||
if (UPstream::master())
|
||||
{
|
||||
os.beginParticleCoordinates(nTotParcels);
|
||||
}
|
||||
|
||||
if (!nTotParcels)
|
||||
if (noCloud)
|
||||
{
|
||||
return false; // DONE
|
||||
}
|
||||
|
||||
|
||||
// Gather sizes (offsets irrelevant)
|
||||
const globalIndex procAddr(globalIndex::gatherOnly{}, nLocalParcels);
|
||||
|
||||
|
||||
DynamicList<floatVector> positions;
|
||||
positions.reserve(UPstream::master() ? procAddr.maxSize() : nLocalParcels);
|
||||
|
||||
// Extract positions from parcel.
|
||||
// Store as floatVector, since that is what Ensight will write anyhow
|
||||
|
||||
if (parcelsPtr)
|
||||
{
|
||||
const auto& parcels = *parcelsPtr;
|
||||
|
||||
positions.resize_nocopy(parcels.size()); // same as nLocalParcels
|
||||
|
||||
auto outIter = positions.begin();
|
||||
|
||||
if (std::is_same<float, vector::cmptType>::value)
|
||||
{
|
||||
for (const passiveParticle& p : parcels)
|
||||
{
|
||||
*outIter = p.position();
|
||||
++outIter;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const passiveParticle& p : parcels)
|
||||
{
|
||||
vector pos(p.position());
|
||||
|
||||
(*outIter).x() = narrowFloat(pos.x());
|
||||
(*outIter).y() = narrowFloat(pos.y());
|
||||
(*outIter).z() = narrowFloat(pos.z());
|
||||
|
||||
++outIter;
|
||||
}
|
||||
}
|
||||
|
||||
parcelsPtr.reset(nullptr);
|
||||
return false; // All empty
|
||||
}
|
||||
|
||||
if (UPstream::master())
|
||||
@ -178,6 +127,9 @@ bool Foam::ensightOutput::writeCloudPositions
|
||||
}
|
||||
|
||||
|
||||
positions.clear();
|
||||
positions.reserve_nocopy(procAddr.maxNonLocalSize());
|
||||
|
||||
// Receive and write
|
||||
for (const label proci : procAddr.subProcs())
|
||||
{
|
||||
@ -186,6 +138,7 @@ bool Foam::ensightOutput::writeCloudPositions
|
||||
if (procSize)
|
||||
{
|
||||
positions.resize_nocopy(procSize);
|
||||
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
@ -205,7 +158,7 @@ bool Foam::ensightOutput::writeCloudPositions
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (UPstream::is_subrank())
|
||||
{
|
||||
if (positions.size())
|
||||
{
|
||||
@ -223,4 +176,86 @@ bool Foam::ensightOutput::writeCloudPositions
|
||||
}
|
||||
|
||||
|
||||
bool Foam::ensightOutput::writeCloudPositions
|
||||
(
|
||||
ensightFile& os,
|
||||
DynamicList<floatVector>& positions
|
||||
)
|
||||
{
|
||||
return ensightOutput::writeCloudPositions
|
||||
(
|
||||
os,
|
||||
positions,
|
||||
// Gather sizes (offsets irrelevant)
|
||||
globalIndex(globalIndex::gatherOnly{}, positions.size())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::ensightOutput::writeCloudPositions
|
||||
(
|
||||
ensightFile& os,
|
||||
const fvMesh& mesh,
|
||||
const word& cloudName,
|
||||
bool exists
|
||||
)
|
||||
{
|
||||
autoPtr<Cloud<passiveParticle>> parcelsPtr;
|
||||
|
||||
if (exists)
|
||||
{
|
||||
parcelsPtr.reset(new Cloud<passiveParticle>(mesh, cloudName, false));
|
||||
}
|
||||
|
||||
const label nLocalParcels
|
||||
(
|
||||
parcelsPtr ? parcelsPtr->size() : 0
|
||||
);
|
||||
|
||||
// Gather sizes (offsets irrelevant)
|
||||
// and total number of parcels (all processes)
|
||||
const globalIndex procAddr(globalIndex::gatherOnly{}, nLocalParcels);
|
||||
|
||||
// Extract positions from parcel.
|
||||
// Store as floatVector, since that is what Ensight will write anyhow
|
||||
|
||||
DynamicList<floatVector> positions;
|
||||
positions.reserve(UPstream::master() ? procAddr.maxSize() : nLocalParcels);
|
||||
|
||||
if (parcelsPtr)
|
||||
{
|
||||
const auto& parcels = *parcelsPtr;
|
||||
|
||||
positions.resize_nocopy(parcels.size()); // same as nLocalParcels
|
||||
|
||||
auto iter = positions.begin();
|
||||
|
||||
if (std::is_same<float, vector::cmptType>::value)
|
||||
{
|
||||
for (const auto& p : parcels)
|
||||
{
|
||||
*iter = p.position();
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto& p : parcels)
|
||||
{
|
||||
const vector pos(p.position());
|
||||
|
||||
(*iter).x() = narrowFloat(pos.x());
|
||||
(*iter).y() = narrowFloat(pos.y());
|
||||
(*iter).z() = narrowFloat(pos.z());
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
parcelsPtr.reset(nullptr);
|
||||
}
|
||||
|
||||
return ensightOutput::writeCloudPositions(os, positions, procAddr);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -40,6 +40,8 @@ SourceFiles
|
||||
|
||||
#include "ensightFile.H"
|
||||
#include "IOField.H"
|
||||
#include "DynamicList.H"
|
||||
#include "vector.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -48,6 +50,7 @@ namespace Foam
|
||||
|
||||
// Forward Declarations
|
||||
class fvMesh;
|
||||
class globalIndex;
|
||||
|
||||
namespace ensightOutput
|
||||
{
|
||||
@ -55,6 +58,34 @@ namespace ensightOutput
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
//- Write cloud positions
|
||||
bool writeCloudPositions
|
||||
(
|
||||
//! Output file (must be valid on master)
|
||||
ensightFile& os,
|
||||
|
||||
//! The positions (measured data) to write.
|
||||
//! Also used as intermediate buffer (on master)
|
||||
DynamicList<floatVector>& positions,
|
||||
|
||||
//! The global sizes of \p positions (must be valid on master)
|
||||
//! and consistent with \p positions dimensions
|
||||
const globalIndex& procAddr
|
||||
);
|
||||
|
||||
|
||||
//- Write cloud positions
|
||||
bool writeCloudPositions
|
||||
(
|
||||
//! Output file (must be valid on master)
|
||||
ensightFile& os,
|
||||
|
||||
//! The positions (measured data) to write.
|
||||
//! Also used as intermediate buffer (on master)
|
||||
DynamicList<floatVector>& positions
|
||||
);
|
||||
|
||||
|
||||
//- Write cloud positions
|
||||
bool writeCloudPositions
|
||||
(
|
||||
@ -80,7 +111,23 @@ bool writeCloudField
|
||||
ensightFile& os,
|
||||
|
||||
//! The cloud field
|
||||
const IOField<Type>& field
|
||||
const UList<Type>& field,
|
||||
|
||||
//! The global sizes of \p field (must be valid on master)
|
||||
//! and consistent with \p field dimensions
|
||||
const globalIndex& procAddr
|
||||
);
|
||||
|
||||
|
||||
//- Write cloud field, returning true if the field is non-empty.
|
||||
template<class Type>
|
||||
bool writeCloudField
|
||||
(
|
||||
//! Output file (must be valid on master)
|
||||
ensightFile& os,
|
||||
|
||||
//! The cloud field
|
||||
const UList<Type>& field
|
||||
);
|
||||
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -39,7 +39,6 @@ Foam::label Foam::ensightOutput::Detail::writeCloudFieldContent
|
||||
label count
|
||||
)
|
||||
{
|
||||
// Write master data
|
||||
for (Type val : field) // <-- working on a copy!
|
||||
{
|
||||
if (mag(val) < 1e-90) // approximately root(ROOTVSMALL)
|
||||
@ -70,18 +69,20 @@ template<class Type>
|
||||
bool Foam::ensightOutput::writeCloudField
|
||||
(
|
||||
ensightFile& os,
|
||||
const IOField<Type>& field
|
||||
const UList<Type>& field,
|
||||
const globalIndex& procAddr
|
||||
)
|
||||
{
|
||||
if (returnReduceAnd(field.empty()))
|
||||
bool allEmpty(!procAddr.totalSize());
|
||||
Pstream::broadcast(allEmpty);
|
||||
|
||||
if (allEmpty)
|
||||
{
|
||||
return false;
|
||||
return false; // All empty
|
||||
}
|
||||
|
||||
// Gather sizes (offsets irrelevant)
|
||||
const globalIndex procAddr(globalIndex::gatherOnly{}, field.size());
|
||||
|
||||
if (Pstream::master())
|
||||
if (UPstream::master())
|
||||
{
|
||||
// 6 values per line
|
||||
label count = 0;
|
||||
@ -128,7 +129,7 @@ bool Foam::ensightOutput::writeCloudField
|
||||
os.newline();
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (UPstream::is_subrank())
|
||||
{
|
||||
if (field.size())
|
||||
{
|
||||
@ -146,6 +147,23 @@ bool Foam::ensightOutput::writeCloudField
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
bool Foam::ensightOutput::writeCloudField
|
||||
(
|
||||
ensightFile& os,
|
||||
const UList<Type>& field
|
||||
)
|
||||
{
|
||||
return ensightOutput::writeCloudField
|
||||
(
|
||||
os,
|
||||
field,
|
||||
// Gather sizes (offsets irrelevant)
|
||||
globalIndex(globalIndex::gatherOnly{}, field.size())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
bool Foam::ensightOutput::readWriteCloudField
|
||||
(
|
||||
@ -162,10 +180,11 @@ bool Foam::ensightOutput::readWriteCloudField
|
||||
|
||||
IOobject io(fieldObject);
|
||||
io.readOpt(IOobject::READ_IF_PRESENT);
|
||||
io.registerObject(IOobject::NO_REGISTER);
|
||||
|
||||
IOField<Type> field(io);
|
||||
|
||||
writeCloudField(os, field);
|
||||
ensightOutput::writeCloudField(os, field);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user