mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: direct ensight output of float/double
- since ensight format is always float and also always written component-wise, perform the double -> float narrowing when extracting the components. This reduces the amount of data transferred between processors. ENH: avoid vtk/ensight parallel communication of empty messages - since ensight writes by element type (eg, tet, hex, polyhedral) the individual written field sections will tend to be relatively sparse. Skip zero-size messages, which should help reduce some of the synchronization bottlenecks. ENH: use 'data chunking' when writing ensight files in parallel - since ensight fields are written on a per-element basis, the corresponding segment can become rather sparsely distributed. With 'data chunking', we attempt to get as many send/recv messages in before flushing the buffer for writing. This should make the sequential send/recv less affected by the IO time. ENH: allow use of an external buffer when writing ensight components STYLE: remove last vestiges of autoPtr<ensightFile> for output routines
This commit is contained in:
@ -43,9 +43,23 @@ const char* const Foam::ensightFile::coordinates = "coordinates";
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::ensightFile::hasUndef(const UList<scalar>& field)
|
||||
bool Foam::ensightFile::hasUndef(const UList<float>& field)
|
||||
{
|
||||
for (const scalar& val : field)
|
||||
for (const float val : field)
|
||||
{
|
||||
if (std::isnan(val))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::ensightFile::hasUndef(const UList<double>& field)
|
||||
{
|
||||
for (const double val : field)
|
||||
{
|
||||
if (std::isnan(val))
|
||||
{
|
||||
@ -354,15 +368,32 @@ void Foam::ensightFile::writeList(const UList<label>& field)
|
||||
{
|
||||
for (const label val : field)
|
||||
{
|
||||
write(scalar(val));
|
||||
write(float(val));
|
||||
newline();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::ensightFile::writeList(const UList<scalar>& field)
|
||||
void Foam::ensightFile::writeList(const UList<float>& field)
|
||||
{
|
||||
for (const scalar val : field)
|
||||
for (const float val : field)
|
||||
{
|
||||
if (std::isnan(val))
|
||||
{
|
||||
writeUndef();
|
||||
}
|
||||
else
|
||||
{
|
||||
write(val);
|
||||
}
|
||||
newline();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::ensightFile::writeList(const UList<double>& field)
|
||||
{
|
||||
for (const double val : field)
|
||||
{
|
||||
if (std::isnan(val))
|
||||
{
|
||||
|
||||
@ -228,26 +228,42 @@ public:
|
||||
// Adds newline after each value (ascii stream)
|
||||
void writeList(const UList<label>& field);
|
||||
|
||||
//- Write a list of floating-point as "%12.5e" or as binary
|
||||
//- (double is narrowed to float).
|
||||
//- Write a list of floats as "%12.5e" or as binary.
|
||||
// Adds newline after each value (ascii stream)
|
||||
void writeList(const UList<scalar>& field);
|
||||
void writeList(const UList<float>& field);
|
||||
|
||||
//- Write an indirect list of scalars as "%12.5e" or as binary
|
||||
//- Write a list of double as "%12.5e" or as binary.
|
||||
//- (double is narrowed to float)
|
||||
// Adds newline after each value (ascii stream)
|
||||
void writeList(const UList<double>& field);
|
||||
|
||||
//- Write an indirect list of float as "%12.5e" or as binary
|
||||
// Adds newline after each value (ascii stream)
|
||||
template<class Addr>
|
||||
void writeList(const IndirectListBase<float, Addr>& field);
|
||||
|
||||
//- Write an indirect list of double as "%12.5e" or as binary.
|
||||
//- (double is narrowed to float)
|
||||
// Adds newline after each value (ascii stream)
|
||||
template<class Addr>
|
||||
void writeList(const IndirectListBase<scalar, Addr>& field);
|
||||
void writeList(const IndirectListBase<double, Addr>& field);
|
||||
|
||||
|
||||
// Other Methods
|
||||
|
||||
//- Check for any NaN in the field
|
||||
static bool hasUndef(const UList<scalar>& field);
|
||||
static bool hasUndef(const UList<float>& field);
|
||||
|
||||
//- Check for any NaN in the field
|
||||
static bool hasUndef(const UList<double>& field);
|
||||
|
||||
//- Check for any NaN in the field
|
||||
template<class Addr>
|
||||
static bool hasUndef(const IndirectListBase<scalar, Addr>& field);
|
||||
static bool hasUndef(const IndirectListBase<float, Addr>& field);
|
||||
|
||||
//- Check for any NaN in the field
|
||||
template<class Addr>
|
||||
static bool hasUndef(const IndirectListBase<double, Addr>& field);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -28,9 +28,24 @@ License
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
template<class Addr>
|
||||
bool Foam::ensightFile::hasUndef(const IndirectListBase<scalar, Addr>& field)
|
||||
bool Foam::ensightFile::hasUndef(const IndirectListBase<float, Addr>& field)
|
||||
{
|
||||
for (const scalar val : field)
|
||||
for (const float val : field)
|
||||
{
|
||||
if (std::isnan(val))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<class Addr>
|
||||
bool Foam::ensightFile::hasUndef(const IndirectListBase<double, Addr>& field)
|
||||
{
|
||||
for (const double val : field)
|
||||
{
|
||||
if (std::isnan(val))
|
||||
{
|
||||
@ -56,9 +71,27 @@ void Foam::ensightFile::writeLabels(const IndirectListBase<label, Addr>& list)
|
||||
|
||||
|
||||
template<class Addr>
|
||||
void Foam::ensightFile::writeList(const IndirectListBase<scalar, Addr>& field)
|
||||
void Foam::ensightFile::writeList(const IndirectListBase<float, Addr>& field)
|
||||
{
|
||||
for (const scalar val : field)
|
||||
for (const float val : field)
|
||||
{
|
||||
if (std::isnan(val))
|
||||
{
|
||||
writeUndef();
|
||||
}
|
||||
else
|
||||
{
|
||||
write(val);
|
||||
}
|
||||
newline();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Addr>
|
||||
void Foam::ensightFile::writeList(const IndirectListBase<double, Addr>& field)
|
||||
{
|
||||
for (const double val : field)
|
||||
{
|
||||
if (std::isnan(val))
|
||||
{
|
||||
|
||||
@ -32,6 +32,23 @@ License
|
||||
#include "polyMesh.H"
|
||||
#include "ListOps.H"
|
||||
#include "manifoldCellsMeshObject.H"
|
||||
#include "debug.H"
|
||||
#include "defineDebugSwitch.H"
|
||||
#include "registerSwitch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Globals * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineDebugSwitchWithName(Foam::ensightOutput, "ensight", 0);
|
||||
|
||||
registerDebugSwitchWithName(Foam::ensightOutput, ensightOutput, "ensight");
|
||||
|
||||
int Foam::ensightOutput::maxChunk_
|
||||
(
|
||||
Foam::debug::optimisationSwitch("ensight.maxChunk", 0)
|
||||
);
|
||||
|
||||
registerOptSwitch("ensight.maxChunk", int, Foam::ensightOutput::maxChunk_);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -38,6 +38,7 @@ SourceFiles
|
||||
#ifndef Foam_ensightOutput_H
|
||||
#define Foam_ensightOutput_H
|
||||
|
||||
#include "ensightOutputFwd.H"
|
||||
#include "ensightFile.H"
|
||||
#include "ensightGeoFile.H"
|
||||
#include "ensightCells.H"
|
||||
@ -186,7 +187,8 @@ void writeFaceConnectivity
|
||||
const ensightFaces::elemType etype,
|
||||
const label nTotal,
|
||||
const UIndirectList<face>& faces,
|
||||
bool parallel //!< Collective write?
|
||||
//! Prefer collective write?
|
||||
bool parallel
|
||||
);
|
||||
|
||||
|
||||
@ -197,7 +199,8 @@ void writeFaceConnectivity
|
||||
const ensightFaces::elemType etype,
|
||||
const label nTotal,
|
||||
const faceUList& faces,
|
||||
bool parallel //!< Collective write?
|
||||
//! Prefer collective write?
|
||||
bool parallel
|
||||
);
|
||||
|
||||
|
||||
@ -207,7 +210,8 @@ void writeFaceConnectivity
|
||||
ensightGeoFile& os,
|
||||
const ensightFaces& part,
|
||||
const faceUList& faces,
|
||||
bool parallel //!< Collective write?
|
||||
//! Prefer collective write?
|
||||
bool parallel
|
||||
);
|
||||
|
||||
|
||||
@ -219,7 +223,8 @@ void writeFaceConnectivityPresorted
|
||||
ensightGeoFile& os,
|
||||
const ensightFaces& part,
|
||||
const faceUList& faces,
|
||||
bool parallel //!< Collective write?
|
||||
//! Prefer collective write?
|
||||
bool parallel
|
||||
);
|
||||
|
||||
|
||||
@ -232,10 +237,20 @@ void writeFaceConnectivityPresorted
|
||||
template<class Type>
|
||||
bool writeField
|
||||
(
|
||||
//! Component scratch buffer
|
||||
ensightOutput::floatBufferType& scratch,
|
||||
|
||||
//! Output file (must be valid on master)
|
||||
ensightFile& os,
|
||||
|
||||
//! The field content to be written
|
||||
const Field<Type>& fld,
|
||||
|
||||
//! The addressing (element-wise) into the field
|
||||
const ensightCells& part,
|
||||
bool parallel //!< Collective write?
|
||||
|
||||
//! Prefer collective write?
|
||||
bool parallel
|
||||
);
|
||||
|
||||
//- Write a field of faces values as an indirect list,
|
||||
@ -243,13 +258,69 @@ bool writeField
|
||||
template<class Type>
|
||||
bool writeField
|
||||
(
|
||||
//! Component scratch buffer
|
||||
ensightOutput::floatBufferType& scratch,
|
||||
|
||||
//! Output file (must be valid on master)
|
||||
ensightFile& os,
|
||||
|
||||
//! The field content to be written
|
||||
const Field<Type>& fld,
|
||||
|
||||
//! The addressing (element-wise) into the field
|
||||
const ensightFaces& part,
|
||||
bool parallel //!< Collective write?
|
||||
|
||||
//! Prefer collective write?
|
||||
bool parallel
|
||||
);
|
||||
|
||||
|
||||
//- Write a field of cell values as an indirect list,
|
||||
//- using the cell ids from ensightCells
|
||||
template<class Type>
|
||||
bool writeField
|
||||
(
|
||||
//! Output file (must be valid on master)
|
||||
ensightFile& os,
|
||||
|
||||
//! The field content to be written
|
||||
const Field<Type>& fld,
|
||||
|
||||
//! The addressing (element-wise) into the field
|
||||
const ensightCells& part,
|
||||
|
||||
//! Prefer collective write?
|
||||
bool parallel
|
||||
)
|
||||
{
|
||||
ensightOutput::floatBufferType scratch;
|
||||
return ensightOutput::writeField(scratch, os, fld, part, parallel);
|
||||
}
|
||||
|
||||
|
||||
//- Write a field of faces values as an indirect list,
|
||||
//- using the face ids from ensightFaces
|
||||
template<class Type>
|
||||
bool writeField
|
||||
(
|
||||
//! Output file (must be valid on master)
|
||||
ensightFile& os,
|
||||
|
||||
//! The field content to be written
|
||||
const Field<Type>& fld,
|
||||
|
||||
//! The addressing (element-wise) into the field
|
||||
const ensightFaces& part,
|
||||
|
||||
//! Prefer collective write?
|
||||
bool parallel
|
||||
)
|
||||
{
|
||||
ensightOutput::floatBufferType scratch;
|
||||
return ensightOutput::writeField(scratch, os, fld, part, parallel);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Namespace ensightOutput::Detail
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -302,48 +373,109 @@ void writeLabelListList
|
||||
);
|
||||
|
||||
|
||||
//- Copy specified field component into a scalar buffer
|
||||
//- works for various lists types. Must be adequately sized before calling
|
||||
//- Copy specified field component into a scalar buffer.
|
||||
//- Works for various lists types. Must be adequately sized before calling
|
||||
template<template<typename> class FieldContainer, class Type>
|
||||
void copyComponent
|
||||
(
|
||||
List<scalar>& cmptBuffer,
|
||||
//! Input field data
|
||||
const FieldContainer<Type>& input,
|
||||
const direction cmpt
|
||||
|
||||
//! Component to be extracted
|
||||
const direction cmpt,
|
||||
|
||||
//! [out] Component scratch buffer
|
||||
UList<float>& cmptBuffer
|
||||
);
|
||||
|
||||
|
||||
//- Write field content (component-wise)
|
||||
template<template<typename> class FieldContainer, class Type>
|
||||
void writeFieldContent
|
||||
(
|
||||
ensightFile& os,
|
||||
const FieldContainer<Type>& fld,
|
||||
bool parallel //!< Collective write?
|
||||
);
|
||||
|
||||
|
||||
//- Write coordinates (component-wise) for the given part
|
||||
//- Write coordinates (component-wise) for the given part.
|
||||
//
|
||||
// Has internal check for (nPoints != 0)
|
||||
template<template<typename> class FieldContainer>
|
||||
bool writeCoordinates
|
||||
(
|
||||
//! Output file (must be valid on master)
|
||||
ensightGeoFile& os,
|
||||
|
||||
//! The ensight part id
|
||||
const label partId,
|
||||
|
||||
//! The ensight part description
|
||||
const word& partName,
|
||||
|
||||
//! The total number of points
|
||||
const label nPoints,
|
||||
|
||||
//! The point field to be written
|
||||
const FieldContainer<Foam::point>& fld,
|
||||
bool parallel //!< Collective write?
|
||||
|
||||
//! Prefer collective write?
|
||||
bool parallel
|
||||
);
|
||||
|
||||
|
||||
//- Write field content (component-wise) for the given ensight element type
|
||||
//- Write field content (component-wise) for the given ensight element type.
|
||||
template<template<typename> class FieldContainer, class Type>
|
||||
bool writeFieldComponents
|
||||
void writeFieldComponents
|
||||
(
|
||||
//! Component scratch buffer
|
||||
ensightOutput::floatBufferType& scratch,
|
||||
|
||||
//! Output file (must be valid on master)
|
||||
ensightFile& os,
|
||||
|
||||
//! The ensight element type (ignored if nullptr)
|
||||
const char* key,
|
||||
|
||||
//! The field content to be written for this element type
|
||||
const FieldContainer<Type>& fld,
|
||||
bool parallel //!< Collective write?
|
||||
|
||||
//! Prefer collective write?
|
||||
bool parallel
|
||||
);
|
||||
|
||||
//- Write field content (component-wise) for the given ensight element type.
|
||||
template<template<typename> class FieldContainer, class Type>
|
||||
void writeFieldComponents
|
||||
(
|
||||
//! Output file (must be valid on master)
|
||||
ensightFile& os,
|
||||
|
||||
//! The ensight element type (can be nullptr)
|
||||
const char* key,
|
||||
|
||||
//! The field content to be written for this element type
|
||||
const FieldContainer<Type>& fld,
|
||||
|
||||
//!< Prefer collective write?
|
||||
bool parallel
|
||||
)
|
||||
{
|
||||
ensightOutput::floatBufferType scratch;
|
||||
Detail::writeFieldComponents(scratch, os, key, fld, parallel);
|
||||
}
|
||||
|
||||
|
||||
//- Write a sub-field of faces values as an indirect list,
|
||||
//- using the sub-list sizing information from ensightFaces
|
||||
template<class Type>
|
||||
bool writeFaceSubField
|
||||
(
|
||||
//! Component scratch buffer
|
||||
ensightOutput::floatBufferType& scratch,
|
||||
|
||||
//! Output file (must be valid on master)
|
||||
ensightFile& os,
|
||||
|
||||
//! The field content to be written
|
||||
const Field<Type>& fld,
|
||||
|
||||
//! The addressing (element-wise) into the field
|
||||
const ensightFaces& part,
|
||||
|
||||
//! Prefer collective write?
|
||||
bool parallel
|
||||
);
|
||||
|
||||
|
||||
@ -352,11 +484,22 @@ bool writeFieldComponents
|
||||
template<class Type>
|
||||
bool writeFaceSubField
|
||||
(
|
||||
//! Output file (must be valid on master)
|
||||
ensightFile& os,
|
||||
|
||||
//! The field content to be written
|
||||
const Field<Type>& fld,
|
||||
|
||||
//! The addressing (element-wise) into the field
|
||||
const ensightFaces& part,
|
||||
bool parallel //!< Collective write?
|
||||
);
|
||||
|
||||
//! Prefer collective write?
|
||||
bool parallel
|
||||
)
|
||||
{
|
||||
ensightOutput::floatBufferType scratch;
|
||||
return Detail::writeFaceSubField(scratch, os, fld, part, parallel);
|
||||
}
|
||||
|
||||
|
||||
//- Write a field of faces values as an indirect list,
|
||||
@ -364,12 +507,44 @@ bool writeFaceSubField
|
||||
template<class Type>
|
||||
bool writeFaceLocalField
|
||||
(
|
||||
//! Component scratch buffer
|
||||
ensightOutput::floatBufferType& scratch,
|
||||
|
||||
//! Output file (must be valid on master)
|
||||
ensightFile& os,
|
||||
|
||||
//! The field content to be written
|
||||
const Field<Type>& fld,
|
||||
|
||||
//! The addressing (element-wise) into the field
|
||||
const ensightFaces& part,
|
||||
bool parallel //!< Collective write?
|
||||
|
||||
//! Prefer collective write?
|
||||
bool parallel
|
||||
);
|
||||
|
||||
//- Write a field of faces values as an indirect list,
|
||||
//- using the face order from ensightFaces
|
||||
template<class Type>
|
||||
bool writeFaceLocalField
|
||||
(
|
||||
//! Output file (must be valid on master)
|
||||
ensightFile& os,
|
||||
|
||||
//! The field content to be written
|
||||
const Field<Type>& fld,
|
||||
|
||||
//! The addressing (element-wise) into the field
|
||||
const ensightFaces& part,
|
||||
|
||||
//! Prefer collective write?
|
||||
bool parallel
|
||||
)
|
||||
{
|
||||
ensightOutput::floatBufferType scratch;
|
||||
return Detail::writeFaceLocalField(scratch, os, fld, part, parallel);
|
||||
}
|
||||
|
||||
|
||||
} // End namespace Detail
|
||||
|
||||
|
||||
78
src/fileFormats/ensight/output/ensightOutputFwd.H
Normal file
78
src/fileFormats/ensight/output/ensightOutputFwd.H
Normal file
@ -0,0 +1,78 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Namespace
|
||||
Foam::ensightOutput
|
||||
|
||||
Description
|
||||
A collection of functions for writing ensight file content.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_ensightOutputFwd_H
|
||||
#define Foam_ensightOutputFwd_H
|
||||
|
||||
#include "DynamicList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class ensightFile;
|
||||
class ensightGeoFile;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Namespace ensightOutput
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
namespace ensightOutput
|
||||
{
|
||||
|
||||
//- The list type used for component-wise buffering.
|
||||
// Always has value_type = \c float (what ensight uses internally)
|
||||
typedef DynamicList<float> floatBufferType;
|
||||
|
||||
//- Static debugging option
|
||||
extern int debug;
|
||||
|
||||
//- Upper limit on number of items for bundled off-processor field transfers.
|
||||
//- The component-wise transfer uses float (4 bytes).
|
||||
// Eg, 5M for 50 ranks of 100k cells each
|
||||
extern int maxChunk_;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace ensightOutput
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -55,9 +55,9 @@ void Foam::ensightOutput::Detail::writeLabelListList
|
||||
template<template<typename> class FieldContainer, class Type>
|
||||
void Foam::ensightOutput::Detail::copyComponent
|
||||
(
|
||||
List<scalar>& cmptBuffer,
|
||||
const FieldContainer<Type>& input,
|
||||
const direction cmpt
|
||||
const direction cmpt,
|
||||
UList<float>& cmptBuffer
|
||||
)
|
||||
{
|
||||
if (cmptBuffer.size() < input.size())
|
||||
@ -70,78 +70,178 @@ void Foam::ensightOutput::Detail::copyComponent
|
||||
|
||||
auto iter = cmptBuffer.begin();
|
||||
|
||||
for (const Type& val : input)
|
||||
if (std::is_same<float, typename pTraits<Type>::cmptType>::value)
|
||||
{
|
||||
*iter = component(val, cmpt);
|
||||
++iter;
|
||||
// Direct copy
|
||||
for (const Type& val : input)
|
||||
{
|
||||
*iter = component(val, cmpt);
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy with narrowing
|
||||
for (const Type& val : input)
|
||||
{
|
||||
*iter = narrowFloat(component(val, cmpt));
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<template<typename> class FieldContainer, class Type>
|
||||
void Foam::ensightOutput::Detail::writeFieldContent
|
||||
void Foam::ensightOutput::Detail::writeFieldComponents
|
||||
(
|
||||
ensightOutput::floatBufferType& scratch,
|
||||
ensightFile& os,
|
||||
const char* key,
|
||||
const FieldContainer<Type>& fld,
|
||||
bool parallel
|
||||
)
|
||||
{
|
||||
// already checked prior to calling, but extra safety
|
||||
parallel = parallel && Pstream::parRun();
|
||||
|
||||
const label localSize = fld.size();
|
||||
|
||||
// Gather sizes (offsets irrelevant)
|
||||
const globalIndex procAddr
|
||||
(
|
||||
parallel
|
||||
? globalIndex(globalIndex::gatherOnly{}, fld.size())
|
||||
: globalIndex(globalIndex::gatherNone{}, fld.size())
|
||||
? globalIndex(globalIndex::gatherOnly{}, localSize)
|
||||
: globalIndex(globalIndex::gatherNone{}, localSize)
|
||||
);
|
||||
|
||||
if (Pstream::master() && key)
|
||||
{
|
||||
os.writeKeyword(key);
|
||||
}
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
DynamicList<scalar> cmptBuffer(procAddr.maxSize());
|
||||
// Buffer size needed for an individual rank
|
||||
const label minSize(max(localSize, procAddr.maxSize()));
|
||||
|
||||
// Buffer size needed for all nonLocal ranks
|
||||
const label nonLocalSize(procAddr.totalSize() - localSize);
|
||||
|
||||
// Maximum off-processor transfer size
|
||||
const label maxTransfer =
|
||||
(
|
||||
(ensightOutput::maxChunk_ > 0)
|
||||
? min(static_cast<label>(ensightOutput::maxChunk_), nonLocalSize)
|
||||
: static_cast<label>(0)
|
||||
);
|
||||
|
||||
// Allocate at least enough to process a single rank, but potentially
|
||||
// receive multiple ranks at a time before writing
|
||||
|
||||
scratch.resize_nocopy(max(minSize, maxTransfer));
|
||||
|
||||
if (Pstream::master() && debug > 1)
|
||||
{
|
||||
Info<< "ensight";
|
||||
if (key)
|
||||
{
|
||||
Info<< " (" << key << ')';
|
||||
}
|
||||
|
||||
Info<< " total-size:" << procAddr.totalSize()
|
||||
<< " buf-size:" << scratch.size() << "/" << scratch.capacity()
|
||||
<< " any-proc:" << minSize
|
||||
<< " off-proc:" << nonLocalSize << endl;
|
||||
|
||||
Info<< "proc-sends: (";
|
||||
|
||||
label nPending = localSize;
|
||||
|
||||
Info<< (localSize ? '0' : '_');
|
||||
|
||||
// Receive others, writing as needed
|
||||
for (const label proci : procAddr.subProcs())
|
||||
{
|
||||
const label procSize = procAddr.localSize(proci);
|
||||
|
||||
if (procSize)
|
||||
{
|
||||
if (nPending + procSize > scratch.size())
|
||||
{
|
||||
// Flush buffer
|
||||
nPending = 0;
|
||||
Info<< ") (";
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< ' ';
|
||||
}
|
||||
|
||||
Info<< proci;
|
||||
nPending += procSize;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< ')' << endl;
|
||||
}
|
||||
|
||||
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
|
||||
{
|
||||
const direction cmpt = ensightPTraits<Type>::componentOrder[d];
|
||||
|
||||
// Write master data
|
||||
cmptBuffer.resize_nocopy(procAddr.localSize(0));
|
||||
copyComponent(cmptBuffer, fld, cmpt);
|
||||
os.writeList(cmptBuffer);
|
||||
// Master
|
||||
copyComponent(fld, cmpt, scratch);
|
||||
label nPending = localSize;
|
||||
|
||||
// Receive and write
|
||||
// Receive others, writing as needed
|
||||
for (const label proci : procAddr.subProcs())
|
||||
{
|
||||
cmptBuffer.resize_nocopy(procAddr.localSize(proci));
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
cmptBuffer.data_bytes(),
|
||||
cmptBuffer.size_bytes()
|
||||
);
|
||||
os.writeList(cmptBuffer);
|
||||
const label procSize = procAddr.localSize(proci);
|
||||
|
||||
if (procSize)
|
||||
{
|
||||
if (nPending + procSize > scratch.size())
|
||||
{
|
||||
// Flush buffer
|
||||
os.writeList(SubList<float>(scratch, nPending));
|
||||
nPending = 0;
|
||||
}
|
||||
|
||||
SubList<float> slot(scratch, procSize, nPending);
|
||||
nPending += procSize;
|
||||
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
slot.data_bytes(),
|
||||
slot.size_bytes()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (nPending)
|
||||
{
|
||||
// Flush buffer
|
||||
os.writeList(SubList<float>(scratch, nPending));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (parallel)
|
||||
else if (parallel && localSize)
|
||||
{
|
||||
// Send
|
||||
List<scalar> cmptBuffer(fld.size());
|
||||
scratch.resize_nocopy(localSize);
|
||||
|
||||
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
|
||||
{
|
||||
const direction cmpt = ensightPTraits<Type>::componentOrder[d];
|
||||
|
||||
copyComponent(cmptBuffer, fld, cmpt);
|
||||
copyComponent(fld, cmpt, scratch);
|
||||
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
cmptBuffer.cdata_bytes(),
|
||||
cmptBuffer.size_bytes()
|
||||
scratch.cdata_bytes(),
|
||||
scratch.size_bytes()
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -159,45 +259,31 @@ bool Foam::ensightOutput::Detail::writeCoordinates
|
||||
bool parallel
|
||||
)
|
||||
{
|
||||
parallel = parallel && Pstream::parRun();
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
os.beginPart(partId, partName);
|
||||
os.beginCoordinates(nPoints);
|
||||
}
|
||||
|
||||
ensightOutput::Detail::writeFieldContent(os, fld, parallel);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<template<typename> class FieldContainer, class Type>
|
||||
bool Foam::ensightOutput::Detail::writeFieldComponents
|
||||
(
|
||||
ensightFile& os,
|
||||
const char* key,
|
||||
const FieldContainer<Type>& fld,
|
||||
bool parallel
|
||||
)
|
||||
{
|
||||
parallel = parallel && Pstream::parRun();
|
||||
|
||||
// Preliminary checks
|
||||
bool ok = (Pstream::master() && (nPoints > 0));
|
||||
if (parallel)
|
||||
{
|
||||
// No field
|
||||
if (parallel ? returnReduceAnd(fld.empty()) : fld.empty()) return false;
|
||||
Pstream::broadcast(ok);
|
||||
}
|
||||
|
||||
|
||||
if (Pstream::master())
|
||||
if (ok)
|
||||
{
|
||||
os.writeKeyword(key);
|
||||
ensightOutput::floatBufferType scratch;
|
||||
ensightOutput::Detail::writeFieldComponents
|
||||
(
|
||||
scratch,
|
||||
os,
|
||||
nullptr, // (no element type)
|
||||
fld,
|
||||
parallel
|
||||
);
|
||||
}
|
||||
|
||||
ensightOutput::Detail::writeFieldContent(os, fld, parallel);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -205,6 +291,7 @@ bool Foam::ensightOutput::Detail::writeFieldComponents
|
||||
template<class Type>
|
||||
bool Foam::ensightOutput::Detail::writeFaceSubField
|
||||
(
|
||||
ensightOutput::floatBufferType& scratch,
|
||||
ensightFile& os,
|
||||
const Field<Type>& fld,
|
||||
const ensightFaces& part,
|
||||
@ -213,13 +300,17 @@ bool Foam::ensightOutput::Detail::writeFaceSubField
|
||||
{
|
||||
parallel = parallel && Pstream::parRun();
|
||||
|
||||
// Preliminary checks: total() contains pre-reduced information
|
||||
{
|
||||
// No geometry
|
||||
if (parallel ? !part.total() : !part.size()) return false;
|
||||
// Need geometry and field. part.total() is already reduced
|
||||
const bool good =
|
||||
(
|
||||
parallel
|
||||
? (part.total() && returnReduceOr(fld.size()))
|
||||
: (part.size() && fld.size())
|
||||
);
|
||||
|
||||
// No field
|
||||
if (parallel ? returnReduceAnd(fld.empty()) : fld.empty()) return false;
|
||||
if (!good)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -232,13 +323,18 @@ bool Foam::ensightOutput::Detail::writeFaceSubField
|
||||
{
|
||||
const auto etype = ensightFaces::elemType(typei);
|
||||
|
||||
ensightOutput::Detail::writeFieldComponents
|
||||
(
|
||||
os,
|
||||
ensightFaces::key(etype),
|
||||
SubField<Type>(fld, part.range(etype)),
|
||||
parallel
|
||||
);
|
||||
// Write elements of this type
|
||||
if (parallel ? part.total(etype) : part.size(etype))
|
||||
{
|
||||
ensightOutput::Detail::writeFieldComponents
|
||||
(
|
||||
scratch,
|
||||
os,
|
||||
ensightFaces::key(etype),
|
||||
SubField<Type>(fld, part.range(etype)),
|
||||
parallel
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -248,6 +344,7 @@ bool Foam::ensightOutput::Detail::writeFaceSubField
|
||||
template<class Type>
|
||||
bool Foam::ensightOutput::Detail::writeFaceLocalField
|
||||
(
|
||||
ensightOutput::floatBufferType& scratch,
|
||||
ensightFile& os,
|
||||
const Field<Type>& fld,
|
||||
const ensightFaces& part,
|
||||
@ -256,15 +353,20 @@ bool Foam::ensightOutput::Detail::writeFaceLocalField
|
||||
{
|
||||
parallel = parallel && Pstream::parRun();
|
||||
|
||||
// Preliminary checks: total() contains pre-reduced information
|
||||
{
|
||||
// No geometry
|
||||
if (parallel ? !part.total() : !part.size()) return false;
|
||||
// Need geometry and field. part.total() is already reduced
|
||||
const bool good =
|
||||
(
|
||||
parallel
|
||||
? (part.total() && returnReduceOr(fld.size()))
|
||||
: (part.size() && fld.size())
|
||||
);
|
||||
|
||||
// No field
|
||||
if (parallel ? returnReduceAnd(fld.empty()) : fld.empty()) return false;
|
||||
if (!good)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool validAddressing = (part.size() == part.faceOrder().size());
|
||||
|
||||
if (parallel)
|
||||
@ -289,13 +391,18 @@ bool Foam::ensightOutput::Detail::writeFaceLocalField
|
||||
{
|
||||
const auto etype = ensightFaces::elemType(typei);
|
||||
|
||||
ensightOutput::Detail::writeFieldComponents
|
||||
(
|
||||
os,
|
||||
ensightFaces::key(etype),
|
||||
UIndirectList<Type>(fld, part.faceOrder(etype)),
|
||||
parallel
|
||||
);
|
||||
// Write elements of this type
|
||||
if (parallel ? part.total(etype) : part.size(etype))
|
||||
{
|
||||
ensightOutput::Detail::writeFieldComponents
|
||||
(
|
||||
scratch,
|
||||
os,
|
||||
ensightFaces::key(etype),
|
||||
UIndirectList<Type>(fld, part.faceOrder(etype)),
|
||||
parallel
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -307,6 +414,7 @@ bool Foam::ensightOutput::Detail::writeFaceLocalField
|
||||
template<class Type>
|
||||
bool Foam::ensightOutput::writeField
|
||||
(
|
||||
ensightOutput::floatBufferType& scratch,
|
||||
ensightFile& os,
|
||||
const Field<Type>& fld,
|
||||
const ensightCells& part,
|
||||
@ -315,13 +423,17 @@ bool Foam::ensightOutput::writeField
|
||||
{
|
||||
parallel = parallel && Pstream::parRun();
|
||||
|
||||
// Preliminary checks: total() contains pre-reduced information
|
||||
{
|
||||
// No geometry
|
||||
if (parallel ? !part.total() : !part.size()) return false;
|
||||
// Need geometry and field. part.total() is already reduced
|
||||
const bool good =
|
||||
(
|
||||
parallel
|
||||
? (part.total() && returnReduceOr(fld.size()))
|
||||
: (part.size() && fld.size())
|
||||
);
|
||||
|
||||
// No field
|
||||
if (parallel ? returnReduceAnd(fld.empty()) : fld.empty()) return false;
|
||||
if (!good)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -334,13 +446,18 @@ bool Foam::ensightOutput::writeField
|
||||
{
|
||||
const auto etype = ensightCells::elemType(typei);
|
||||
|
||||
ensightOutput::Detail::writeFieldComponents
|
||||
(
|
||||
os,
|
||||
ensightCells::key(etype),
|
||||
UIndirectList<Type>(fld, part.cellIds(etype)),
|
||||
parallel
|
||||
);
|
||||
// Write elements of this type
|
||||
if (parallel ? part.total(etype) : part.size(etype))
|
||||
{
|
||||
ensightOutput::Detail::writeFieldComponents
|
||||
(
|
||||
scratch,
|
||||
os,
|
||||
ensightCells::key(etype),
|
||||
UIndirectList<Type>(fld, part.cellIds(etype)),
|
||||
parallel
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -350,6 +467,7 @@ bool Foam::ensightOutput::writeField
|
||||
template<class Type>
|
||||
bool Foam::ensightOutput::writeField
|
||||
(
|
||||
ensightOutput::floatBufferType& scratch,
|
||||
ensightFile& os,
|
||||
const Field<Type>& fld,
|
||||
const ensightFaces& part,
|
||||
@ -358,13 +476,17 @@ bool Foam::ensightOutput::writeField
|
||||
{
|
||||
parallel = parallel && Pstream::parRun();
|
||||
|
||||
// Preliminary checks: total() contains pre-reduced information
|
||||
{
|
||||
// No geometry
|
||||
if (parallel ? !part.total() : !part.size()) return false;
|
||||
// Need geometry and field. part.total() is already reduced
|
||||
const bool good =
|
||||
(
|
||||
parallel
|
||||
? (part.total() && returnReduceOr(fld.size()))
|
||||
: (part.size() && fld.size())
|
||||
);
|
||||
|
||||
// No field
|
||||
if (parallel ? returnReduceAnd(fld.empty()) : fld.empty()) return false;
|
||||
if (!good)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -377,13 +499,18 @@ bool Foam::ensightOutput::writeField
|
||||
{
|
||||
const auto etype = ensightFaces::elemType(typei);
|
||||
|
||||
ensightOutput::Detail::writeFieldComponents
|
||||
(
|
||||
os,
|
||||
ensightFaces::key(etype),
|
||||
UIndirectList<Type>(fld, part.faceIds(etype)),
|
||||
parallel
|
||||
);
|
||||
// Write elements of this type
|
||||
if (parallel ? part.total(etype) : part.size(etype))
|
||||
{
|
||||
ensightOutput::Detail::writeFieldComponents
|
||||
(
|
||||
scratch,
|
||||
os,
|
||||
ensightFaces::key(etype),
|
||||
UIndirectList<Type>(fld, part.faceIds(etype)),
|
||||
parallel
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@ -99,7 +99,7 @@ Foam::FixedList<Foam::label, 5> Foam::ensightCells::sizes() const
|
||||
{
|
||||
FixedList<label, 5> count;
|
||||
|
||||
forAll(count, typei)
|
||||
for (int typei = 0; typei < nTypes; ++typei)
|
||||
{
|
||||
count[typei] = size(elemType(typei));
|
||||
}
|
||||
@ -108,14 +108,14 @@ Foam::FixedList<Foam::label, 5> Foam::ensightCells::sizes() const
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::ensightCells::total() const
|
||||
Foam::label Foam::ensightCells::totalSize() const noexcept
|
||||
{
|
||||
label nTotal = 0;
|
||||
forAll(sizes_, typei)
|
||||
label count = 0;
|
||||
for (label n : sizes_)
|
||||
{
|
||||
nTotal += sizes_[typei];
|
||||
count += n;
|
||||
}
|
||||
return nTotal;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@ -137,11 +137,10 @@ void Foam::ensightCells::clearOut()
|
||||
|
||||
void Foam::ensightCells::reduce()
|
||||
{
|
||||
forAll(sizes_, typei)
|
||||
for (int typei = 0; typei < nTypes; ++typei)
|
||||
{
|
||||
sizes_[typei] = size(elemType(typei));
|
||||
}
|
||||
// Can reduce FixedList with sumOp<label> in a single operation
|
||||
Foam::reduce(sizes_, sumOp<label>());
|
||||
}
|
||||
|
||||
|
||||
@ -82,7 +82,7 @@ public:
|
||||
// Static Functions
|
||||
|
||||
//- The ensight element name for the specified 'Cell' type
|
||||
inline static const char* key(const elemType etype);
|
||||
inline static const char* key(const elemType etype) noexcept;
|
||||
|
||||
|
||||
private:
|
||||
@ -183,7 +183,10 @@ public:
|
||||
|
||||
//- The global size of all element types.
|
||||
// This value is only meaningful after a reduce operation.
|
||||
label total() const;
|
||||
label totalSize() const noexcept;
|
||||
|
||||
//- Same as totalSize()
|
||||
label total() const noexcept { return totalSize(); }
|
||||
|
||||
//- The global size of the specified element type.
|
||||
// This value is only meaningful after a reduce operation.
|
||||
|
||||
@ -46,7 +46,7 @@ inline bool Foam::ensightCells::manifold() const noexcept
|
||||
}
|
||||
|
||||
|
||||
inline const char* Foam::ensightCells::key(const elemType etype)
|
||||
inline const char* Foam::ensightCells::key(const elemType etype) noexcept
|
||||
{
|
||||
return elemNames[etype];
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -124,7 +124,7 @@ Foam::FixedList<Foam::label, 3> Foam::ensightFaces::sizes() const
|
||||
{
|
||||
FixedList<label, 3> count;
|
||||
|
||||
forAll(count, typei)
|
||||
for (int typei = 0; typei < nTypes; ++typei)
|
||||
{
|
||||
count[typei] = size(elemType(typei));
|
||||
}
|
||||
@ -133,14 +133,14 @@ Foam::FixedList<Foam::label, 3> Foam::ensightFaces::sizes() const
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::ensightFaces::total() const
|
||||
Foam::label Foam::ensightFaces::totalSize() const noexcept
|
||||
{
|
||||
label nTotal = 0;
|
||||
forAll(sizes_, typei)
|
||||
label count = 0;
|
||||
for (label n : sizes_)
|
||||
{
|
||||
nTotal += sizes_[typei];
|
||||
count += n;
|
||||
}
|
||||
return nTotal;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@ -163,11 +163,10 @@ void Foam::ensightFaces::clearOut()
|
||||
|
||||
void Foam::ensightFaces::reduce()
|
||||
{
|
||||
forAll(sizes_, typei)
|
||||
for (int typei = 0; typei < nTypes; ++typei)
|
||||
{
|
||||
sizes_[typei] = size(elemType(typei));
|
||||
}
|
||||
// Can reduce FixedList with sumOp<label> in a single operation
|
||||
Foam::reduce(sizes_, sumOp<label>());
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -97,7 +97,7 @@ public:
|
||||
// Static Functions
|
||||
|
||||
//- The ensight element name for the specified 'Face' type
|
||||
static inline const char* key(const elemType etype);
|
||||
static inline const char* key(const elemType etype) noexcept;
|
||||
|
||||
|
||||
private:
|
||||
@ -162,7 +162,10 @@ public:
|
||||
|
||||
//- The global size of all element types.
|
||||
// This value is only meaningful after a reduce operation.
|
||||
label total() const;
|
||||
label totalSize() const noexcept;
|
||||
|
||||
//- Same as totalSize
|
||||
label total() const noexcept { return totalSize(); }
|
||||
|
||||
//- The global size of the specified element type.
|
||||
// This value is only meaningful after a reduce operation.
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -46,7 +46,7 @@ Foam::ensightFaces::add(const elemType etype, label id, bool flip)
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline const char* Foam::ensightFaces::key(const elemType etype)
|
||||
inline const char* Foam::ensightFaces::key(const elemType etype) noexcept
|
||||
{
|
||||
return elemNames[etype];
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013-2015 OpenFOAM Foundation
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -41,11 +41,20 @@ Foam::ensightPTraits<Foam::label>::componentOrder[] = {0};
|
||||
|
||||
template<>
|
||||
const char* const
|
||||
Foam::ensightPTraits<Foam::scalar>::typeName = "scalar";
|
||||
Foam::ensightPTraits<float>::typeName = "scalar";
|
||||
|
||||
template<>
|
||||
const Foam::direction
|
||||
Foam::ensightPTraits<Foam::scalar>::componentOrder[] = {0};
|
||||
Foam::ensightPTraits<float>::componentOrder[] = {0};
|
||||
|
||||
|
||||
template<>
|
||||
const char* const
|
||||
Foam::ensightPTraits<double>::typeName = "scalar";
|
||||
|
||||
template<>
|
||||
const Foam::direction
|
||||
Foam::ensightPTraits<double>::componentOrder[] = {0};
|
||||
|
||||
|
||||
template<>
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013-2015 OpenFOAM Foundation
|
||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -47,7 +47,7 @@ namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class ensightPTraits Declaration
|
||||
Class ensightPTraits Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Type>
|
||||
@ -69,8 +69,11 @@ struct ensightPTraits
|
||||
template<> const char* const ensightPTraits<label>::typeName;
|
||||
template<> const direction ensightPTraits<label>::componentOrder[];
|
||||
|
||||
template<> const char* const ensightPTraits<scalar>::typeName;
|
||||
template<> const direction ensightPTraits<scalar>::componentOrder[];
|
||||
template<> const char* const ensightPTraits<float>::typeName;
|
||||
template<> const direction ensightPTraits<float>::componentOrder[];
|
||||
|
||||
template<> const char* const ensightPTraits<double>::typeName;
|
||||
template<> const direction ensightPTraits<double>::componentOrder[];
|
||||
|
||||
template<> const char* const ensightPTraits<vector>::typeName;
|
||||
template<> const direction ensightPTraits<vector>::componentOrder[];
|
||||
|
||||
@ -130,7 +130,7 @@ void Foam::vtk::writeListParallel
|
||||
)
|
||||
{
|
||||
// Gather sizes (offsets irrelevant)
|
||||
const globalIndex procAddr(values.size(), globalIndex::gatherOnly{});
|
||||
const globalIndex procAddr(globalIndex::gatherOnly{}, values.size());
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
@ -146,33 +146,40 @@ void Foam::vtk::writeListParallel
|
||||
|
||||
for (const label proci : procAddr.subProcs())
|
||||
{
|
||||
recvData.resize_nocopy(procAddr.localSize(proci));
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
const label procSize = procAddr.localSize(proci);
|
||||
|
||||
// With value offset
|
||||
const label offsetId = procOffset.localStart(proci);
|
||||
for (const label val : recvData)
|
||||
if (procSize)
|
||||
{
|
||||
vtk::write(fmt, val + offsetId);
|
||||
recvData.resize_nocopy(procSize);
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
|
||||
// With value offset
|
||||
const label offsetId = procOffset.localStart(proci);
|
||||
for (const label val : recvData)
|
||||
{
|
||||
vtk::write(fmt, val + offsetId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
values.cdata_bytes(),
|
||||
values.size_bytes()
|
||||
);
|
||||
if (values.size())
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
values.cdata_bytes(),
|
||||
values.size_bytes()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -171,7 +171,7 @@ void Foam::vtk::writeListParallel
|
||||
|
||||
|
||||
// Gather sizes (offsets irrelevant)
|
||||
const globalIndex procAddr(values.size(), globalIndex::gatherOnly{});
|
||||
const globalIndex procAddr(globalIndex::gatherOnly{}, values.size());
|
||||
|
||||
|
||||
if (Pstream::master())
|
||||
@ -184,27 +184,34 @@ void Foam::vtk::writeListParallel
|
||||
|
||||
for (const label proci : procAddr.subProcs())
|
||||
{
|
||||
recvData.resize_nocopy(procAddr.localSize(proci));
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
vtk::writeList(fmt, recvData);
|
||||
const label procSize = procAddr.localSize(proci);
|
||||
|
||||
if (procSize)
|
||||
{
|
||||
recvData.resize_nocopy(procSize);
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
vtk::writeList(fmt, recvData);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
values.cdata_bytes(),
|
||||
values.size_bytes()
|
||||
);
|
||||
if (values.size())
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
values.cdata_bytes(),
|
||||
values.size_bytes()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,7 +240,7 @@ void Foam::vtk::writeListParallel
|
||||
}
|
||||
|
||||
// Gather sizes (offsets irrelevant)
|
||||
const globalIndex procAddr(sendData.size(), globalIndex::gatherOnly{});
|
||||
const globalIndex procAddr(globalIndex::gatherOnly{}, sendData.size());
|
||||
|
||||
|
||||
if (Pstream::master())
|
||||
@ -246,26 +253,34 @@ void Foam::vtk::writeListParallel
|
||||
|
||||
for (const label proci : procAddr.subProcs())
|
||||
{
|
||||
recvData.resize_nocopy(procAddr.localSize(proci));
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
vtk::writeList(fmt, recvData);
|
||||
const label procSize = procAddr.localSize(proci);
|
||||
|
||||
if (procSize)
|
||||
{
|
||||
recvData.resize_nocopy(procSize);
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
vtk::writeList(fmt, recvData);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
sendData.cdata_bytes(),
|
||||
sendData.size_bytes()
|
||||
);
|
||||
if (sendData.size())
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
sendData.cdata_bytes(),
|
||||
sendData.size_bytes()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,7 +309,7 @@ void Foam::vtk::writeListParallel
|
||||
}
|
||||
|
||||
// Gather sizes (offsets irrelevant)
|
||||
const globalIndex procAddr(sendData.size(), globalIndex::gatherOnly{});
|
||||
const globalIndex procAddr(globalIndex::gatherOnly{}, sendData.size());
|
||||
|
||||
|
||||
if (Pstream::master())
|
||||
@ -307,26 +322,35 @@ void Foam::vtk::writeListParallel
|
||||
|
||||
for (const label proci : procAddr.subProcs())
|
||||
{
|
||||
recvData.resize_nocopy(procAddr.localSize(proci));
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
vtk::writeList(fmt, recvData);
|
||||
const label procSize = procAddr.localSize(proci);
|
||||
|
||||
if (procSize)
|
||||
{
|
||||
recvData.resize_nocopy(procSize);
|
||||
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
vtk::writeList(fmt, recvData);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
sendData.cdata_bytes(),
|
||||
sendData.size_bytes()
|
||||
);
|
||||
if (sendData.size())
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
sendData.cdata_bytes(),
|
||||
sendData.size_bytes()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -349,8 +373,8 @@ void Foam::vtk::writeListsParallel
|
||||
|
||||
|
||||
// Gather sizes (offsets irrelevant)
|
||||
const globalIndex procAddr1(values1.size(), globalIndex::gatherOnly{});
|
||||
const globalIndex procAddr2(values2.size(), globalIndex::gatherOnly{});
|
||||
const globalIndex procAddr1(globalIndex::gatherOnly{}, values1.size());
|
||||
const globalIndex procAddr2(globalIndex::gatherOnly{}, values2.size());
|
||||
|
||||
|
||||
if (Pstream::master())
|
||||
@ -368,45 +392,61 @@ void Foam::vtk::writeListsParallel
|
||||
for (const label proci : procAddr1.subProcs())
|
||||
{
|
||||
// values1
|
||||
recvData.resize_nocopy(procAddr1.localSize(proci));
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
vtk::writeList(fmt, recvData);
|
||||
label procSize = procAddr1.localSize(proci);
|
||||
|
||||
if (procSize)
|
||||
{
|
||||
recvData.resize_nocopy(procSize);
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
vtk::writeList(fmt, recvData);
|
||||
}
|
||||
|
||||
// values2
|
||||
recvData.resize_nocopy(procAddr2.localSize(proci));
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
vtk::writeList(fmt, recvData);
|
||||
procSize = procAddr2.localSize(proci);
|
||||
|
||||
if (procSize)
|
||||
{
|
||||
recvData.resize_nocopy(procSize);
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
vtk::writeList(fmt, recvData);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
values1.cdata_bytes(),
|
||||
values1.size_bytes()
|
||||
);
|
||||
if (values1.size())
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
values1.cdata_bytes(),
|
||||
values1.size_bytes()
|
||||
);
|
||||
}
|
||||
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
values2.cdata_bytes(),
|
||||
values2.size_bytes()
|
||||
);
|
||||
if (values2.size())
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
values2.cdata_bytes(),
|
||||
values2.size_bytes()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -437,8 +477,8 @@ void Foam::vtk::writeListsParallel
|
||||
|
||||
|
||||
// Gather sizes (offsets irrelevant)
|
||||
const globalIndex procAddr1(values1.size(), globalIndex::gatherOnly{});
|
||||
const globalIndex procAddr2(sendData2.size(), globalIndex::gatherOnly{});
|
||||
const globalIndex procAddr1(globalIndex::gatherOnly{}, values1.size());
|
||||
const globalIndex procAddr2(globalIndex::gatherOnly{}, sendData2.size());
|
||||
|
||||
|
||||
if (Pstream::master())
|
||||
@ -457,45 +497,61 @@ void Foam::vtk::writeListsParallel
|
||||
for (const label proci : procAddr1.subProcs())
|
||||
{
|
||||
// values1
|
||||
recvData.resize_nocopy(procAddr1.localSize(proci));
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
vtk::writeList(fmt, recvData);
|
||||
label procSize = procAddr1.localSize(proci);
|
||||
|
||||
if (procSize)
|
||||
{
|
||||
recvData.resize_nocopy(procSize);
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
vtk::writeList(fmt, recvData);
|
||||
}
|
||||
|
||||
// values2
|
||||
recvData.resize_nocopy(procAddr2.localSize(proci));
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
vtk::writeList(fmt, recvData);
|
||||
procSize = procAddr2.localSize(proci);
|
||||
|
||||
if (procSize)
|
||||
{
|
||||
recvData.resize_nocopy(procSize);
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
recvData.data_bytes(),
|
||||
recvData.size_bytes()
|
||||
);
|
||||
vtk::writeList(fmt, recvData);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
values1.cdata_bytes(),
|
||||
values1.size_bytes()
|
||||
);
|
||||
if (values1.size())
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
values1.cdata_bytes(),
|
||||
values1.size_bytes()
|
||||
);
|
||||
}
|
||||
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
sendData2.cdata_bytes(),
|
||||
sendData2.size_bytes()
|
||||
);
|
||||
if (sendData2.size())
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
UPstream::masterNo(),
|
||||
sendData2.cdata_bytes(),
|
||||
sendData2.size_bytes()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user