ENH: improved sample surfaces and surface writers (#1206)

- The writers have changed from being a generic state-less set of
  routines to more properly conforming to the normal notion of a writer.
  These changes allow us to combine output fields (eg, in a single
  VTK/vtp file for each timestep).

  Parallel data reduction and any associated bookkeeping is now part
  of the surface writers.
  This improves their re-usability and avoids unnecessary
  and premature data reduction at the sampling stage.

  It is now possible to have different output formats on a per-surface
  basis.

- A new feature of the surface sampling is the ability to "store" the
  sampled surfaces and fields onto a registry for reuse by other
  function objects.

  Additionally, the "store" can be triggered at the execution phase
  as well
This commit is contained in:
Mark Olesen
2019-02-07 18:11:34 +01:00
committed by Andrew Heather
parent 16bc63864e
commit 181c974b11
70 changed files with 6034 additions and 4784 deletions

View File

@ -8,7 +8,6 @@
#include "wedgePolyPatch.H"
#include "unitConversion.H"
#include "polyMeshTetDecomposition.H"
#include "surfaceWriter.H"
#include "checkTools.H"
#include "functionObject.H"
@ -482,7 +481,7 @@ Foam::label Foam::checkGeometry
(
const polyMesh& mesh,
const bool allGeometry,
const autoPtr<surfaceWriter>& surfWriter,
autoPtr<surfaceWriter>& surfWriter,
const autoPtr<writer<scalar>>& setWriter
)
{
@ -542,7 +541,7 @@ Foam::label Foam::checkGeometry
nonAlignedPoints.write();
if (setWriter.valid())
{
mergeAndWrite(setWriter(), nonAlignedPoints);
mergeAndWrite(*setWriter, nonAlignedPoints);
}
}
}
@ -576,7 +575,7 @@ Foam::label Foam::checkGeometry
cells.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), cells);
mergeAndWrite(*surfWriter, cells);
}
}
}
@ -592,7 +591,7 @@ Foam::label Foam::checkGeometry
aspectCells.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), aspectCells);
mergeAndWrite(*surfWriter, aspectCells);
}
}
}
@ -613,7 +612,7 @@ Foam::label Foam::checkGeometry
faces.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), faces);
mergeAndWrite(*surfWriter, faces);
}
}
}
@ -635,7 +634,7 @@ Foam::label Foam::checkGeometry
cells.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), cells);
mergeAndWrite(*surfWriter, cells);
}
}
}
@ -658,7 +657,7 @@ Foam::label Foam::checkGeometry
faces.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), faces);
mergeAndWrite(*surfWriter, faces);
}
}
}
@ -680,7 +679,7 @@ Foam::label Foam::checkGeometry
faces.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), faces);
mergeAndWrite(*surfWriter, faces);
}
}
}
@ -702,7 +701,7 @@ Foam::label Foam::checkGeometry
faces.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), faces);
mergeAndWrite(*surfWriter, faces);
}
}
}
@ -726,7 +725,7 @@ Foam::label Foam::checkGeometry
faces.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), faces);
mergeAndWrite(*surfWriter, faces);
}
}
}
@ -759,7 +758,7 @@ Foam::label Foam::checkGeometry
faces.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), faces);
mergeAndWrite(*surfWriter, faces);
}
}
}
@ -784,7 +783,7 @@ Foam::label Foam::checkGeometry
points.write();
if (setWriter.valid())
{
mergeAndWrite(setWriter(), points);
mergeAndWrite(*setWriter, points);
}
}
}
@ -807,7 +806,7 @@ Foam::label Foam::checkGeometry
nearPoints.write();
if (setWriter.valid())
{
mergeAndWrite(setWriter(), nearPoints);
mergeAndWrite(*setWriter, nearPoints);
}
}
}
@ -831,7 +830,7 @@ Foam::label Foam::checkGeometry
faces.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), faces);
mergeAndWrite(*surfWriter, faces);
}
}
}
@ -854,7 +853,7 @@ Foam::label Foam::checkGeometry
faces.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), faces);
mergeAndWrite(*surfWriter, faces);
}
}
}
@ -875,7 +874,7 @@ Foam::label Foam::checkGeometry
cells.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), cells);
mergeAndWrite(*surfWriter, cells);
}
}
}
@ -895,7 +894,7 @@ Foam::label Foam::checkGeometry
cells.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), cells);
mergeAndWrite(*surfWriter, cells);
}
}
}
@ -916,7 +915,7 @@ Foam::label Foam::checkGeometry
faces.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), faces);
mergeAndWrite(*surfWriter, faces);
}
}
}
@ -937,7 +936,7 @@ Foam::label Foam::checkGeometry
faces.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), faces);
mergeAndWrite(*surfWriter, faces);
}
}
}
@ -952,14 +951,10 @@ Foam::label Foam::checkGeometry
autoPtr<surfaceWriter> patchWriter;
if (!surfWriter.valid())
{
patchWriter.reset(new vtkSurfaceWriter());
patchWriter.reset(new surfaceWriters::vtkWriter());
}
const surfaceWriter& wr =
(
surfWriter.valid()
? surfWriter()
: patchWriter()
);
surfaceWriter& wr = (surfWriter.valid() ? *surfWriter : *patchWriter);
// Currently only do AMI checks
@ -1017,22 +1012,22 @@ Foam::label Foam::checkGeometry
if (Pstream::master())
{
wr.write
const word fName
(
outputDir,
(
"patch" + Foam::name(cpp.index())
+ "-src_" + tmName
),
meshedSurfRef
(
mergedPoints,
mergedFaces
),
"weightsSum",
mergedWeights,
false
"patch" + Foam::name(cpp.index())
+ "-src_" + tmName
);
wr.open
(
mergedPoints,
mergedFaces,
(outputDir / fName),
false // serial - already merged
);
wr.write("weightsSum", mergedWeights);
wr.clear();
}
if (isA<cyclicACMIPolyPatch>(pbm[patchi]))
@ -1049,22 +1044,22 @@ Foam::label Foam::checkGeometry
if (Pstream::master())
{
wr.write
const word fName
(
outputDir,
(
"patch" + Foam::name(cpp.index())
+ "-src_" + tmName
),
meshedSurfRef
(
mergedPoints,
mergedFaces
),
"mask",
mergedMask,
false
"patch" + Foam::name(cpp.index())
+ "-src_" + tmName
);
wr.open
(
mergedPoints,
mergedFaces,
(outputDir / fName),
false // serial - already merged
);
wr.write("mask", mergedMask);
wr.clear();
}
}
}
@ -1101,22 +1096,22 @@ Foam::label Foam::checkGeometry
if (Pstream::master())
{
wr.write
const word fName
(
outputDir,
(
"patch" + Foam::name(cpp.index())
+ "-tgt_" + tmName
),
meshedSurfRef
(
mergedPoints,
mergedFaces
),
"weightsSum",
mergedWeights,
false
"patch" + Foam::name(cpp.index())
+ "-tgt_" + tmName
);
wr.open
(
mergedPoints,
mergedFaces,
(outputDir / fName),
false // serial - already merged
);
wr.write("weightsSum", mergedWeights);
wr.clear();
}
if (isA<cyclicACMIPolyPatch>(pbm[patchi]))
@ -1129,24 +1124,25 @@ Foam::label Foam::checkGeometry
pp.neighbPatch().mask(),
mergedMask
);
if (Pstream::master())
{
wr.write
const word fName
(
outputDir,
(
"patch" + Foam::name(cpp.index())
+ "-tgt_" + tmName
),
meshedSurfRef
(
mergedPoints,
mergedFaces
),
"mask",
mergedMask,
false
"patch" + Foam::name(cpp.index())
+ "-tgt_" + tmName
);
wr.open
(
mergedPoints,
mergedFaces,
(outputDir / fName),
false // serial - already merged
);
wr.write("mask", mergedMask);
wr.clear();
}
}
}

View File

@ -27,7 +27,7 @@ namespace Foam
(
const polyMesh& mesh,
const bool allGeometry,
const autoPtr<surfaceWriter>&,
const autoPtr<writer<scalar>>&
autoPtr<surfaceWriter>& surfWriter,
const autoPtr<writer<scalar>>& setWriter
);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2017 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2017 OpenFOAM Foundation
@ -67,8 +67,8 @@ Usage
#include "Time.H"
#include "fvMesh.H"
#include "globalMeshData.H"
#include "surfaceWriter.H"
#include "vtkSetWriter.H"
#include "vtkSurfaceWriter.H"
#include "IOdictionary.H"
#include "checkTools.H"
@ -149,16 +149,19 @@ int main(int argc, char *argv[])
);
if (!writeFields && args.found("writeAllFields"))
{
selectedFields.insert("nonOrthoAngle");
selectedFields.insert("faceWeight");
selectedFields.insert("skewness");
selectedFields.insert("cellDeterminant");
selectedFields.insert("aspectRatio");
selectedFields.insert("cellShapes");
selectedFields.insert("cellVolume");
selectedFields.insert("cellVolumeRatio");
selectedFields.insert("minTetVolume");
selectedFields.insert("cellRegion");
selectedFields.insert
({
"nonOrthoAngle",
"faceWeight",
"skewness",
"cellDeterminant",
"aspectRatio",
"cellShapes",
"cellVolume",
"cellVolumeRatio",
"minTetVolume",
"cellRegion"
});
}

View File

@ -10,7 +10,7 @@ Foam::label Foam::checkMeshQuality
(
const polyMesh& mesh,
const dictionary& dict,
const autoPtr<surfaceWriter>& writer
autoPtr<surfaceWriter>& writer
)
{
label noFailedChecks = 0;
@ -29,9 +29,10 @@ Foam::label Foam::checkMeshQuality
<< " faces in error to set " << faces.name() << endl;
faces.instance() = mesh.pointsInstance();
faces.write();
if (writer.valid())
{
mergeAndWrite(writer(), faces);
mergeAndWrite(*writer, faces);
}
}
}

View File

@ -6,8 +6,8 @@ namespace Foam
label checkMeshQuality
(
const polyMesh&,
const dictionary&,
const autoPtr<surfaceWriter>&
const polyMesh& mesh,
const dictionary& dict,
autoPtr<surfaceWriter>& writer
);
}

View File

@ -209,7 +209,7 @@ void Foam::printMeshStats(const polyMesh& mesh, const bool allTopology)
void Foam::mergeAndWrite
(
const polyMesh& mesh,
const surfaceWriter& writer,
surfaceWriter& writer,
const word& name,
const indirectPrimitivePatch& setPatch,
const fileName& outputDir
@ -242,37 +242,37 @@ void Foam::mergeAndWrite
// Write
if (Pstream::master())
{
writer.write
writer.open
(
outputDir,
name,
meshedSurfRef
(
mergedPoints,
mergedFaces
)
mergedPoints,
mergedFaces,
(outputDir / name),
false // serial - already merged
);
writer.writeGeometry();
writer.clear();
}
}
else
{
writer.write
writer.open
(
outputDir,
name,
meshedSurfRef
(
setPatch.localPoints(),
setPatch.localFaces()
)
setPatch.localPoints(),
setPatch.localFaces(),
(outputDir / name),
false // serial - already merged
);
writer.writeGeometry();
writer.clear();
}
}
void Foam::mergeAndWrite
(
const surfaceWriter& writer,
surfaceWriter& writer,
const faceSet& set
)
{
@ -299,7 +299,7 @@ void Foam::mergeAndWrite
void Foam::mergeAndWrite
(
const surfaceWriter& writer,
surfaceWriter& writer,
const cellSet& set
)
{

View File

@ -5,12 +5,12 @@
namespace Foam
{
class polyMesh;
class surfaceWriter;
class pointSet;
class faceSet;
class cellSet;
class fileName;
class polyMesh;
class surfaceWriter;
void printMeshStats(const polyMesh& mesh, const bool allTopology);
@ -19,7 +19,7 @@ namespace Foam
void mergeAndWrite
(
const polyMesh& mesh,
const surfaceWriter& writer,
surfaceWriter& writer,
const word& name,
const indirectPrimitivePatch& setPatch,
const fileName& outputDir
@ -27,15 +27,15 @@ namespace Foam
//- Write vtk representation of (assembled) faceSet to surface file in
// postProcessing/ directory
void mergeAndWrite(const surfaceWriter&, const faceSet&);
void mergeAndWrite(surfaceWriter& writer, const faceSet& set);
//- Write vtk representation of (assembled) cellSet to surface file in
// postProcessing/ directory
void mergeAndWrite(const surfaceWriter&, const cellSet&);
void mergeAndWrite(surfaceWriter& writer, const cellSet& set);
//- Write vtk representation of (assembled) pointSet to 'set' file in
// postProcessing/ directory
void mergeAndWrite(const writer<scalar>&, const pointSet&);
void mergeAndWrite(const writer<scalar>& writer, const pointSet& set);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -35,7 +35,7 @@ License
#include "IOmanip.H"
#include "emptyPolyPatch.H"
#include "processorPolyPatch.H"
#include "surfaceWriter.H"
#include "vtkSurfaceWriter.H"
#include "checkTools.H"
#include "treeBoundBox.H"
@ -114,7 +114,7 @@ Foam::label Foam::checkTopology
const polyMesh& mesh,
const bool allTopology,
const bool allGeometry,
const autoPtr<surfaceWriter>& surfWriter,
autoPtr<surfaceWriter>& surfWriter,
const autoPtr<writer<scalar>>& setWriter
)
{
@ -203,7 +203,7 @@ Foam::label Foam::checkTopology
cells.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), cells);
mergeAndWrite(*surfWriter, cells);
}
}
else
@ -227,7 +227,7 @@ Foam::label Foam::checkTopology
points.write();
if (setWriter.valid())
{
mergeAndWrite(setWriter(), points);
mergeAndWrite(*setWriter, points);
}
}
}
@ -249,7 +249,7 @@ Foam::label Foam::checkTopology
faces.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), faces);
mergeAndWrite(*surfWriter, faces);
}
}
}
@ -269,7 +269,7 @@ Foam::label Foam::checkTopology
faces.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), faces);
mergeAndWrite(*surfWriter, faces);
}
}
}
@ -290,7 +290,7 @@ Foam::label Foam::checkTopology
cells.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), cells);
mergeAndWrite(*surfWriter, cells);
}
}
@ -314,7 +314,7 @@ Foam::label Foam::checkTopology
faces.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), faces);
mergeAndWrite(*surfWriter, faces);
}
}
}
@ -369,7 +369,7 @@ Foam::label Foam::checkTopology
oneCells.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), oneCells);
mergeAndWrite(*surfWriter, oneCells);
}
}
@ -385,7 +385,7 @@ Foam::label Foam::checkTopology
twoCells.write();
if (surfWriter.valid())
{
mergeAndWrite(surfWriter(), twoCells);
mergeAndWrite(*surfWriter, twoCells);
}
}
}
@ -530,7 +530,7 @@ Foam::label Foam::checkTopology
points.write();
if (setWriter.valid())
{
mergeAndWrite(setWriter(), points);
mergeAndWrite(*setWriter, points);
}
}
}
@ -641,7 +641,7 @@ Foam::label Foam::checkTopology
points.write();
if (setWriter.valid())
{
mergeAndWrite(setWriter(), points);
mergeAndWrite(*setWriter, points);
}
}

View File

@ -5,8 +5,8 @@
namespace Foam
{
class polyMesh;
class surfaceWriter;
class pointSet;
class surfaceWriter;
template<class PatchType>
void checkPatch
@ -19,10 +19,10 @@ namespace Foam
label checkTopology
(
const polyMesh&,
const bool,
const bool,
const autoPtr<surfaceWriter>&,
const autoPtr<writer<scalar>>&
const polyMesh& mesh,
const bool allTopology,
const bool allGeometry,
autoPtr<surfaceWriter>& surfWriter,
const autoPtr<writer<scalar>>& setWriter
);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -128,7 +128,7 @@ labelList countBins
void writeZoning
(
const surfaceWriter& writer,
surfaceWriter& writer,
const triSurface& surf,
const labelList& faceZone,
const word& fieldName,
@ -136,43 +136,23 @@ void writeZoning
const fileName& surfFileNameBase
)
{
Info<< "Writing zoning to "
<< fileName
(
surfFilePath
/ fieldName
+ '_'
+ surfFileNameBase
+ '.'
+ writer.type()
)
<< " ..." << endl << endl;
// Transcribe faces
faceList faces;
surf.triFaceFaces(faces);
// Convert data
scalarField scalarFaceZone(faceZone.size());
forAll(faceZone, i)
{
scalarFaceZone[i] = faceZone[i];
}
faceList faces(surf.size());
forAll(surf, i)
{
faces[i] = surf[i];
}
writer.write
writer.open
(
surfFilePath,
surfFileNameBase,
meshedSurfRef
(
surf.points(),
faces
),
fieldName,
scalarFaceZone,
false // face based data
surf.points(),
faces,
(surfFilePath / surfFileNameBase),
false // serial - already merged
);
fileName outputName = writer.write(fieldName, labelField(faceZone));
writer.clear();
Info<< "Wrote zoning to " << outputName << nl << endl;
}
@ -213,7 +193,7 @@ void writeParts
fileName subName
(
surfFilePath
/surfFileNameBase + "_" + name(zone) + ".obj"
/ surfFileNameBase + "_" + name(zone) + ".obj"
);
Info<< "writing part " << zone << " size " << subSurf.size()
@ -377,6 +357,7 @@ int main(int argc, char *argv[])
if (writeSets)
{
surfWriter = surfaceWriter::New(surfaceFormat);
// Option1: hard-coded format
edgeFormat = "obj";
//// Option2: same type as surface format. Problem is e.g. .obj format
@ -514,38 +495,29 @@ int main(int argc, char *argv[])
)
);
const fileName qualityName
// Transcribe faces
faceList faces;
subSurf.triFaceFaces(faces);
surfWriter->open
(
surfFilePath
/ "illegal"
+ '_'
+ surfFileNameBase
+ '.'
+ surfWriter().type()
subSurf.points(),
faces,
(surfFilePath / surfFileNameBase),
false // serial - already merged
);
Info<< "Writing illegal triangles to "
<< qualityName << " ..." << endl << endl;
// Convert data
faceList faces(subSurf.size());
forAll(subSurf, i)
{
faces[i] = subSurf[i];
}
surfWriter().write
fileName outputName = surfWriter->write
(
surfFilePath,
surfFileNameBase,
meshedSurfRef
(
subSurf.points(),
faces
),
"illegal",
scalarField(subSurf.size(), Zero),
false // face based data
scalarField(subSurf.size(), Zero)
);
surfWriter->clear();
Info<< "Wrote illegal triangles to "
<< outputName << nl << endl;
}
else if (outputThreshold > 0)
{
@ -645,38 +617,24 @@ int main(int argc, char *argv[])
// Dump for subsetting
if (surfWriter.valid())
{
const fileName qualityName
(
surfFilePath
/ "quality"
+ '_'
+ surfFileNameBase
+ '.'
+ surfWriter().type()
);
Info<< "Writing triangle-quality to "
<< qualityName << " ..." << endl << endl;
// Convert data
// Transcribe faces
faceList faces(surf.size());
forAll(surf, i)
{
faces[i] = surf[i];
}
surf.triFaceFaces(faces);
surfWriter().write
surfWriter->open
(
surfFilePath,
surfFileNameBase,
meshedSurfRef
(
surf.points(),
faces
),
"quality",
triQ,
false // face based data
surf.points(),
faces,
(surfFilePath / surfFileNameBase),
false // serial - already merged
);
fileName outputName = surfWriter->write("quality", triQ);
surfWriter->clear();
Info<< "Wrote triangle-quality to "
<< outputName << nl << endl;
}
else if (outputThreshold > 0)
{
@ -926,11 +884,12 @@ int main(int argc, char *argv[])
if (!surfWriter.valid())
{
surfWriter.reset(new vtkSurfaceWriter());
surfWriter.reset(new surfaceWriters::vtkWriter());
}
writeZoning
(
surfWriter(),
*surfWriter,
surf,
faceZone,
"zone",
@ -991,11 +950,12 @@ int main(int argc, char *argv[])
{
if (!surfWriter.valid())
{
surfWriter.reset(new vtkSurfaceWriter());
surfWriter.reset(new surfaceWriters::vtkWriter());
}
writeZoning
(
surfWriter(),
*surfWriter,
surf,
normalZone,
"normal",

View File

@ -953,20 +953,23 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
{
const word formatName(dict.get<word>("surfaceFormat"));
if (formatName != "none")
{
surfaceWriterPtr_.reset
surfaceWriterPtr_.reset
(
surfaceWriter::New
(
surfaceWriter::New
(
formatName,
dict.subOrEmptyDict("formatOptions")
.subOrEmptyDict(formatName)
)
);
formatName,
dict.subOrEmptyDict("formatOptions").subOrEmptyDict(formatName)
)
);
if (surfaceWriterPtr_->enabled())
{
Info<< " surfaceFormat = " << formatName << nl;
}
else
{
surfaceWriterPtr_->clear();
}
}
Info<< nl << endl;

View File

@ -384,22 +384,26 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
Field<Type> values(getFieldValues<Type>(fieldName, true));
// Write raw values on surface if specified
if (surfaceWriterPtr_.valid())
if (surfaceWriterPtr_.valid() && surfaceWriterPtr_->enabled())
{
Field<Type> allValues(values);
combineFields(allValues);
if (Pstream::master())
{
surfaceWriterPtr_->write
surfaceWriterPtr_->open
(
outputDir(),
regionTypeNames_[regionType_] + ("_" + regionName_),
surfToWrite,
fieldName,
allValues,
false
(
outputDir()
/ regionTypeNames_[regionType_] + ("_" + regionName_)
),
false // serial - already merged
);
surfaceWriterPtr_->write(fieldName, allValues);
surfaceWriterPtr_->clear();
}
}

View File

@ -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 |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2017 OpenFOAM Foundation
@ -28,8 +28,8 @@ License
#include "FacePostProcessing.H"
#include "Pstream.H"
#include "ListListOps.H"
#include "surfaceWriter.H"
#include "globalIndex.H"
#include "surfaceWriter.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -194,35 +194,26 @@ void Foam::FacePostProcessing<CloudType>::write()
)
);
autoPtr<surfaceWriter> writer
auto writer = surfaceWriter::New
(
surfaceWriter::New
(
surfaceFormat_,
this->coeffDict().subOrEmptyDict("formatOptions").
subOrEmptyDict(surfaceFormat_)
)
surfaceFormat_,
this->coeffDict().subOrEmptyDict("formatOptions")
.subOrEmptyDict(surfaceFormat_)
);
writer->write
writer->open
(
this->writeTimeDir(),
fZone.name(),
meshedSurfRef(allPoints, allFaces),
"massTotal",
zoneMassTotal[zoneI],
false
allPoints,
allFaces,
(this->writeTimeDir() / fZone.name()),
false // serial - already merged
);
writer->write
(
this->writeTimeDir(),
fZone.name(),
meshedSurfRef(allPoints, allFaces),
"massFlowRate",
zoneMassFlowRate[zoneI],
false
);
writer->write("massTotal", zoneMassTotal[zoneI]);
writer->write("massFlowRate", zoneMassFlowRate[zoneI]);
writer->clear();
}
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2012-2017 OpenFOAM Foundation
@ -462,40 +462,26 @@ void Foam::ParticleCollector<CloudType>::write()
<< endl;
if (surfaceFormat_ != "none")
if (surfaceFormat_ != "none" && Pstream::master())
{
if (Pstream::master())
{
autoPtr<surfaceWriter> writer
(
surfaceWriter::New
(
surfaceFormat_,
this->coeffDict().subOrEmptyDict("formatOptions").
subOrEmptyDict(surfaceFormat_)
)
);
auto writer = surfaceWriter::New
(
surfaceFormat_,
this->coeffDict().subOrEmptyDict("formatOptions")
.subOrEmptyDict(surfaceFormat_)
);
writer->write
(
this->writeTimeDir(),
"collector",
meshedSurfRef(points_, faces_),
"massTotal",
faceMassTotal,
false
);
writer->open
(
points_,
faces_,
(this->writeTimeDir() / "collector"),
false // serial - already merged
);
writer->write
(
this->writeTimeDir(),
"collector",
meshedSurfRef(points_, faces_),
"massFlowRate",
faceMassFlowRate,
false
);
}
writer->write("massFlowRate", faceMassFlowRate);
writer->write("massTotal", faceMassTotal);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -275,22 +275,19 @@ Foam::scalar surfaceNoise::writeSurfaceData
}
}
// Could also have meshedSurface implement meshedSurf
if (writeSurface)
{
fileName outFileName = writerPtr_->write
writerPtr_->open
(
outDir,
fName,
meshedSurfRef
(
surf.points(),
surf.surfFaces()
),
title,
allData,
false
surf.points(),
surf.surfFaces(),
(outDir / fName),
false // serial - already merged
);
writerPtr_->write(title, allData);
writerPtr_->clear();
}
// TO BE VERIFIED: area-averaged values
@ -305,22 +302,19 @@ Foam::scalar surfaceNoise::writeSurfaceData
{
const meshedSurface& surf = readerPtr_->geometry();
// Could also have meshedSurface implement meshedSurf
if (writeSurface)
{
writerPtr_->write
writerPtr_->open
(
outDir,
fName,
meshedSurfRef
(
surf.points(),
surf.surfFaces()
),
title,
data,
false
surf.points(),
surf.surfFaces(),
(outDir / fName),
false // serial - already merged
);
writerPtr_->write(title, data);
writerPtr_->clear();
}
// TO BE VERIFIED: area-averaged values
@ -442,13 +436,12 @@ bool surfaceNoise::read(const dictionary& dict)
const word writerType(dict.get<word>("writer"));
dictionary optDict
writerPtr_ = surfaceWriter::New
(
writerType,
dict.subOrEmptyDict("writeOptions").subOrEmptyDict(writerType)
);
writerPtr_ = surfaceWriter::New(writerType, optDict);
return true;
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -111,7 +111,7 @@ SeeAlso
namespace Foam
{
// Forward declaration of classes
// Forward declarations
class surfaceReader;
class surfaceWriter;

View File

@ -50,8 +50,8 @@ sampledSurface/distanceSurface/sampledDistanceSurface.C
sampledSurface/sampledCuttingPlane/sampledCuttingPlane.C
sampledSurface/sampledCuttingSurface/sampledCuttingSurface.C
sampledSurface/sampledSurface/sampledSurface.C
sampledSurface/sampledSurface/sampledSurfaceRegister.C
sampledSurface/sampledSurfaces/sampledSurfaces.C
sampledSurface/sampledSurfaces/sampledSurfacesGrouping.C
sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C
sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMeshNormal.C
sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.C
@ -59,24 +59,11 @@ sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.C
/* Proof-of-concept: */
/* sampledSurface/triSurfaceMesh/sampledDiscreteSurface.C */
readers = sampledSurface/readers
surfWriters = sampledSurface/writers
$(surfWriters)/surfaceWriter.C
$(surfWriters)/ensight/ensightSurfaceWriter.C
$(surfWriters)/foam/foamSurfaceWriter.C
$(surfWriters)/nastran/nastranSurfaceWriter.C
$(surfWriters)/proxy/proxySurfaceWriter.C
$(surfWriters)/raw/rawSurfaceWriter.C
$(surfWriters)/starcd/starcdSurfaceWriter.C
$(surfWriters)/vtk/vtkSurfaceWriter.C
$(surfWriters)/boundaryData/boundaryDataSurfaceWriter.C
surfReaders = sampledSurface/readers
$(surfReaders)/surfaceReader.C
$(surfReaders)/surfaceReaderNew.C
$(surfReaders)/ensight/ensightSurfaceReader.C
$(readers)/surfaceReader.C
$(readers)/surfaceReaderNew.C
$(readers)/ensight/ensightSurfaceReader.C
graphField/writePatchGraph.C
graphField/writeCellGraph.C

View File

@ -38,6 +38,17 @@ namespace Foam
}
const Foam::wordList Foam::sampledSurface::surfaceFieldTypes
({
"surfaceScalarField",
"surfaceVectorField",
"surfaceSphericalTensorField",
"surfaceSymmTensorField",
"surfaceTensorField"
});
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::sampledSurface::clearGeom() const
@ -57,10 +68,8 @@ Foam::autoPtr<Foam::sampledSurface> Foam::sampledSurface::New
{
const word sampleType(dict.get<word>("type"));
if (debug)
{
Info<< "Selecting sampledType " << sampleType << endl;
}
DebugInfo
<< "Selecting sampledType " << sampleType << endl;
auto cstrIter = wordConstructorTablePtr_->cfind(sampleType);

View File

@ -65,17 +65,15 @@ SourceFiles
#ifndef sampledSurface_H
#define sampledSurface_H
#include "meshedSurf.H"
#include "word.H"
#include "labelList.H"
#include "faceList.H"
#include "polySurface.H"
#include "surfMesh.H"
#include "typeInfo.H"
#include "runTimeSelectionTables.H"
#include "autoPtr.H"
#include "polyMesh.H"
#include "volFieldsFwd.H"
#include "surfaceFieldsFwd.H"
#include "surfaceMesh.H"
#include "polyMesh.H"
#include "interpolation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -84,18 +82,26 @@ namespace Foam
{
/*---------------------------------------------------------------------------*\
Class sampledSurface Declaration
Class sampledSurface Declaration
\*---------------------------------------------------------------------------*/
class sampledSurface
:
public meshedSurf
{
public:
// Public Static Data
//- Class names for surface field types
static const wordList surfaceFieldTypes;
private:
// Private Data
//- Name of sample surface
//- The name of the sample surface
word name_;
//- Reference to mesh
@ -104,15 +110,13 @@ private:
//- Should surface sampling be enabled?
bool enabled_;
//- Do we intend to interpolate the information?
const bool interpolate_;
//- Interpolate information to the nodes?
bool interpolate_;
//- Total surface area (demand-driven)
mutable scalar area_;
protected:
// Protected Member Functions
@ -163,9 +167,7 @@ public:
);
// iNew helper class
//- Class for PtrList read-construction
//- PtrList read-construction helper
class iNew
{
//- Reference to the volume mesh
@ -188,6 +190,34 @@ public:
};
//- PtrList read-construction helper that captures dictionaries used
//- during creation.
class iNewCapture
{
//- Reference to the volume mesh
const polyMesh& mesh_;
//- Captured (recorded) dictionaries
DynamicList<dictionary>& capture_;
public:
iNewCapture(const polyMesh& mesh, DynamicList<dictionary>& capture)
:
mesh_(mesh),
capture_(capture)
{}
autoPtr<sampledSurface> operator()(Istream& is) const
{
word name(is);
capture_.append(dictionary(is));
return sampledSurface::New(name, mesh_, capture_.last());
}
};
// Constructors
//- Construct from name, mesh
@ -245,13 +275,13 @@ public:
return name_;
}
//- Sampling is enabled
//- Surface is enabled
bool enabled() const
{
return enabled_;
}
//- Interpolation requested for surface
//- interpolation to nodes requested for surface
bool interpolate() const
{
return interpolate_;
@ -301,6 +331,99 @@ public:
}
// General registry storage (optional)
//- Get surface from registry if available.
// \param obr The objectRegistry to use
// \param lookupName Optional lookup name, use surface name if empty
// \return surface or nullptr
polySurface* getRegistrySurface
(
const objectRegistry& obr,
word lookupName = ""
) const;
//- Copy surface into registry.
// \param obr The objectRegistry to use
// \param lookupName Optional lookup name, use surface name if empty
// \return surface or nullptr it surface should not be stored
polySurface* storeRegistrySurface
(
objectRegistry& obr,
word lookupName = ""
) const;
//- Remove surface from registry.
// \param obr The objectRegistry to use
// \param lookupName Optional lookup name, use surface name if empty
// \return True if surface existed and was removed
bool removeRegistrySurface
(
objectRegistry& obr,
word lookupName = ""
) const;
//- Copy/store sampled field onto registered surface (if it exists)
template<class Type, class GeoMeshType>
bool storeRegistryField
(
const objectRegistry& obr,
const word& fieldName,
const dimensionSet& dims,
const Field<Type>& values,
word lookupName = ""
) const;
//- Move/store sampled field onto registered surface (if it exists)
template<class Type, class GeoMeshType>
bool storeRegistryField
(
const objectRegistry& obr,
const word& fieldName,
const dimensionSet& dims,
Field<Type>&& values,
word lookupName = ""
) const;
// Specialized surfMesh storage (optional)
//- Get surface from registry if available.
// \param lookupName Optional lookup name, use surface name if empty
// \return surface or nullptr
surfMesh* getSurfMesh(word lookupName = "") const;
//- Copy surface into registry.
// \param lookupName Optional lookup name, use surface name if empty
// \return surface or nullptr it surface should not be stored
surfMesh* storeSurfMesh(word lookupName = "") const;
//- Remove surface from registry.
// \param lookupName Optional lookup name, use surface name if empty
// \return True if surface existed and was removed
bool removeSurfMesh(word lookupName = "") const;
//- Copy/store sampled Face field onto surfMesh (if it exists)
template<class Type, class GeoMeshType>
bool storeSurfMeshField
(
const word& fieldName,
const dimensionSet& dims,
const Field<Type>& values,
word lookupName = ""
) const;
//- Move/store sampled Face field onto surfMesh (if it exists)
template<class Type, class GeoMeshType>
bool storeSurfMeshField
(
const word& fieldName,
const dimensionSet& dims,
Field<Type>&& values,
word lookupName = ""
) const;
// Sample (faces)
//- Sample volume field onto surface faces

View File

@ -2,10 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010, 2018-2019 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -26,200 +24,12 @@ License
\*---------------------------------------------------------------------------*/
#include "sampledSurface.H"
#include "polyMesh.H"
#include "fvMesh.H"
#include "MeshedSurface.H"
#include "demandDrivenData.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(sampledSurface, 0);
defineRunTimeSelectionTable(sampledSurface, word);
}
const Foam::wordList Foam::sampledSurface::surfaceFieldTypes
({
"surfaceScalarField",
"surfaceVectorField",
"surfaceSphericalTensorField",
"surfaceSymmTensorField",
"surfaceTensorField"
});
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::sampledSurface::clearGeom() const
{
area_ = -1;
}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::sampledSurface> Foam::sampledSurface::New
(
const word& name,
const polyMesh& mesh,
const dictionary& dict
)
{
const word sampleType(dict.get<word>("type"));
if (debug)
{
Info<< "Selecting sampledType " << sampleType << endl;
}
auto cstrIter = wordConstructorTablePtr_->cfind(sampleType);
if (!cstrIter.found())
{
FatalErrorInFunction
<< "Unknown sample type "
<< sampleType << nl << nl
<< "Valid sample types :" << endl
<< wordConstructorTablePtr_->sortedToc()
<< exit(FatalError);
}
return autoPtr<sampledSurface>(cstrIter()(name, mesh, dict));
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::sampledSurface::sampledSurface(const word& name, std::nullptr_t)
:
name_(name),
mesh_(NullObjectRef<polyMesh>()),
enabled_(true),
interpolate_(false),
area_(-1),
writerType_(),
formatOptions_()
{}
Foam::sampledSurface::sampledSurface
(
const word& name,
const polyMesh& mesh,
const bool interpolate
)
:
name_(name),
mesh_(mesh),
enabled_(true),
interpolate_(interpolate),
area_(-1),
writerType_(),
formatOptions_()
{}
Foam::sampledSurface::sampledSurface
(
const word& name,
const polyMesh& mesh,
const dictionary& dict
)
:
name_(dict.lookupOrDefault<word>("name", name)),
mesh_(mesh),
enabled_(dict.lookupOrDefault("enabled", true)),
interpolate_(dict.lookupOrDefault("interpolate", false)),
area_(-1),
writerType_(dict.lookupOrDefault<word>("surfaceFormat", "")),
formatOptions_(dict.subOrEmptyDict("formatOptions"))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::sampledSurface::~sampledSurface()
{
clearGeom();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::scalar Foam::sampledSurface::area() const
{
if (area_ < 0)
{
area_ = gSum(magSf());
}
return area_;
}
bool Foam::sampledSurface::withSurfaceFields() const
{
return false;
}
Foam::tmp<Foam::scalarField> Foam::sampledSurface::sample
(
const surfaceScalarField& sField
) const
{
NotImplemented;
return nullptr;
}
Foam::tmp<Foam::vectorField> Foam::sampledSurface::sample
(
const surfaceVectorField& sField
) const
{
NotImplemented;
return nullptr;
}
Foam::tmp<Foam::sphericalTensorField> Foam::sampledSurface::sample
(
const surfaceSphericalTensorField& sField
) const
{
NotImplemented;
return nullptr;
}
Foam::tmp<Foam::symmTensorField> Foam::sampledSurface::sample
(
const surfaceSymmTensorField& sField
) const
{
NotImplemented;
return nullptr;
}
Foam::tmp<Foam::tensorField> Foam::sampledSurface::sample
(
const surfaceTensorField& sField
) const
{
NotImplemented;
return nullptr;
}
void Foam::sampledSurface::print(Ostream& os) const
{
os << type();
}
Foam::polySurface* Foam::sampledSurface::getRegistrySurface
(
const objectRegistry& obr,
@ -250,15 +60,11 @@ Foam::polySurface* Foam::sampledSurface::storeRegistrySurface
if (!surfptr)
{
surfptr = new polySurface
(
lookupName,
obr,
true // Add to registry - owned by registry
);
// Construct null and add to registry (owned by registry)
surfptr = new polySurface(lookupName, obr, true);
}
surfptr->deepCopy(*this); // Copy in geometry (removes old fields)
surfptr->copySurface(*this); // Copy in geometry (removes old fields)
return surfptr;
}
@ -281,13 +87,50 @@ bool Foam::sampledSurface::removeRegistrySurface
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const sampledSurface& s)
Foam::surfMesh* Foam::sampledSurface::getSurfMesh(word lookupName) const
{
s.print(os);
os.check(FUNCTION_NAME);
return os;
if (lookupName.empty())
{
lookupName = this->name();
}
return mesh().getObjectPtr<surfMesh>(lookupName);
}
Foam::surfMesh* Foam::sampledSurface::storeSurfMesh(word lookupName) const
{
if (lookupName.empty())
{
lookupName = this->name();
}
surfMesh* surfptr = getSurfMesh();
if (!surfptr)
{
// Construct null and add owned by registry
surfptr = new surfMesh(lookupName, mesh());
surfptr->store(); // Add to registry - owned by registry
}
surfptr->copySurface(*this); // Copy in geometry (removes old fields)
return surfptr;
}
bool Foam::sampledSurface::removeSurfMesh(word lookupName) const
{
surfMesh* surfptr = getSurfMesh(lookupName);
if (surfptr)
{
return mesh().checkOut(*surfptr);
}
return false;
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -116,4 +116,100 @@ Foam::sampledSurface::pointAverage
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type, class GeoMeshType>
bool Foam::sampledSurface::storeRegistryField
(
const objectRegistry& obr,
const word& fieldName,
const dimensionSet& dims,
const Field<Type>& values,
word lookupName
) const
{
polySurface* surfptr = this->getRegistrySurface(obr, lookupName);
if (surfptr)
{
surfptr->storeField<Type, GeoMeshType>
(
fieldName, dims, values
);
}
return surfptr;
}
template<class Type, class GeoMeshType>
bool Foam::sampledSurface::storeRegistryField
(
const objectRegistry& obr,
const word& fieldName,
const dimensionSet& dims,
Field<Type>&& values,
word lookupName
) const
{
polySurface* surfptr = this->getRegistrySurface(obr, lookupName);
if (surfptr)
{
surfptr->storeField<Type, GeoMeshType>
(
fieldName, dims, std::move(values)
);
}
return surfptr;
}
template<class Type, class GeoMeshType>
bool Foam::sampledSurface::storeSurfMeshField
(
const word& fieldName,
const dimensionSet& dims,
const Field<Type>& values,
word lookupName
) const
{
surfMesh* surfptr = this->getSurfMesh(lookupName);
if (surfptr)
{
surfptr->storeField<Type, GeoMeshType>
(
fieldName, dims, values
);
}
return surfptr;
}
template<class Type, class GeoMeshType>
bool Foam::sampledSurface::storeSurfMeshField
(
const word& fieldName,
const dimensionSet& dims,
Field<Type>&& values,
word lookupName
) const
{
surfMesh* surfptr = this->getSurfMesh(lookupName);
if (surfptr)
{
surfptr->storeField<Type, GeoMeshType>
(
fieldName, dims, std::move(values)
);
}
return surfptr;
}
// ************************************************************************* //

View File

@ -26,15 +26,15 @@ License
\*---------------------------------------------------------------------------*/
#include "sampledSurfaces.H"
#include "volFields.H"
#include "dictionary.H"
#include "Time.H"
#include "IOmanip.H"
#include "interpolationCell.H"
#include "volPointInterpolation.H"
#include "PatchTools.H"
#include "polySurface.H"
#include "mapPolyMesh.H"
#include "sampledTriSurfaceMesh.H"
#include "stringListOps.H"
#include "volFields.H"
#include "HashOps.H"
#include "PstreamCombineReduceOps.H"
#include "Time.H"
#include "UIndirectList.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -51,66 +51,154 @@ namespace Foam
);
}
bool Foam::sampledSurfaces::verbose_ = false;
Foam::scalar Foam::sampledSurfaces::mergeTol_ = 1e-10;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::sampledSurfaces::writeGeometry() const
Foam::polySurface* Foam::sampledSurfaces::getRegistrySurface
(
const sampledSurface& s
) const
{
// Write to time directory under outputPath_
// Skip surfaces without faces (eg, a failed cut-plane)
return s.getRegistrySurface
(
storedObjects(),
IOobject::groupName(name(), s.name())
);
}
const fileName outputDir = outputPath_/time_.timeName();
forAll(*this, surfi)
Foam::polySurface* Foam::sampledSurfaces::storeRegistrySurface
(
const sampledSurface& s
)
{
return s.storeRegistrySurface
(
storedObjects(),
IOobject::groupName(name(), s.name())
);
}
bool Foam::sampledSurfaces::removeRegistrySurface
(
const sampledSurface& s
)
{
return s.removeRegistrySurface
(
storedObjects(),
IOobject::groupName(name(), s.name())
);
}
void Foam::sampledSurfaces::countFields()
{
wordList allFields; // Just needed for warnings
HashTable<wordHashSet> selected;
if (loadFromFiles_)
{
const sampledSurface& s = operator[](surfi);
// Check files for a particular time
IOobjectList objects(obr_, obr_.time().timeName());
if (Pstream::parRun())
allFields = objects.names();
selected = objects.classes(fieldSelection_);
}
else
{
// Check currently available fields
allFields = obr_.names();
selected = obr_.classes(fieldSelection_);
}
if (Pstream::parRun())
{
Pstream::mapCombineGather(selected, HashSetOps::plusEqOp<word>());
Pstream::mapCombineScatter(selected);
}
DynamicList<label> missed(fieldSelection_.size());
// Detect missing fields
forAll(fieldSelection_, i)
{
if (findStrings(fieldSelection_[i], allFields).empty())
{
if (Pstream::master() && mergedList_[surfi].size())
{
formatter_->write
(
outputDir,
s.name(),
mergedList_[surfi]
);
}
missed.append(i);
}
else if (s.faces().size())
}
if (missed.size())
{
WarningInFunction
<< nl
<< "Cannot find "
<< (loadFromFiles_ ? "field file" : "registered field")
<< " matching "
<< UIndirectList<wordRe>(fieldSelection_, missed) << endl;
}
// Currently only support volume and surface field types
label nVolumeFields = 0;
label nSurfaceFields = 0;
forAllConstIters(selected, iter)
{
const word& clsName = iter.key();
const label n = iter.val().size();
if (fieldTypes::volume.found(clsName))
{
formatter_->write(outputDir, s.name(), s);
nVolumeFields += n;
}
else if (sampledSurface::surfaceFieldTypes.found(clsName))
{
nSurfaceFields += n;
}
}
// Now propagate field counts (per surface)
label surfi = 0;
for (const sampledSurface& s : surfaces())
{
writers_[surfi].nFields() =
(
nVolumeFields
+ (s.withSurfaceFields() ? nSurfaceFields : 0)
+ ((s.hasFaceIds() && !s.interpolate()) ? 1 : 0)
);
++surfi;
}
}
void Foam::sampledSurfaces::writeOriginalIds()
Foam::autoPtr<Foam::surfaceWriter> Foam::sampledSurfaces::newWriter
(
word writeType,
const dictionary& formatOptions,
const dictionary& surfDict
)
{
const word fieldName = "Ids";
const fileName outputDir = outputPath_/time_.timeName();
// Per-surface adjustment
surfDict.readIfPresent<word>("surfaceFormat", writeType);
forAll(*this, surfi)
{
const sampledSurface& s = operator[](surfi);
dictionary options = formatOptions.subOrEmptyDict(writeType);
if (s.hasFaceIds())
{
const labelList& idLst = s.originalIds();
options.merge
(
surfDict.subOrEmptyDict("formatOptions").subOrEmptyDict(writeType)
);
// Transcribe from label to scalar
Field<scalar> ids(idLst.size());
forAll(idLst, i)
{
ids[i] = idLst[i];
}
writeSurface(ids, surfi, fieldName, outputDir);
}
}
return surfaceWriter::New(writeType, options);
}
@ -126,6 +214,8 @@ Foam::sampledSurfaces::sampledSurfaces
functionObjects::fvMeshFunctionObject(name, runTime, dict),
PtrList<sampledSurface>(),
loadFromFiles_(false),
verbose_(false),
onExecute_(false),
outputPath_
(
time_.globalPath()/functionObject::outputPrefix/name
@ -133,9 +223,9 @@ Foam::sampledSurfaces::sampledSurfaces
fieldSelection_(),
sampleFaceScheme_(),
sampleNodeScheme_(),
mergedList_(),
changedGeom_(),
formatter_(nullptr)
writers_(),
actions_(),
nFaces_()
{
outputPath_.clean(); // Remove unneeded ".."
@ -154,6 +244,8 @@ Foam::sampledSurfaces::sampledSurfaces
functionObjects::fvMeshFunctionObject(name, obr, dict),
PtrList<sampledSurface>(),
loadFromFiles_(loadFromFiles),
verbose_(false),
onExecute_(false),
outputPath_
(
time_.globalPath()/functionObject::outputPrefix/name
@ -161,9 +253,9 @@ Foam::sampledSurfaces::sampledSurfaces
fieldSelection_(),
sampleFaceScheme_(),
sampleNodeScheme_(),
mergedList_(),
changedGeom_(),
formatter_(nullptr)
writers_(),
actions_(),
nFaces_()
{
outputPath_.clean(); // Remove unneeded ".."
@ -179,60 +271,19 @@ void Foam::sampledSurfaces::verbose(const bool verbosity)
}
bool Foam::sampledSurfaces::execute()
{
return true;
}
bool Foam::sampledSurfaces::write()
{
if (empty())
{
return true;
}
// Finalize surfaces, merge points etc.
update();
const label nFields = classifyFields();
// Write geometry first if required,
// or when no fields would otherwise be written
if (formatter_->separateGeometry() || !nFields)
{
writeGeometry();
changedGeom_ = false;
}
const IOobjectList objects(obr_, obr_.time().timeName());
sampleAndWrite<volScalarField>(objects);
sampleAndWrite<volVectorField>(objects);
sampleAndWrite<volSphericalTensorField>(objects);
sampleAndWrite<volSymmTensorField>(objects);
sampleAndWrite<volTensorField>(objects);
sampleAndWrite<surfaceScalarField>(objects);
sampleAndWrite<surfaceVectorField>(objects);
sampleAndWrite<surfaceSphericalTensorField>(objects);
sampleAndWrite<surfaceSymmTensorField>(objects);
sampleAndWrite<surfaceTensorField>(objects);
return true;
}
bool Foam::sampledSurfaces::read(const dictionary& dict)
{
fvMeshFunctionObject::read(dict);
PtrList<sampledSurface>::clear();
mergedList_.clear();
changedGeom_.clear();
writers_.clear();
actions_.clear();
nFaces_.clear();
fieldSelection_.clear();
verbose_ = dict.lookupOrDefault("verbose", false);
onExecute_ = dict.lookupOrDefault("sampleOnExecute", false);
sampleFaceScheme_ =
dict.lookupOrDefault<word>("sampleScheme", "cell");
@ -241,82 +292,160 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
const entry* eptr = dict.findEntry("surfaces");
// Surface writer type and format options
const word writerType =
(eptr ? dict.get<word>("surfaceFormat") : word::null);
const dictionary formatOptions(dict.subOrEmptyDict("formatOptions"));
// Store on registry?
const bool dfltStore = dict.lookupOrDefault("store", false);
if (eptr && eptr->isDict())
{
PtrList<sampledSurface> surfs(eptr->dict().size());
actions_.resize(surfs.size(), ACTION_WRITE); // Default action
writers_.resize(surfs.size());
nFaces_.resize(surfs.size(), Zero);
label surfi = 0;
for (const entry& dEntry : eptr->dict())
{
if (dEntry.isDict())
if (!dEntry.isDict())
{
autoPtr<sampledSurface> surf =
sampledSurface::New
(
dEntry.keyword(),
mesh_,
dEntry.dict()
);
if (surf.valid() && surf->enabled())
{
surfs.set(surfi, surf);
++surfi;
}
continue;
}
const dictionary& surfDict = dEntry.dict();
autoPtr<sampledSurface> surf =
sampledSurface::New
(
dEntry.keyword(),
mesh_,
surfDict
);
if (!surf.valid() || !surf->enabled())
{
continue;
}
// Define the surface
surfs.set(surfi, surf);
// Define additional action(s)
if (surfDict.lookupOrDefault("store", dfltStore))
{
actions_[surfi] |= ACTION_STORE;
}
if (surfDict.lookupOrDefault("surfMeshStore", false))
{
actions_[surfi] |= ACTION_SURF_MESH;
}
// Define surface writer, but do NOT yet attach a surface
writers_.set
(
surfi,
newWriter(writerType, formatOptions, surfDict)
);
writers_[surfi].isPointData() = surfs[surfi].interpolate();
// Use outputDir/TIME/surface-name
writers_[surfi].useTimeDir() = true;
writers_[surfi].verbose() = verbose_;
++surfi;
}
surfs.resize(surfi);
actions_.resize(surfi);
writers_.resize(surfi);
surfaces().transfer(surfs);
}
else if (eptr)
{
PtrList<sampledSurface> surfs
// This is slightly trickier.
// We want access to the individual dictionaries used for construction
DynamicList<dictionary> capture;
PtrList<sampledSurface> input
(
eptr->stream(),
sampledSurface::iNew(mesh_)
sampledSurface::iNewCapture(mesh_, capture)
);
forAll(surfs, surfi)
PtrList<sampledSurface> surfs(input.size());
actions_.resize(surfs.size(), ACTION_WRITE); // Default action
writers_.resize(surfs.size());
nFaces_.resize(surfs.size(), Zero);
label surfi = 0;
forAll(input, inputi)
{
if (!surfs[surfi].enabled())
const dictionary& surfDict = capture[inputi];
autoPtr<sampledSurface> surf = input.set(inputi, nullptr);
if (!surf.valid() || !surf->enabled())
{
surfs.set(surfi, nullptr);
continue;
}
// Define the surface
surfs.set(surfi, surf);
// Define additional action(s)
if (surfDict.lookupOrDefault("store", dfltStore))
{
actions_[surfi] |= ACTION_STORE;
}
if (surfDict.lookupOrDefault("surfMeshStore", false))
{
actions_[surfi] |= ACTION_SURF_MESH;
}
// Define surface writer, but do NOT yet attach a surface
writers_.set
(
surfi,
newWriter(writerType, formatOptions, surfDict)
);
writers_[surfi].isPointData() = surfs[surfi].interpolate();
// Use outputDir/TIME/surface-name
writers_[surfi].useTimeDir() = true;
writers_[surfi].verbose() = verbose_;
++surfi;
}
surfs.resize(surfs.squeezeNull());
surfs.resize(surfi);
actions_.resize(surfi);
writers_.resize(surfi);
surfaces().transfer(surfs);
}
const auto& surfs = surfaces();
// Have some surfaces, so sort out which fields are needed and report
if (surfs.size())
{
nFaces_.resize(surfs.size(), Zero);
dict.readEntry("fields", fieldSelection_);
fieldSelection_.uniq();
// The surface writer and format options
const word writerType(dict.get<word>("surfaceFormat"));
// Define the surface formatter
// Optionally defined extra controls for the output formats
formatter_ = surfaceWriter::New
(
writerType,
dict.subOrEmptyDict("formatOptions").subOrEmptyDict(writerType)
);
if (Pstream::parRun())
{
mergedList_.resize(size());
}
// Ensure all surfaces and merge information are expired
expire();
label surfi = 0;
for (const sampledSurface& s : surfs)
{
@ -324,7 +453,18 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
{
Info<< "Sampled surface:" << nl;
}
Info<< " " << s.name() << " -> " << writerType << nl;
Info<< " " << s.name() << " -> " << writers_[surfi].type();
if (actions_[surfi] & ACTION_STORE)
{
Info<< ", store on registry ("
<< IOobject::groupName(name(), s.name()) << ')';
}
if (actions_[surfi] & ACTION_SURF_MESH)
{
Info<< ", store as surfMesh (deprecated)";
}
Info<< nl;
++surfi;
}
@ -334,24 +474,171 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
if (debug && Pstream::master())
{
Pout<< "sample fields:" << fieldSelection_ << nl
<< "sample surfaces:" << nl << "(" << nl;
<< "sample surfaces:" << nl << '(' << nl;
for (const sampledSurface& s : surfaces())
{
Pout<< " " << s << nl;
}
Pout<< ")" << endl;
Pout<< ')' << endl;
}
// New geometry
changedGeom_.resize(size());
changedGeom_ = true;
// Ensure all surfaces and merge information are expired
expire();
return true;
}
bool Foam::sampledSurfaces::performAction(unsigned request)
{
if
(
empty()
|| (request == ACTION_NONE)
|| !testAny
(
actions_,
[=] (unsigned action) { return (request & action); }
)
)
{
return true;
}
// Finalize surfaces, update information, writer associations etc.
update();
bool noFaces = true;
for (const label n : nFaces_)
{
if (n) noFaces = false;
}
if (noFaces)
{
// No surfaces with faces at all.
return true;
}
// Determine the per-surface number of fields, including Ids etc.
// Only seems to be needed for VTK legacy
countFields();
forAll(*this, surfi)
{
const sampledSurface& s = (*this)[surfi];
if (!nFaces_[surfi])
{
continue;
}
if ((request & actions_[surfi]) & ACTION_STORE)
{
storeRegistrySurface(s);
}
if ((request & actions_[surfi]) & ACTION_SURF_MESH)
{
s.storeSurfMesh();
}
if ((request & actions_[surfi]) & ACTION_WRITE)
{
// Output writers
surfaceWriter& outWriter = writers_[surfi];
if (outWriter.needsUpdate())
{
outWriter.setSurface(s);
}
outWriter.open(outputPath_/s.name());
outWriter.beginTime(obr_.time());
// Write geometry if no fields would otherwise be written
if (!outWriter.nFields() || outWriter.separateGeometry())
{
outWriter.writeGeometry();
continue;
}
// Write original ids - as label or scalar field
const word fieldName("Ids");
if (s.hasFaceIds() && !s.interpolate())
{
writeSurface
(
outWriter,
Field<label>(s.originalIds()),
fieldName
);
}
}
}
const IOobjectList objects(obr_, obr_.time().timeName());
performAction<volScalarField>(objects, request);
performAction<volVectorField>(objects, request);
performAction<volSphericalTensorField>(objects, request);
performAction<volSymmTensorField>(objects, request);
performAction<volTensorField>(objects, request);
// Only bother with surface fields if a sampler supports them
if
(
testAny
(
surfaces(),
[] (const sampledSurface& s) { return s.withSurfaceFields(); }
)
)
{
performAction<surfaceScalarField>(objects, request);
performAction<surfaceVectorField>(objects, request);
performAction<surfaceSphericalTensorField>(objects, request);
performAction<surfaceSymmTensorField>(objects, request);
performAction<surfaceTensorField>(objects, request);
}
// Finish this time step
forAll(writers_, surfi)
{
if ((request & actions_[surfi]) & ACTION_WRITE)
{
writers_[surfi].endTime();
}
}
return true;
}
bool Foam::sampledSurfaces::execute()
{
if (onExecute_)
{
return performAction(ACTION_ALL & ~ACTION_WRITE);
}
return true;
}
bool Foam::sampledSurfaces::write()
{
return performAction(ACTION_ALL);
}
void Foam::sampledSurfaces::updateMesh(const mapPolyMesh& mpm)
{
if (&mpm.mesh() == &mesh_)
@ -383,9 +670,9 @@ void Foam::sampledSurfaces::readUpdate(const polyMesh::readUpdateState state)
bool Foam::sampledSurfaces::needsUpdate() const
{
forAll(*this, surfi)
for (const sampledSurface& s : surfaces())
{
if (operator[](surfi).needsUpdate())
if (s.needsUpdate())
{
return true;
}
@ -397,26 +684,29 @@ bool Foam::sampledSurfaces::needsUpdate() const
bool Foam::sampledSurfaces::expire()
{
bool justExpired = false;
// Dimension as fraction of mesh bounding box
const scalar mergeDim = mergeTol_ * mesh_.bounds().mag();
forAll(*this, surfi)
label nChanged = 0;
label surfi = 0;
for (sampledSurface& s : surfaces())
{
if (operator[](surfi).expire())
if (s.expire())
{
justExpired = true;
++nChanged;
}
// Clear merge information
if (Pstream::parRun())
{
mergedList_[surfi].clear();
}
writers_[surfi].expire();
writers_[surfi].mergeDim() = mergeDim;
nFaces_[surfi] = 0;
++surfi;
}
changedGeom_ = true;
// true if any surfaces just expired
return justExpired;
// True if any surfaces just expired
return nChanged;
}
@ -427,48 +717,24 @@ bool Foam::sampledSurfaces::update()
return false;
}
bool updated = false;
label nUpdated = 0;
// Serial: quick and easy, no merging required
if (!Pstream::parRun())
label surfi = 0;
for (sampledSurface& s : surfaces())
{
forAll(*this, surfi)
{
sampledSurface& s = operator[](surfi);
if (s.update())
{
updated = true;
changedGeom_[surfi] = true;
}
}
return updated;
}
// Dimension as fraction of mesh bounding box
const scalar mergeDim = mergeTol_*mesh_.bounds().mag();
if (Pstream::master() && debug)
{
Pout<< nl << "Merging all points within "
<< mergeDim << " metre" << endl;
}
forAll(*this, surfi)
{
sampledSurface& s = operator[](surfi);
if (s.update())
{
updated = true;
changedGeom_[surfi] = true;
mergedList_[surfi].merge(s, mergeDim);
++nUpdated;
writers_[surfi].expire();
}
nFaces_[surfi] = returnReduce(s.faces().size(), sumOp<label>());
++surfi;
}
return updated;
return nUpdated;
}

View File

@ -53,8 +53,12 @@ Description
// (only used if interpolate=true for the surfaces below)
interpolationScheme cell;
// Optional: registry storage
store true
// Output surface format
surfaceFormat vtk;
formatOptions
{
vtk
@ -76,6 +80,12 @@ Description
// Optional: generate values on points instead of faces
interpolate true;
// Optional: alternative output type
surfaceFormat ensight;
// Optional: registry storage
store true
}
);
}
@ -84,13 +94,24 @@ Description
Entries:
\table
Property | Description | Required | Default
type | surfaces | yes |
surfaces | list or dictionary of sample surfaces | recommended |
fields | word/regex list of fields to sampled | yes |
type | Type-name: surfaces | yes |
surfaces | Dictionary or list of sample surfaces | expected |
fields | word/regex list of fields to sample | yes |
sampleScheme | scheme to obtain face centre value | no | cell
interpolationScheme | scheme to obtain node values | no | cellPoint
surfaceFormat | output surface format | yes |
formatOptions | dictionary of format options | no |
sampleOnExecute | Sample (store) on execution as well | no | false
store | Store surface/fields on registry | no | false
\endtable
Additional per-surface entries:
\table
Property | Description | Required | Default
store | Store surface/fields on registry | no |
surfaceFormat | output surface format | no |
formatOptions | dictionary of format options | no |
surfMeshStore | Store surface/fields as surfMesh (transitional) | no |
\endtable
Note
@ -111,10 +132,8 @@ SourceFiles
#include "fvMeshFunctionObject.H"
#include "sampledSurface.H"
#include "surfaceWriter.H"
#include "mergedSurf.H"
#include "volFieldsFwd.H"
#include "surfaceFieldsFwd.H"
#include "wordRes.H"
#include "IOobjectList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -122,6 +141,9 @@ SourceFiles
namespace Foam
{
// Forward Declarations
class polySurface;
/*---------------------------------------------------------------------------*\
Class sampledSurfaces Declaration
\*---------------------------------------------------------------------------*/
@ -133,23 +155,36 @@ class sampledSurfaces
{
// Static Data Members
//- Output verbosity
static bool verbose_;
//- Tolerance for merging points (fraction of mesh bounding box)
static scalar mergeTol_;
//- Local control for sampling actions
enum sampleActionType : unsigned
{
ACTION_NONE = 0,
ACTION_WRITE = 0x1,
ACTION_STORE = 0x2,
ACTION_SURF_MESH = 0x4,
ACTION_ALL = 0xF
};
// Private Data
//- Load fields from files (not from objectRegistry)
const bool loadFromFiles_;
//- Output verbosity
bool verbose_;
//- Perform sample/store actions on execute as well
bool onExecute_;
//- Output path
fileName outputPath_;
// Read from dictonary
// Read from dictionary
//- Names of fields to sample
wordRes fieldSelection_;
@ -161,19 +196,16 @@ class sampledSurfaces
word sampleNodeScheme_;
// Surfaces
// Output control
//- Merged meshed surfaces (parallel only)
List<mergedSurf> mergedList_;
//- Surface writers (one per surface)
PtrList<surfaceWriter> writers_;
//- Track which surfaces have changed
List<bool> changedGeom_;
//- Per-surface selection of store/write actions
List<unsigned> actions_;
// Calculated
//- Surface formatter
autoPtr<surfaceWriter> formatter_;
//- Cached values of the global number of faces per-surface
labelList nFaces_;
// Private Member Functions
@ -190,42 +222,82 @@ class sampledSurfaces
return *this;
}
//- Return number of fields
label classifyFields();
//- A new surfaceWriter, with per-surface formatOptions
static autoPtr<surfaceWriter> newWriter
(
word writeType,
const dictionary& formatOptions,
const dictionary& surfDict
);
//- Write geometry only
void writeGeometry() const;
//- Write scalar field with original ids
void writeOriginalIds();
//- Perform sampling action with store/write
bool performAction(unsigned request);
//- Count selected/sampled fields per surface
void countFields();
//- Write sampled fieldName on surface and on outputDir path
template<class Type>
void writeSurface
(
surfaceWriter& writer,
const Field<Type>& values,
const label surfi,
const word& fieldName
);
//- Sample and store/write a specific volume field
template<class Type>
void performAction
(
const GeometricField<Type, fvPatchField, volMesh>& fld,
unsigned request
);
//- Sample and store/write a specific surface field
template<class Type>
void performAction
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& fld,
unsigned request
);
//- Sample and write all applicable sampled fields
template<class GeoField>
void performAction
(
const IOobjectList& objects,
unsigned request
);
//- Get surface from registry if available.
// \return surface or nullptr
polySurface* getRegistrySurface(const sampledSurface& s) const;
//- Put surface onto registry, when enabled.
// \return surface or nullptr it surface should not be stored
polySurface* storeRegistrySurface(const sampledSurface& s);
//- Remove surface from registry.
// \return True if surface existed and was removed
bool removeRegistrySurface(const sampledSurface& s);
//- Store sampled field onto surface registry if it exists
template<class Type, class GeoMeshType>
bool storeRegistryField
(
const sampledSurface& s,
const word& fieldName,
const fileName& outputDir
const dimensionSet& dims,
Field<Type>&& values
);
//- Sample and write a particular volume field
template<class Type>
void sampleAndWrite
(
const GeometricField<Type, fvPatchField, volMesh>& vField
);
//- Sample and write a particular surface field
template<class Type>
void sampleAndWrite
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& sField
);
//- Sample and write all sampled fields
template<class Type> void sampleAndWrite(const IOobjectList& objects);
//- Test surfaces for condition
template<class Container, class Predicate>
static bool testAny(const Container& items, const Predicate& pred);
//- No copy construct
sampledSurfaces(const sampledSurfaces&) = delete;

View File

@ -1,89 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2015 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "sampledSurfaces.H"
#include "IOobjectList.H"
#include "UIndirectList.H"
#include "ListOps.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::label Foam::sampledSurfaces::classifyFields()
{
label nFields = 0;
wordList allFields; // Just needed for warnings
HashTable<wordHashSet> available;
if (loadFromFiles_)
{
// Check files for a particular time
IOobjectList objects(obr_, obr_.time().timeName());
allFields = objects.names();
available = objects.classes(fieldSelection_);
}
else
{
// Check currently available fields
allFields = obr_.names();
available = obr_.classes(fieldSelection_);
}
DynamicList<label> missed(fieldSelection_.size());
// Detect missing fields
forAll(fieldSelection_, i)
{
if (!ListOps::found(allFields, fieldSelection_[i]))
{
missed.append(i);
}
}
if (missed.size())
{
WarningInFunction
<< nl
<< "Cannot find "
<< (loadFromFiles_ ? "field file" : "registered field")
<< " matching "
<< UIndirectList<wordRe>(fieldSelection_, missed) << endl;
}
// Total number selected
forAllConstIters(available, iter)
{
nFields += iter.val().size();
}
return nFields;
}
// ************************************************************************* //

View File

@ -28,110 +28,61 @@ License
#include "sampledSurfaces.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "globalIndex.H"
#include "stringListOps.H"
#include "polySurface.H"
#include "polySurfaceFields.H"
#include "polySurfacePointFields.H"
#include "surfMesh.H"
#include "surfGeoMesh.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::sampledSurfaces::writeSurface
(
surfaceWriter& writer,
const Field<Type>& values,
const label surfi,
const word& fieldName,
const fileName& outputDir
const word& fieldName
)
{
const sampledSurface& s = operator[](surfi);
fileName outputName = writer.write(fieldName, values);
if (changedGeom_[surfi])
{
// Trigger any changes
formatter_->updateMesh(outputDir, s.name());
changedGeom_[surfi] = false;
}
// Case-local file name with "<case>" to make relocatable
if (Pstream::parRun())
{
// Gather all values into single field
Field<Type> allValues;
dictionary propsDict;
propsDict.add
(
"file",
time_.relativePath(outputName, true)
);
setProperty(fieldName, propsDict);
}
globalIndex::gatherOp(values, allValues);
fileName sampleFile;
if (Pstream::master())
{
// Renumber (point data) to correspond to merged points
if (mergedList_[surfi].pointsMap().size() == allValues.size())
{
inplaceReorder(mergedList_[surfi].pointsMap(), allValues);
allValues.resize(mergedList_[surfi].points().size());
}
// Write to time directory under outputPath_
// skip surface without faces (eg, a failed cut-plane)
if (mergedList_[surfi].size())
{
sampleFile = formatter_->write
(
outputDir,
s.name(),
mergedList_[surfi],
fieldName,
allValues,
s.interpolate()
);
}
}
Pstream::scatter(sampleFile);
if (sampleFile.size())
{
// Case-local file name with "<case>" to make relocatable
dictionary propsDict;
propsDict.add
(
"file",
time_.relativePath(sampleFile, true)
);
setProperty(fieldName, propsDict);
}
}
else
{
// Write to time directory under outputPath_
// skip surface without faces (eg, a failed cut-plane)
if (s.faces().size())
{
fileName fName = formatter_->write
(
outputDir,
s.name(),
s,
fieldName,
values,
s.interpolate()
);
// Case-local file name with "<case>" to make relocatable
dictionary propsDict;
propsDict.add
(
"file",
time_.relativePath(fName, true)
);
setProperty(fieldName, propsDict);
}
}
template<class Type, class GeoMeshType>
bool Foam::sampledSurfaces::storeRegistryField
(
const sampledSurface& s,
const word& fieldName,
const dimensionSet& dims,
Field<Type>&& values
)
{
return s.storeRegistryField<Type, GeoMeshType>
(
storedObjects(),
fieldName,
dims,
std::move(values),
IOobject::groupName(name(), s.name())
);
}
template<class Type>
void Foam::sampledSurfaces::sampleAndWrite
void Foam::sampledSurfaces::performAction
(
const GeometricField<Type, fvPatchField, volMesh>& vField
const GeometricField<Type, fvPatchField, volMesh>& fld,
unsigned request
)
{
// The sampler for this field
@ -140,13 +91,20 @@ void Foam::sampledSurfaces::sampleAndWrite
// The interpolator for this field
autoPtr<interpolation<Type>> interpPtr;
const word& fieldName = vField.name();
const fileName outputDir = outputPath_/vField.time().timeName();
const word& fieldName = fld.name();
const dimensionSet& dims = fld.dimensions();
forAll(*this, surfi)
{
const sampledSurface& s = operator[](surfi);
// Skip surface without faces (eg, failed cut-plane)
if (!nFaces_[surfi])
{
continue;
}
Field<Type> values;
if (s.interpolate())
@ -156,7 +114,7 @@ void Foam::sampledSurfaces::sampleAndWrite
interpPtr = interpolation<Type>::New
(
sampleNodeScheme_,
vField
fld
);
}
@ -169,56 +127,117 @@ void Foam::sampledSurfaces::sampleAndWrite
samplePtr = interpolation<Type>::New
(
sampleFaceScheme_,
vField
fld
);
}
values = s.sample(*samplePtr);
}
writeSurface<Type>(values, surfi, fieldName, outputDir);
if ((request & actions_[surfi]) & ACTION_WRITE)
{
writeSurface<Type>(writers_[surfi], values, fieldName);
}
if ((request & actions_[surfi]) & ACTION_SURF_MESH)
{
// Face fields only!
s.storeSurfMeshField<Type, surfGeoMesh>
(
fieldName, dims, values
);
}
if ((request & actions_[surfi]) & ACTION_STORE)
{
if (s.interpolate())
{
storeRegistryField<Type, polySurfacePointGeoMesh>
(
s, fieldName, dims, std::move(values)
);
}
else
{
storeRegistryField<Type, polySurfaceGeoMesh>
(
s, fieldName, dims, std::move(values)
);
}
}
}
}
template<class Type>
void Foam::sampledSurfaces::sampleAndWrite
void Foam::sampledSurfaces::performAction
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& sField
const GeometricField<Type, fvsPatchField, surfaceMesh>& fld,
unsigned request
)
{
const word& fieldName = sField.name();
const fileName outputDir = outputPath_/sField.time().timeName();
const word& fieldName = fld.name();
const dimensionSet& dims = fld.dimensions();
forAll(*this, surfi)
{
const sampledSurface& s = operator[](surfi);
Field<Type> values(s.sample(sField));
writeSurface<Type>(values, surfi, fieldName, outputDir);
const sampledSurface& s = (*this)[surfi];
// Skip surface without faces (eg, failed cut-plane)
if (!nFaces_[surfi])
{
continue;
}
Field<Type> values(s.sample(fld));
if ((request & actions_[surfi]) & ACTION_WRITE)
{
writeSurface<Type>(writers_[surfi], values, fieldName);
}
if ((request & actions_[surfi]) & ACTION_SURF_MESH)
{
s.storeSurfMeshField<Type, surfGeoMesh>
(
fieldName, dims, values
);
}
if ((request & actions_[surfi]) & ACTION_STORE)
{
storeRegistryField<Type, polySurfaceGeoMesh>
(
s, fieldName, dims, std::move(values)
);
}
}
}
template<class GeoField>
void Foam::sampledSurfaces::sampleAndWrite(const IOobjectList& objects)
void Foam::sampledSurfaces::performAction
(
const IOobjectList& objects,
unsigned request
)
{
wordList fieldNames;
if (loadFromFiles_)
{
fieldNames = objects.sortedNames(GeoField::typeName, fieldSelection_);
fieldNames = objects.sortedNames<GeoField>(fieldSelection_);
}
else
{
fieldNames = mesh_.thisDb().sortedNames<GeoField>(fieldSelection_);
writeOriginalIds();
}
for (const word& fieldName : fieldNames)
{
if (verbose_)
{
Info<< "sampleAndWrite: " << fieldName << endl;
Info<< "sampleWrite: " << fieldName << endl;
}
if (loadFromFiles_)
@ -235,17 +254,37 @@ void Foam::sampledSurfaces::sampleAndWrite(const IOobjectList& objects)
mesh_
);
sampleAndWrite(fld);
performAction(fld, request);
}
else
{
sampleAndWrite
performAction
(
mesh_.thisDb().lookupObject<GeoField>(fieldName)
mesh_.thisDb().lookupObject<GeoField>(fieldName),
request
);
}
}
}
template<class Container, class Predicate>
bool Foam::sampledSurfaces::testAny
(
const Container& items,
const Predicate& pred
)
{
for (const auto& item : items)
{
if (pred(item))
{
return true;
}
}
return false;
}
// ************************************************************************* //

View File

@ -1,116 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2015 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "boundaryDataSurfaceWriter.H"
#include "makeSurfaceWriterMethods.H"
#include "argList.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
makeSurfaceWriterType(boundaryDataSurfaceWriter);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Field writing implementation
#include "boundaryDataSurfaceWriterImpl.C"
// Field writing methods
defineSurfaceWriterWriteFields(Foam::boundaryDataSurfaceWriter);
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::fileName Foam::boundaryDataSurfaceWriter::write
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const bool verbose
) const
{
// geometry: rootdir/surfaceName/"points"
// field: rootdir/surfaceName/time/field
const fileName baseDir(outputDir.path()/surfaceName);
const fileName timeName(outputDir.name());
const pointField& points = surf.points();
// Dummy time to use as an objectRegistry
const fileName caseDir(argList::envGlobalPath());
Time dummyTime
(
caseDir.path(), // root-path,
caseDir.name(), // case-name,
"system", //
"constant", //
false // no function objects
);
// Write points
if (verbose)
{
Info<< "Writing points to " << baseDir/"points" << endl;
}
pointIOField pts
(
IOobject
(
baseDir/"points",
dummyTime,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
points
);
{
// Do like regIOobject::writeObject but don't do instance() adaptation
// since this would write to e.g. 0/ instead of postProcessing/
// Try opening an OFstream for object
mkDir(pts.path());
OFstream os(pts.objectPath());
//pts.writeHeader(os);
pts.writeData(os);
//pts.writeEndDivider(os);
}
return baseDir;
}
// ************************************************************************* //

View File

@ -1,231 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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/>.
Class
Foam::boundaryDataSurfaceWriter
Description
A surfaceWriter for outputting to a form useable for the
timeVaryingMapped boundary condition. This reads the data from
constant/boundaryData/\<patch\> directory
Typical way of working:
- use a sampledSurface of type 'patch' (to sample a patch):
\verbatim
surfaces
{
type surfaces;
surfaceFormat boundaryData;
fields ( p );
surfaces
(
outlet
{
type patch;
patches (outlet);
interpolate false;
}
);
}
\endverbatim
- write using this writer.
- move postProcessing/surfaces/outlet to constant/boundaryData/outlet
in your destination case.
- use a timeVaryingMappedFixedValue condition to read and interpolate
the profile:
type timeVaryingMappedFixedValue;
setAverage false; // do not use read average
offset 0; // do not apply offset to values
Note:
- with 'interpolate false' the data is on the face centres of the
patch. Take care that a 2D geometry will only have a single row
of face centres so might not provide a valid triangulation
(this is what timeVaryingMappedFixedValue uses to do interpolation)
(Alternatively use timeVaryingMappedFixedValue with mapMethod 'nearest')
\heading Output file locations
The \c rootdir normally corresponds to something like
\c postProcessing/\<name\>
where the geometry is written as:
\verbatim
rootdir
`-- surfaceName
`-- "points"
\endverbatim
and field data:
\verbatim
rootdir
`-- surfaceName
|-- "points"
`-- timeName
`-- field
\endverbatim
SourceFiles
boundaryDataSurfaceWriter.C
\*---------------------------------------------------------------------------*/
#ifndef boundaryDataSurfaceWriter_H
#define boundaryDataSurfaceWriter_H
#include "surfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class boundaryDataSurfaceWriter Declaration
\*---------------------------------------------------------------------------*/
class boundaryDataSurfaceWriter
:
public surfaceWriter
{
// Private Member Functions
//- Templated write operation
template<class Type>
fileName writeTemplate
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<Type>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const;
public:
//- Runtime type information
TypeName("boundaryData");
// Constructors
//- Construct null
boundaryDataSurfaceWriter() = default;
//- Destructor
virtual ~boundaryDataSurfaceWriter() = default;
// Member Functions
//- Write single surface geometry to file.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write scalarField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<scalar>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write vectorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<vector>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write sphericalTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<sphericalTensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write symmTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<symmTensor>& values,//!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write tensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<tensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,132 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2015 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify i
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/>.
\*---------------------------------------------------------------------------*/
#include "OFstream.H"
#include "OSspecific.H"
#include "IOmanip.H"
#include "Time.H"
#include "pointIOField.H"
#include "primitivePatch.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
Foam::fileName Foam::boundaryDataSurfaceWriter::writeTemplate
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const word& fieldName,
const Field<Type>& values,
const bool isNodeValues,
const bool verbose
) const
{
// geometry: rootdir/surfaceName/"points"
// field: rootdir/surfaceName/time/field
const fileName baseDir(outputDir.path()/surfaceName);
const fileName timeName(outputDir.name());
const pointField& points = surf.points();
const faceList& faces = surf.faces();
// Dummy time to use as an objectRegistry
const fileName caseDir(argList::envGlobalPath());
Time dummyTime
(
caseDir.path(), // root-path
caseDir.name(), // case-name
"system", //
"constant", //
false // no function objects
);
// Write points
pointIOField pts
(
IOobject
(
baseDir/"points",
dummyTime,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
label(0)
);
if (isNodeValues)
{
if (verbose)
{
Info<< "Writing points to " << baseDir/"points" << endl;
}
pts = points;
}
else
{
if (verbose)
{
Info<< "Writing face centres to " << baseDir/"points" << endl;
}
primitivePatch pp(SubList<face>(faces, faces.size()), points);
pts = pp.faceCentres();
}
{
// Do like regIOobject::writeObject but don't do instance() adaptation
// since this would write to e.g. 0/ instead of postProcessing/
// Try opening an OFstream for object
mkDir(pts.path());
OFstream os(pts.objectPath());
//pts.writeHeader(os);
pts.writeData(os);
//pts.writeEndDivider(os);
}
// Write field
{
fileName valsDir(baseDir/timeName);
mkDir(valsDir);
OFstream os(valsDir/fieldName);
os << values;
}
return baseDir;
}
// ************************************************************************* //

View File

@ -1,259 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
Class
Foam::ensightSurfaceWriter
Description
A surfaceWriter for Ensight format.
\verbatim
formatOptions
{
ensight
{
format ascii;
collateTimes true;
}
}
\endverbatim
Format options:
\table
Property | Description | Required | Default
format | ascii/binary | no | ascii
collateTimes | use common geometry for times | no | true
\endtable
SourceFiles
ensightSurfaceWriter.C
\*---------------------------------------------------------------------------*/
#ifndef ensightSurfaceWriter_H
#define ensightSurfaceWriter_H
#include "surfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightSurfaceWriter Declaration
\*---------------------------------------------------------------------------*/
class ensightSurfaceWriter
:
public surfaceWriter
{
// Private data
//- Write option (default: IOstream::ASCII)
IOstream::streamFormat writeFormat_;
//- Collate times (default: true)
bool collateTimes_;
// Private Member Functions
//- Print time-set for ensight case file
static void printTimeset
(
OSstream& os,
const label ts,
const scalar& timeValue
);
//- Print time-set for ensight case file
static void printTimeset
(
OSstream& os,
const label ts,
const UList<scalar>& times
);
//- Templated write operation - one file per timestep
template<class Type>
fileName writeCollated
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<Type>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const;
//- Templated write operation - all time steps in single file
template<class Type>
fileName writeUncollated
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<Type>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const;
//- Templated write operation
template<class Type>
fileName writeTemplate
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<Type>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const;
public:
//- Runtime type information
TypeName("ensight");
// Constructors
//- Construct null
ensightSurfaceWriter();
//- Construct with some output options
ensightSurfaceWriter(const dictionary& options);
//- Destructor
virtual ~ensightSurfaceWriter() = default;
// Member Functions
//- True if the surface format supports geometry in a separate file.
// False if geometry and field must be in a single file
virtual bool separateGeometry() const;
//- Trigger for geometry changes.
// \note this is a stop-gap solution
virtual void updateMesh
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName //!< Name of surface
) const; // override
//- Write single surface geometry to file.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write scalarField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<scalar>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write vectorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<vector>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write sphericalTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<sphericalTensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write symmTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<symmTensor>& values,//!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write tensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<tensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,531 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2014 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "IOmanip.H"
#include "Fstream.H"
#include "OSspecific.H"
#include "ensightCase.H"
#include "ensightPartFaces.H"
#include "ensightOutput.H"
#include "ensightPTraits.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
Foam::fileName Foam::ensightSurfaceWriter::writeUncollated
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const word& fieldName,
const Field<Type>& values,
const bool isNodeValues,
const bool verbose
) const
{
const ensight::FileName surfName(surfaceName);
const ensight::VarName varName(fieldName);
// geometry: rootdir/time/<field>/surfaceName.case
// geometry: rootdir/time/<field>/surfaceName.<index>.mesh
// field: rootdir/time/<field>/surfaceName.<index>.field
// Variable name as sub-directory for results
// eg, something like this:
// - VAR1/SURF1.case
// - VAR1/SURF1.0000.mesh
// - VAR1/SURF1.0001.VAR1
// - VAR1/SURF2.case
// - VAR1/SURF2.0000.mesh
// - VAR1/SURF2.0001.VAR1
// and
// - VAR2/SURF1.case
// - VAR2/SURF1.0000.mesh
// - VAR2/SURF1.0001.VAR2
const fileName baseDir = outputDir/varName;
const fileName timeDir = outputDir.name();
// Convert timeDir to a value (if possible - use 0.0 otherwise)
scalar timeValue = 0.0;
readScalar(timeDir, timeValue);
if (!isDir(baseDir))
{
mkDir(baseDir);
}
OFstream osCase(baseDir/surfName + ".case", IOstream::ASCII);
// Format options
osCase.setf(ios_base::left);
osCase.setf(ios_base::scientific, ios_base::floatfield);
osCase.precision(5);
ensightGeoFile osGeom
(
baseDir,
surfName + ".00000000.mesh",
writeFormat_
);
ensightFile osField
(
baseDir,
surfName + ".00000000." + varName,
writeFormat_
);
if (verbose)
{
Info<< "Writing case file to " << osCase.name() << endl;
}
osCase
<< "FORMAT" << nl
<< "type: ensight gold" << nl
<< nl
<< "GEOMETRY" << nl
<< "model: 1 " << osGeom.name().name() << nl
<< nl
<< "VARIABLE" << nl
<< ensightPTraits<Type>::typeName
<<
(
isNodeValues
? " per node: 1 " // time-set 1
: " per element: 1 " // time-set 1
)
<< setw(15) << varName << ' '
<< surfName.c_str() << ".********." << varName << nl;
osCase
<< nl
<< "TIME" << nl;
printTimeset(osCase, 1, timeValue);
osCase << "# end" << nl;
ensightPartFaces ensPart
(
0,
osGeom.name().name(),
surf.points(),
surf.faces(),
true // contiguous points
);
osGeom << ensPart;
// Write field
osField.writeKeyword(ensightPTraits<Type>::typeName);
if (isNodeValues)
{
ensightOutput::Serial::writePointField
(
values,
ensPart,
osField
// false // serial
);
}
else
{
ensightOutput::Detail::writeFaceField
(
values,
ensPart,
osField,
false // serial
);
}
return osCase.name();
}
template<class Type>
Foam::fileName Foam::ensightSurfaceWriter::writeCollated
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const word& fieldName,
const Field<Type>& values,
const bool isNodeValues,
const bool verbose
) const
{
const ensight::FileName surfName(surfaceName);
const ensight::VarName varName(fieldName);
// geometry: rootdir/surfaceName/surfaceName.case
// geometry: rootdir/surfaceName/surfaceName/data/<index>/geometry
// field: rootdir/surfaceName/surfaceName/data/<index>/field
// Use surface name as sub-directory for results
// eg, something like this:
// - SURF1/SURF1.case
// - SURF1/SURF1/data/00000000/geometry
// - SURF1/SURF1/data/00000000/VAR1
// - SURF1/SURF1/data/00000000/VAR2
// and
// - SURF2/SURF2.case
// - SURF2/SURF2/data/00000000/geometry
// - SURF2/SURF2/data/00000000/VAR1
// - SURF2/SURF2/data/00000000/VAR2
// Names "data" and "geometry" as per ensightCase:
const char* fmt = "%08d";
const char* mask = "data/********/";
const fileName baseDir = outputDir.path()/surfName;
const fileName timeDir = outputDir.name();
// Convert timeDir to a value (if possible - use 0.0 otherwise)
scalar timeValue = 0.0;
readScalar(timeDir, timeValue);
scalar meshValue = 0;
if (!isDir(baseDir))
{
mkDir(baseDir);
}
label meshIndex = 0;
label timeIndex = 0;
fileName geometryName;
// Do case file
{
dictionary dict;
scalarList meshes;
scalarList times;
bool stateChanged = false;
if (isFile(baseDir/"fieldsDict"))
{
IFstream is(baseDir/"fieldsDict");
if (is.good() && dict.read(is))
{
dict.readIfPresent("meshes", meshes);
dict.readIfPresent("times", times);
timeIndex = 1+findLower(times, timeValue);
if (dict.readIfPresent("updateMesh", meshValue))
{
meshIndex = 1+findLower(meshes, meshValue);
dict.remove("updateMesh");
stateChanged = true;
}
else if (meshes.size())
{
meshIndex = meshes.size()-1;
meshValue = meshes.last();
}
else
{
meshIndex = 0;
}
}
}
// Update stored times list
meshes.resize(meshIndex+1, -1);
times.resize(timeIndex+1, -1);
if (meshes[meshIndex] != meshValue)
{
stateChanged = true;
}
if (times[timeIndex] != timeValue)
{
stateChanged = true;
}
meshes[meshIndex] = meshValue;
times[timeIndex] = timeValue;
geometryName =
"data"/word::printf(fmt, meshIndex)/ensightCase::geometryName;
// Add my information to dictionary
{
dict.set("meshes", meshes);
dict.set("times", times);
if (dict.found("fields"))
{
dictionary& fieldsDict = dict.subDict("fields");
if (!fieldsDict.found(fieldName))
{
dictionary fieldDict;
fieldDict.set("type", ensightPTraits<Type>::typeName);
fieldDict.set("name", varName); // ensight variable name
fieldsDict.set(fieldName, fieldDict);
stateChanged = true;
}
}
else
{
dictionary fieldDict;
fieldDict.set("type", ensightPTraits<Type>::typeName);
fieldDict.set("name", varName); // ensight variable name
dictionary fieldsDict;
fieldsDict.set(fieldName, fieldDict);
dict.set("fields", fieldsDict);
stateChanged = true;
}
}
if (stateChanged)
{
if (verbose)
{
Info<< "Writing state file to fieldsDict" << endl;
}
{
OFstream os(baseDir/"fieldsDict");
os << "// Summary of Ensight fields, times" << nl << nl;
dict.write(os, false);
}
OFstream osCase(baseDir/surfName + ".case", IOstream::ASCII);
// Format options
osCase.setf(ios_base::left);
osCase.setf(ios_base::scientific, ios_base::floatfield);
osCase.precision(5);
if (verbose)
{
Info<< "Writing case file to " << osCase.name() << endl;
}
// The geometry can be any of the following:
// 0: constant/static
// 1: moving, with the same frequency as the data
// 2: moving, with different frequency as the data
const label tsGeom =
(meshes.size() == 1 ? 0 : meshes == times ? 1 : 2);
osCase
<< "FORMAT" << nl
<< "type: ensight gold" << nl
<< nl
<< "GEOMETRY" << nl;
if (tsGeom)
{
// moving
osCase
<< "model: " << tsGeom << " " // time-set (1|2)
<< mask << geometryName.name() << nl;
}
else
{
// steady
osCase
<< "model: "
<< geometryName.c_str() << nl;
}
osCase
<< nl
<< "VARIABLE" << nl;
const dictionary& fieldsDict = dict.subDict("fields");
for (const entry& dEntry : fieldsDict)
{
const dictionary& subDict = dEntry.dict();
const word fieldType(subDict.get<word>("type"));
const word varName = subDict.lookupOrDefault
(
"name",
dEntry.keyword() // fieldName as fallback
);
osCase
<< fieldType
<<
(
isNodeValues
? " per node: 1 " // time-set 1
: " per element: 1 " // time-set 1
)
<< setw(15) << varName << ' '
<< mask << varName << nl;
}
osCase
<< nl
<< "TIME" << nl;
printTimeset(osCase, 1, times);
if (tsGeom == 2)
{
printTimeset(osCase, 2, meshes);
}
osCase << "# end" << nl;
}
}
// Location for data (and possibly the geometry as well)
fileName dataDir = baseDir/"data"/word::printf(fmt, timeIndex);
// As per mkdir -p "data/00000000"
mkDir(dataDir);
const fileName meshFile(baseDir/geometryName);
// Write geometry
ensightPartFaces ensPart
(
0,
meshFile.name(),
surf.points(),
surf.faces(),
true // contiguous points
);
if (!exists(meshFile))
{
if (verbose)
{
Info<< "Writing mesh file to " << meshFile.name() << endl;
}
// Use two-argument form for path-name to avoid validating the base-dir
ensightGeoFile osGeom(meshFile.path(), meshFile.name(), writeFormat_);
osGeom << ensPart;
}
// Write field
ensightFile osField
(
dataDir,
varName,
writeFormat_
);
if (verbose)
{
Info<< "Writing field file to " << osField.name() << endl;
}
// Write field
osField.writeKeyword(ensightPTraits<Type>::typeName);
if (isNodeValues)
{
ensightOutput::Serial::writePointField
(
values,
ensPart,
osField
// serial
);
}
else
{
ensightOutput::Detail::writeFaceField
(
values,
ensPart,
osField,
false // serial
);
}
// Place a timestamp in the directory for future reference
{
OFstream timeStamp(dataDir/"time");
timeStamp
<< "# timestep time" << nl
<< dataDir.name() << " " << timeValue << nl;
}
return baseDir/surfName + ".case";
}
template<class Type>
Foam::fileName Foam::ensightSurfaceWriter::writeTemplate
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const word& fieldName,
const Field<Type>& values,
const bool isNodeValues,
const bool verbose
) const
{
if (collateTimes_)
{
return writeCollated
(
outputDir,
surfaceName,
surf,
fieldName,
values,
isNodeValues,
verbose
);
}
else
{
return writeUncollated
(
outputDir,
surfaceName,
surf,
fieldName,
values,
isNodeValues,
verbose
);
}
}
// ************************************************************************* //

View File

@ -1,98 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "foamSurfaceWriter.H"
#include "OFstream.H"
#include "makeSurfaceWriterMethods.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
makeSurfaceWriterType(foamSurfaceWriter);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Field writing implementation
#include "foamSurfaceWriterImpl.C"
// Field writing methods
defineSurfaceWriterWriteFields(Foam::foamSurfaceWriter);
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::fileName Foam::foamSurfaceWriter::write
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const bool verbose
) const
{
// Output:
// - rootdir/time/surfaceName/{points,faces}
fileName surfaceDir(outputDir/surfaceName);
if (!isDir(surfaceDir))
{
mkDir(surfaceDir);
}
if (verbose)
{
Info<< "Writing geometry to " << surfaceDir << endl;
}
const pointField& points = surf.points();
const faceList& faces = surf.faces();
// Points
OFstream(surfaceDir/"points")() << points;
// Faces
OFstream(surfaceDir/"faces")() << faces;
// Face centers. Not really necessary but very handy when reusing as inputs
// for e.g. timeVaryingMapped bc.
pointField faceCentres(faces.size(), Zero);
forAll(faces, facei)
{
faceCentres[facei] = faces[facei].centre(points);
}
OFstream(surfaceDir/"faceCentres")() << faceCentres;
return surfaceDir;
}
// ************************************************************************* //

View File

@ -1,209 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
Class
Foam::foamSurfaceWriter
Description
A surfaceWriter for OpenFOAM surfaces
\heading Output file locations
The \c rootdir normally corresponds to something like
\c postProcessing/\<name\>
\subheading Geometry
\verbatim
rootdir
`-- timeName
`-- surfaceName
|-- "points"
|-- "faceCentres"
`-- "faces"
\endverbatim
\subheading Fields
\verbatim
rootdir
`-- timeName
`-- surfaceName
|-- scalarField
| |-- field
| `-- field
|-- vectorField
|-- field
`-- field
\endverbatim
SourceFiles
foamSurfaceWriter.C
\*---------------------------------------------------------------------------*/
#ifndef foamSurfaceWriter_H
#define foamSurfaceWriter_H
#include "surfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class foamSurfaceWriter Declaration
\*---------------------------------------------------------------------------*/
class foamSurfaceWriter
:
public surfaceWriter
{
// Private Member Functions
//- Templated write operation
template<class Type>
fileName writeTemplate
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<Type>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const;
public:
//- Runtime type information
TypeName("foam");
// Constructors
//- Construct null
foamSurfaceWriter() = default;
//- Destructor
virtual ~foamSurfaceWriter() = default;
// Member Functions
//- True if the surface format supports geometry in a separate file.
// False if geometry and field must be in a single file
virtual bool separateGeometry() const
{
return true;
}
//- Write single surface geometry to file.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write scalarField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<scalar>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write vectorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<vector>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write sphericalTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<sphericalTensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write symmTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<symmTensor>& values,//!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write tensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<tensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,77 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2014 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "OFstream.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
Foam::fileName Foam::foamSurfaceWriter::writeTemplate
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const word& fieldName,
const Field<Type>& values,
const bool isNodeValues,
const bool verbose
) const
{
// Geometry should already have been written
// Values to separate directory (e.g. "scalarField/p")
// field: rootdir/time/surfaceName/fieldType/field
const word fieldTypeName
(
word(pTraits<Type>::typeName) + FieldBase::typeName
);
const fileName base(outputDir/surfaceName);
const fileName outputFile(base / fieldTypeName / fieldName);
if (verbose)
{
Info<< "Writing field " << fieldName << " to " << base << endl;
}
if (!isDir(outputFile.path()))
{
mkDir(outputFile.path());
}
// Write field
OFstream os(outputFile);
os << values;
return os.name();
}
// ************************************************************************* //

View File

@ -1,136 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "rawSurfaceWriter.H"
#include "OFstream.H"
#include "OSspecific.H"
#include "makeSurfaceWriterMethods.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
makeSurfaceWriterType(rawSurfaceWriter);
addToRunTimeSelectionTable(surfaceWriter, rawSurfaceWriter, wordDict);
}
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Emit x,y,z
static inline void writePoint(Ostream& os, const point& p)
{
os << p.x() << ' ' << p.y() << ' ' << p.z();
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Field writing implementation
#include "rawSurfaceWriterImpl.C"
// Field writing methods
defineSurfaceWriterWriteFields(Foam::rawSurfaceWriter);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::rawSurfaceWriter::rawSurfaceWriter()
:
surfaceWriter(),
writeCompression_(IOstream::UNCOMPRESSED)
{}
Foam::rawSurfaceWriter::rawSurfaceWriter(const dictionary& options)
:
surfaceWriter(),
writeCompression_(IOstream::UNCOMPRESSED)
{
if (options.found("compression"))
{
writeCompression_ =
IOstream::compressionEnum(options.get<word>("compression"));
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::fileName Foam::rawSurfaceWriter::write
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const bool verbose
) const
{
// geometry: rootdir/time/surfaceName.raw
const pointField& points = surf.points();
const faceList& faces = surf.faces();
if (!isDir(outputDir))
{
mkDir(outputDir);
}
OFstream os
(
outputDir/surfaceName + ".raw",
IOstream::ASCII,
IOstream::currentVersion,
writeCompression_
);
if (verbose)
{
Info<< "Writing geometry to " << os.name() << endl;
}
// Header
os << "# geometry NO_DATA " << faces.size() << nl
<< "# x y z" << nl;
// Write faces centres
for (const face& f : faces)
{
writePoint(os, f.centre(points));
os << nl;
}
os << nl;
return os.name();
}
// ************************************************************************* //

View File

@ -1,220 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
Class
Foam::rawSurfaceWriter
Description
A surfaceWriter for raw output.
The formatOptions for raw:
\table
Property | Description | Required | Default
compression | on / off | no | off
\endtable
For example,
\verbatim
formatOptions
{
raw
{
compression on;
}
}
\endverbatim
\heading Output file locations
The \c rootdir normally corresponds to something like
\c postProcessing/\<name\>
\subheading Geometry
\verbatim
rootdir
`-- timeName
`-- surfaceName.{raw}
\endverbatim
\subheading Fields
\verbatim
rootdir
`-- timeName
|-- <field0>_surfaceName.{raw}
`-- <field1>_surfaceName.{raw}
\endverbatim
SourceFiles
rawSurfaceWriter.C
\*---------------------------------------------------------------------------*/
#ifndef rawSurfaceWriter_H
#define rawSurfaceWriter_H
#include "surfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class rawSurfaceWriter Declaration
\*---------------------------------------------------------------------------*/
class rawSurfaceWriter
:
public surfaceWriter
{
// Private data
//- Output compression (default: uncompressed)
IOstream::compressionType writeCompression_;
// Private Member Functions
//- Templated write operation
template<class Type>
fileName writeTemplate
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<Type>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const;
public:
//- Runtime type information
TypeName("raw");
// Constructors
//- Construct null
rawSurfaceWriter();
//- Construct with some output options
rawSurfaceWriter(const dictionary& options);
//- Destructor
virtual ~rawSurfaceWriter() = default;
// Member Functions
//- Write single surface geometry to file.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write scalarField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<scalar>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write vectorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<vector>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write sphericalTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<sphericalTensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write symmTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<symmTensor>& values,//!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write tensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<tensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,215 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
Class
Foam::starcdSurfaceWriter
Description
A surfaceWriter for STARCD files.
The geometry is written via the MeshedSurfaceProxy, the fields
are written in a trivial ASCII format with ID and VALUE as
so-called user data. These \c .usr files can be read into proSTAR
with these types of commands. For element data:
\verbatim
getuser FILENAME.usr cell scalar free
getuser FILENAME.usr cell vector free
\endverbatim
and for vertex data:
\verbatim
getuser FILENAME.usr vertex scalar free
getuser FILENAME.usr vertex vector free
\endverbatim
\heading Output file locations
The \c rootdir normally corresponds to something like
\c postProcessing/\<name\>
\subheading Geometry
\verbatim
rootdir
`-- timeName
`-- surfaceName.{cel,vrt,inp}
\endverbatim
\subheading Fields
\verbatim
rootdir
`-- timeName
|-- <field0>_surfaceName.{usr}
`-- <field1>_surfaceName.{usr}
\endverbatim
SourceFiles
starcdSurfaceWriter.C
\*---------------------------------------------------------------------------*/
#ifndef starcdSurfaceWriter_H
#define starcdSurfaceWriter_H
#include "surfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class starcdSurfaceWriter Declaration
\*---------------------------------------------------------------------------*/
class starcdSurfaceWriter
:
public surfaceWriter
{
// Private Member Functions
//- Templated write operation
template<class Type>
fileName writeTemplate
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<Type>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const;
public:
//- Runtime type information
TypeName("starcd");
// Constructors
//- Construct null
starcdSurfaceWriter() = default;
//- Destructor
virtual ~starcdSurfaceWriter() = default;
// Member Functions
//- True if the surface format supports geometry in a separate file.
// False if geometry and field must be in a single file
virtual bool separateGeometry() const
{
return true;
}
//- Write single surface geometry to file.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write scalarField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<scalar>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write vectorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<vector>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write sphericalTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<sphericalTensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write symmTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<symmTensor>& values,//!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write tensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<tensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,94 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2014 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "OFstream.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Emit each component
template<class Type>
static inline void writeData(Ostream& os, const Type& val)
{
const direction ncmpt = pTraits<Type>::nComponents;
for (direction cmpt=0; cmpt < ncmpt; ++cmpt)
{
os << ' ' << component(val, cmpt);
}
os << nl;
}
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
Foam::fileName Foam::starcdSurfaceWriter::writeTemplate
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf&,
const word& fieldName,
const Field<Type>& values,
const bool isNodeValues,
const bool verbose
) const
{
// field: rootdir/time/<field>_surfaceName.usr
if (!isDir(outputDir))
{
mkDir(outputDir);
}
OFstream os(outputDir/fieldName + '_' + surfaceName + ".usr");
if (verbose)
{
Info<< "Writing field " << fieldName << " to " << os.name() << endl;
}
// 1-based ids
label elemId = 1;
// No header, just write values
for (const Type& val : values)
{
os << elemId;
writeData(os, val);
++elemId;
}
return os.name();
}
// ************************************************************************* //

View File

@ -1,126 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2015 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "surfaceWriter.H"
#include "MeshedSurfaceProxy.H"
#include "proxySurfaceWriter.H"
#include "HashTable.H"
#include "word.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(surfaceWriter, 0);
defineRunTimeSelectionTable(surfaceWriter, word);
defineRunTimeSelectionTable(surfaceWriter, wordDict);
addNamedToRunTimeSelectionTable
(
surfaceWriter,
surfaceWriter,
word,
null
);
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::autoPtr<Foam::surfaceWriter>
Foam::surfaceWriter::New(const word& writeType)
{
const auto cstrIter = wordConstructorTablePtr_->cfind(writeType);
if (cstrIter.found())
{
return autoPtr<surfaceWriter>(cstrIter()());
}
else if (MeshedSurfaceProxy<face>::canWriteType(writeType))
{
// Unknown, but proxy handler can manage it
return autoPtr<surfaceWriter>(new proxySurfaceWriter(writeType));
}
FatalErrorInFunction
<< "Unknown write type \"" << writeType << "\"\n\n"
<< "Valid types : "
<< wordConstructorTablePtr_->sortedToc() << nl
<< "Valid proxy types : "
<< MeshedSurfaceProxy<face>::writeTypes() << endl
<< exit(FatalError);
return nullptr;
}
Foam::autoPtr<Foam::surfaceWriter>
Foam::surfaceWriter::New(const word& writeType, const dictionary& options)
{
{
// Constructor with options (dictionary)
const auto cstrIter = wordDictConstructorTablePtr_->cfind(writeType);
if (cstrIter.found())
{
return autoPtr<surfaceWriter>(cstrIter()(options));
}
}
// Drop through to version without options
const auto cstrIter = wordConstructorTablePtr_->cfind(writeType);
if (cstrIter.found())
{
return autoPtr<surfaceWriter>(cstrIter()());
}
else if (MeshedSurfaceProxy<face>::canWriteType(writeType))
{
// Unknown, but proxy handler can manage it
return autoPtr<surfaceWriter>
(
new proxySurfaceWriter(writeType, options)
);
}
FatalErrorInFunction
<< "Unknown write type \"" << writeType << "\"\n\n"
<< "Valid types : "
<< wordConstructorTablePtr_->sortedToc() << nl
<< "Valid proxy types : "
<< MeshedSurfaceProxy<face>::writeTypes() << endl
<< exit(FatalError);
return nullptr;
}
// ************************************************************************* //

View File

@ -1,230 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2012 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
Class
Foam::surfaceWriter
Description
Base class for surface writers
SourceFiles
surfaceWriter.C
\*---------------------------------------------------------------------------*/
#ifndef surfaceWriter_H
#define surfaceWriter_H
#include "typeInfo.H"
#include "autoPtr.H"
#include "fileName.H"
#include "meshedSurfRef.H"
#include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class surfaceWriter Declaration
\*---------------------------------------------------------------------------*/
class surfaceWriter
{
public:
//- Runtime type information
TypeName("surfaceWriter");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
surfaceWriter,
word,
(),
()
);
declareRunTimeSelectionTable
(
autoPtr,
surfaceWriter,
wordDict,
(
const dictionary& options
),
(options)
);
// Selectors
//- Return a reference to the selected surfaceWriter
static autoPtr<surfaceWriter> New(const word& writeType);
//- Return a reference to the selected surfaceWriter
// Select with extra write option
static autoPtr<surfaceWriter> New
(
const word& writeType,
const dictionary& writeOptions
);
// Constructors
//- Construct null
surfaceWriter() = default;
//- Destructor
virtual ~surfaceWriter() = default;
// Member Functions
//- True if the surface format supports geometry in a separate file.
// False if geometry and field must be in a single file
virtual bool separateGeometry() const
{
return false;
}
//- Trigger for geometry changes.
// \note this is a stop-gap solution until the writing infrastructure
// is improved.
virtual void updateMesh
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName //!< Name of surface
) const
{}
//- Write single surface geometry to file.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const bool verbose = false //!< Additional verbosity
) const
{
return fileName::null;
}
//- Write scalarField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<scalar>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const
{
return fileName::null;
}
//- Write vectorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<vector>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const
{
return fileName::null;
}
//- Write sphericalTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<sphericalTensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const
{
return fileName::null;
}
//- Write symmTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<symmTensor>& values,//!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const
{
return fileName::null;
}
//- Write tensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<tensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const
{
return fileName::null;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,192 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "vtkSurfaceWriter.H"
#include "foamVtkOutputOptions.H"
#include "OSspecific.H"
#include <fstream>
#include "makeSurfaceWriterMethods.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
makeSurfaceWriterType(vtkSurfaceWriter);
addToRunTimeSelectionTable(surfaceWriter, vtkSurfaceWriter, wordDict);
}
// Field writing implementation
#include "vtkSurfaceWriterImpl.C"
// Field writing methods
defineSurfaceWriterWriteFields(Foam::vtkSurfaceWriter);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::vtkSurfaceWriter::writeGeometry
(
vtk::formatter& format,
const meshedSurf& surf,
std::string title
)
{
const pointField& points = surf.points();
const faceList& faces = surf.faces();
if (title.empty())
{
title = "sampleSurface";
}
vtk::legacy::fileHeader
(
format,
title,
vtk::fileTag::POLY_DATA
);
vtk::legacy::beginPoints(format.os(), points.size());
vtk::writeList(format, points);
format.flush();
// Write faces
// connectivity count without additional storage (done internally)
label nConnectivity = 0;
for (const face& f : faces)
{
nConnectivity += f.size();
}
vtk::legacy::beginPolys
(
format.os(),
faces.size(),
nConnectivity
);
for (const face& f : faces)
{
format.write(f.size()); // The size prefix
vtk::writeList(format, f);
}
format.flush();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::vtkSurfaceWriter::vtkSurfaceWriter()
:
surfaceWriter(),
fmtType_(unsigned(vtk::formatType::LEGACY_ASCII)),
precision_(IOstream::defaultPrecision())
{}
Foam::vtkSurfaceWriter::vtkSurfaceWriter(const dictionary& options)
:
surfaceWriter(),
fmtType_(static_cast<unsigned>(vtk::formatType::LEGACY_ASCII)),
precision_(IOstream::defaultPrecision())
{
#if 0
// Future
// format: ascii | binary
// legacy true | false
vtk::outputOptions opts(static_cast<vtk::formatType>(fmtType_));
const word formatName = options.lookupOrDefault<word>("format", "");
if (formatName.size())
{
opts.ascii
(
IOstream::formatEnum(formatName) == IOstream::ASCII
);
}
if (options.lookupOrDefault("legacy", false))
{
opts.legacy(true);
}
// Convert back to raw data type
fmtType_ = static_cast<unsigned>(opts.fmt());
#endif
// The write precision for ASCII formatters
precision_ =
options.lookupOrDefaultCompat
(
"precision", {{"writePrecision", -1806}},
IOstream::defaultPrecision()
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::fileName Foam::vtkSurfaceWriter::write
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const bool verbose
) const
{
// geometry: rootdir/time/surfaceName.{vtk|vtp}
fileName outputFile(outputDir/surfaceName + ".vtk");
if (!isDir(outputDir))
{
mkDir(outputDir);
}
if (verbose)
{
Info<< "Writing geometry to " << outputFile << endl;
}
// As vtk::outputOptions
vtk::outputOptions opts(static_cast<vtk::formatType>(fmtType_));
opts.legacy(true);
opts.precision(precision_);
std::ofstream os(outputFile);
auto format = opts.newFormatter(os);
writeGeometry(*format, surf, surfaceName);
return outputFile;
}
// ************************************************************************* //

View File

@ -1,251 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
Class
Foam::vtkSurfaceWriter
Description
A surfaceWriter for VTK legacy format.
The formatOptions for vtk:
\table
Property | Description | Required | Default
format | [FUTURE] ascii or binary format | no | ascii
legacy | [FUTURE] Legacy VTK output | no | true
precision | Write precision in ascii | no | same as IOstream
\endtable
For example,
\verbatim
formatOptions
{
vtk
{
precision 10;
}
}
\endverbatim
\heading Output file locations
The \c rootdir normally corresponds to something like
\c postProcessing/\<name\>
\subheading Geometry
\verbatim
rootdir
`-- timeName
`-- surfaceName.{vtk}
\endverbatim
\subheading Fields
\verbatim
rootdir
`-- timeName
`-- <field>_surfaceName.{vtk}
\endverbatim
Note
Uses ASCII-only output.
All data are written as \c double due to portability issues
(paraview on window).
SourceFiles
vtkSurfaceWriter.C
\*---------------------------------------------------------------------------*/
#ifndef vtkSurfaceWriter_H
#define vtkSurfaceWriter_H
#include "surfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace vtk
{
// Forward declarations
class formatter;
}
/*---------------------------------------------------------------------------*\
Class vtkSurfaceWriter Declaration
\*---------------------------------------------------------------------------*/
class vtkSurfaceWriter
:
public surfaceWriter
{
// Private data
//- The VTK output format type.
// Stored as a raw value to avoid a dependency on fileFormats
unsigned fmtType_;
//- ASCII write precision
unsigned precision_;
// Private Member Functions
static void writeGeometry
(
vtk::formatter& format,
const meshedSurf& surf,
std::string title = ""
);
template<class Type>
static void writeField
(
vtk::formatter& format,
const Field<Type>& values
);
//- Templated write operation
template<class Type>
fileName writeTemplate
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<Type>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const;
public:
//- Runtime type information
TypeName("vtk");
// Constructors
//- Construct null
vtkSurfaceWriter();
//- Construct with some output options
explicit vtkSurfaceWriter(const dictionary& options);
//- Destructor
virtual ~vtkSurfaceWriter() = default;
// Member Functions
//- Write single surface geometry to file.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write scalarField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<scalar>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write vectorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<vector>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write sphericalTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<sphericalTensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write symmTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<symmTensor>& values,//!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write tensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<tensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,153 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2014 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "foamVtkOutputOptions.H"
#include "OSspecific.H"
#include <fstream>
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
template<class Type>
static inline void beginFloatField
(
vtk::formatter& format,
const word& fieldName,
const Field<Type>& values
)
{
// Use 'double' instead of 'float' for ASCII output (issue #891)
if (format.opts().ascii())
{
format.os()
<< fieldName << ' '
<< int(pTraits<Type>::nComponents) << ' '
<< values.size() << " double" << nl;
}
else
{
format.os()
<< fieldName << ' '
<< int(pTraits<Type>::nComponents) << ' '
<< values.size() << " float" << nl;
}
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// // Unspecialized (unknown) data type - map as zeros
// void Foam::vtkSurfaceWriter::writeZeros
// (
// vtk::formatter& format,
// const label count
// )
// {
// const float val(0);
//
// for (label i=0; i < count; ++i)
// {
// format.write(val);
// }
// format.flush();
// }
template<class Type>
void Foam::vtkSurfaceWriter::writeField
(
vtk::formatter& format,
const Field<Type>& values
)
{
vtk::writeList(format, values);
format.flush();
}
template<class Type>
Foam::fileName Foam::vtkSurfaceWriter::writeTemplate
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const word& fieldName,
const Field<Type>& values,
const bool isNodeValues,
const bool verbose
) const
{
// field: rootdir/time/<field>_surfaceName.{vtk|vtp}
fileName outputFile(outputDir/fieldName + '_' + surfaceName + ".vtk");
if (!isDir(outputDir))
{
mkDir(outputDir);
}
if (verbose)
{
Info<< "Writing field " << fieldName << " to "
<< outputFile << endl;
}
// As vtk::outputOptions
vtk::outputOptions opts(static_cast<vtk::formatType>(fmtType_));
opts.legacy(true);
opts.precision(precision_);
std::ofstream os(outputFile);
auto format = opts.newFormatter(os);
writeGeometry(*format, surf);
if (isNodeValues)
{
format->os()
<< "POINT_DATA "
<< values.size() << nl
<< "FIELD attributes 1" << nl;
}
else
{
format->os()
<< "CELL_DATA "
<< values.size() << nl
<< "FIELD attributes 1" << nl;
}
beginFloatField(*format, fieldName, values);
writeField(*format, values);
return outputFile;
}
// ************************************************************************* //

View File

@ -243,6 +243,7 @@ bool Foam::surfMeshSamplers::read(const dictionary& dict)
surfaces().transfer(surfs);
}
auto& surfs = surfaces();
if (surfs.size())
{
@ -252,9 +253,6 @@ bool Foam::surfMeshSamplers::read(const dictionary& dict)
Info<< type() << " fields: " << flatOutput(fieldSelection_) << nl;
Info<< nl;
// Ensure all surfaces and merge information are expired
expire();
// Need to initialize corresponding surfMesh for others in the chain.
// This can simply be a zero-sized placeholder, or the real surface with
// faces.
@ -346,18 +344,18 @@ bool Foam::surfMeshSamplers::needsUpdate() const
bool Foam::surfMeshSamplers::expire()
{
bool justExpired = false;
label nChanged = 0;
for (surfMeshSample& s : surfaces())
{
if (s.expire())
{
justExpired = true;
++nChanged;
}
}
// True if any surfaces just expired
return justExpired;
return nChanged;
}
@ -368,16 +366,17 @@ bool Foam::surfMeshSamplers::update()
return false;
}
bool updated = false;
label nUpdated = 0;
for (surfMeshSample& s : surfaces())
{
if (s.update())
{
updated = true;
++nUpdated;
}
}
return updated;
return nUpdated;
}

View File

@ -57,4 +57,20 @@ triSurface/fields/triSurfaceFields.C
triSurface/patches/geometricSurfacePatch.C
triSurface/patches/surfacePatch.C
writers = writers
$(writers)/surfaceWriter.C
$(writers)/boundaryData/boundaryDataSurfaceWriter.C
$(writers)/ensight/ensightSurfaceWriter.C
$(writers)/foam/foamSurfaceWriter.C
$(writers)/nastran/nastranSurfaceWriter.C
$(writers)/null/nullSurfaceWriter.C
$(writers)/proxy/proxySurfaceWriter.C
$(writers)/raw/rawSurfaceWriter.C
$(writers)/starcd/starcdSurfaceWriter.C
$(writers)/vtk/vtkSurfaceWriter.C
/* $(writers)/x3d/x3dSurfaceWriter.C */
LIB = $(FOAM_LIBBIN)/libsurfMesh

View File

@ -0,0 +1,275 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2015 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "boundaryDataSurfaceWriter.H"
#include "argList.H"
#include "OFstream.H"
#include "OSspecific.H"
#include "IOmanip.H"
#include "Time.H"
#include "pointIOField.H"
#include "primitivePatch.H"
#include "surfaceWriterMethods.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace surfaceWriters
{
defineTypeName(boundaryDataWriter);
addToRunTimeSelectionTable(surfaceWriter, boundaryDataWriter, word);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::surfaceWriters::boundaryDataWriter::boundaryDataWriter()
:
surfaceWriter()
{}
Foam::surfaceWriters::boundaryDataWriter::boundaryDataWriter
(
const dictionary& options
)
:
surfaceWriter(options)
{}
Foam::surfaceWriters::boundaryDataWriter::boundaryDataWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
boundaryDataWriter(options)
{
open(surf, outputPath, parallel);
}
Foam::surfaceWriters::boundaryDataWriter::boundaryDataWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
boundaryDataWriter(options)
{
open(points, faces, outputPath, parallel);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::fileName Foam::surfaceWriters::boundaryDataWriter::write()
{
checkOpen();
// Geometry: rootdir/surfaceName/"points"
// Field: rootdir/surfaceName/<TIME>/field
fileName surfaceDir = outputPath_;
// Write points
if (verbose_)
{
Info<< "Writing points to " << surfaceDir/"points" << endl;
}
// Dummy time to use as an objectRegistry
const fileName caseDir(argList::envGlobalPath());
Time dummyTime
(
caseDir.path(), // root-path,
caseDir.name(), // case-name,
"system", //
"constant", //
false, // no function objects
false // no libs
);
const meshedSurf& surf = surface();
if (Pstream::master() || !parallel_)
{
if (!isDir(surfaceDir))
{
mkDir(surfaceDir);
}
pointIOField pts
(
IOobject
(
surfaceDir/"points",
dummyTime,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
surf.points()
);
// Do like regIOobject::writeObject but don't do instance() adaptation
// since this would write to e.g. 0/ instead of postProcessing/
// Try opening an OFstream for object
OFstream os(pts.objectPath());
//pts.writeHeader(os);
pts.writeData(os);
//pts.writeEndDivider(os);
}
return surfaceDir;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::fileName Foam::surfaceWriters::boundaryDataWriter::writeTemplate
(
const word& fieldName,
const Field<Type>& localValues
)
{
checkOpen();
// Geometry: rootdir/surfaceName/"points"
// Field: rootdir/surfaceName/<TIME>/field
fileName surfaceDir = outputPath_;
const fileName outputFile(surfaceDir/timeName()/fieldName);
// Dummy time to use as an objectRegistry
const fileName caseDir(argList::envGlobalPath());
Time dummyTime
(
caseDir.path(), // root-path,
caseDir.name(), // case-name,
"system", //
"constant", //
false, // no function objects
false // no libs
);
// Geometry merge() implicit
tmp<Field<Type>> tfield = mergeField(localValues);
const meshedSurf& surf = surface();
if (Pstream::master() || !parallel_)
{
const pointField& points = surf.points();
const faceList& faces = surf.faces();
if (!isDir(outputFile.path()))
{
mkDir(outputFile.path());
}
pointIOField pts
(
IOobject
(
surfaceDir/"points",
dummyTime,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
label(0)
);
if (this->isPointData())
{
if (verbose_)
{
Info<< "Writing points to "
<< surfaceDir/"points" << endl;
}
pts = points;
}
else
{
if (verbose_)
{
Info<< "Writing face centres to "
<< surfaceDir/"points" << endl;
}
primitivePatch pp(SubList<face>(faces, faces.size()), points);
pts = pp.faceCentres();
}
{
// Do like regIOobject::writeObject but don't do instance()
// adaptation
// since this would write to e.g. 0/ instead of postProcessing/
// Try opening an OFstream for object
OFstream os(pts.objectPath());
//pts.writeHeader(os);
pts.writeData(os);
//pts.writeEndDivider(os);
}
// Write field
OFstream(outputFile)() << tfield();
}
return surfaceDir;
}
// Field writing methods
defineSurfaceWriterWriteFields(Foam::surfaceWriters::boundaryDataWriter);
// ************************************************************************* //

View File

@ -0,0 +1,187 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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/>.
Class
Foam::surfaceWriters::boundaryDataWriter
Description
A surfaceWriter for outputting to a form useable for the
timeVaryingMapped boundary condition. This reads the data from
constant/boundaryData/\<patch\> directory
Typical way of working:
- use a sampledSurface of type 'patch' (to sample a patch):
\verbatim
surfaces
{
type surfaces;
surfaceFormat boundaryData;
fields ( p );
surfaces
(
outlet
{
type patch;
patches (outlet);
interpolate false;
}
);
}
\endverbatim
- write using this writer.
- move postProcessing/surfaces/outlet to constant/boundaryData/outlet
in your destination case.
- use a timeVaryingMappedFixedValue condition to read and interpolate
the profile:
type timeVaryingMappedFixedValue;
setAverage false; // do not use read average
offset 0; // do not apply offset to values
Note:
- with 'interpolate false' the data is on the face centres of the
patch. Take care that a 2D geometry will only have a single row
of face centres so might not provide a valid triangulation
(this is what timeVaryingMappedFixedValue uses to do interpolation)
(Alternatively use timeVaryingMappedFixedValue with mapMethod 'nearest')
\heading Output file locations
The \c rootdir normally corresponds to something like
\c postProcessing/\<name\>
where the geometry is written as:
\verbatim
rootdir
`-- surfaceName
`-- "points"
\endverbatim
and field data:
\verbatim
rootdir
`-- surfaceName
|-- "points"
`-- timeName
`-- field
\endverbatim
SourceFiles
boundaryDataSurfaceWriter.C
\*---------------------------------------------------------------------------*/
#ifndef boundaryDataSurfaceWriter_H
#define boundaryDataSurfaceWriter_H
#include "surfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace surfaceWriters
{
/*---------------------------------------------------------------------------*\
Class boundaryDataWriter Declaration
\*---------------------------------------------------------------------------*/
class boundaryDataWriter
:
public surfaceWriter
{
// Private Member Functions
//- Templated write field operation
template<class Type>
fileName writeTemplate
(
const word& fieldName, //!< Name of field
const Field<Type>& localValues //!< Local field values to write
);
public:
//- Runtime type information
TypeNameNoDebug("boundaryData");
// Constructors
//- Construct null
boundaryDataWriter();
//- Construct with some output options
boundaryDataWriter(const dictionary& options);
//- Construct from components
boundaryDataWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Construct from components
boundaryDataWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Destructor
virtual ~boundaryDataWriter() = default;
// Member Functions
//- Write surface geometry to file.
virtual fileName write(); // override
declareSurfaceWriterWriteMethod(label);
declareSurfaceWriterWriteMethod(scalar);
declareSurfaceWriterWriteMethod(vector);
declareSurfaceWriterWriteMethod(sphericalTensor);
declareSurfaceWriterWriteMethod(symmTensor);
declareSurfaceWriterWriteMethod(tensor);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace surfaceWriters
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,10 +2,10 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2013 OpenFOAM Foundation
| Copyright (C) 2011-2014 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -26,29 +26,32 @@ License
\*---------------------------------------------------------------------------*/
#include "ensightSurfaceWriter.H"
#include "IOmanip.H"
#include "Fstream.H"
#include "OSspecific.H"
#include "ensightCase.H"
#include "ensightPartFaces.H"
#include "makeSurfaceWriterMethods.H"
#include "ensightOutput.H"
#include "ensightPTraits.H"
#include "surfaceWriterMethods.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
makeSurfaceWriterType(ensightSurfaceWriter);
addToRunTimeSelectionTable(surfaceWriter, ensightSurfaceWriter, wordDict);
namespace surfaceWriters
{
defineTypeName(ensightWriter);
addToRunTimeSelectionTable(surfaceWriter, ensightWriter, word);
addToRunTimeSelectionTable(surfaceWriter, ensightWriter, wordDict);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Field writing implementation
#include "ensightSurfaceWriterImpl.C"
// Field writing methods
defineSurfaceWriterWriteFields(Foam::ensightSurfaceWriter);
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
void Foam::ensightSurfaceWriter::printTimeset
void Foam::surfaceWriters::ensightWriter::printTimeset
(
OSstream& os,
const label ts,
@ -69,7 +72,7 @@ void Foam::ensightSurfaceWriter::printTimeset
}
void Foam::ensightSurfaceWriter::printTimeset
void Foam::surfaceWriters::ensightWriter::printTimeset
(
OSstream& os,
const label ts,
@ -100,10 +103,9 @@ void Foam::ensightSurfaceWriter::printTimeset
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightSurfaceWriter::ensightSurfaceWriter()
Foam::surfaceWriters::ensightWriter::ensightWriter()
:
surfaceWriter(),
writeFormat_(IOstream::ASCII),
@ -111,9 +113,12 @@ Foam::ensightSurfaceWriter::ensightSurfaceWriter()
{}
Foam::ensightSurfaceWriter::ensightSurfaceWriter(const dictionary& options)
Foam::surfaceWriters::ensightWriter::ensightWriter
(
const dictionary& options
)
:
surfaceWriter(),
surfaceWriter(options),
writeFormat_
(
IOstreamOption::formatNames.lookupOrDefault
@ -128,6 +133,35 @@ Foam::ensightSurfaceWriter::ensightSurfaceWriter(const dictionary& options)
{}
Foam::surfaceWriters::ensightWriter::ensightWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
ensightWriter(options)
{
open(surf, outputPath, parallel);
}
Foam::surfaceWriters::ensightWriter::ensightWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
ensightWriter(options)
{
open(points, faces, outputPath, parallel);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Note that ensight does supports geometry in a separate file,
@ -135,114 +169,53 @@ Foam::ensightSurfaceWriter::ensightSurfaceWriter(const dictionary& options)
// (when there are fields).
//
// Make this false to let the field writers take back control
bool Foam::ensightSurfaceWriter::separateGeometry() const
bool Foam::surfaceWriters::ensightWriter::separateGeometry() const
{
return false;
}
void Foam::ensightSurfaceWriter::updateMesh
(
const fileName& outputDir,
const fileName& surfaceName
) const
Foam::fileName Foam::surfaceWriters::ensightWriter::write()
{
if (collateTimes_ && Pstream::master())
// if (collateTimes_)
// {
// return writeCollated();
// }
// else
// {
// return writeUncollated();
// }
return writeUncollated();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ensightSurfaceWriterCollated.C"
#include "ensightSurfaceWriterUncollated.C"
// Field writing implementations
template<class Type>
Foam::fileName Foam::surfaceWriters::ensightWriter::writeTemplate
(
const word& fieldName,
const Field<Type>& localValues
)
{
if (collateTimes_)
{
const ensight::FileName surfName(surfaceName);
const fileName baseDir = outputDir.path()/surfName;
const fileName timeDir = outputDir.name();
// Convert timeDir to a value (if possible - use 0.0 otherwise)
scalar timeValue = 0.0;
readScalar(timeDir, timeValue);
if (!isDir(baseDir))
{
mkDir(baseDir);
}
dictionary dict;
if (isFile(baseDir/"fieldsDict"))
{
IFstream is(baseDir/"fieldsDict");
if (is.good() && dict.read(is))
{
// ... any futher actions
}
}
dict.set("updateMesh", timeValue);
{
OFstream os(baseDir/"fieldsDict");
os << "// Summary of Ensight fields, times" << nl << nl;
dict.write(os, false);
}
return writeCollated(fieldName, localValues);
}
else
{
return writeUncollated(fieldName, localValues);
}
}
Foam::fileName Foam::ensightSurfaceWriter::write
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const bool verbose
) const
{
const ensight::FileName surfName(surfaceName);
// Uncollated
// ==========
// geometry: rootdir/time/surfaceName.case
// geometry: rootdir/time/surfaceName.00000000.mesh
if (!isDir(outputDir))
{
mkDir(outputDir);
}
OFstream osCase(outputDir/surfName + ".case");
ensightGeoFile osGeom
(
outputDir,
surfName + ".00000000.mesh",
writeFormat_
);
if (verbose)
{
Info<< "Writing case file to " << osCase.name() << endl;
}
const pointField& points = surf.points();
const faceList& faces = surf.faces();
osCase
<< "FORMAT" << nl
<< "type: ensight gold" << nl
<< nl
<< "GEOMETRY" << nl
<< "model: 1 " << osGeom.name().name() << nl
<< nl
<< "TIME" << nl;
printTimeset(osCase, 1, 0.0);
ensightPartFaces ensPart(0, osGeom.name().name(), points, faces, true);
osGeom << ensPart;
return osCase.name();
// Collated?
// ========
// geometry: rootdir/surfaceName/surfaceName.case
// geometry: rootdir/surfaceName/surfaceName.mesh
}
defineSurfaceWriterWriteFields(Foam::surfaceWriters::ensightWriter);
// ************************************************************************* //

View File

@ -0,0 +1,198 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2011, 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
Class
Foam::surfaceWriters::ensightWriter
Description
A surfaceWriter for Ensight format.
\verbatim
formatOptions
{
ensight
{
format ascii;
collateTimes true;
}
}
\endverbatim
Format options:
\table
Property | Description | Required | Default
format | ascii/binary | no | ascii
collateTimes | use common geometry for times | no | true
\endtable
SourceFiles
ensightSurfaceWriter.C
\*---------------------------------------------------------------------------*/
#ifndef ensightSurfaceWriter_H
#define ensightSurfaceWriter_H
#include "surfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace surfaceWriters
{
/*---------------------------------------------------------------------------*\
Class ensightWriter Declaration
\*---------------------------------------------------------------------------*/
class ensightWriter
:
public surfaceWriter
{
// Private Data
//- Write option (default: IOstream::ASCII)
IOstream::streamFormat writeFormat_;
//- Collate times (default: true)
bool collateTimes_;
// Private Member Functions
//- Print time-set for ensight case file
static void printTimeset
(
OSstream& os,
const label ts,
const scalar& timeValue
);
//- Print time-set for ensight case file
static void printTimeset
(
OSstream& os,
const label ts,
const UList<scalar>& times
);
//- Write geometry
fileName writeCollated();
//- Write geometry
fileName writeUncollated();
//- Templated write operation - one file per timestep
template<class Type>
fileName writeCollated
(
const word& fieldName, //!< Name of field
const Field<Type>& localValues //!< Local field values to write
);
//- Templated write operation - all time steps in single file
template<class Type>
fileName writeUncollated
(
const word& fieldName, //!< Name of field
const Field<Type>& localValues //!< Local field values to write
);
//- Templated write operation
template<class Type>
fileName writeTemplate
(
const word& fieldName, //!< Name of field
const Field<Type>& localValues //!< Local field values to write
);
public:
//- Runtime type information
TypeNameNoDebug("ensight");
// Constructors
//- Construct null
ensightWriter();
//- Construct with some output options
explicit ensightWriter(const dictionary& options);
//- Construct from components
ensightWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Construct from components
ensightWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Destructor
virtual ~ensightWriter() = default;
// Member Functions
//- True if the surface format supports geometry in a separate file.
// False if geometry and field must be in a single file
virtual bool separateGeometry() const;
//- Write single surface geometry to file.
virtual fileName write(); // override
declareSurfaceWriterWriteMethod(label);
declareSurfaceWriterWriteMethod(scalar);
declareSurfaceWriterWriteMethod(vector);
declareSurfaceWriterWriteMethod(sphericalTensor);
declareSurfaceWriterWriteMethod(symmTensor);
declareSurfaceWriterWriteMethod(tensor);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace surfaceWriters
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,376 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2014 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated()
{
// Collated?
// ========
// Geometry: rootdir/surfaceName/surfaceName.case
// Geometry: rootdir/surfaceName/surfaceName.mesh
return fileName();
}
template<class Type>
Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated
(
const word& fieldName,
const Field<Type>& localValues
)
{
checkOpen();
const ensight::FileName surfName(outputPath_.name());
const ensight::VarName varName(fieldName);
// Collated
// ========
// Geometry: rootdir/surfaceName/surfaceName.case
// Geometry: rootdir/surfaceName/data/<index>/geometry
// Field: rootdir/surfaceName/data/<index>/field
// Use surface name as sub-directory for results. Eg,
// - SURF1/SURF1.case
// - SURF1/data/00000000/geometry
// - SURF1/data/00000000/VAR1
// - SURF1/data/00000000/VAR2
// Names "data" and "geometry" as per ensightCase:
const char* fmt = "%08d";
const char* mask = "data/********/";
// Ignore the useTimeDir setting - manage ourselves
const fileName baseDir = outputPath_;
const word timeDir = timeName();
const scalar timeValue = currTime_.value();
const fileName outputFile = baseDir / surfName + ".case";
if (verbose_)
{
Info<< "Writing case file to " << outputFile << endl;
}
// Mesh changed since last output? Do before any merging.
const bool meshChanged = (!upToDate_);
// geometry merge() implicit
tmp<Field<Type>> tfield = mergeField(localValues);
const meshedSurf& surf = surface();
if (Pstream::master() || !parallel_)
{
if (!isDir(outputFile.path()))
{
mkDir(outputFile.path());
}
scalar meshValue = 0;
label meshIndex = 0;
label timeIndex = 0;
fileName geometryName;
// Do case file
{
dictionary dict;
scalarList meshes;
scalarList times;
bool stateChanged = meshChanged;
if (isFile(baseDir/"fieldsDict"))
{
IFstream is(baseDir/"fieldsDict");
if (is.good() && dict.read(is))
{
dict.readIfPresent("meshes", meshes);
dict.readIfPresent("times", times);
timeIndex = 1+findLower(times, timeValue);
if (meshChanged)
{
meshValue = timeValue;
meshIndex = 1+findLower(meshes, meshValue);
}
else if (meshes.size())
{
meshIndex = meshes.size()-1;
meshValue = meshes.last();
}
else
{
meshIndex = 0;
}
}
}
// Update stored times list
meshes.resize(meshIndex+1, -1);
times.resize(timeIndex+1, -1);
if (meshes[meshIndex] != meshValue)
{
stateChanged = true;
}
if (times[timeIndex] != timeValue)
{
stateChanged = true;
}
meshes[meshIndex] = meshValue;
times[timeIndex] = timeValue;
geometryName =
"data"/word::printf(fmt, meshIndex)/ensightCase::geometryName;
// Add my information to dictionary
{
dict.set("meshes", meshes);
dict.set("times", times);
if (dict.found("fields"))
{
dictionary& fieldsDict = dict.subDict("fields");
if (!fieldsDict.found(fieldName))
{
dictionary fieldDict;
fieldDict.set("type", ensightPTraits<Type>::typeName);
fieldDict.set("name", varName); // ensight variable name
fieldsDict.set(fieldName, fieldDict);
stateChanged = true;
}
}
else
{
dictionary fieldDict;
fieldDict.set("type", ensightPTraits<Type>::typeName);
fieldDict.set("name", varName); // ensight variable name
dictionary fieldsDict;
fieldsDict.set(fieldName, fieldDict);
dict.set("fields", fieldsDict);
stateChanged = true;
}
}
if (stateChanged)
{
if (verbose_)
{
Info<< "Writing state file to fieldsDict" << endl;
}
{
OFstream os(baseDir/"fieldsDict");
os << "// Summary of Ensight fields, times" << nl << nl;
dict.write(os, false);
}
OFstream osCase(outputFile, IOstream::ASCII);
// Format options
osCase.setf(ios_base::left);
osCase.setf(ios_base::scientific, ios_base::floatfield);
osCase.precision(5);
if (verbose_)
{
Info<< "Writing case file to " << osCase.name() << endl;
}
// The geometry can be any of the following:
// 0: constant/static
// 1: moving, with the same frequency as the data
// 2: moving, with different frequency as the data
const label tsGeom =
(meshes.size() == 1 ? 0 : meshes == times ? 1 : 2);
osCase
<< "FORMAT" << nl
<< "type: ensight gold" << nl
<< nl
<< "GEOMETRY" << nl;
if (tsGeom)
{
// moving
osCase
<< "model: " << tsGeom << " " // time-set (1|2)
<< mask << geometryName.name() << nl;
}
else
{
// steady
osCase
<< "model: "
<< geometryName.c_str() << nl;
}
osCase
<< nl
<< "VARIABLE" << nl;
const dictionary& fieldsDict = dict.subDict("fields");
for (const entry& dEntry : fieldsDict)
{
const dictionary& subDict = dEntry.dict();
const word fieldType(subDict.get<word>("type"));
const word varName = subDict.lookupOrDefault
(
"name",
dEntry.keyword() // fieldName as fallback
);
osCase
<< fieldType
<<
(
this->isPointData()
? " per node: 1 " // time-set 1
: " per element: 1 " // time-set 1
)
<< setw(15) << varName << ' '
<< mask << varName << nl;
}
osCase
<< nl
<< "TIME" << nl;
printTimeset(osCase, 1, times);
if (tsGeom == 2)
{
printTimeset(osCase, 2, meshes);
}
osCase << "# end" << nl;
}
}
// Location for data (and possibly the geometry as well)
fileName dataDir = baseDir/"data"/word::printf(fmt, timeIndex);
// As per mkdir -p "data/00000000"
mkDir(dataDir);
const fileName meshFile(baseDir/geometryName);
// Write geometry
ensightPartFaces ensPart
(
0,
meshFile.name(),
surf.points(),
surf.faces(),
true // contiguous points
);
if (!exists(meshFile))
{
if (verbose_)
{
Info<< "Writing mesh file to " << meshFile.name() << endl;
}
// Use two-argument form for path-name to avoid validating base-dir
ensightGeoFile osGeom
(
meshFile.path(),
meshFile.name(),
writeFormat_
);
osGeom << ensPart;
}
// Write field
ensightFile osField
(
dataDir,
varName,
writeFormat_
);
if (verbose_)
{
Info<< "Writing field file to " << osField.name() << endl;
}
// Write field
osField.writeKeyword(ensightPTraits<Type>::typeName);
if (this->isPointData())
{
ensightOutput::Serial::writePointField
(
tfield(),
ensPart,
osField
// serial
);
}
else
{
ensightOutput::Detail::writeFaceField
(
tfield(),
ensPart,
osField,
false // serial
);
}
// Place a timestamp in the directory for future reference
{
OFstream timeStamp(dataDir/"time");
timeStamp
<< "# timestep time" << nl
<< dataDir.name() << " " << timeValue << nl;
}
}
return outputFile;
}
// ************************************************************************* //

View File

@ -0,0 +1,252 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2014 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated()
{
checkOpen();
const ensight::FileName surfName(outputPath_.name());
// Uncollated
// ==========
// Geometry: rootdir/<TIME>/surfaceName.case
// Geometry: rootdir/<TIME>/surfaceName.00000000.mesh
fileName outputDir;
if (useTimeDir() && !timeName().empty())
{
// Splice in time-directory
outputDir = outputPath_.path() / timeName();
}
else
{
outputDir = outputPath_.path();
}
const fileName outputFile = outputDir / surfName + ".case";
if (verbose_)
{
Info<< "Writing case file to " << outputFile << endl;
}
const meshedSurf& surf = surface();
if (Pstream::master() || !parallel_)
{
if (!isDir(outputDir))
{
mkDir(outputDir);
}
OFstream osCase(outputFile);
ensightGeoFile osGeom
(
outputDir,
surfName + ".00000000.mesh",
writeFormat_
);
osCase
<< "FORMAT" << nl
<< "type: ensight gold" << nl
<< nl
<< "GEOMETRY" << nl
<< "model: 1 " << osGeom.name().name() << nl
<< nl
<< "TIME" << nl;
printTimeset(osCase, 1, 0.0);
ensightPartFaces ensPart
(
0,
osGeom.name().name(),
surf.points(),
surf.faces(),
true // contiguous points
);
osGeom << ensPart;
}
return outputFile;
}
template<class Type>
Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated
(
const word& fieldName,
const Field<Type>& localValues
)
{
checkOpen();
const ensight::FileName surfName(outputPath_.name());
const ensight::VarName varName(fieldName);
// Uncollated
// ==========
// geometry: rootdir/time/<field>/surfaceName.case
// geometry: rootdir/time/<field>/surfaceName.<index>.mesh
// field: rootdir/time/<field>/surfaceName.<index>.<field>
// Variable name as sub-directory for results. Eg,
// - VAR1/SURF1.case
// - VAR1/SURF1.00000000.mesh
// - VAR1/SURF1.00000001.VAR1
// and
// - VAR2/SURF1.case
// - VAR2/SURF1.00000000.mesh
// - VAR2/SURF1.00000001.VAR2
fileName outputDir;
if (useTimeDir() && !timeName().empty())
{
// Splice in time-directory
outputDir = outputPath_.path() / timeName();
}
else
{
outputDir = outputPath_.path();
}
const fileName baseDir = outputDir / varName;
const word timeDir = timeName();
const scalar timeValue = currTime_.value();
const fileName outputFile = baseDir / surfName + ".case";
if (verbose_)
{
Info<< "Writing case file to " << outputFile << endl;
}
// geometry merge() implicit
tmp<Field<Type>> tfield = mergeField(localValues);
const meshedSurf& surf = surface();
if (Pstream::master() || !parallel_)
{
if (!isDir(outputFile.path()))
{
mkDir(outputFile.path());
}
OFstream osCase(outputFile, IOstream::ASCII);
// Format options
osCase.setf(ios_base::left);
osCase.setf(ios_base::scientific, ios_base::floatfield);
osCase.precision(5);
ensightGeoFile osGeom
(
baseDir,
surfName + ".00000000.mesh",
writeFormat_
);
ensightFile osField
(
baseDir,
surfName + ".00000000." + varName,
writeFormat_
);
osCase
<< "FORMAT" << nl
<< "type: ensight gold" << nl
<< nl
<< "GEOMETRY" << nl
<< "model: 1 " << osGeom.name().name() << nl
<< nl
<< "VARIABLE" << nl
<< ensightPTraits<Type>::typeName
<<
(
this->isPointData()
? " per node: 1 " // time-set 1
: " per element: 1 " // time-set 1
)
<< setw(15) << varName << ' '
<< surfName.c_str() << ".********." << varName << nl;
osCase
<< nl
<< "TIME" << nl;
printTimeset(osCase, 1, timeValue);
osCase << "# end" << nl;
ensightPartFaces ensPart
(
0,
osGeom.name().name(),
surf.points(),
surf.faces(),
true // contiguous points
);
osGeom << ensPart;
// Write field
osField.writeKeyword(ensightPTraits<Type>::typeName);
if (this->isPointData())
{
ensightOutput::Serial::writePointField
(
tfield(),
ensPart,
osField
// serial
);
}
else
{
ensightOutput::Detail::writeFaceField
(
tfield(),
ensPart,
osField,
false // serial
);
}
}
return outputFile;
}
// ************************************************************************* //

View File

@ -0,0 +1,208 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "foamSurfaceWriter.H"
#include "OFstream.H"
#include "OSspecific.H"
#include "surfaceWriterMethods.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace surfaceWriters
{
defineTypeName(foamWriter);
addToRunTimeSelectionTable(surfaceWriter, foamWriter, word);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::surfaceWriters::foamWriter::foamWriter()
:
surfaceWriter()
{}
Foam::surfaceWriters::foamWriter::foamWriter
(
const dictionary& options
)
:
surfaceWriter(options)
{}
Foam::surfaceWriters::foamWriter::foamWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
foamWriter(options)
{
open(surf, outputPath, parallel);
}
Foam::surfaceWriters::foamWriter::foamWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
foamWriter(options)
{
open(points, faces, outputPath, parallel);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::fileName Foam::surfaceWriters::foamWriter::write()
{
checkOpen();
// Geometry:
// - rootdir/<TIME>/surfaceName/{points,faces}
fileName surfaceDir = outputPath_;
if (useTimeDir() && !timeName().empty())
{
// Splice in time-directory
surfaceDir = outputPath_.path() / timeName() / outputPath_.name();
}
if (verbose_)
{
Info<< "Writing geometry to " << surfaceDir << endl;
}
const meshedSurf& surf = surface();
if (Pstream::master() || !parallel_)
{
const pointField& points = surf.points();
const faceList& faces = surf.faces();
if (!isDir(surfaceDir))
{
mkDir(surfaceDir);
}
// Points
OFstream(surfaceDir/"points")() << points;
// Faces
OFstream(surfaceDir/"faces")() << faces;
// Face centers.
// Not really necessary but very handy when reusing as inputs
// for e.g. timeVaryingMapped bc.
pointField faceCentres(faces.size(), Zero);
forAll(faces, facei)
{
faceCentres[facei] = faces[facei].centre(points);
}
OFstream(surfaceDir/"faceCentres")() << faceCentres;
}
return surfaceDir;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::fileName Foam::surfaceWriters::foamWriter::writeTemplate
(
const word& fieldName,
const Field<Type>& localValues
)
{
checkOpen();
// Geometry should already have been written
// Values to separate directory (e.g. "scalarField/p")
// Field: rootdir/<TIME>/surfaceName/fieldType/field
//?? -> or rootdir/surfaceName/fieldType/<TIME>/field
fileName surfaceDir = outputPath_;
if (useTimeDir() && !timeName().empty())
{
// Splice in time-directory
surfaceDir = outputPath_.path() / timeName() / outputPath_.name();
}
const fileName outputFile
(
surfaceDir
/ (word(pTraits<Type>::typeName) + FieldBase::typeName)
/ fieldName
);
if (verbose_)
{
Info<< "Writing field " << fieldName << " to " << surfaceDir << endl;
}
// geometry merge() implicit
tmp<Field<Type>> tfield = mergeField(localValues);
if (Pstream::master())
{
if (!isDir(outputFile.path()))
{
mkDir(outputFile.path());
}
// Write field
OFstream(outputFile)() << tfield();
}
return outputFile;
}
// Field writing methods
defineSurfaceWriterWriteFields(Foam::surfaceWriters::foamWriter);
// ************************************************************************* //

View File

@ -0,0 +1,163 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
Class
Foam::surfaceWriters::foamWriter
Description
A surfaceWriter for OpenFOAM surfaces
\heading Output file locations
The \c rootdir normally corresponds to something like
\c postProcessing/\<name\>
\subheading Geometry
\verbatim
rootdir
`-- timeName
`-- surfaceName
|-- "points"
|-- "faceCentres"
`-- "faces"
\endverbatim
\subheading Fields
\verbatim
rootdir
`-- timeName
`-- surfaceName
|-- scalarField
| |-- field
| `-- field
|-- vectorField
|-- field
`-- field
\endverbatim
SourceFiles
foamSurfaceWriter.C
\*---------------------------------------------------------------------------*/
#ifndef foamSurfaceWriter_H
#define foamSurfaceWriter_H
#include "surfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace surfaceWriters
{
/*---------------------------------------------------------------------------*\
Class foamWriter Declaration
\*---------------------------------------------------------------------------*/
class foamWriter
:
public surfaceWriter
{
// Private Member Functions
//- Templated write operation
template<class Type>
fileName writeTemplate
(
const word& fieldName, //!< Name of field
const Field<Type>& localValues //!< Local field values to write
);
public:
//- Runtime type information
TypeNameNoDebug("foam");
// Constructors
//- Construct null
foamWriter();
//- Construct with some output options
explicit foamWriter(const dictionary& options);
//- Construct from components
foamWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Construct from components
foamWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Destructor
virtual ~foamWriter() = default;
// Member Functions
//- The surface format has geometry in a separate file.
virtual bool separateGeometry() const
{
return true;
}
//- Write surface geometry to file.
virtual fileName write(); // override
declareSurfaceWriterWriteMethod(label);
declareSurfaceWriterWriteMethod(scalar);
declareSurfaceWriterWriteMethod(vector);
declareSurfaceWriterWriteMethod(sphericalTensor);
declareSurfaceWriterWriteMethod(symmTensor);
declareSurfaceWriterWriteMethod(tensor);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace surfaceWriters
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2012-2016 OpenFOAM Foundation
@ -26,17 +26,22 @@ License
\*---------------------------------------------------------------------------*/
#include "nastranSurfaceWriter.H"
#include "IOmanip.H"
#include "Pair.H"
#include "HashSet.H"
#include "makeSurfaceWriterMethods.H"
#include "IOmanip.H"
#include "OSspecific.H"
#include "surfaceWriterMethods.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
makeSurfaceWriterType(nastranSurfaceWriter);
addToRunTimeSelectionTable(surfaceWriter, nastranSurfaceWriter, wordDict);
namespace surfaceWriters
{
defineTypeName(nastranWriter);
addToRunTimeSelectionTable(surfaceWriter, nastranWriter, word);
addToRunTimeSelectionTable(surfaceWriter, nastranWriter, wordDict);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -45,11 +50,12 @@ namespace Foam
#include "nastranSurfaceWriterImpl.C"
// Field writing methods
defineSurfaceWriterWriteFields(Foam::nastranSurfaceWriter);
defineSurfaceWriterWriteFields(Foam::surfaceWriters::nastranWriter);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::Ostream& Foam::nastranSurfaceWriter::writeKeyword
Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeKeyword
(
Ostream& os,
const word& keyword
@ -59,7 +65,7 @@ Foam::Ostream& Foam::nastranSurfaceWriter::writeKeyword
}
void Foam::nastranSurfaceWriter::writeCoord
void Foam::surfaceWriters::nastranWriter::writeCoord
(
Ostream& os,
const point& pt,
@ -117,7 +123,7 @@ void Foam::nastranSurfaceWriter::writeCoord
}
void Foam::nastranSurfaceWriter::writeFace
void Foam::surfaceWriters::nastranWriter::writeFace
(
Ostream& os,
const word& faceType,
@ -193,7 +199,7 @@ void Foam::nastranSurfaceWriter::writeFace
}
void Foam::nastranSurfaceWriter::writeGeometry
void Foam::surfaceWriters::nastranWriter::writeGeometry
(
Ostream& os,
const meshedSurf& surf,
@ -257,13 +263,13 @@ void Foam::nastranSurfaceWriter::writeGeometry
}
Foam::Ostream& Foam::nastranSurfaceWriter::writeFooter
Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeFooter
(
Ostream& os,
const meshedSurf& surf
) const
{
// zone id have been used for the PID. Find unique values.
// Zone id have been used for the PID. Find unique values.
labelList pidsUsed = labelHashSet(surf.zoneIds()).sortedToc();
if (pidsUsed.empty())
@ -286,7 +292,7 @@ Foam::Ostream& Foam::nastranSurfaceWriter::writeFooter
}
// use single material ID
// Use single material ID
const label MID = 1;
@ -307,7 +313,7 @@ Foam::Ostream& Foam::nastranSurfaceWriter::writeFooter
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::nastranSurfaceWriter::nastranSurfaceWriter()
Foam::surfaceWriters::nastranWriter::nastranWriter()
:
surfaceWriter(),
writeFormat_(fieldFormat::SHORT),
@ -317,9 +323,12 @@ Foam::nastranSurfaceWriter::nastranSurfaceWriter()
{}
Foam::nastranSurfaceWriter::nastranSurfaceWriter(const dictionary& options)
Foam::surfaceWriters::nastranWriter::nastranWriter
(
const dictionary& options
)
:
surfaceWriter(),
surfaceWriter(options),
writeFormat_
(
fileFormats::NASCore::fieldFormatNames.lookupOrDefault
@ -353,43 +362,82 @@ Foam::nastranSurfaceWriter::nastranSurfaceWriter(const dictionary& options)
}
Foam::surfaceWriters::nastranWriter::nastranWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
nastranWriter(options)
{
open(surf, outputPath, parallel);
}
Foam::surfaceWriters::nastranWriter::nastranWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
nastranWriter(options)
{
open(points, faces, outputPath, parallel);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::fileName Foam::nastranSurfaceWriter::write
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const bool verbose
) const
Foam::fileName Foam::surfaceWriters::nastranWriter::write()
{
// geometry: rootdir/time/surfaceName.nas
checkOpen();
if (!isDir(outputDir))
// Geometry: rootdir/<TIME>/surfaceName.nas
fileName outputFile = outputPath_;
if (useTimeDir() && !timeName().empty())
{
mkDir(outputDir);
// Splice in time-directory
outputFile = outputPath_.path() / timeName() / outputPath_.name();
}
outputFile.ext("nas");
if (verbose_)
{
Info<< "Writing nastran geometry to " << outputFile << endl;
}
OFstream os(outputDir/surfaceName + ".nas");
fileFormats::NASCore::setPrecision(os, writeFormat_);
if (verbose)
const meshedSurf& surf = surface();
if (Pstream::master() || !parallel_)
{
Info<< "Writing nastran file to " << os.name() << endl;
if (!isDir(outputFile.path()))
{
mkDir(outputFile.path());
}
OFstream os(outputFile);
fileFormats::NASCore::setPrecision(os, writeFormat_);
os << "TITLE=OpenFOAM " << outputPath_.name()
<< " mesh" << nl
<< "$" << nl
<< "BEGIN BULK" << nl;
List<DynamicList<face>> decomposedFaces;
writeGeometry(os, surf, decomposedFaces);
writeFooter(os, surf)
<< "ENDDATA" << nl;
}
os << "TITLE=OpenFOAM " << surfaceName.c_str()
<< " mesh" << nl
<< "$" << nl
<< "BEGIN BULK" << nl;
List<DynamicList<face>> decomposedFaces;
writeGeometry(os, surf, decomposedFaces);
writeFooter(os, surf)
<< "ENDDATA" << nl;
return os.name();
return outputFile;
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2017 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2012-2016 OpenFOAM Foundation
@ -24,7 +24,7 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::nastranSurfaceWriter
Foam::surfaceWriters::nastranWriter
Description
A surface writer for the Nastran file format - both surface mesh and fields
@ -82,7 +82,7 @@ Description
SourceFiles
nastranSurfaceWriter.C
nastranSurfaceWriterTemplates.C
nastranSurfaceWriterImpl.C
\*---------------------------------------------------------------------------*/
@ -97,12 +97,14 @@ SourceFiles
namespace Foam
{
namespace surfaceWriters
{
/*---------------------------------------------------------------------------*\
Class nastranSurfaceWriter Declaration
Class nastranWriter Declaration
\*---------------------------------------------------------------------------*/
class nastranSurfaceWriter
class nastranWriter
:
public surfaceWriter
{
@ -117,7 +119,7 @@ public:
private:
// Private data
// Private Data
//- Field format (width and separator)
fieldFormat writeFormat_;
@ -189,123 +191,68 @@ private:
template<class Type>
fileName writeTemplate
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<Type>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const;
const Field<Type>& localValues //!< Local field values to write
);
public:
//- Runtime type information
TypeName("nastran");
TypeNameNoDebug("nastran");
// Constructors
//- Construct null
nastranSurfaceWriter();
nastranWriter();
//- Construct with some output options
nastranSurfaceWriter(const dictionary& options);
explicit nastranWriter(const dictionary& options);
//- Construct from components
nastranWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Construct from components
nastranWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Destructor
virtual ~nastranSurfaceWriter() = default;
virtual ~nastranWriter() = default;
// Member Functions
//- True if the surface format supports geometry in a separate file.
// False if geometry and field must be in a single file
virtual bool separateGeometry() const
{
return false;
}
// Write
//- Write single surface geometry to file.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write surface geometry to file.
virtual fileName write(); // override
//- Write scalarField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<scalar>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write vectorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<vector>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write sphericalTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<sphericalTensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write symmTensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<symmTensor>& values,//!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
//- Write tensorField for a single surface to file.
// One value per face or vertex.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const word& fieldName, //!< Name of field
const Field<tensor>& values, //!< Field values to write
const bool isNodeValues = false,//!< Values are per-vertex
const bool verbose = false //!< Additional verbosity
) const; // override
declareSurfaceWriterWriteMethod(label);
declareSurfaceWriterWriteMethod(scalar);
declareSurfaceWriterWriteMethod(vector);
declareSurfaceWriterWriteMethod(sphericalTensor);
declareSurfaceWriterWriteMethod(symmTensor);
declareSurfaceWriterWriteMethod(tensor);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace surfaceWriters
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2017 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2012-2016 OpenFOAM Foundation
@ -32,7 +32,7 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
Foam::Ostream& Foam::nastranSurfaceWriter::writeValue
Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeValue
(
Ostream& os,
const Type& value
@ -64,7 +64,7 @@ Foam::Ostream& Foam::nastranSurfaceWriter::writeValue
template<class Type>
Foam::Ostream& Foam::nastranSurfaceWriter::writeFaceValue
Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeFaceValue
(
Ostream& os,
const loadFormat format,
@ -144,17 +144,14 @@ Foam::Ostream& Foam::nastranSurfaceWriter::writeFaceValue
template<class Type>
Foam::fileName Foam::nastranSurfaceWriter::writeTemplate
Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const word& fieldName,
const Field<Type>& values,
const bool isNodeValues,
const bool verbose
) const
const Field<Type>& localValues
)
{
checkOpen();
if (!fieldMap_.found(fieldName))
{
FatalErrorInFunction
@ -168,74 +165,97 @@ Foam::fileName Foam::nastranSurfaceWriter::writeTemplate
const loadFormat& format(fieldMap_[fieldName]);
// field: rootdir/time/field/surfaceName.nas
// Field: rootdir/<TIME>/field/surfaceName.nas
if (!isDir(outputDir/fieldName))
fileName outputFile = outputPath_.path();
if (useTimeDir() && !timeName().empty())
{
mkDir(outputDir/fieldName);
// Splice in time-directory
outputFile /= timeName();
}
outputFile /= fieldName / outputPath_.name();
outputFile.ext("nas");
if (verbose_)
{
Info<< "Writing field " << fieldName << " to " << outputFile << endl;
}
// const scalar timeValue = Foam::name(this->mesh().time().timeValue());
const scalar timeValue = 0.0;
OFstream os(outputDir/fieldName/surfaceName + ".nas");
fileFormats::NASCore::setPrecision(os, writeFormat_);
// geometry merge() implicit
tmp<Field<Type>> tfield = mergeField(localValues);
if (verbose)
const meshedSurf& surf = surface();
if (Pstream::master() || !parallel_)
{
Info<< "Writing nastran file to " << os.name() << endl;
}
const auto& values = tfield();
os << "TITLE=OpenFOAM " << surfaceName.c_str()
<< " " << fieldName << " data" << nl
<< "$" << nl
<< "TIME " << timeValue << nl
<< "$" << nl
<< "BEGIN BULK" << nl;
List<DynamicList<face>> decomposedFaces;
writeGeometry(os, surf, decomposedFaces);
os << "$" << nl
<< "$ Field data" << nl
<< "$" << nl;
label elemId = 0;
if (isNodeValues)
{
for (const DynamicList<face>& dFaces : decomposedFaces)
if (!isDir(outputFile.path()))
{
for (const face& f : dFaces)
{
Type v = Zero;
mkDir(outputFile.path());
}
for (const label verti : f)
const scalar timeValue = 0.0;
OFstream os(outputFile);
fileFormats::NASCore::setPrecision(os, writeFormat_);
if (verbose_)
{
Info<< "Writing nastran file to " << os.name() << endl;
}
os << "TITLE=OpenFOAM " << outputFile.name()
<< " " << fieldName << " data" << nl
<< "$" << nl
<< "TIME " << timeValue << nl
<< "$" << nl
<< "BEGIN BULK" << nl;
List<DynamicList<face>> decomposedFaces;
writeGeometry(os, surf, decomposedFaces);
os << "$" << nl
<< "$ Field data" << nl
<< "$" << nl;
label elemId = 0;
if (this->isPointData())
{
for (const DynamicList<face>& dFaces : decomposedFaces)
{
for (const face& f : dFaces)
{
v += values[verti];
Type v = Zero;
for (const label verti : f)
{
v += values[verti];
}
v /= f.size();
writeFaceValue(os, format, v, ++elemId);
}
v /= f.size();
writeFaceValue(os, format, v, ++elemId);
}
}
}
else
{
for (const DynamicList<face>& dFaces : decomposedFaces)
else
{
forAll(dFaces, facei)
for (const DynamicList<face>& dFaces : decomposedFaces)
{
writeFaceValue(os, format, values[facei], ++elemId);
forAll(dFaces, facei)
{
writeFaceValue(os, format, values[facei], ++elemId);
}
}
}
writeFooter(os, surf)
<< "ENDDATA" << endl;
}
writeFooter(os, surf)
<< "ENDDATA" << endl;
return os.name();
return outputFile;
}

View File

@ -0,0 +1,121 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "nullSurfaceWriter.H"
#include "surfaceWriterMethods.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace surfaceWriters
{
defineTypeName(nullWriter);
addToRunTimeSelectionTable(surfaceWriter, nullWriter, word);
addToRunTimeSelectionTable(surfaceWriter, nullWriter, wordDict);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::surfaceWriters::nullWriter::nullWriter()
:
surfaceWriter()
{}
Foam::surfaceWriters::nullWriter::nullWriter(const dictionary& options)
:
surfaceWriter()
{}
Foam::surfaceWriters::nullWriter::nullWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
surfaceWriter()
{}
Foam::surfaceWriters::nullWriter::nullWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
surfaceWriter()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::surfaceWriters::nullWriter::needsUpdate() const
{
return false;
}
bool Foam::surfaceWriters::nullWriter::enabled() const
{
return false;
}
void Foam::surfaceWriters::nullWriter::setSurface
(
const meshedSurf& surf,
bool parallel
)
{}
void Foam::surfaceWriters::nullWriter::setSurface
(
const pointField& points,
const faceList& faces,
bool parallel
)
{}
void Foam::surfaceWriters::nullWriter::open(const fileName& outputPath)
{}
// Field writing methods
defineSurfaceWriterWriteFields(Foam::surfaceWriters::nullWriter);
// ************************************************************************* //

View File

@ -0,0 +1,149 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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/>.
Class
Foam::surfaceWriters::nullWriter
Description
Suppresses output of geometry and fields
SourceFiles
nullSurfaceWriter.C
\*---------------------------------------------------------------------------*/
#ifndef nullSurfaceWriter_H
#define nullSurfaceWriter_H
#include "surfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace surfaceWriters
{
/*---------------------------------------------------------------------------*\
Class nullWriter Declaration
\*---------------------------------------------------------------------------*/
class nullWriter
:
public surfaceWriter
{
public:
//- Runtime type information
TypeNameNoDebug("none");
// Constructors
//- Construct for a given extension
nullWriter();
//- Construct for a given extension
explicit nullWriter(const dictionary& options);
//- Construct from components
nullWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Construct from components
nullWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Destructor
virtual ~nullWriter() = default;
// Member Functions
// Capability
//- Never needs an update.
virtual bool needsUpdate() const;
//- The null writer is always disabled, which lets the caller
//- skip various (possibly expensive) preparatory operations.
virtual bool enabled() const;
// Surface association
//- Change association with a surface (no-op).
virtual void setSurface
(
const meshedSurf& s,
bool parallel = Pstream::parRun()
); // override
//- Change association with a surface (no-op).
virtual void setSurface
(
const pointField& points,
const faceList& faces,
bool parallel = Pstream::parRun()
); // override
// Output
//- Open for output on specified path, using existing surface (no-op)
virtual void open(const fileName& outputPath); // override
// Write
declareSurfaceWriterWriteMethod(label);
declareSurfaceWriterWriteMethod(scalar);
declareSurfaceWriterWriteMethod(vector);
declareSurfaceWriterWriteMethod(sphericalTensor);
declareSurfaceWriterWriteMethod(symmTensor);
declareSurfaceWriterWriteMethod(tensor);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace surfaceWriters
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011 OpenFOAM Foundation
@ -28,78 +28,129 @@ License
#include "proxySurfaceWriter.H"
#include "MeshedSurfaceProxy.H"
#include "OSspecific.H"
#include "makeSurfaceWriterMethods.H"
#include "surfaceWriterMethods.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(proxySurfaceWriter, 0);
namespace surfaceWriters
{
defineTypeName(proxyWriter);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::proxySurfaceWriter::proxySurfaceWriter(const word& fileExt)
Foam::surfaceWriters::proxyWriter::proxyWriter(const word& fileExt)
:
surfaceWriter(),
fileExtension_(fileExt)
{}
Foam::proxySurfaceWriter::proxySurfaceWriter
Foam::surfaceWriters::proxyWriter::proxyWriter
(
const word& fileExt,
const dictionary& options
)
:
surfaceWriter(),
surfaceWriter(options),
fileExtension_(fileExt),
options_(options)
{}
Foam::surfaceWriters::proxyWriter::proxyWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
proxyWriter(outputPath.ext(), options)
{
surfaceWriter::open(surf, outputPath, parallel);
}
Foam::surfaceWriters::proxyWriter::proxyWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
proxyWriter(outputPath.ext(), options)
{
surfaceWriter::open(points, faces, outputPath, parallel);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::fileName Foam::proxySurfaceWriter::write
void Foam::surfaceWriters::proxyWriter::open
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const bool verbose
) const
const fileName& outputPath
)
{
fileExtension_ = outputPath.ext();
surfaceWriter::open(outputPath);
}
Foam::fileName Foam::surfaceWriters::proxyWriter::write()
{
checkOpen();
// Avoid bad values
if (fileExtension_.empty())
{
return fileName::null;
}
fileName outputFile(outputDir/surfaceName + '.' + fileExtension_);
// Geometry: rootdir/<TIME>/surfaceName.{extension}
if (!isDir(outputFile.path()))
fileName outputFile = outputPath_;
if (useTimeDir() && !timeName().empty())
{
mkDir(outputFile.path());
// Splice in time-directory
outputFile = outputPath_.path() / timeName() / outputPath_.name();
}
outputFile.ext(fileExtension_);
if (verbose)
if (verbose_)
{
Info<< "Writing geometry to " << outputFile << endl;
}
MeshedSurfaceProxy<face>
(
surf.points(),
surf.faces()
).write
(
outputFile,
fileExtension_,
options_
);
const meshedSurf& surf = surface();
if (Pstream::master() || !parallel_)
{
if (!isDir(outputFile.path()))
{
mkDir(outputFile.path());
}
MeshedSurfaceProxy<face>(surf.points(), surf.faces()).write
(
outputFile,
fileExtension_,
options_
);
}
return outputFile;
}
// Field writing methods
defineSurfaceWriterWriteFields(Foam::surfaceWriters::proxyWriter);
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011 OpenFOAM Foundation
@ -24,11 +24,11 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::proxySurfaceWriter
Foam::surfaceWriters::proxyWriter
Description
A surfaceWriter that writes the geometry via the MeshedSurfaceProxy, but
which does not support any fields.
A surfaceWriter that writes the geometry via the MeshedSurfaceProxy,
but which does not support any fields.
\heading Output file locations
@ -59,16 +59,18 @@ SourceFiles
namespace Foam
{
namespace surfaceWriters
{
/*---------------------------------------------------------------------------*\
Class proxySurfaceWriter Declaration
Class proxyWriter Declaration
\*---------------------------------------------------------------------------*/
class proxySurfaceWriter
class proxyWriter
:
public surfaceWriter
{
// Private data
// Private Data
//- The file extension associated with the proxy
word fileExtension_;
@ -80,46 +82,75 @@ class proxySurfaceWriter
public:
//- Runtime type information
TypeName("proxy");
TypeNameNoDebug("proxy");
// Constructors
//- Construct for a given extension
explicit proxySurfaceWriter(const word& fileExt);
explicit proxyWriter(const word& fileExt);
//- Construct for a given extension, with some output options
proxySurfaceWriter(const word& fileExt, const dictionary& options);
proxyWriter(const word& fileExt, const dictionary& options);
//- Construct from components, taking extension from outputPath
proxyWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Construct from components, taking extension from outputPath
proxyWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Destructor
virtual ~proxySurfaceWriter() = default;
virtual ~proxyWriter() = default;
// Member Functions
// Capability
//- True if the surface format supports geometry in a separate file.
// False if geometry and field must be in a single file
//- A separate file is required for geometry.
virtual bool separateGeometry() const
{
return true;
}
//- Write single surface geometry to file.
virtual fileName write
(
const fileName& outputDir, //!< output-dir
const fileName& surfaceName, //!< Name of surface
const meshedSurf& surf, //!< Surface geometry
const bool verbose = false //!< Additional verbosity
) const; // override
// Output
//- Open for output on specified path, using existing surface
virtual void open(const fileName& outputPath); // override
// Write
//- Write surface geometry to file.
virtual fileName write(); // override
declareSurfaceWriterWriteMethod(label);
declareSurfaceWriterWriteMethod(scalar);
declareSurfaceWriterWriteMethod(vector);
declareSurfaceWriterWriteMethod(sphericalTensor);
declareSurfaceWriterWriteMethod(symmTensor);
declareSurfaceWriterWriteMethod(tensor);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace surfaceWriters
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,185 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2008-2011, 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "rawSurfaceWriter.H"
#include "OFstream.H"
#include "OSspecific.H"
#include "surfaceWriterMethods.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace surfaceWriters
{
defineTypeName(rawWriter);
addToRunTimeSelectionTable(surfaceWriter, rawWriter, word);
addToRunTimeSelectionTable(surfaceWriter, rawWriter, wordDict);
}
}
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Emit x,y,z
static inline void writePoint(Foam::Ostream& os, const Foam::point& p)
{
os << p.x() << ' ' << p.y() << ' ' << p.z();
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Field writing implementation
#include "rawSurfaceWriterImpl.C"
// Field writing methods
defineSurfaceWriterWriteFields(Foam::surfaceWriters::rawWriter);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::surfaceWriters::rawWriter::rawWriter()
:
surfaceWriter(),
writeCompression_(IOstream::UNCOMPRESSED)
{}
Foam::surfaceWriters::rawWriter::rawWriter
(
const dictionary& options
)
:
surfaceWriter(options),
writeCompression_
(
IOstream::compressionEnum
(
options.lookupOrDefault<word>("compression", "false")
)
)
{}
Foam::surfaceWriters::rawWriter::rawWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
rawWriter(options)
{
open(surf, outputPath, parallel);
}
Foam::surfaceWriters::rawWriter::rawWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
rawWriter(options)
{
open(points, faces, outputPath, parallel);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::fileName Foam::surfaceWriters::rawWriter::write()
{
checkOpen();
// Geometry: rootdir/<TIME>/surfaceName.raw
fileName outputFile = outputPath_;
if (useTimeDir() && !timeName().empty())
{
// Splice in time-directory
outputFile = outputPath_.path() / timeName() / outputPath_.name();
}
outputFile.ext("raw");
if (verbose_)
{
Info<< "Writing geometry to " << outputFile << endl;
}
const meshedSurf& surf = surface();
if (Pstream::master() || !parallel_)
{
const pointField& points = surf.points();
const faceList& faces = surf.faces();
if (!isDir(outputFile.path()))
{
mkDir(outputFile.path());
}
OFstream os
(
outputFile,
IOstream::ASCII,
IOstream::currentVersion,
writeCompression_
);
// Header
{
os << "# geometry NO_DATA " << faces.size() << nl
<< "# x y z" << nl;
}
// Write faces centres
for (const face& f : faces)
{
writePoint(os, f.centre(points));
os << nl;
}
os << nl;
}
return outputFile;
}
// ************************************************************************* //

View File

@ -0,0 +1,172 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2008-2011, 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
Class
Foam::surfaceWriters::rawWriter
Description
A surfaceWriter for raw output.
The formatOptions for raw:
\table
Property | Description | Required | Default
compression | on / off | no | off
\endtable
For example,
\verbatim
formatOptions
{
raw
{
compression on;
}
}
\endverbatim
\heading Output file locations
The \c rootdir normally corresponds to something like
\c postProcessing/\<name\>
\subheading Geometry
\verbatim
rootdir
`-- timeName
`-- surfaceName.{raw}
\endverbatim
\subheading Fields
\verbatim
rootdir
`-- timeName
|-- <field0>_surfaceName.{raw}
`-- <field1>_surfaceName.{raw}
\endverbatim
SourceFiles
rawSurfaceWriter.C
\*---------------------------------------------------------------------------*/
#ifndef rawSurfaceWriter_H
#define rawSurfaceWriter_H
#include "surfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace surfaceWriters
{
/*---------------------------------------------------------------------------*\
Class rawWriter Declaration
\*---------------------------------------------------------------------------*/
class rawWriter
:
public surfaceWriter
{
// Private data
//- Output compression (default: uncompressed)
IOstream::compressionType writeCompression_;
// Private Member Functions
//- Templated write operation
template<class Type>
fileName writeTemplate
(
const word& fieldName, //!< Name of field
const Field<Type>& localValues //!< Local field values to write
);
public:
//- Runtime type information
TypeNameNoDebug("raw");
// Constructors
//- Construct null
rawWriter();
//- Construct with some output options
explicit rawWriter(const dictionary& options);
//- Construct from components
rawWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Construct from components
rawWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Destructor
virtual ~rawWriter() = default;
// Member Functions
//- Write surface geometry to file.
virtual fileName write(); // override
declareSurfaceWriterWriteMethod(label);
declareSurfaceWriterWriteMethod(scalar);
declareSurfaceWriterWriteMethod(vector);
declareSurfaceWriterWriteMethod(sphericalTensor);
declareSurfaceWriterWriteMethod(symmTensor);
declareSurfaceWriterWriteMethod(tensor);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace surfaceWriters
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2008-2011, 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2014 OpenFOAM Foundation
@ -47,6 +47,13 @@ namespace Foam
template<class Type>
static inline void writeHeader(Ostream& os, const word& fieldName) {}
template<>
void writeHeader<label>(Ostream& os, const word& fieldName)
{
os << "# x y z"
<< " " << fieldName << nl;
}
template<>
void writeHeader<scalar>(Ostream& os, const word& fieldName)
{
@ -101,69 +108,96 @@ namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
Foam::fileName Foam::rawSurfaceWriter::writeTemplate
Foam::fileName Foam::surfaceWriters::rawWriter::writeTemplate
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const word& fieldName,
const Field<Type>& values,
const bool isNodeValues,
const bool verbose
) const
const Field<Type>& localValues
)
{
// field: rootdir/time/<field>_surfaceName.raw
checkOpen();
const pointField& points = surf.points();
const faceList& faces = surf.faces();
// Field: rootdir/<TIME>/<field>_surfaceName.raw
if (!isDir(outputDir))
fileName outputFile = outputPath_.path();
if (useTimeDir() && !timeName().empty())
{
mkDir(outputDir);
// Splice in time-directory
outputFile /= timeName();
}
OFstream os(outputDir/fieldName + '_' + surfaceName + ".raw");
// Append <field>_surfaceName.raw
outputFile /= fieldName + '_' + outputPath_.name();
outputFile.ext("raw");
if (verbose)
if (verbose_)
{
Info<< "Writing field " << fieldName << " to " << os.name() << endl;
Info<< "Writing field " << fieldName << " to " << outputFile << endl;
}
// Header
os << "# " << fieldName;
if (isNodeValues)
{
os << " POINT_DATA " << values.size() << nl;
}
else
{
os << " FACE_DATA " << values.size() << nl;
}
// Header
// # x y z field
writeHeader<Type>(os, fieldName);
// geometry merge() implicit
tmp<Field<Type>> tfield = mergeField(localValues);
if (isNodeValues)
const meshedSurf& surf = surface();
if (Pstream::master() || !parallel_)
{
// Node values
forAll(values, elemi)
const auto& values = tfield();
const pointField& points = surf.points();
const faceList& faces = surf.faces();
if (!isDir(outputFile.path()))
{
writePoint(os, points[elemi]);
writeData(os, values[elemi]);
mkDir(outputFile.path());
}
}
else
{
// Face values
forAll(values, elemi)
OFstream os
(
outputFile,
IOstream::ASCII,
IOstream::currentVersion,
writeCompression_
);
// Header
{
writePoint(os, faces[elemi].centre(points));
writeData(os, values[elemi]);
os << "# " << fieldName;
if (this->isPointData())
{
os << " POINT_DATA ";
}
else
{
os << " FACE_DATA ";
}
os << values.size() << nl;
// # x y z field
writeHeader<Type>(os, fieldName);
}
if (this->isPointData())
{
// Node values
forAll(values, elemi)
{
writePoint(os, points[elemi]);
writeData(os, values[elemi]);
}
}
else
{
// Face values
forAll(values, elemi)
{
writePoint(os, faces[elemi].centre(points));
writeData(os, values[elemi]);
}
}
}
return os.name();
return outputFile;
}

View File

@ -0,0 +1,217 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2008-2011, 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "starcdSurfaceWriter.H"
#include "OFstream.H"
#include "OSspecific.H"
#include "MeshedSurfaceProxy.H"
#include "surfaceWriterMethods.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace surfaceWriters
{
defineTypeName(starcdWriter);
addToRunTimeSelectionTable(surfaceWriter, starcdWriter, word);
}
}
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Emit each component
template<class Type>
static inline void writeData(Ostream& os, const Type& val)
{
const direction ncmpt = pTraits<Type>::nComponents;
for (direction cmpt=0; cmpt < ncmpt; ++cmpt)
{
os << ' ' << component(val, cmpt);
}
os << nl;
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::surfaceWriters::starcdWriter::starcdWriter()
:
surfaceWriter()
{}
Foam::surfaceWriters::starcdWriter::starcdWriter
(
const dictionary& options
)
:
surfaceWriter(options)
{}
Foam::surfaceWriters::starcdWriter::starcdWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
starcdWriter(options)
{
open(surf, outputPath, parallel);
}
Foam::surfaceWriters::starcdWriter::starcdWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
starcdWriter(options)
{
open(points, faces, outputPath, parallel);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::fileName Foam::surfaceWriters::starcdWriter::write()
{
checkOpen();
// Geometry: rootdir/<TIME>/surfaceName.{inp,cel,vrt}
fileName outputFile = outputPath_;
if (useTimeDir() && !timeName().empty())
{
// Splice in time-directory
outputFile = outputPath_.path() / timeName() / outputPath_.name();
}
outputFile.ext("inp");
if (verbose_)
{
Info<< "Writing geometry to " << outputFile << endl;
}
const meshedSurf& surf = surface();
if (Pstream::master() || !parallel_)
{
if (!isDir(outputFile.path()))
{
mkDir(outputFile.path());
}
MeshedSurfaceProxy<face>
(
surf.points(),
surf.faces()
).write(outputFile, "inp");
}
return outputFile;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::fileName Foam::surfaceWriters::starcdWriter::writeTemplate
(
const word& fieldName,
const Field<Type>& localValues
)
{
checkOpen();
// Field: rootdir/<TIME>/<field>_surfaceName.usr
fileName outputFile = outputPath_.path();
if (useTimeDir() && !timeName().empty())
{
// Splice in time-directory
outputFile /= timeName();
}
// Append <field>_surfaceName.usr
outputFile /= fieldName + '_' + outputPath_.name();
outputFile.ext("usr");
if (verbose_)
{
Info<< "Writing field " << fieldName << " to " << outputFile << endl;
}
// geometry merge() implicit
tmp<Field<Type>> tfield = mergeField(localValues);
if (Pstream::master() || !parallel_)
{
const auto& values = tfield();
if (!isDir(outputFile.path()))
{
mkDir(outputFile.path());
}
OFstream os(outputFile);
// 1-based ids
label elemId = 1;
// No header, just write values
for (const Type& val : values)
{
os << elemId;
writeData(os, val);
++elemId;
}
}
return outputFile;
}
// Field writing methods
defineSurfaceWriterWriteFields(Foam::surfaceWriters::starcdWriter);
// ************************************************************************* //

View File

@ -0,0 +1,170 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2008-2011, 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
Class
Foam::surfaceWriters::starcdWriter
Description
A surfaceWriter for STARCD files.
The geometry is written via the MeshedSurfaceProxy, the fields
are written in a trivial ASCII format with ID and VALUE as
so-called user data. These \c .usr files can be read into proSTAR
with these types of commands. For element data:
\verbatim
getuser FILENAME.usr cell scalar free
getuser FILENAME.usr cell vector free
\endverbatim
and for vertex data:
\verbatim
getuser FILENAME.usr vertex scalar free
getuser FILENAME.usr vertex vector free
\endverbatim
\heading Output file locations
The \c rootdir normally corresponds to something like
\c postProcessing/\<name\>
\subheading Geometry
\verbatim
rootdir
`-- timeName
`-- surfaceName.{cel,vrt,inp}
\endverbatim
\subheading Fields
\verbatim
rootdir
`-- timeName
|-- <field0>_surfaceName.{usr}
`-- <field1>_surfaceName.{usr}
\endverbatim
SourceFiles
starcdSurfaceWriter.C
\*---------------------------------------------------------------------------*/
#ifndef starcdSurfaceWriter_H
#define starcdSurfaceWriter_H
#include "surfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace surfaceWriters
{
/*---------------------------------------------------------------------------*\
Class starcdWriter Declaration
\*---------------------------------------------------------------------------*/
class starcdWriter
:
public surfaceWriter
{
// Private Member Functions
//- Templated write operation
template<class Type>
fileName writeTemplate
(
const word& fieldName, //!< Name of field
const Field<Type>& localValues //!< Local field values to write
);
public:
//- Runtime type information
TypeNameNoDebug("starcd");
// Constructors
//- Construct null
starcdWriter();
//- Construct with some output options
explicit starcdWriter(const dictionary& options);
//- Construct from components
starcdWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Construct from components
starcdWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Destructor
virtual ~starcdWriter() = default;
// Member Functions
//- True if the surface format supports geometry in a separate file.
// False if geometry and field must be in a single file
virtual bool separateGeometry() const
{
return true;
}
//- Write single surface geometry to file.
virtual fileName write(); // override
declareSurfaceWriterWriteMethod(label);
declareSurfaceWriterWriteMethod(scalar);
declareSurfaceWriterWriteMethod(vector);
declareSurfaceWriterWriteMethod(sphericalTensor);
declareSurfaceWriterWriteMethod(symmTensor);
declareSurfaceWriterWriteMethod(tensor);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace surfaceWriters
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,458 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "surfaceWriter.H"
#include "proxySurfaceWriter.H"
#include "MeshedSurfaceProxy.H"
#include "Time.H"
#include "globalIndex.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(surfaceWriter, 0);
defineRunTimeSelectionTable(surfaceWriter, word);
defineRunTimeSelectionTable(surfaceWriter, wordDict);
}
Foam::scalar Foam::surfaceWriter::defaultMergeDim = 1e-8;
const Foam::meshedSurf::emptySurface Foam::surfaceWriter::emptySurface_;
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
bool Foam::surfaceWriter::supportedType(const word& writeType)
{
return
(
wordConstructorTablePtr_->found(writeType)
|| wordDictConstructorTablePtr_->found(writeType)
|| MeshedSurfaceProxy<face>::canWriteType(writeType)
);
}
Foam::autoPtr<Foam::surfaceWriter>
Foam::surfaceWriter::New(const word& writeType)
{
// Constructors without dictionary options
auto cstrIter = wordConstructorTablePtr_->cfind(writeType);
if (!cstrIter.found())
{
if (MeshedSurfaceProxy<face>::canWriteType(writeType))
{
// Generally unknown, but handle via 'proxy' handler
return autoPtr<surfaceWriter>
(
new surfaceWriters::proxyWriter(writeType)
);
}
FatalErrorInFunction
<< "Unknown write type \"" << writeType << "\"\n\n"
<< "Valid write types : "
<< flatOutput(wordConstructorTablePtr_->sortedToc()) << nl
<< "Valid proxy types : "
<< MeshedSurfaceProxy<face>::writeTypes() << endl
<< exit(FatalError);
}
return autoPtr<surfaceWriter>(cstrIter()());
}
Foam::autoPtr<Foam::surfaceWriter>
Foam::surfaceWriter::New
(
const word& writeType,
const dictionary& writeOpts
)
{
// Constructors with dictionary options
auto cstrIter2 = wordDictConstructorTablePtr_->cfind(writeType);
if (cstrIter2.found())
{
return autoPtr<surfaceWriter>(cstrIter2()(writeOpts));
}
// Constructors without dictionary options
auto cstrIter = wordConstructorTablePtr_->cfind(writeType);
if (!cstrIter.found())
{
if (MeshedSurfaceProxy<face>::canWriteType(writeType))
{
// Generally unknown, but handle via 'proxy' handler
return autoPtr<surfaceWriter>
(
new surfaceWriters::proxyWriter(writeType, writeOpts)
);
}
FatalErrorInFunction
<< "Unknown write type \"" << writeType << "\"\n\n"
<< "Valid write types : "
<< wordConstructorTablePtr_->sortedToc() << nl
<< "Valid proxy types : "
<< MeshedSurfaceProxy<face>::writeTypes() << endl
<< exit(FatalError);
}
return autoPtr<surfaceWriter>(cstrIter()());
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::surfaceWriter::surfaceWriter()
:
surf_(std::cref<meshedSurf>(emptySurface_)),
upToDate_(false),
parallel_(true),
useTimeDir_(false),
isPointData_(false),
verbose_(false),
nFields_(0),
mergeDim_(defaultMergeDim),
merged_(),
currTime_(),
outputPath_()
{
surfaceWriter::close();
}
Foam::surfaceWriter::surfaceWriter(const dictionary& options)
:
surfaceWriter()
{
options.readIfPresent("verbose", verbose_);
}
Foam::surfaceWriter::surfaceWriter
(
const meshedSurf& surf,
bool parallel,
const dictionary& options
)
:
surfaceWriter(options)
{
setSurface(surf, parallel);
}
Foam::surfaceWriter::surfaceWriter
(
const pointField& points,
const faceList& faces,
bool parallel,
const dictionary& options
)
:
surfaceWriter(options)
{
setSurface(points, faces, parallel);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::surfaceWriter::setTime(const instant& inst)
{
currTime_ = inst;
}
void Foam::surfaceWriter::setTime(scalar timeValue)
{
currTime_ = instant(timeValue);
}
void Foam::surfaceWriter::setTime(scalar timeValue, const word& timeName)
{
currTime_.value() = timeValue;
currTime_.name() = timeName;
}
void Foam::surfaceWriter::unsetTime()
{
currTime_.value() = 0;
currTime_.name().clear();
}
void Foam::surfaceWriter::beginTime(const Time& t)
{
setTime(t.value(), t.timeName());
}
void Foam::surfaceWriter::beginTime(const instant& inst)
{
setTime(inst);
}
void Foam::surfaceWriter::endTime()
{
unsetTime();
}
void Foam::surfaceWriter::open(const fileName& outputPath)
{
outputPath_ = outputPath;
}
void Foam::surfaceWriter::open
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel
)
{
close();
setSurface(surf, parallel);
open(outputPath);
}
void Foam::surfaceWriter::open
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel
)
{
close();
setSurface(points, faces, parallel);
open(outputPath);
}
void Foam::surfaceWriter::close()
{
outputPath_.clear();
}
void Foam::surfaceWriter::clear()
{
close();
expire();
surf_ = std::cref<meshedSurf>(emptySurface_);
}
void Foam::surfaceWriter::setSurface
(
const meshedSurf& surf,
bool parallel
)
{
expire();
surf_ = std::cref<meshedSurf>(surf);
}
void Foam::surfaceWriter::setSurface
(
const pointField& points,
const faceList& faces,
bool parallel
)
{
expire();
setSurface(meshedSurfRef(points, faces), parallel);
}
bool Foam::surfaceWriter::needsUpdate() const
{
return !upToDate_;
}
bool Foam::surfaceWriter::expire()
{
const bool changed = upToDate_;
upToDate_ = false;
nFields_ = 0;
merged_.clear();
return changed;
}
bool Foam::surfaceWriter::hasSurface() const
{
return (&emptySurface_ != &(surf_.get()));
}
bool Foam::surfaceWriter::empty() const
{
const bool value = surf_.get().faces().empty();
return (parallel_ ? returnReduce(value, andOp<bool>()) : value);
}
Foam::label Foam::surfaceWriter::size() const
{
const label value = surf_.get().faces().size();
return (parallel_ ? returnReduce(value, sumOp<label>()) : value);
}
bool Foam::surfaceWriter::checkOpen() const
{
if (outputPath_.empty())
{
FatalErrorInFunction
<< type() << " : Attempted to write without a path" << nl
<< exit(FatalIOError);
}
return !outputPath_.empty();
}
bool Foam::surfaceWriter::merge() const
{
bool changed = false;
if (parallel_ && Pstream::parRun() && !upToDate_)
{
changed = merged_.merge(surf_.get(), mergeDim_);
}
upToDate_ = true;
return changed;
}
const Foam::meshedSurf& Foam::surfaceWriter::surface() const
{
merge();
if (parallel_ && Pstream::parRun())
{
return merged_;
}
return surf_.get();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::surfaceWriter::mergeFieldTemplate
(
const Field<Type>& fld
) const
{
if (parallel_ && Pstream::parRun())
{
// Ensure geometry is also merged
merge();
// Gather all values
auto tfield = tmp<Field<Type>>::New();
auto& allFld = tfield.ref();
globalIndex::gatherOp(fld, allFld);
// Renumber (point data) to correspond to merged points
if (Pstream::master() && this->isPointData())
{
inplaceReorder(merged_.pointsMap(), allFld);
allFld.resize(merged_.points().size());
}
return tfield;
}
// Mark that any geometry changes have been taken care of
upToDate_ = true;
return fld;
}
#define defineSurfaceWriterMergeMethod(ThisClass, Type) \
Foam::tmp<Foam::Field<Type>> \
ThisClass::mergeField(const Field<Type>& fld) const \
{ \
return mergeFieldTemplate(fld); \
}
defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::label);
defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::scalar);
defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::vector);
defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::sphericalTensor);
defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::symmTensor);
defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::tensor)
#undef defineSurfaceWriterMergeMethod
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const InfoProxy<surfaceWriter>& ip
)
{
const surfaceWriter& w = ip.t_;
os << "surfaceWriter:"
<< " upToDate: " << w.upToDate_
<< " PointData: " << w.isPointData_
<< " nFields: " << w.nFields_
<< " time: " << w.currTime_
<< " path: " << w.outputPath_ << endl;
return os;
}
// ************************************************************************* //

View File

@ -0,0 +1,491 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2012 OpenFOAM Foundation
-------------------------------------------------------------------------------
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::surfaceWriters
Description
Namespace for surface writers
Class
Foam::surfaceWriter
Description
Base class for surface writers.
The surfaceWriter interface is rather large since we need a writer that
can either be initially defined without a surface association
and have that added at a later stage, or be defined with a surface
association.
\verbatim
formatOptions
{
someFormat // Eg, ensight, vtk, etc
{
verbose true;
}
}
\endverbatim
Format options:
\table
Property | Description | Required | Default
verbose | Additional output verbosity | no | no
\endtable
SourceFiles
sampledWriter.C
sampledWriterI.H
sampledWriterImpl.C
\*---------------------------------------------------------------------------*/
#ifndef surfaceWriter_H
#define surfaceWriter_H
#include <functional>
#include "typeInfo.H"
#include "autoPtr.H"
#include "tmp.H"
#include "Field.H"
#include "fileName.H"
#include "instant.H"
#include "mergedSurf.H"
#include "meshedSurfRef.H"
#include "InfoProxy.H"
#include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
class Time;
class surfaceWriter;
Ostream& operator<<(Ostream& os, const InfoProxy<surfaceWriter>& ip);
/*---------------------------------------------------------------------------*\
Class surfaceWriter Declaration
\*---------------------------------------------------------------------------*/
class surfaceWriter
{
protected:
// Static data members
//- Placeholder
static const meshedSurf::emptySurface emptySurface_;
// Protected data
//- Reference to the surface
std::reference_wrapper<const meshedSurf> surf_;
//- The topology/surface is up-to-date?
mutable bool upToDate_;
//- Writing in parallel (vai master)
bool parallel_;
//- Writer should do something funny
bool useTimeDir_;
//- Is point vs cell data
bool isPointData_;
//- Additional output verbosity
bool verbose_;
//- The number of fields
label nFields_;
//- Dimension for merging
scalar mergeDim_;
//- Merging information and the resulting merged surface (parallel)
mutable mergedSurf merged_;
//- The current time value/name
instant currTime_;
//- The full output directory and file (surface) name
fileName outputPath_;
// Protected Member Functions
//- Verify that the outputPath_ has been set or FatalError
bool checkOpen() const;
//- Merge surfaces if they are not already upToDate (parallel)
//- or simply mark the surface as being up-to-date
virtual bool merge() const;
//- Merge surfaces (if not upToDate) and return merged or
//- the regular surface
const meshedSurf& surface() const;
//- Gather (merge) fields with renumbering and shrinking for point data
template<class Type>
tmp<Field<Type>> mergeFieldTemplate(const Field<Type>& fld) const;
#undef declareSurfaceWriterMergeMethod
#define declareSurfaceWriterMergeMethod(Type) \
tmp<Field<Type>> mergeField(const Field<Type>& fld) const;
declareSurfaceWriterMergeMethod(label);
declareSurfaceWriterMergeMethod(scalar);
declareSurfaceWriterMergeMethod(vector);
declareSurfaceWriterMergeMethod(sphericalTensor);
declareSurfaceWriterMergeMethod(symmTensor);
declareSurfaceWriterMergeMethod(tensor);
#undef declareSurfaceWriterMergeMethod
//- Dummy templated write operation
template<class Type>
fileName writeTemplate
(
const word& fieldName, //!< Name of field
const Field<Type>& localValues //!< Local field values to write
)
{
return fileName::null;
}
public:
// Public data
//- The default merge dimension (1e-8)
static scalar defaultMergeDim;
//- Runtime type information
TypeName("surfaceWriter");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
surfaceWriter,
word,
(),
()
);
declareRunTimeSelectionTable
(
autoPtr,
surfaceWriter,
wordDict,
(
const dictionary& writeOpts
),
(writeOpts)
);
// Selectors
//- True if New is likely to succeed for this writeType
static bool supportedType(const word& writeType);
//- Return a reference to the selected surfaceWriter
static autoPtr<surfaceWriter> New(const word& writeType);
//- Return a reference to the selected surfaceWriter
// Select with extra write option
static autoPtr<surfaceWriter> New
(
const word& writeType,
const dictionary& writeOptions
);
// Constructors
//- Construct null
surfaceWriter();
//- Construct null with specified options
explicit surfaceWriter(const dictionary& options);
//- Construct from components
explicit surfaceWriter
(
const meshedSurf& surf,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Construct from components
surfaceWriter
(
const pointField& points,
const faceList& faces,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Destructor
virtual ~surfaceWriter() = default;
// Member Functions
// Capability
//- The writer is enabled. If the writer is not enabled, it may be
//- possible for the caller to skip various preparatory operations.
// This method is primarily useful for the null writer
virtual bool enabled() const
{
return true;
}
//- True if the surface format requires geometry in a separate file.
virtual bool separateGeometry() const
{
return false;
}
// Bookkeeping
//- Does the writer need an update (eg, lagging behind surface changes)
virtual bool needsUpdate() const;
//- Mark that surface changed and the writer will need an update,
//- and set nFields = 0.
// May also free up unneeded data.
// Return false if it was previously already expired.
virtual bool expire();
//- Close any open output, remove association with a surface and
//- expire the writer. The parallel flag remains untouched.
virtual void clear();
// Surface association
//- Change association with a surface and expire the writer
virtual void setSurface
(
const meshedSurf& surf,
bool parallel = Pstream::parRun()
);
//- Change association with a surface and expire the writer
virtual void setSurface
(
const pointField& points,
const faceList& faces,
bool parallel = Pstream::parRun()
);
// Queries, Access
//- Writer is associated with a surface
bool hasSurface() const;
//- The surface to write is empty if the global number of faces is zero
bool empty() const;
//- The global number of faces for the associated surface
label size() const;
//- The number of expected output fields.
// Currently only used by the legacy VTK format.
inline label nFields() const;
//- The number of expected output fields.
// Currently only used by the legacy VTK format.
inline label& nFields();
//- Are the field data to be treated as point data?
inline bool isPointData() const;
//- Set handling of field data to face/point data.
inline bool& isPointData();
//- Should a time directory be spliced into the output path?
inline bool useTimeDir() const;
//- Change handling of spliced output path.
inline bool& useTimeDir();
//- Get output verbosity
inline bool verbose() const;
//- Set output verbosity
inline bool& verbose();
//- The current value of the point merge dimension (metre)
inline scalar mergeDim() const;
//- The current value of the point merge dimension (metre)
inline scalar& mergeDim();
// Time
//- True if there is a known time
inline bool hasTime() const;
//- The current time value/name
inline const word& timeName() const;
//- The current time value/name
inline scalar timeValue() const;
//- Set the current time
void setTime(const instant& inst);
//- Set current time from timeValue, auto generating the name
void setTime(scalar timeValue);
//- Set current time from timeValue and timeName
void setTime(scalar timeValue, const word& timeName);
//- Clear the current time
void unsetTime();
//- Begin a time-step
virtual void beginTime(const Time& t);
//- Begin a time-step
virtual void beginTime(const instant& inst);
//- End a time-step
virtual void endTime();
// Output
//- Open for output on specified path, using existing surface
virtual void open(const fileName& outputPath);
//- Open from components
virtual void open
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel = Pstream::parRun()
);
//- Open from components
virtual void open
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel = Pstream::parRun()
);
//- Finish output, performing any necessary cleanup
virtual void close();
// Write
//- Write single surface geometry to file.
virtual fileName writeGeometry() const
{
return fileName::null;
}
#undef declareSurfaceWriterWriteMethod
#define declareSurfaceWriterWriteMethod(Type) \
/**! Write field of Type (per face or vertex) */ \
virtual fileName write \
( \
const word& fieldName, /*!< Name of field */ \
const Field<Type>& values /*!< Field values to write */ \
) = 0
declareSurfaceWriterWriteMethod(label);
declareSurfaceWriterWriteMethod(scalar);
declareSurfaceWriterWriteMethod(vector);
declareSurfaceWriterWriteMethod(sphericalTensor);
declareSurfaceWriterWriteMethod(symmTensor);
declareSurfaceWriterWriteMethod(tensor);
#undef declareSurfaceWriterWriteMethod
#define declareSurfaceWriterWriteMethod(Type) \
\
/**! Write field of Type (per face or vertex) */ \
virtual fileName write \
( \
const word& fieldName, /*!< Name of field */ \
const Field<Type>& values /*!< Field values to write */ \
) // override
// Other IO
//- Return info proxy.
virtual InfoProxy<surfaceWriter> info() const
{
return *this;
}
//- Output info proxy
friend Ostream& operator<<
(
Ostream& os,
const InfoProxy<surfaceWriter>& ip
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "surfaceWriterI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,10 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,56 +23,83 @@ License
\*---------------------------------------------------------------------------*/
#include "starcdSurfaceWriter.H"
#include "MeshedSurfaceProxy.H"
#include "OFstream.H"
#include "OSspecific.H"
#include "makeSurfaceWriterMethods.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
makeSurfaceWriterType(starcdSurfaceWriter);
}
// Field writing implementation
#include "starcdSurfaceWriterImpl.C"
// Field writing methods
defineSurfaceWriterWriteFields(Foam::starcdSurfaceWriter);
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::fileName Foam::starcdSurfaceWriter::write
(
const fileName& outputDir,
const fileName& surfaceName,
const meshedSurf& surf,
const bool verbose
) const
inline Foam::label Foam::surfaceWriter::nFields() const
{
// geometry: rootdir/time/surfaceName.{raw,vrt,inp}
return nFields_;
}
fileName outputFile(outputDir/surfaceName + ".inp");
if (verbose)
{
Info<< "Writing geometry to " << outputFile << endl;
}
inline Foam::label& Foam::surfaceWriter::nFields()
{
return nFields_;
}
if (!isDir(outputFile.path()))
{
mkDir(outputFile.path());
}
MeshedSurfaceProxy<face>(surf.points(), surf.faces()).write
(
outputFile
);
inline bool Foam::surfaceWriter::isPointData() const
{
return isPointData_;
}
return outputFile;
inline bool& Foam::surfaceWriter::isPointData()
{
return isPointData_;
}
inline bool Foam::surfaceWriter::useTimeDir() const
{
return useTimeDir_;
}
inline bool& Foam::surfaceWriter::useTimeDir()
{
return useTimeDir_;
}
inline bool Foam::surfaceWriter::verbose() const
{
return verbose_;
}
inline bool& Foam::surfaceWriter::verbose()
{
return verbose_;
}
inline Foam::scalar Foam::surfaceWriter::mergeDim() const
{
return mergeDim_;
}
inline Foam::scalar& Foam::surfaceWriter::mergeDim()
{
return mergeDim_;
}
inline bool Foam::surfaceWriter::hasTime() const
{
return currTime_.name().size();
}
inline const Foam::word& Foam::surfaceWriter::timeName() const
{
return currTime_.name();
}
inline Foam::scalar Foam::surfaceWriter::timeValue() const
{
return currTime_.name().empty() ? 0 : currTime_.value();
}

View File

@ -2,10 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -24,56 +22,35 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
InClass
Foam::makeSurfaceWriterMethods
Foam::surfaceWriterMethods
Description
Convenience macros for instantiating writer methods for surfaceWriter
classes.
Convenience macros for instantiating surfaceWriter methods.
\*---------------------------------------------------------------------------*/
#ifndef makeSurfaceWriterMethods_H
#define makeSurfaceWriterMethods_H
#include "surfaceWriter.H"
#include "addToRunTimeSelectionTable.H"
#ifndef surfaceWriterMethods_H
#define surfaceWriterMethods_H
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#define makeSurfaceWriterType(ThisClass) \
defineTypeNameAndDebug(ThisClass, 0); \
addToRunTimeSelectionTable(surfaceWriter, ThisClass, word)
// Instantiate templated method for standard types
#define defineSurfaceWriterWriteField(ThisClass, FieldType) \
Foam::fileName ThisClass::write \
( \
const fileName& outputDir, \
const fileName& surfaceName, \
const meshedSurf& surf, \
const word& fieldName, \
const Field<FieldType>& values, \
const bool isNodeValues, \
const bool verbose \
) const \
const Field<FieldType>& values \
) \
{ \
return writeTemplate \
( \
outputDir, \
surfaceName, \
surf, \
fieldName, \
values, \
isNodeValues, \
verbose \
); \
return writeTemplate(fieldName, values); \
}
#define defineSurfaceWriterWriteFields(ThisClass) \
defineSurfaceWriterWriteField(ThisClass, label); \
defineSurfaceWriterWriteField(ThisClass, scalar); \
defineSurfaceWriterWriteField(ThisClass, vector); \
defineSurfaceWriterWriteField(ThisClass, sphericalTensor); \

View File

@ -0,0 +1,291 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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/>.
\*---------------------------------------------------------------------------*/
#include "vtkSurfaceWriter.H"
#include "foamVtkSurfaceWriter.H"
#include "surfaceWriterMethods.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace surfaceWriters
{
defineTypeName(vtkWriter);
addToRunTimeSelectionTable(surfaceWriter, vtkWriter, word);
addToRunTimeSelectionTable(surfaceWriter, vtkWriter, wordDict);
// Accept vtp ending as well
addNamedToRunTimeSelectionTable
(
surfaceWriter,
vtkWriter,
word,
vtp
);
addNamedToRunTimeSelectionTable
(
surfaceWriter,
vtkWriter,
wordDict,
vtp
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::surfaceWriters::vtkWriter::vtkWriter()
:
surfaceWriter(),
fmtType_(static_cast<unsigned>(vtk::formatType::INLINE_BASE64)),
precision_(IOstream::defaultPrecision()),
writer_(nullptr)
{}
Foam::surfaceWriters::vtkWriter::vtkWriter
(
const vtk::outputOptions& opts
)
:
surfaceWriter(),
fmtType_(static_cast<unsigned>(opts.fmt())),
precision_(opts.precision()),
writer_(nullptr)
{}
Foam::surfaceWriters::vtkWriter::vtkWriter
(
const dictionary& options
)
:
surfaceWriter(options),
fmtType_(static_cast<unsigned>(vtk::formatType::INLINE_BASE64)),
precision_
(
options.lookupOrDefaultCompat
(
"precision", {{"writePrecision", 1806}},
IOstream::defaultPrecision()
)
),
writer_(nullptr)
{
// format: ascii | binary
// legacy: true | false
vtk::outputOptions opts(vtk::formatType::INLINE_BASE64);
const word formatName = options.lookupOrDefault<word>("format", "");
if (formatName.size())
{
opts.ascii
(
IOstream::formatEnum(formatName) == IOstream::ASCII
);
}
if (options.lookupOrDefault("legacy", false))
{
opts.legacy(true);
}
// Convert back to raw data type
fmtType_ = static_cast<unsigned>(opts.fmt());
}
Foam::surfaceWriters::vtkWriter::vtkWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
vtkWriter(options)
{
open(surf, outputPath, parallel);
}
Foam::surfaceWriters::vtkWriter::vtkWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
vtkWriter(options)
{
open(points, faces, outputPath, parallel);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::surfaceWriters::vtkWriter::close()
{
writer_.clear();
surfaceWriter::close();
}
void Foam::surfaceWriters::vtkWriter::beginTime(const Time& t)
{
writer_.clear();
surfaceWriter::beginTime(t);
}
void Foam::surfaceWriters::vtkWriter::beginTime(const instant& inst)
{
writer_.clear();
surfaceWriter::beginTime(inst);
}
void Foam::surfaceWriters::vtkWriter::endTime()
{
writer_.clear();
surfaceWriter::endTime();
}
Foam::fileName Foam::surfaceWriters::vtkWriter::write()
{
checkOpen();
if (needsUpdate())
{
writer_.clear();
}
merge();
// From raw unsigned values to vtk::outputOptions
vtk::outputOptions opts(static_cast<vtk::formatType>(fmtType_), precision_);
// Geometry: rootdir/<TIME>/surfaceName.{vtk|vtp}
fileName outputFile = outputPath_;
if (useTimeDir() && !timeName().empty())
{
// Splice in time-directory
outputFile = outputPath_.path() / timeName() / outputPath_.name();
}
outputFile.ext(vtk::surfaceWriter::ext(opts));
if (verbose_)
{
Info<< "Writing geometry to " << outputFile << endl;
}
const meshedSurf& surf = surface();
if (writer_.empty() && (Pstream::master() || !parallel_))
{
writer_.reset
(
new vtk::surfaceWriter
(
surf.points(),
surf.faces(),
opts,
outputFile,
false // serial!
)
);
if (this->hasTime())
{
// Time name in title
writer_->setTime(currTime_);
writer_->writeTimeValue();
}
else
{
// Surface name in title
writer_->beginFile(outputPath_.nameLessExt());
}
writer_->writeGeometry();
}
return outputFile;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::fileName Foam::surfaceWriters::vtkWriter::writeTemplate
(
const word& fieldName,
const Field<Type>& localValues
)
{
// Field: rootdir/<TIME>/surfaceName.{vtk|vtp}
// Open file, writing geometry (if required)
fileName outputFile = this->write();
if (verbose_)
{
Info<< "Writing field " << fieldName << " to " << outputFile << endl;
}
// geometry merge() implicit
tmp<Field<Type>> tfield = mergeField(localValues);
if (Pstream::master() || !parallel_)
{
if (this->isPointData())
{
writer_->beginPointData(nFields_);
}
else
{
writer_->beginCellData(nFields_);
}
writer_->write(fieldName, tfield());
}
return outputFile;
}
// Field writing methods
defineSurfaceWriterWriteFields(Foam::surfaceWriters::vtkWriter);
// ************************************************************************* //

View File

@ -0,0 +1,203 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2008-2011, 2015-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011 OpenFOAM Foundation
-------------------------------------------------------------------------------
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/>.
Class
Foam::surfaceWriters::vtkWriter
Description
A surfaceWriter for VTK legacy (.vtk) or XML (.vtp) format.
The formatOptions for vtk:
\table
Property | Description | Required | Default
format | ascii or binary format | no | binary
legacy | Legacy VTK output | no | false
precision | Write precision in ascii | no | same as IOstream
\endtable
For example,
\verbatim
formatOptions
{
vtk
{
format binary;
legacy false;
precision 10;
}
}
\endverbatim
\heading Output file locations
The \c rootdir normally corresponds to something like
\c postProcessing/\<name\>
\subheading Geometry and Fields
\verbatim
rootdir
`-- timeName
`-- surfaceName.{vtk,vtp}
\endverbatim
SourceFiles
vtkSurfaceWriter.C
\*---------------------------------------------------------------------------*/
#ifndef vtkSurfaceWriter_H
#define vtkSurfaceWriter_H
#include "surfaceWriter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace vtk
{
// Forward declarations
class outputOptions;
class surfaceWriter;
}
namespace surfaceWriters
{
/*---------------------------------------------------------------------------*\
Class vtkWriter Declaration
\*---------------------------------------------------------------------------*/
class vtkWriter
:
public surfaceWriter
{
// Private Data
//- The VTK output format type.
// Stored as a raw value to avoid a header dependency on fileFormats
unsigned fmtType_;
//- ASCII write precision
unsigned precision_;
//- Backend writer - master only
autoPtr<Foam::vtk::surfaceWriter> writer_;
// Private Member Functions
//- Templated write field operation
template<class Type>
fileName writeTemplate
(
const word& fieldName, //!< Name of field
const Field<Type>& localValues //!< Local field values to write
);
public:
//- Runtime type information
TypeNameNoDebug("vtk");
// Constructors
//- Construct null
vtkWriter();
//- Construct with some output options
explicit vtkWriter(const vtk::outputOptions& opts);
//- Construct with some output options
explicit vtkWriter(const dictionary& options);
//- Construct from components
// The file name is with/without an extension.
vtkWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Construct from components with specified output path.
// The file name is with/without an extension.
vtkWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel = Pstream::parRun(),
const dictionary& options = dictionary()
);
//- Destructor
virtual ~vtkWriter() = default;
// Member Functions
//- Finish output, clears backend.
virtual void close(); // override
//- Begin time step. Clears existing backend.
virtual void beginTime(const Time& t); // override
//- Begin time step. Clears existing backend.
virtual void beginTime(const instant& inst); // override
//- End time step. Clears existing backend.
virtual void endTime(); // override
// Write
//- Write surface geometry to file.
virtual fileName write(); // override
declareSurfaceWriterWriteMethod(label);
declareSurfaceWriterWriteMethod(scalar);
declareSurfaceWriterWriteMethod(vector);
declareSurfaceWriterWriteMethod(sphericalTensor);
declareSurfaceWriterWriteMethod(symmTensor);
declareSurfaceWriterWriteMethod(tensor);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace surfaceWriters
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //