Commit 3dd1a13b authored by Mark Olesen's avatar Mark Olesen

ENH: restructuring of ensight output files

- changed ensightOutput from a class solely comprising static methods to
  a namespace and added in sub-namespaces Detail and Serial.

  This makes it easier to "mix-in" functions at different levels.
  Refactored and combined some serial/parallel code where possible.

  The general ensightOutput namespace has now shifted to be in the
  fileFormats lib, while leaving volField outputs in the conversion lib
  and cloud outputs in the lagrangian-intermediate lib.

  The ensightCloud namespace is now simply folded into the new
  ensightOutput namespace.

  These changes clean up some code, reduce fragmentation and
  duplication and removes the previous libconversion dependency for
  sampling.

- use int for ensight nTypes constexpr

Note: issue #1176 is unaffected except for the change in file name:

   ensightOutputTemplates.C -> ensightOutputVolFieldTemplates.C
parent 9042bc2b
......@@ -56,7 +56,7 @@ if (doLagrangian)
{
autoPtr<ensightFile> os = ensCase.newCloud(cloudName);
ensightCloud::writePositions
ensightOutput::writeCloudPositions
(
mesh,
cloudName,
......@@ -104,7 +104,7 @@ if (doLagrangian)
autoPtr<ensightFile> os =
ensCase.newCloudData<scalar>(cloudName, fieldName);
wrote = ensightCloud::writeCloudField<scalar>
wrote = ensightOutput::writeCloudField<scalar>
(
fieldObject, fieldExists, os
);
......@@ -114,7 +114,7 @@ if (doLagrangian)
autoPtr<ensightFile> os =
ensCase.newCloudData<vector>(cloudName, fieldName);
wrote = ensightCloud::writeCloudField<vector>
wrote = ensightOutput::writeCloudField<vector>
(
fieldObject, fieldExists, os
);
......
......@@ -99,8 +99,8 @@ Note
#include "ensightCase.H"
#include "ensightGeoFile.H"
#include "ensightMesh.H"
#include "ensightOutput.H"
#include "ensightOutputCloud.H"
#include "ensightOutputVolField.H"
#include "fvMeshSubsetProxy.H"
// local files
......
......@@ -62,11 +62,11 @@ bool writeVolField
autoPtr<ensightFile> os = ensCase.newData<Type>(field.name());
bool wrote = ensightOutput::writeField<Type>
bool wrote = ensightOutput::writeVolField<Type>
(
field,
ensMesh,
os,
os.ref(),
nodeValues
);
......
......@@ -55,7 +55,7 @@ if (doLagrangian)
{
autoPtr<ensightFile> os = ensCase.newCloud(cloudName);
ensightCloud::writePositions
ensightOutput::writeCloudPositions
(
mesh,
cloudName,
......@@ -103,7 +103,7 @@ if (doLagrangian)
autoPtr<ensightFile> os =
ensCase.newCloudData<scalar>(cloudName, fieldName);
wrote = ensightCloud::writeCloudField<scalar>
wrote = ensightOutput::writeCloudField<scalar>
(
fieldObject, fieldExists, os
);
......@@ -113,7 +113,7 @@ if (doLagrangian)
autoPtr<ensightFile> os =
ensCase.newCloudData<vector>(cloudName, fieldName);
wrote = ensightCloud::writeCloudField<vector>
wrote = ensightOutput::writeCloudField<vector>
(
fieldObject, fieldExists, os
);
......
......@@ -94,8 +94,8 @@ Note
#include "ensightCase.H"
#include "ensightGeoFile.H"
#include "ensightParts.H"
#include "ensightSerialOutput.H"
#include "ensightOutputCloud.H"
#include "ensightOutputVolField.H"
#include "fvMeshSubsetProxy.H"
// local files
......
......@@ -61,11 +61,12 @@ bool writeVolField
autoPtr<ensightFile> os = ensCase.newData<Type>(field.name());
bool wrote = ensightSerialOutput::writeField<Type>
// Currently serial only
bool wrote = ensightOutput::Serial::writeVolField<Type>
(
field,
ensParts,
os
os.ref()
);
tfield.clear();
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -21,25 +21,22 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::ensightSerialOutput
InNamespace
Foam::ensightOutput
Description
A collection of functions for writing ensight file content in serial.
Can be considered transitional and may eventually merge with ensightOutput.
SourceFiles
ensightSerialOutputTemplates.C
A collection of functions for writing volField content in ensight format.
\*---------------------------------------------------------------------------*/
#ifndef ensightSerialOutput_H
#define ensightSerialOutput_H
#ifndef ensightOutputVolField_H
#define ensightOutputVolField_H
#include "ensightOutput.H"
#include "ensightPart.H"
#include "ensightParts.H"
#include "ensightPartFaces.H"
#include "ensightPartCells.H"
#include "ensightParts.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -47,98 +44,103 @@ SourceFiles
namespace Foam
{
// Forward declarations
class ensightMesh;
namespace ensightOutput
{
/*---------------------------------------------------------------------------*\
Namespace ensightOutput::Detail
\*---------------------------------------------------------------------------*/
namespace Detail
{
//- Write volume field component-wise
template<class Type>
bool writeVolField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightMesh& ensMesh,
ensightFile& os
);
//- Write point field component-wise
template<class Type>
bool writePointField
(
const GeometricField<Type, pointPatchField, pointMesh>& pf,
const ensightMesh& ensMesh,
ensightFile& os
);
} // End namespace Detail
/*---------------------------------------------------------------------------*\
Namespace ensightOutput
\*---------------------------------------------------------------------------*/
//- Write volume field component-wise
template<class Type>
bool writeVolField
(
const GeometricField<Type, fvPatchField, volMesh>&,
const ensightMesh& ensMesh,
ensightFile& os,
const bool nodeValues = false
);
/*---------------------------------------------------------------------------*\
Class ensightSerialOutput Declaration
Namespace ensightOutput::Serial
\*---------------------------------------------------------------------------*/
class ensightSerialOutput
namespace Serial
{
// Private Methods
//- Write field content (component-wise) for the given ensight element type
template<template<typename> class FieldContainer, class Type>
static void writeFieldContent
(
const word& key,
const FieldContainer<Type>& fld,
ensightFile& os
);
//- No null constructor
ensightSerialOutput() = delete;
public:
// Public Methods
//- Write field component-wise
template<class Type>
static bool writeField
(
const Field<Type>&,
const ensightPartFaces& part,
ensightFile& os,
const bool nodeValues
);
//- Write volume field component-wise
template<class Type>
static bool writeField
(
const GeometricField<Type, fvPatchField, volMesh>&,
const ensightPartCells& part,
ensightFile& os
);
//- Write volume field component-wise
template<class Type>
static bool writeField
(
const GeometricField<Type, fvPatchField, volMesh>&,
const ensightParts& list,
ensightFile& os
);
//- Write volume field component-wise
template<class Type>
static inline bool writeField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightPartCells& part,
autoPtr<ensightFile>& output
)
{
return writeField(vf, part, output.ref());
}
//- Write volume field component-wise
template<class Type>
static inline bool writeField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightParts& list,
autoPtr<ensightFile>& output
)
{
return writeField(vf, list, output.ref());
}
};
//- Write volume field component-wise for specified faces
template<class Type>
bool writeVolField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightPartFaces& part,
ensightFile& os
);
//- Write volume field component-wise for specified cells
template<class Type>
bool writeVolField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightPartCells& part,
ensightFile& os
);
//- Write volume field component-wise
template<class Type>
bool writeVolField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightParts& list,
ensightFile& os
);
} // End namespace Serial
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace ensightOutput
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightSerialOutputTemplates.C"
#include "ensightOutputVolFieldTemplates.C"
#endif
#endif
......
......@@ -23,191 +23,29 @@ License
\*---------------------------------------------------------------------------*/
#include "ensightFile.H"
#include "ensightOutput.H"
#include "ensightPTraits.H"
#include "ensightOutputVolField.H"
#include "ensightMesh.H"
#include "fvMesh.H"
#include "volFields.H"
#include "IOField.H"
#include "OFstream.H"
#include "IOmanip.H"
#include "Time.H"
#include "volPointInterpolation.H"
#include "globalIndex.H"
#include "uindirectPrimitivePatch.H"
#include "volPointInterpolation.H"
#include "interpolation.H"
#include "linear.H"
#include "processorFvPatch.H"
#include "uindirectPrimitivePatch.H"
// * * * * * * * * * * Static Private Member Functions * * * * * * * * * * * //
template<template<typename> class FieldContainer, class Type>
void Foam::ensightOutput::writeFieldContent
(
const char* key,
const FieldContainer<Type>& fld,
ensightFile& os
)
{
if (returnReduce(fld.size(), sumOp<label>()) > 0)
{
if (Pstream::master())
{
os.writeKeyword(key);
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
const label cmpt = ensightPTraits<Type>::componentOrder[d];
os.writeList(fld.component(cmpt));
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
scalarField received(fromSlave);
os.writeList(received);
}
}
}
else
{
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
const label cmpt = ensightPTraits<Type>::componentOrder[d];
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster
<< fld.component(cmpt);
}
}
}
}
template<class Type>
bool Foam::ensightOutput::writeFaceField
(
const Field<Type>& pf,
const ensightFaces& ensFaces,
Foam::ensightFile& os
)
{
if (ensFaces.total())
{
if (Pstream::master())
{
os.beginPart(ensFaces.index());
}
for (label typei=0; typei < ensightFaces::nTypes; ++typei)
{
const ensightFaces::elemType what =
ensightFaces::elemType(typei);
writeFieldContent
(
ensightFaces::key(what),
Field<Type>(pf, ensFaces.faceIds(what)),
os
);
}
return true;
}
return false;
}
template<class Type>
bool Foam::ensightOutput::writeFaceSubField
(
const Field<Type>& pf,
const ensightFaces& ensFaces,
Foam::ensightFile& os
)
{
if (ensFaces.total())
{
if (Pstream::master())
{
os.beginPart(ensFaces.index());
}
label start = 0; // start of sublist
for (label typei=0; typei < ensightFaces::nTypes; ++typei)
{
const ensightFaces::elemType what =
ensightFaces::elemType(typei);
const label size = ensFaces.faceIds(what).size();
writeFieldContent
(
ensightFaces::key(what),
SubField<Type>(pf, size, start),
os
);
start += size; // start of next sublist
}
return true;
}
return false;
}
template<class Type>
bool Foam::ensightOutput::writeCellField
(
const Field<Type>& vf,
const ensightCells& ensCells,
ensightFile& os
)
{
if (ensCells.total())
{
if (Pstream::master())
{
os.beginPart(ensCells.index());
}
for (label typei=0; typei < ensightCells::nTypes; ++typei)
{
const ensightCells::elemType what =
ensightCells::elemType(typei);
writeFieldContent
(
ensightCells::key(what),
Field<Type>(vf, ensCells.cellIds(what)),
os
);
}
return true;
}
return false;
}
// * * * * * * * * * * * * * * * * Detail * * * * * * * * * * * * * * * * * //
template<class Type>
bool Foam::ensightOutput::writeField
bool Foam::ensightOutput::Detail::writeVolField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightMesh& ensMesh,
ensightFile& os
)
{
constexpr bool parallel = true;
const fvMesh& mesh = ensMesh.mesh();
const ensightCells& meshCells = ensMesh.meshCells();
const Map<word>& patchLookup = ensMesh.patches();
......@@ -219,7 +57,7 @@ bool Foam::ensightOutput::writeField
//
if (ensMesh.useInternalMesh())
{
writeCellField(vf, meshCells, os);
Detail::writeCellField(vf, meshCells, os, parallel);
}
//
......@@ -230,13 +68,14 @@ bool Foam::ensightOutput::writeField
for (const label patchId : patchIds)
{
const word& patchName = patchLookup[patchId];
const ensightFaces& ensFaces = patchFaces[patchName];
const ensightFaces& part = patchFaces[patchName];
writeFaceField
(
vf.boundaryField()[patchId],
ensFaces,
os
part,
os,
parallel
);
}
......@@ -291,17 +130,17 @@ bool Foam::ensightOutput::writeField
for (const word& zoneName : zoneNames)
{
const ensightFaces& ensFaces = zoneFaces[zoneName];
const ensightFaces& part = zoneFaces[zoneName];
// Field (local size)
Field<Type> values(ensFaces.size());
Field<Type> values(part.size());
// Loop over face ids to store the needed field values
// - internal faces use linear interpolation
// - boundary faces use the corresponding patch value
forAll(ensFaces, i)
forAll(part, i)
{
const label faceId = ensFaces[i];
const label faceId = part[i];
values[i] =
(
mesh.isInternalFace(faceId)
......@@ -312,7 +151,7 @@ bool Foam::ensightOutput::writeField
// The field is already copied in the proper order
// - just need its corresponding sub-fields
writeFaceSubField(values, ensFaces, os);
Detail::writeFaceSubField(values, part, os, parallel);
}
}
......@@ -321,13 +160,15 @@ bool Foam::ensightOutput::writeField
template<class Type>
bool Foam::ensightOutput::ensightPointField
bool Foam::ensightOutput::Detail::writePointField
(
const GeometricField<Type, pointPatchField, pointMesh>& pf,
const ensightMesh& ensMesh,
ensightFile& os
)
{
constexpr bool parallel = true;
const fvMesh& mesh = ensMesh.mesh();
const Map<word>& patchLookup = ensMesh.patches();
......@@ -344,11 +185,12 @@ bool Foam::ensightOutput::ensightPointField
os.beginPart(0); // 0 = internalMesh
}
writeFieldContent
Detail::writeFieldComponents
(
"coordinates",
Field<Type>(pf.internalField(), ensMesh.uniquePointMap()),
os
os,
parallel
);
}
......@@ -360,7 +202,7 @@ bool Foam::ensightOutput::ensightPointField
for (const label patchId : patchIds)
{
const word& patchName = patchLookup[patchId];
const ensightFaces& ensFaces = patchFaces[patchName];
const ensightFaces& part = patchFaces[patchName];