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
|
const UList<floatVector>& points
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
for (const floatVector& p : points)
|
for (const auto& p : points)
|
||||||
{
|
{
|
||||||
os.write(p.x());
|
os.write(p.x());
|
||||||
os.write(p.y());
|
os.write(p.y());
|
||||||
@ -59,7 +59,7 @@ static inline label writeMeasured_ascii
|
|||||||
const UList<floatVector>& points
|
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.writeInt(++pointId, 8); // 1-index and an unusual width
|
||||||
os.write(p.x());
|
os.write(p.x());
|
||||||
@ -79,75 +79,24 @@ static inline label writeMeasured_ascii
|
|||||||
bool Foam::ensightOutput::writeCloudPositions
|
bool Foam::ensightOutput::writeCloudPositions
|
||||||
(
|
(
|
||||||
ensightFile& os,
|
ensightFile& os,
|
||||||
const fvMesh& mesh,
|
DynamicList<floatVector>& positions,
|
||||||
const word& cloudName,
|
const globalIndex& procAddr
|
||||||
bool exists
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
label nLocalParcels(0);
|
// Total number of parcels across all ranks
|
||||||
autoPtr<Cloud<passiveParticle>> parcelsPtr;
|
const label nTotParcels = procAddr.totalSize();
|
||||||
|
|
||||||
if (exists)
|
bool noCloud(!procAddr.totalSize());
|
||||||
{
|
Pstream::broadcast(noCloud);
|
||||||
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>());
|
|
||||||
|
|
||||||
if (UPstream::master())
|
if (UPstream::master())
|
||||||
{
|
{
|
||||||
os.beginParticleCoordinates(nTotParcels);
|
os.beginParticleCoordinates(nTotParcels);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nTotParcels)
|
if (noCloud)
|
||||||
{
|
{
|
||||||
return false; // DONE
|
return false; // All empty
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UPstream::master())
|
if (UPstream::master())
|
||||||
@ -178,6 +127,9 @@ bool Foam::ensightOutput::writeCloudPositions
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
positions.clear();
|
||||||
|
positions.reserve_nocopy(procAddr.maxNonLocalSize());
|
||||||
|
|
||||||
// Receive and write
|
// Receive and write
|
||||||
for (const label proci : procAddr.subProcs())
|
for (const label proci : procAddr.subProcs())
|
||||||
{
|
{
|
||||||
@ -186,6 +138,7 @@ bool Foam::ensightOutput::writeCloudPositions
|
|||||||
if (procSize)
|
if (procSize)
|
||||||
{
|
{
|
||||||
positions.resize_nocopy(procSize);
|
positions.resize_nocopy(procSize);
|
||||||
|
|
||||||
UIPstream::read
|
UIPstream::read
|
||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
@ -205,7 +158,7 @@ bool Foam::ensightOutput::writeCloudPositions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (UPstream::is_subrank())
|
||||||
{
|
{
|
||||||
if (positions.size())
|
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
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2016-2022 OpenCFD Ltd.
|
Copyright (C) 2016-2024 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -40,6 +40,8 @@ SourceFiles
|
|||||||
|
|
||||||
#include "ensightFile.H"
|
#include "ensightFile.H"
|
||||||
#include "IOField.H"
|
#include "IOField.H"
|
||||||
|
#include "DynamicList.H"
|
||||||
|
#include "vector.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -48,6 +50,7 @@ namespace Foam
|
|||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
class fvMesh;
|
class fvMesh;
|
||||||
|
class globalIndex;
|
||||||
|
|
||||||
namespace ensightOutput
|
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
|
//- Write cloud positions
|
||||||
bool writeCloudPositions
|
bool writeCloudPositions
|
||||||
(
|
(
|
||||||
@ -80,7 +111,23 @@ bool writeCloudField
|
|||||||
ensightFile& os,
|
ensightFile& os,
|
||||||
|
|
||||||
//! The cloud field
|
//! 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
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2016-2022 OpenCFD Ltd.
|
Copyright (C) 2016-2024 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -39,7 +39,6 @@ Foam::label Foam::ensightOutput::Detail::writeCloudFieldContent
|
|||||||
label count
|
label count
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Write master data
|
|
||||||
for (Type val : field) // <-- working on a copy!
|
for (Type val : field) // <-- working on a copy!
|
||||||
{
|
{
|
||||||
if (mag(val) < 1e-90) // approximately root(ROOTVSMALL)
|
if (mag(val) < 1e-90) // approximately root(ROOTVSMALL)
|
||||||
@ -70,18 +69,20 @@ template<class Type>
|
|||||||
bool Foam::ensightOutput::writeCloudField
|
bool Foam::ensightOutput::writeCloudField
|
||||||
(
|
(
|
||||||
ensightFile& os,
|
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
|
// 6 values per line
|
||||||
label count = 0;
|
label count = 0;
|
||||||
@ -128,7 +129,7 @@ bool Foam::ensightOutput::writeCloudField
|
|||||||
os.newline();
|
os.newline();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (UPstream::is_subrank())
|
||||||
{
|
{
|
||||||
if (field.size())
|
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>
|
template<class Type>
|
||||||
bool Foam::ensightOutput::readWriteCloudField
|
bool Foam::ensightOutput::readWriteCloudField
|
||||||
(
|
(
|
||||||
@ -162,10 +180,11 @@ bool Foam::ensightOutput::readWriteCloudField
|
|||||||
|
|
||||||
IOobject io(fieldObject);
|
IOobject io(fieldObject);
|
||||||
io.readOpt(IOobject::READ_IF_PRESENT);
|
io.readOpt(IOobject::READ_IF_PRESENT);
|
||||||
|
io.registerObject(IOobject::NO_REGISTER);
|
||||||
|
|
||||||
IOField<Type> field(io);
|
IOField<Type> field(io);
|
||||||
|
|
||||||
writeCloudField(os, field);
|
ensightOutput::writeCloudField(os, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user