mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: refactor coordSet writers (#2347)
- the very old 'writer' class was fully stateless and always templated on an particular output type. This is now replaced with a 'coordSetWriter' with similar concepts as previously introduced for surface writers (#1206). - writers change from being a generic state-less set of routines to more properly conforming to the normal notion of a writer. - Parallel data is done *outside* of the writers, since they are used in a wide variety of contexts and the caller is currently still in a better position for deciding how to combine parallel data. ENH: update sampleSets to sample on per-field basis (#2347) - sample/write a field in a single step. - support for 'sampleOnExecute' to obtain values at execution intervals without writing. - support 'sets' input as a dictionary entry (as well as a list), which is similar to the changes for sampled-surface and permits use of changeDictionary to modify content. - globalIndex for gather to reduce parallel communication, less code - qualify the sampleSet results (properties) with the name of the set. The sample results were previously without a qualifier, which meant that only the last property value was actually saved (previous ones overwritten). For example, ``` sample1 { scalar { average(line,T) 349.96521; min(line,T) 349.9544281; max(line,T) 350; average(cells,T) 349.9854619; min(cells,T) 349.6589286; max(cells,T) 350.4967271; average(line,epsilon) 0.04947733869; min(line,epsilon) 0.04449639927; max(line,epsilon) 0.06452856475; } label { size(line,T) 79; size(cells,T) 1720; size(line,epsilon) 79; } } ``` ENH: update particleTracks application - use globalIndex to manage original parcel addressing and for gathering. Simplify code by introducing a helper class, storing intermediate fields in hash tables instead of separate lists. ADDITIONAL NOTES: - the regionSizeDistribution largely retains separate writers since the utility of placing sum/dev/count for all fields into a single file is questionable. - the streamline writing remains a "soft" upgrade, which means that scalar and vector fields are still collected a priori and not on-the-fly. This is due to how the streamline infrastructure is currently handled (should be upgraded in the future).
This commit is contained in:
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -40,7 +40,7 @@ Description
|
|||||||
#include "IOdictionary.H"
|
#include "IOdictionary.H"
|
||||||
#include "searchableSurfaces.H"
|
#include "searchableSurfaces.H"
|
||||||
#include "conformalVoronoiMesh.H"
|
#include "conformalVoronoiMesh.H"
|
||||||
#include "vtkSetWriter.H"
|
#include "vtkCoordSetWriter.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
@ -106,8 +106,10 @@ int main(int argc, char *argv[])
|
|||||||
foamyHexMeshDict.getOrDefault("singleRegionName", true)
|
foamyHexMeshDict.getOrDefault("singleRegionName", true)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
autoPtr<coordSetWriter> setWriterPtr(new coordSetWriters::vtkWriter());
|
||||||
|
|
||||||
// Write some stats
|
// Write some stats
|
||||||
allGeometry.writeStats(List<wordList>(0), Info);
|
allGeometry.writeStats(List<wordList>(), Info);
|
||||||
// Check topology
|
// Check topology
|
||||||
allGeometry.checkTopology(true);
|
allGeometry.checkTopology(true);
|
||||||
// Check geometry
|
// Check geometry
|
||||||
@ -115,7 +117,7 @@ int main(int argc, char *argv[])
|
|||||||
(
|
(
|
||||||
100.0, // max size ratio
|
100.0, // max size ratio
|
||||||
1e-9, // intersection tolerance
|
1e-9, // intersection tolerance
|
||||||
autoPtr<writer<scalar>>(new vtkSetWriter<scalar>()),
|
setWriterPtr,
|
||||||
0.01, // min triangle quality
|
0.01, // min triangle quality
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -51,7 +51,7 @@ Description
|
|||||||
#include "refinementParameters.H"
|
#include "refinementParameters.H"
|
||||||
#include "snapParameters.H"
|
#include "snapParameters.H"
|
||||||
#include "layerParameters.H"
|
#include "layerParameters.H"
|
||||||
#include "vtkSetWriter.H"
|
#include "vtkCoordSetWriter.H"
|
||||||
#include "faceSet.H"
|
#include "faceSet.H"
|
||||||
#include "motionSmoother.H"
|
#include "motionSmoother.H"
|
||||||
#include "polyTopoChange.H"
|
#include "polyTopoChange.H"
|
||||||
@ -854,19 +854,25 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
const bool keepPatches(meshDict.getOrDefault("keepPatches", false));
|
const bool keepPatches(meshDict.getOrDefault("keepPatches", false));
|
||||||
|
|
||||||
// format to be used for writing lines
|
// Writer for writing lines
|
||||||
const word setFormat
|
autoPtr<coordSetWriter> setFormatter;
|
||||||
(
|
{
|
||||||
meshDict.getOrDefault<word>
|
const word setFormat
|
||||||
(
|
(
|
||||||
"setFormat",
|
meshDict.getOrDefault<word>
|
||||||
vtkSetWriter<scalar>::typeName
|
(
|
||||||
)
|
"setFormat",
|
||||||
);
|
coordSetWriters::vtkWriter::typeName // Default: "vtk"
|
||||||
const autoPtr<writer<scalar>> setFormatter
|
)
|
||||||
(
|
);
|
||||||
writer<scalar>::New(setFormat)
|
|
||||||
);
|
setFormatter = coordSetWriter::New
|
||||||
|
(
|
||||||
|
setFormat,
|
||||||
|
meshDict.subOrEmptyDict("formatOptions").optionalSubDict(setFormat)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const scalar maxSizeRatio
|
const scalar maxSizeRatio
|
||||||
(
|
(
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
#include "checkTools.H"
|
#include "checkTools.H"
|
||||||
#include "functionObject.H"
|
#include "functionObject.H"
|
||||||
|
|
||||||
#include "vtkSetWriter.H"
|
#include "vtkCoordSetWriter.H"
|
||||||
#include "vtkSurfaceWriter.H"
|
#include "vtkSurfaceWriter.H"
|
||||||
|
|
||||||
#include "cyclicACMIPolyPatch.H"
|
#include "cyclicACMIPolyPatch.H"
|
||||||
@ -537,7 +537,7 @@ Foam::label Foam::checkGeometry
|
|||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
const bool allGeometry,
|
const bool allGeometry,
|
||||||
autoPtr<surfaceWriter>& surfWriter,
|
autoPtr<surfaceWriter>& surfWriter,
|
||||||
const autoPtr<writer<scalar>>& setWriter
|
autoPtr<coordSetWriter>& setWriter
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
label noFailedChecks = 0;
|
label noFailedChecks = 0;
|
||||||
@ -594,7 +594,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< nonAlignedPoints.name() << endl;
|
<< nonAlignedPoints.name() << endl;
|
||||||
nonAlignedPoints.instance() = mesh.pointsInstance();
|
nonAlignedPoints.instance() = mesh.pointsInstance();
|
||||||
nonAlignedPoints.write();
|
nonAlignedPoints.write();
|
||||||
if (setWriter)
|
if (setWriter && setWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*setWriter, nonAlignedPoints);
|
mergeAndWrite(*setWriter, nonAlignedPoints);
|
||||||
}
|
}
|
||||||
@ -628,7 +628,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< " non closed cells to set " << cells.name() << endl;
|
<< " non closed cells to set " << cells.name() << endl;
|
||||||
cells.instance() = mesh.pointsInstance();
|
cells.instance() = mesh.pointsInstance();
|
||||||
cells.write();
|
cells.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, cells);
|
mergeAndWrite(*surfWriter, cells);
|
||||||
}
|
}
|
||||||
@ -644,7 +644,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< aspectCells.name() << endl;
|
<< aspectCells.name() << endl;
|
||||||
aspectCells.instance() = mesh.pointsInstance();
|
aspectCells.instance() = mesh.pointsInstance();
|
||||||
aspectCells.write();
|
aspectCells.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, aspectCells);
|
mergeAndWrite(*surfWriter, aspectCells);
|
||||||
}
|
}
|
||||||
@ -665,7 +665,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< " zero area faces to set " << faces.name() << endl;
|
<< " zero area faces to set " << faces.name() << endl;
|
||||||
faces.instance() = mesh.pointsInstance();
|
faces.instance() = mesh.pointsInstance();
|
||||||
faces.write();
|
faces.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, faces);
|
mergeAndWrite(*surfWriter, faces);
|
||||||
}
|
}
|
||||||
@ -687,7 +687,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< " zero volume cells to set " << cells.name() << endl;
|
<< " zero volume cells to set " << cells.name() << endl;
|
||||||
cells.instance() = mesh.pointsInstance();
|
cells.instance() = mesh.pointsInstance();
|
||||||
cells.write();
|
cells.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, cells);
|
mergeAndWrite(*surfWriter, cells);
|
||||||
}
|
}
|
||||||
@ -710,7 +710,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< " non-orthogonal faces to set " << faces.name() << endl;
|
<< " non-orthogonal faces to set " << faces.name() << endl;
|
||||||
faces.instance() = mesh.pointsInstance();
|
faces.instance() = mesh.pointsInstance();
|
||||||
faces.write();
|
faces.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, faces);
|
mergeAndWrite(*surfWriter, faces);
|
||||||
}
|
}
|
||||||
@ -732,7 +732,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< faces.name() << endl;
|
<< faces.name() << endl;
|
||||||
faces.instance() = mesh.pointsInstance();
|
faces.instance() = mesh.pointsInstance();
|
||||||
faces.write();
|
faces.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, faces);
|
mergeAndWrite(*surfWriter, faces);
|
||||||
}
|
}
|
||||||
@ -754,7 +754,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< " skew faces to set " << faces.name() << endl;
|
<< " skew faces to set " << faces.name() << endl;
|
||||||
faces.instance() = mesh.pointsInstance();
|
faces.instance() = mesh.pointsInstance();
|
||||||
faces.write();
|
faces.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, faces);
|
mergeAndWrite(*surfWriter, faces);
|
||||||
}
|
}
|
||||||
@ -778,7 +778,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< faces.name() << endl;
|
<< faces.name() << endl;
|
||||||
faces.instance() = mesh.pointsInstance();
|
faces.instance() = mesh.pointsInstance();
|
||||||
faces.write();
|
faces.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, faces);
|
mergeAndWrite(*surfWriter, faces);
|
||||||
}
|
}
|
||||||
@ -811,7 +811,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< "decomposition tets to set " << faces.name() << endl;
|
<< "decomposition tets to set " << faces.name() << endl;
|
||||||
faces.instance() = mesh.pointsInstance();
|
faces.instance() = mesh.pointsInstance();
|
||||||
faces.write();
|
faces.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, faces);
|
mergeAndWrite(*surfWriter, faces);
|
||||||
}
|
}
|
||||||
@ -836,7 +836,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< endl;
|
<< endl;
|
||||||
points.instance() = mesh.pointsInstance();
|
points.instance() = mesh.pointsInstance();
|
||||||
points.write();
|
points.write();
|
||||||
if (setWriter)
|
if (setWriter && setWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*setWriter, points);
|
mergeAndWrite(*setWriter, points);
|
||||||
}
|
}
|
||||||
@ -859,7 +859,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< " apart) points to set " << nearPoints.name() << endl;
|
<< " apart) points to set " << nearPoints.name() << endl;
|
||||||
nearPoints.instance() = mesh.pointsInstance();
|
nearPoints.instance() = mesh.pointsInstance();
|
||||||
nearPoints.write();
|
nearPoints.write();
|
||||||
if (setWriter)
|
if (setWriter && setWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*setWriter, nearPoints);
|
mergeAndWrite(*setWriter, nearPoints);
|
||||||
}
|
}
|
||||||
@ -883,7 +883,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< endl;
|
<< endl;
|
||||||
faces.instance() = mesh.pointsInstance();
|
faces.instance() = mesh.pointsInstance();
|
||||||
faces.write();
|
faces.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, faces);
|
mergeAndWrite(*surfWriter, faces);
|
||||||
}
|
}
|
||||||
@ -906,7 +906,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< " warped faces to set " << faces.name() << endl;
|
<< " warped faces to set " << faces.name() << endl;
|
||||||
faces.instance() = mesh.pointsInstance();
|
faces.instance() = mesh.pointsInstance();
|
||||||
faces.write();
|
faces.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, faces);
|
mergeAndWrite(*surfWriter, faces);
|
||||||
}
|
}
|
||||||
@ -927,7 +927,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< " under-determined cells to set " << cells.name() << endl;
|
<< " under-determined cells to set " << cells.name() << endl;
|
||||||
cells.instance() = mesh.pointsInstance();
|
cells.instance() = mesh.pointsInstance();
|
||||||
cells.write();
|
cells.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, cells);
|
mergeAndWrite(*surfWriter, cells);
|
||||||
}
|
}
|
||||||
@ -947,7 +947,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< " concave cells to set " << cells.name() << endl;
|
<< " concave cells to set " << cells.name() << endl;
|
||||||
cells.instance() = mesh.pointsInstance();
|
cells.instance() = mesh.pointsInstance();
|
||||||
cells.write();
|
cells.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, cells);
|
mergeAndWrite(*surfWriter, cells);
|
||||||
}
|
}
|
||||||
@ -968,7 +968,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< faces.name() << endl;
|
<< faces.name() << endl;
|
||||||
faces.instance() = mesh.pointsInstance();
|
faces.instance() = mesh.pointsInstance();
|
||||||
faces.write();
|
faces.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, faces);
|
mergeAndWrite(*surfWriter, faces);
|
||||||
}
|
}
|
||||||
@ -989,7 +989,7 @@ Foam::label Foam::checkGeometry
|
|||||||
<< faces.name() << endl;
|
<< faces.name() << endl;
|
||||||
faces.instance() = mesh.pointsInstance();
|
faces.instance() = mesh.pointsInstance();
|
||||||
faces.write();
|
faces.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, faces);
|
mergeAndWrite(*surfWriter, faces);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ namespace Foam
|
|||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
class polyMesh;
|
class polyMesh;
|
||||||
class wedgePolyPatch;
|
class wedgePolyPatch;
|
||||||
template<class T> class writer;
|
class coordSetWriter;
|
||||||
class surfaceWriter;
|
class surfaceWriter;
|
||||||
|
|
||||||
label findOppositeWedge(const polyMesh&, const wedgePolyPatch&);
|
label findOppositeWedge(const polyMesh&, const wedgePolyPatch&);
|
||||||
@ -47,6 +47,6 @@ namespace Foam
|
|||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
const bool allGeometry,
|
const bool allGeometry,
|
||||||
autoPtr<surfaceWriter>& surfWriter,
|
autoPtr<surfaceWriter>& surfWriter,
|
||||||
const autoPtr<writer<scalar>>& setWriter
|
autoPtr<coordSetWriter>& setWriter
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,7 +74,7 @@ Usage
|
|||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
#include "globalMeshData.H"
|
#include "globalMeshData.H"
|
||||||
#include "vtkSetWriter.H"
|
#include "vtkCoordSetWriter.H"
|
||||||
#include "vtkSurfaceWriter.H"
|
#include "vtkSurfaceWriter.H"
|
||||||
#include "IOdictionary.H"
|
#include "IOdictionary.H"
|
||||||
#include "regionProperties.H"
|
#include "regionProperties.H"
|
||||||
@ -262,11 +262,11 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
|
|
||||||
autoPtr<surfaceWriter> surfWriter;
|
autoPtr<surfaceWriter> surfWriter;
|
||||||
autoPtr<writer<scalar>> setWriter;
|
autoPtr<coordSetWriter> setWriter;
|
||||||
if (writeSets)
|
if (writeSets)
|
||||||
{
|
{
|
||||||
surfWriter = surfaceWriter::New(surfaceFormat);
|
surfWriter = surfaceWriter::New(surfaceFormat);
|
||||||
setWriter = writer<scalar>::New(vtkSetWriter<scalar>::typeName);
|
setWriter = coordSetWriter::New(coordSetWriters::vtkWriter::typeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -41,7 +41,7 @@ License
|
|||||||
#include "faceSet.H"
|
#include "faceSet.H"
|
||||||
#include "cellSet.H"
|
#include "cellSet.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "writer.H"
|
#include "coordSetWriter.H"
|
||||||
#include "surfaceWriter.H"
|
#include "surfaceWriter.H"
|
||||||
#include "syncTools.H"
|
#include "syncTools.H"
|
||||||
#include "globalIndex.H"
|
#include "globalIndex.H"
|
||||||
@ -417,7 +417,7 @@ void Foam::mergeAndWrite
|
|||||||
|
|
||||||
void Foam::mergeAndWrite
|
void Foam::mergeAndWrite
|
||||||
(
|
(
|
||||||
const writer<scalar>& writer,
|
coordSetWriter& writer,
|
||||||
const pointSet& set
|
const pointSet& set
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -441,39 +441,26 @@ void Foam::mergeAndWrite
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Write with scalar pointID
|
// Write with pointID
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
scalarField scalarPointIDs(mergedIDs.size());
|
coordSet coords(set.name(), "distance", mergedPts, mag(mergedPts));
|
||||||
forAll(mergedIDs, i)
|
|
||||||
{
|
|
||||||
scalarPointIDs[i] = 1.0*mergedIDs[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
coordSet points(set.name(), "distance", mergedPts, mag(mergedPts));
|
// Output. E.g. pointSet p0 -> postProcessing/<time>/p0.vtk
|
||||||
|
|
||||||
List<const scalarField*> flds(1, &scalarPointIDs);
|
fileName outputPath
|
||||||
|
|
||||||
wordList fldNames(1, "pointID");
|
|
||||||
|
|
||||||
// Output e.g. pointSet p0 to
|
|
||||||
// postProcessing/<time>/p0.vtk
|
|
||||||
fileName outputDir
|
|
||||||
(
|
(
|
||||||
set.time().globalPath()
|
set.time().globalPath()
|
||||||
/ functionObject::outputPrefix
|
/ functionObject::outputPrefix
|
||||||
/ mesh.pointsInstance()
|
/ mesh.pointsInstance()
|
||||||
// set.name()
|
/ set.name()
|
||||||
);
|
);
|
||||||
outputDir.clean(); // Remove unneeded ".."
|
outputPath.clean(); // Remove unneeded ".."
|
||||||
mkDir(outputDir);
|
|
||||||
|
|
||||||
fileName outputFile(outputDir/writer.getFileName(points, wordList()));
|
writer.open(coords, outputPath);
|
||||||
//fileName outputFile(outputDir/set.name());
|
writer.nFields(1);
|
||||||
|
writer.write("pointID", mergedIDs);
|
||||||
OFstream os(outputFile);
|
writer.close(true);
|
||||||
|
|
||||||
writer.write(points, fldNames, flds, os);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ namespace Foam
|
|||||||
class cellSet;
|
class cellSet;
|
||||||
class fileName;
|
class fileName;
|
||||||
class polyMesh;
|
class polyMesh;
|
||||||
template<class T> class writer;
|
class coordSetWriter;
|
||||||
class surfaceWriter;
|
class surfaceWriter;
|
||||||
|
|
||||||
void printMeshStats(const polyMesh& mesh, const bool allTopology);
|
void printMeshStats(const polyMesh& mesh, const bool allTopology);
|
||||||
@ -36,7 +36,7 @@ namespace Foam
|
|||||||
|
|
||||||
//- Write vtk representation of (assembled) pointSet to 'set' file in
|
//- Write vtk representation of (assembled) pointSet to 'set' file in
|
||||||
// postProcessing/ directory
|
// postProcessing/ directory
|
||||||
void mergeAndWrite(const writer<scalar>& writer, const pointSet& set);
|
void mergeAndWrite(coordSetWriter& writer, const pointSet& set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,7 @@ License
|
|||||||
#include "IOmanip.H"
|
#include "IOmanip.H"
|
||||||
#include "emptyPolyPatch.H"
|
#include "emptyPolyPatch.H"
|
||||||
#include "processorPolyPatch.H"
|
#include "processorPolyPatch.H"
|
||||||
#include "vtkSetWriter.H"
|
#include "vtkCoordSetWriter.H"
|
||||||
#include "vtkSurfaceWriter.H"
|
#include "vtkSurfaceWriter.H"
|
||||||
#include "checkTools.H"
|
#include "checkTools.H"
|
||||||
#include "treeBoundBox.H"
|
#include "treeBoundBox.H"
|
||||||
@ -117,7 +117,7 @@ Foam::label Foam::checkTopology
|
|||||||
const bool allTopology,
|
const bool allTopology,
|
||||||
const bool allGeometry,
|
const bool allGeometry,
|
||||||
autoPtr<surfaceWriter>& surfWriter,
|
autoPtr<surfaceWriter>& surfWriter,
|
||||||
const autoPtr<writer<scalar>>& setWriter
|
autoPtr<coordSetWriter>& setWriter
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
label noFailedChecks = 0;
|
label noFailedChecks = 0;
|
||||||
@ -203,7 +203,7 @@ Foam::label Foam::checkTopology
|
|||||||
<< " illegal cells to set " << cells.name() << endl;
|
<< " illegal cells to set " << cells.name() << endl;
|
||||||
cells.instance() = mesh.pointsInstance();
|
cells.instance() = mesh.pointsInstance();
|
||||||
cells.write();
|
cells.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, cells);
|
mergeAndWrite(*surfWriter, cells);
|
||||||
}
|
}
|
||||||
@ -227,7 +227,7 @@ Foam::label Foam::checkTopology
|
|||||||
<< " unused points to set " << points.name() << endl;
|
<< " unused points to set " << points.name() << endl;
|
||||||
points.instance() = mesh.pointsInstance();
|
points.instance() = mesh.pointsInstance();
|
||||||
points.write();
|
points.write();
|
||||||
if (setWriter)
|
if (setWriter && setWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*setWriter, points);
|
mergeAndWrite(*setWriter, points);
|
||||||
}
|
}
|
||||||
@ -249,7 +249,7 @@ Foam::label Foam::checkTopology
|
|||||||
<< " unordered faces to set " << faces.name() << endl;
|
<< " unordered faces to set " << faces.name() << endl;
|
||||||
faces.instance() = mesh.pointsInstance();
|
faces.instance() = mesh.pointsInstance();
|
||||||
faces.write();
|
faces.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, faces);
|
mergeAndWrite(*surfWriter, faces);
|
||||||
}
|
}
|
||||||
@ -269,7 +269,7 @@ Foam::label Foam::checkTopology
|
|||||||
<< faces.name() << endl;
|
<< faces.name() << endl;
|
||||||
faces.instance() = mesh.pointsInstance();
|
faces.instance() = mesh.pointsInstance();
|
||||||
faces.write();
|
faces.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, faces);
|
mergeAndWrite(*surfWriter, faces);
|
||||||
}
|
}
|
||||||
@ -290,11 +290,10 @@ Foam::label Foam::checkTopology
|
|||||||
<< endl;
|
<< endl;
|
||||||
cells.instance() = mesh.pointsInstance();
|
cells.instance() = mesh.pointsInstance();
|
||||||
cells.write();
|
cells.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, cells);
|
mergeAndWrite(*surfWriter, cells);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,7 +313,7 @@ Foam::label Foam::checkTopology
|
|||||||
<< faces.name() << endl;
|
<< faces.name() << endl;
|
||||||
faces.instance() = mesh.pointsInstance();
|
faces.instance() = mesh.pointsInstance();
|
||||||
faces.write();
|
faces.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, faces);
|
mergeAndWrite(*surfWriter, faces);
|
||||||
}
|
}
|
||||||
@ -369,7 +368,7 @@ Foam::label Foam::checkTopology
|
|||||||
<< endl;
|
<< endl;
|
||||||
oneCells.instance() = mesh.pointsInstance();
|
oneCells.instance() = mesh.pointsInstance();
|
||||||
oneCells.write();
|
oneCells.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, oneCells);
|
mergeAndWrite(*surfWriter, oneCells);
|
||||||
}
|
}
|
||||||
@ -385,7 +384,7 @@ Foam::label Foam::checkTopology
|
|||||||
<< endl;
|
<< endl;
|
||||||
twoCells.instance() = mesh.pointsInstance();
|
twoCells.instance() = mesh.pointsInstance();
|
||||||
twoCells.write();
|
twoCells.write();
|
||||||
if (surfWriter)
|
if (surfWriter && surfWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*surfWriter, twoCells);
|
mergeAndWrite(*surfWriter, twoCells);
|
||||||
}
|
}
|
||||||
@ -530,7 +529,7 @@ Foam::label Foam::checkTopology
|
|||||||
<< " points that are in multiple regions to set "
|
<< " points that are in multiple regions to set "
|
||||||
<< points.name() << endl;
|
<< points.name() << endl;
|
||||||
points.write();
|
points.write();
|
||||||
if (setWriter)
|
if (setWriter && setWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*setWriter, points);
|
mergeAndWrite(*setWriter, points);
|
||||||
}
|
}
|
||||||
@ -641,7 +640,7 @@ Foam::label Foam::checkTopology
|
|||||||
<< " conflicting points to set " << points.name() << endl;
|
<< " conflicting points to set " << points.name() << endl;
|
||||||
points.instance() = mesh.pointsInstance();
|
points.instance() = mesh.pointsInstance();
|
||||||
points.write();
|
points.write();
|
||||||
if (setWriter)
|
if (setWriter && setWriter->enabled())
|
||||||
{
|
{
|
||||||
mergeAndWrite(*setWriter, points);
|
mergeAndWrite(*setWriter, points);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace Foam
|
|||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
class polyMesh;
|
class polyMesh;
|
||||||
class pointSet;
|
class pointSet;
|
||||||
template<class T> class writer;
|
class coordSetWriter;
|
||||||
class surfaceWriter;
|
class surfaceWriter;
|
||||||
|
|
||||||
template<class PatchType>
|
template<class PatchType>
|
||||||
@ -24,6 +24,6 @@ namespace Foam
|
|||||||
const bool allTopology,
|
const bool allTopology,
|
||||||
const bool allGeometry,
|
const bool allGeometry,
|
||||||
autoPtr<surfaceWriter>& surfWriter,
|
autoPtr<surfaceWriter>& surfWriter,
|
||||||
const autoPtr<writer<scalar>>& setWriter
|
autoPtr<coordSetWriter>& setWriter
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,12 @@ label maxTracks(propsDict.getOrDefault<label>("maxTracks", -1));
|
|||||||
word setFormat(propsDict.getOrDefault<word>("setFormat", "vtk"));
|
word setFormat(propsDict.getOrDefault<word>("setFormat", "vtk"));
|
||||||
|
|
||||||
// Optional - if empty, select all
|
// Optional - if empty, select all
|
||||||
const wordRes fieldNames(propsDict.getOrDefault<wordRes>("fields", wordRes()));
|
wordRes acceptFields;
|
||||||
|
propsDict.readIfPresent("fields", acceptFields);
|
||||||
|
|
||||||
|
// Optional
|
||||||
|
wordRes excludeFields;
|
||||||
|
propsDict.readIfPresent("exclude", excludeFields);
|
||||||
|
|
||||||
const word UName(propsDict.getOrDefault<word>("U", "U"));
|
const word UName(propsDict.getOrDefault<word>("U", "U"));
|
||||||
|
|
||||||
|
|||||||
@ -42,199 +42,34 @@ Description
|
|||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "timeSelector.H"
|
#include "timeSelector.H"
|
||||||
#include "OFstream.H"
|
#include "coordSetWriter.H"
|
||||||
#include "passiveParticleCloud.H"
|
#include "passiveParticleCloud.H"
|
||||||
#include "writer.H"
|
#include "particleTracksSampler.H"
|
||||||
#include "ListOps.H"
|
|
||||||
|
|
||||||
#define createTrack(field, trackValues) \
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
createTrackField \
|
|
||||||
( \
|
|
||||||
field, \
|
|
||||||
sampleFrequency, \
|
|
||||||
maxPositions, \
|
|
||||||
startIds, \
|
|
||||||
allOrigProcs, \
|
|
||||||
allOrigIds, \
|
|
||||||
trackValues \
|
|
||||||
);
|
|
||||||
|
|
||||||
#define setFields(fields, fieldNames) \
|
|
||||||
setTrackFields \
|
|
||||||
( \
|
|
||||||
obr, \
|
|
||||||
fields, \
|
|
||||||
fieldNames, \
|
|
||||||
nTracks, \
|
|
||||||
startIds, \
|
|
||||||
allOrigProcs, \
|
|
||||||
allOrigIds, \
|
|
||||||
maxPositions, \
|
|
||||||
sampleFrequency \
|
|
||||||
);
|
|
||||||
|
|
||||||
#define writeFields(fields, fieldNames, tracks, times, dirs) \
|
|
||||||
writeTrackFields \
|
|
||||||
( \
|
|
||||||
fields, \
|
|
||||||
fieldNames, \
|
|
||||||
tracks, \
|
|
||||||
times, \
|
|
||||||
dirs, \
|
|
||||||
setFormat, \
|
|
||||||
formatOptions, \
|
|
||||||
cloudName \
|
|
||||||
);
|
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void createTrackField
|
|
||||||
(
|
|
||||||
const Field<Type>& values,
|
|
||||||
const label sampleFrequency,
|
|
||||||
const label maxPositions,
|
|
||||||
const labelList& startIds,
|
|
||||||
const List<labelField>& allOrigProcs,
|
|
||||||
const List<labelField>& allOrigIds,
|
|
||||||
List<DynamicList<Type>>& trackValues
|
|
||||||
)
|
|
||||||
{
|
|
||||||
List<Field<Type>> procField(Pstream::nProcs());
|
|
||||||
procField[Pstream::myProcNo()] = values;
|
|
||||||
Pstream::gatherList(procField);
|
|
||||||
|
|
||||||
if (!Pstream::master())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const label nTracks = trackValues.size();
|
|
||||||
|
|
||||||
forAll(procField, proci)
|
|
||||||
{
|
|
||||||
forAll(procField[proci], i)
|
|
||||||
{
|
|
||||||
const label globalId =
|
|
||||||
startIds[allOrigProcs[proci][i]] + allOrigIds[proci][i];
|
|
||||||
|
|
||||||
if (globalId % sampleFrequency == 0)
|
|
||||||
{
|
|
||||||
const label trackId = globalId/sampleFrequency;
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
trackId < nTracks
|
|
||||||
&& trackValues[trackId].size() < maxPositions
|
|
||||||
)
|
|
||||||
{
|
|
||||||
trackValues[trackId].append(procField[proci][i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void writeTrackFields
|
void writeTrackFields
|
||||||
(
|
(
|
||||||
List<List<DynamicList<Type>>>& fieldValues,
|
coordSetWriter& writer,
|
||||||
const wordList& fieldNames,
|
HashTable<List<DynamicList<Type>>>& fieldTable
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const List<vectorField>& dirs,
|
|
||||||
const word& setFormat,
|
|
||||||
const dictionary& formatOptions,
|
|
||||||
const word& cloudName
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (fieldValues.empty())
|
for (const word& fieldName : fieldTable.sortedToc())
|
||||||
{
|
{
|
||||||
return;
|
// Steal and reshape from List<DynamicList> to List<Field>
|
||||||
}
|
auto& input = fieldTable[fieldName];
|
||||||
|
|
||||||
auto writerPtr = writer<Type>::New(setFormat, formatOptions);
|
List<Field<Type>> fields(input.size());
|
||||||
|
forAll(input, tracki)
|
||||||
const fileName outFile(writerPtr().getFileName(tracks[0], wordList(0)));
|
|
||||||
|
|
||||||
const fileName outPath
|
|
||||||
(
|
|
||||||
functionObject::outputPrefix/cloud::prefix/cloudName/"particleTracks"
|
|
||||||
);
|
|
||||||
mkDir(outPath);
|
|
||||||
|
|
||||||
OFstream os(outPath/(pTraits<Type>::typeName & "tracks." + outFile.ext()));
|
|
||||||
|
|
||||||
Info<< "Writing " << pTraits<Type>::typeName << " particle tracks in "
|
|
||||||
<< setFormat << " format to " << os.name() << endl;
|
|
||||||
|
|
||||||
|
|
||||||
List<List<Field<Type>>> fields(fieldValues.size());
|
|
||||||
forAll(fields, fieldi)
|
|
||||||
{
|
|
||||||
fields[fieldi].setSize(fieldValues[fieldi].size());
|
|
||||||
forAll(fields[fieldi], tracki)
|
|
||||||
{
|
{
|
||||||
fields[fieldi][tracki].transfer(fieldValues[fieldi][tracki]);
|
fields[tracki].transfer(input[tracki]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writer.write(fieldName, fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
writerPtr().write(true, times, tracks, fieldNames, fields, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::label setTrackFields
|
|
||||||
(
|
|
||||||
const objectRegistry& obr,
|
|
||||||
List<List<DynamicList<Type>>>& fields,
|
|
||||||
List<word>& fieldNames,
|
|
||||||
const label nTracks,
|
|
||||||
const labelList& startIds,
|
|
||||||
const List<labelField>& allOrigProcs,
|
|
||||||
const List<labelField>& allOrigIds,
|
|
||||||
const label maxPositions,
|
|
||||||
const label sampleFrequency
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const auto availableFieldPtrs = obr.lookupClass<IOField<Type>>();
|
|
||||||
|
|
||||||
fieldNames = availableFieldPtrs.toc();
|
|
||||||
|
|
||||||
if (Pstream::parRun())
|
|
||||||
{
|
|
||||||
Pstream::combineGather(fieldNames, ListOps::uniqueEqOp<word>());
|
|
||||||
Pstream::combineScatter(fieldNames);
|
|
||||||
Foam::sort(fieldNames);
|
|
||||||
}
|
|
||||||
|
|
||||||
const label nFields = fieldNames.size();
|
|
||||||
|
|
||||||
if (fields.empty())
|
|
||||||
{
|
|
||||||
fields.setSize(nFields);
|
|
||||||
fieldNames.setSize(nFields);
|
|
||||||
forAll(fields, i)
|
|
||||||
{
|
|
||||||
fields[i].setSize(nTracks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(fieldNames, fieldi)
|
|
||||||
{
|
|
||||||
const word& fieldName = fieldNames[fieldi];
|
|
||||||
|
|
||||||
const auto* fldPtr = obr.cfindObject<IOField<Type>>(fieldName);
|
|
||||||
|
|
||||||
createTrack
|
|
||||||
(
|
|
||||||
fldPtr ? static_cast<const Field<Type>>(*fldPtr) : Field<Type>(),
|
|
||||||
fields[fieldi]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nFields;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -267,6 +102,14 @@ int main(int argc, char *argv[])
|
|||||||
"Override the sample-frequency"
|
"Override the sample-frequency"
|
||||||
);
|
);
|
||||||
argList::addOption
|
argList::addOption
|
||||||
|
(
|
||||||
|
"fields",
|
||||||
|
"wordRes",
|
||||||
|
"Specify single or multiple fields to write "
|
||||||
|
"(default: all or 'fields' from dictionary)\n"
|
||||||
|
"Eg, 'T' or '( \"U.*\" )'"
|
||||||
|
);
|
||||||
|
argList::addOption
|
||||||
(
|
(
|
||||||
"format",
|
"format",
|
||||||
"name",
|
"name",
|
||||||
@ -285,137 +128,147 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#include "createControls.H"
|
#include "createControls.H"
|
||||||
|
|
||||||
|
args.readListIfPresent<wordRe>("fields", acceptFields);
|
||||||
args.readIfPresent("format", setFormat);
|
args.readIfPresent("format", setFormat);
|
||||||
|
|
||||||
args.readIfPresent("stride", sampleFrequency);
|
args.readIfPresent("stride", sampleFrequency);
|
||||||
sampleFrequency = max(1, sampleFrequency); // sanity
|
sampleFrequency = max(1, sampleFrequency); // sanity
|
||||||
|
|
||||||
|
// Setup the writer
|
||||||
|
auto writerPtr =
|
||||||
|
coordSetWriter::New
|
||||||
|
(
|
||||||
|
setFormat,
|
||||||
|
formatOptions.optionalSubDict(setFormat, keyType::LITERAL)
|
||||||
|
);
|
||||||
|
|
||||||
|
writerPtr().useTracks(true);
|
||||||
|
|
||||||
|
if (args.verbose())
|
||||||
|
{
|
||||||
|
writerPtr().verbose(true);
|
||||||
|
}
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
const fileName vtkPath(runTime.rootPath()/runTime.globalCaseName()/"VTK");
|
particleTracksSampler trackSampler;
|
||||||
mkDir(vtkPath);
|
|
||||||
|
|
||||||
Info<< "Scanning times to determine track data for cloud " << cloudName
|
Info<< "Scanning times to determine track data for cloud " << cloudName
|
||||||
<< nl << endl;
|
<< nl << endl;
|
||||||
|
|
||||||
labelList maxIds(Pstream::nProcs(), -1);
|
|
||||||
forAll(timeDirs, timei)
|
|
||||||
{
|
{
|
||||||
runTime.setTime(timeDirs[timei], timei);
|
labelList maxIds(Pstream::nProcs(), -1);
|
||||||
Info<< "Time = " << runTime.timeName() << endl;
|
forAll(timeDirs, timei)
|
||||||
|
|
||||||
Info<< " Reading particle positions" << endl;
|
|
||||||
passiveParticleCloud myCloud(mesh, cloudName);
|
|
||||||
|
|
||||||
Info<< " Read " << returnReduce(myCloud.size(), sumOp<label>())
|
|
||||||
<< " particles" << endl;
|
|
||||||
|
|
||||||
for (const passiveParticle& p : myCloud)
|
|
||||||
{
|
{
|
||||||
const label origId = p.origId();
|
runTime.setTime(timeDirs[timei], timei);
|
||||||
const label origProc = p.origProc();
|
Info<< "Time = " << runTime.timeName() << endl;
|
||||||
|
|
||||||
// Handle case where we are processing particle data generated in
|
passiveParticleCloud myCloud(mesh, cloudName);
|
||||||
// parallel using more cores than when running this application.
|
|
||||||
if (origProc >= maxIds.size())
|
Info<< " Read " << returnReduce(myCloud.size(), sumOp<label>())
|
||||||
|
<< " particles" << endl;
|
||||||
|
|
||||||
|
for (const passiveParticle& p : myCloud)
|
||||||
{
|
{
|
||||||
maxIds.setSize(origProc+1, -1);
|
const label origId = p.origId();
|
||||||
}
|
const label origProc = p.origProc();
|
||||||
|
|
||||||
maxIds[origProc] = max(maxIds[origProc], origId);
|
// Handle case where processing particle data generated in
|
||||||
|
// parallel using more cores than for this application.
|
||||||
|
if (origProc >= maxIds.size())
|
||||||
|
{
|
||||||
|
maxIds.resize(origProc+1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
maxIds[origProc] = max(maxIds[origProc], origId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const label maxNProcs = returnReduce(maxIds.size(), maxOp<label>());
|
||||||
|
maxIds.resize(maxNProcs, -1);
|
||||||
|
|
||||||
|
Pstream::listCombineGather(maxIds, maxEqOp<label>());
|
||||||
|
Pstream::listCombineScatter(maxIds);
|
||||||
|
|
||||||
|
// From ids to count
|
||||||
|
const labelList numIds = maxIds + 1;
|
||||||
|
|
||||||
|
// Set parcel addressing
|
||||||
|
trackSampler.reset(numIds);
|
||||||
|
|
||||||
|
Info<< nl
|
||||||
|
<< "Detected particles originating from "
|
||||||
|
<< maxNProcs << " processors." << nl
|
||||||
|
<< "Particle statistics:" << endl;
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
const globalIndex& parcelAddr = trackSampler.parcelAddr();
|
||||||
|
|
||||||
|
for (const label proci : parcelAddr.allProcs())
|
||||||
|
{
|
||||||
|
Info<< " Found " << parcelAddr.localSize(proci)
|
||||||
|
<< " particles originating"
|
||||||
|
<< " from processor " << proci << nl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
label maxNProcs = returnReduce(maxIds.size(), maxOp<label>());
|
trackSampler.setSampleRate(sampleFrequency, maxPositions, maxTracks);
|
||||||
|
|
||||||
Info<< "Detected particles originating from " << maxNProcs
|
|
||||||
<< " processors." << nl << endl;
|
|
||||||
|
|
||||||
maxIds.setSize(maxNProcs, -1);
|
|
||||||
|
|
||||||
Pstream::listCombineGather(maxIds, maxEqOp<label>());
|
|
||||||
Pstream::listCombineScatter(maxIds);
|
|
||||||
|
|
||||||
labelList numIds = maxIds + 1;
|
|
||||||
|
|
||||||
Info<< nl << "Particle statistics:" << endl;
|
|
||||||
forAll(maxIds, proci)
|
|
||||||
{
|
|
||||||
Info<< " Found " << numIds[proci] << " particles originating"
|
|
||||||
<< " from processor " << proci << endl;
|
|
||||||
}
|
|
||||||
Info<< nl << endl;
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate starting ids for particles on each processor
|
|
||||||
labelList startIds(numIds.size(), Zero);
|
|
||||||
for (label i = 0; i < numIds.size()-1; ++i)
|
|
||||||
{
|
|
||||||
startIds[i+1] += startIds[i] + numIds[i];
|
|
||||||
}
|
|
||||||
label nParticle = startIds.last() + numIds[startIds.size()-1];
|
|
||||||
|
|
||||||
|
|
||||||
// Number of tracks to generate
|
// Number of tracks to generate
|
||||||
const label nTracks =
|
const label nTracks = trackSampler.nTracks();
|
||||||
maxTracks > 0
|
|
||||||
? min(nParticle/sampleFrequency, maxTracks)
|
|
||||||
: nParticle/sampleFrequency;
|
|
||||||
|
|
||||||
// Storage for all particle tracks
|
// Storage for all particle tracks
|
||||||
List<DynamicList<vector>> allTracks(nTracks);
|
List<DynamicList<point>> allTrackPos(nTracks);
|
||||||
List<DynamicList<scalar>> allTrackTimes(nTracks);
|
List<DynamicList<scalar>> allTrackTimes(nTracks);
|
||||||
|
|
||||||
// Lists of field, tracki, trackValues
|
// Track field values by name/type
|
||||||
//List<List<DynamicList<label>>> labelFields;
|
HashTable<List<DynamicList<label>>> labelFields; // <- mostly unused
|
||||||
List<List<DynamicList<scalar>>> scalarFields;
|
HashTable<List<DynamicList<scalar>>> scalarFields;
|
||||||
List<List<DynamicList<vector>>> vectorFields;
|
HashTable<List<DynamicList<vector>>> vectorFields;
|
||||||
List<List<DynamicList<sphericalTensor>>> sphTensorFields;
|
HashTable<List<DynamicList<sphericalTensor>>> sphericalTensorFields;
|
||||||
List<List<DynamicList<symmTensor>>> symTensorFields;
|
HashTable<List<DynamicList<symmTensor>>> symmTensorFields;
|
||||||
List<List<DynamicList<tensor>>> tensorFields;
|
HashTable<List<DynamicList<tensor>>> tensorFields;
|
||||||
//List<word> labelFieldNames;
|
|
||||||
List<word> scalarFieldNames;
|
|
||||||
List<word> vectorFieldNames;
|
|
||||||
List<word> sphTensorFieldNames;
|
|
||||||
List<word> symTensorFieldNames;
|
|
||||||
List<word> tensorFieldNames;
|
|
||||||
|
|
||||||
Info<< "\nGenerating " << nTracks << " particle tracks for cloud "
|
Info<< nl
|
||||||
<< cloudName << nl << endl;
|
<< "Generating " << nTracks
|
||||||
|
<< " particle tracks for cloud " << cloudName << nl << endl;
|
||||||
|
|
||||||
forAll(timeDirs, timei)
|
forAll(timeDirs, timei)
|
||||||
{
|
{
|
||||||
runTime.setTime(timeDirs[timei], timei);
|
runTime.setTime(timeDirs[timei], timei);
|
||||||
Info<< "Time = " << runTime.timeName() << endl;
|
Info<< "Time = " << runTime.timeName() << " (processing)" << endl;
|
||||||
|
|
||||||
// Read particles. Will be size 0 if no particles.
|
// Read particles. Will be size 0 if no particles.
|
||||||
Info<< " Reading particle positions" << endl;
|
|
||||||
passiveParticleCloud myCloud(mesh, cloudName);
|
passiveParticleCloud myCloud(mesh, cloudName);
|
||||||
|
|
||||||
pointField localPositions(myCloud.size(), Zero);
|
pointField localPositions(myCloud.size());
|
||||||
scalarField localTimes(myCloud.size(), Zero);
|
scalarField localTimes(myCloud.size(), runTime.value());
|
||||||
|
|
||||||
List<labelField> allOrigIds(Pstream::nProcs());
|
// Gather track data from all processors that have positions
|
||||||
List<labelField> allOrigProcs(Pstream::nProcs());
|
trackSampler.resetCloud(myCloud.size());
|
||||||
|
|
||||||
// Collect the track data on all processors that have positions
|
|
||||||
allOrigIds[Pstream::myProcNo()].setSize(myCloud.size(), Zero);
|
|
||||||
allOrigProcs[Pstream::myProcNo()].setSize(myCloud.size(), Zero);
|
|
||||||
|
|
||||||
label i = 0;
|
|
||||||
for (const passiveParticle& p : myCloud)
|
|
||||||
{
|
{
|
||||||
allOrigIds[Pstream::myProcNo()][i] = p.origId();
|
labelField& origIds = trackSampler.origParcelIds_;
|
||||||
allOrigProcs[Pstream::myProcNo()][i] = p.origProc();
|
labelField& origProcs = trackSampler.origProcIds_;
|
||||||
localPositions[i] = p.position();
|
|
||||||
localTimes[i] = runTime.value();
|
label np = 0;
|
||||||
++i;
|
for (const passiveParticle& p : myCloud)
|
||||||
|
{
|
||||||
|
origIds[np] = p.origId();
|
||||||
|
origProcs[np] = p.origProc();
|
||||||
|
localPositions[np] = p.position();
|
||||||
|
++np;
|
||||||
|
}
|
||||||
|
|
||||||
|
trackSampler.gatherInplace(origIds);
|
||||||
|
trackSampler.gatherInplace(origProcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect the track data on the master processor
|
|
||||||
Pstream::gatherList(allOrigIds);
|
|
||||||
Pstream::gatherList(allOrigProcs);
|
|
||||||
|
|
||||||
|
// Read cloud fields (from disk) into object registry
|
||||||
objectRegistry obr
|
objectRegistry obr
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
@ -426,63 +279,122 @@ int main(int argc, char *argv[])
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
myCloud.readFromFiles(obr, fieldNames);
|
myCloud.readFromFiles(obr, acceptFields, excludeFields);
|
||||||
|
|
||||||
// Create track positions and track time fields
|
// Create track positions and track time fields
|
||||||
// (not registered as IOFields)
|
// (not registered as IOFields)
|
||||||
// Note: createTrack is a local #define to reduce arg count...
|
|
||||||
createTrack(localPositions, allTracks);
|
trackSampler.createTrackField(localPositions, allTrackPos);
|
||||||
createTrack(localTimes, allTrackTimes);
|
trackSampler.createTrackField(localTimes, allTrackTimes);
|
||||||
|
|
||||||
// Create the track fields
|
// Create the track fields
|
||||||
// Note: setFields is a local #define to reduce arg count...
|
///trackSampler.setTrackFields(obr, labelFields);
|
||||||
//setFields(labelFields, labelFieldNames);
|
trackSampler.setTrackFields(obr, scalarFields);
|
||||||
setFields(scalarFields, scalarFieldNames);
|
trackSampler.setTrackFields(obr, vectorFields);
|
||||||
setFields(vectorFields, vectorFieldNames);
|
trackSampler.setTrackFields(obr, sphericalTensorFields);
|
||||||
setFields(sphTensorFields, sphTensorFieldNames);
|
trackSampler.setTrackFields(obr, symmTensorFields);
|
||||||
setFields(symTensorFields, symTensorFieldNames);
|
trackSampler.setTrackFields(obr, tensorFields);
|
||||||
setFields(tensorFields, tensorFieldNames);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const label nFields =
|
||||||
|
(
|
||||||
|
labelFields.size()
|
||||||
|
+ scalarFields.size()
|
||||||
|
+ vectorFields.size()
|
||||||
|
+ sphericalTensorFields.size()
|
||||||
|
+ symmTensorFields.size()
|
||||||
|
+ tensorFields.size()
|
||||||
|
);
|
||||||
|
|
||||||
|
Info<< nl
|
||||||
|
<< "Extracted " << nFields << " cloud fields" << nl;
|
||||||
|
|
||||||
|
if (nFields)
|
||||||
|
{
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(FieldContent) \
|
||||||
|
if (!FieldContent.empty()) \
|
||||||
|
{ \
|
||||||
|
Info<< " "; \
|
||||||
|
for (const word& fieldName : FieldContent.sortedToc()) \
|
||||||
|
{ \
|
||||||
|
Info<< ' ' << fieldName; \
|
||||||
|
} \
|
||||||
|
Info<< nl; \
|
||||||
|
}
|
||||||
|
|
||||||
|
doLocalCode(labelFields);
|
||||||
|
doLocalCode(scalarFields);
|
||||||
|
doLocalCode(vectorFields);
|
||||||
|
doLocalCode(sphericalTensorFields);
|
||||||
|
doLocalCode(symmTensorFields);
|
||||||
|
doLocalCode(tensorFields);
|
||||||
|
#undef doLocalCode
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< nl
|
||||||
|
<< "Writing particle tracks (" << setFormat << " format)" << nl;
|
||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
PtrList<coordSet> tracks(allTracks.size());
|
PtrList<coordSet> tracks(allTrackPos.size());
|
||||||
List<scalarField> times(tracks.size());
|
List<scalarField> times(allTrackPos.size());
|
||||||
forAll(tracks, tracki)
|
forAll(tracks, tracki)
|
||||||
{
|
{
|
||||||
tracks.set
|
tracks.set
|
||||||
(
|
(
|
||||||
tracki,
|
tracki,
|
||||||
new coordSet("track" + Foam::name(tracki), "distance")
|
new coordSet("track" + Foam::name(tracki), "xyz")
|
||||||
);
|
);
|
||||||
tracks[tracki].transfer(allTracks[tracki]);
|
tracks[tracki].transfer(allTrackPos[tracki]);
|
||||||
times[tracki].transfer(allTrackTimes[tracki]);
|
times[tracki].transfer(allTrackTimes[tracki]);
|
||||||
|
|
||||||
|
if (!tracki) tracks[0].rename("tracks");
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< nl;
|
/// Currently unused
|
||||||
|
/// List<vectorField> dirs(nTracks);
|
||||||
|
/// const auto Uiter = vectorFields.cfind(UName);
|
||||||
|
/// if (Uiter.found())
|
||||||
|
/// {
|
||||||
|
/// const auto& UTracks = *Uiter;
|
||||||
|
/// forAll(UTracks, tracki)
|
||||||
|
/// {
|
||||||
|
/// const auto& U = UTracks[tracki];
|
||||||
|
/// dirs[tracki] = U/(mag(U) + ROOTVSMALL);
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
|
||||||
const label Uid = vectorFieldNames.find(UName);
|
|
||||||
List<vectorField> dirs(nTracks);
|
|
||||||
|
|
||||||
if (Uid != -1)
|
// Write tracks with fields
|
||||||
|
if (nFields)
|
||||||
{
|
{
|
||||||
const auto& UTracks = vectorFields[Uid];
|
auto& writer = *writerPtr;
|
||||||
forAll(UTracks, tracki)
|
|
||||||
{
|
|
||||||
const auto& U = UTracks[tracki];
|
|
||||||
dirs[tracki] = U/(mag(U) + ROOTVSMALL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write track fields
|
const fileName outputPath
|
||||||
// Note: writeFields is a local #define to reduce arg count...
|
(
|
||||||
//writeFields(allLabelFields, labelFieldNames, tracks);
|
functionObject::outputPrefix/cloud::prefix/cloudName
|
||||||
writeFields(scalarFields, scalarFieldNames, tracks, times, dirs);
|
/ "particleTracks" / "tracks"
|
||||||
writeFields(vectorFields, vectorFieldNames, tracks, times, dirs);
|
);
|
||||||
writeFields(sphTensorFields, sphTensorFieldNames, tracks, times, dirs);
|
|
||||||
writeFields(symTensorFields, symTensorFieldNames, tracks, times, dirs);
|
Info<< " "
|
||||||
writeFields(tensorFields, tensorFieldNames, tracks, times, dirs);
|
<< runTime.relativePath(outputPath) << endl;
|
||||||
|
|
||||||
|
writer.open(tracks, outputPath);
|
||||||
|
writer.setTrackTimes(times);
|
||||||
|
writer.nFields(nFields);
|
||||||
|
|
||||||
|
///writeTrackFields(writer, labelFields);
|
||||||
|
writeTrackFields(writer, scalarFields);
|
||||||
|
writeTrackFields(writer, vectorFields);
|
||||||
|
writeTrackFields(writer, sphericalTensorFields);
|
||||||
|
writeTrackFields(writer, symmTensorFields);
|
||||||
|
writeTrackFields(writer, tensorFields);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< "Warning: no fields, did not write" << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< nl << "End\n" << endl;
|
Info<< nl << "End\n" << endl;
|
||||||
|
|||||||
@ -0,0 +1,190 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::particleTracksSampler
|
||||||
|
|
||||||
|
Description
|
||||||
|
Helper class when generating particle tracks.
|
||||||
|
The interface is fairly rudimentary.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
particleTracksSamplerTemplates.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_particleTracksSampler_H
|
||||||
|
#define Foam_particleTracksSampler_H
|
||||||
|
|
||||||
|
#include "globalIndex.H"
|
||||||
|
#include "fieldTypes.H"
|
||||||
|
#include "IOField.H"
|
||||||
|
#include "labelField.H"
|
||||||
|
#include "DynamicList.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
class objectRegistry;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class particleTracksSampler Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class particleTracksSampler
|
||||||
|
{
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- The sampling interval
|
||||||
|
label stride_ = 1;
|
||||||
|
|
||||||
|
//- The number of tracks
|
||||||
|
label nTracks_ = 1;
|
||||||
|
|
||||||
|
//- Upper limit for number of track positions
|
||||||
|
label maxPositions_ = 10000;
|
||||||
|
|
||||||
|
//- The bin for sampled parcels.
|
||||||
|
labelField trackIds_;
|
||||||
|
|
||||||
|
//- The addressing for gathering cloud fields etc
|
||||||
|
globalIndex cloudGather_;
|
||||||
|
|
||||||
|
//- The originating parcel addressing
|
||||||
|
globalIndex origParcelAddr_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Data Members
|
||||||
|
|
||||||
|
//- The originating parcel ids
|
||||||
|
labelField origParcelIds_;
|
||||||
|
|
||||||
|
//- The originating processor ids
|
||||||
|
labelField origProcIds_;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- The original parcel addressing
|
||||||
|
const globalIndex& parcelAddr() const noexcept
|
||||||
|
{
|
||||||
|
return origParcelAddr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Total number of particles
|
||||||
|
label nParticle() const
|
||||||
|
{
|
||||||
|
return origParcelAddr_.totalSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Number of tracks to generate
|
||||||
|
label nTracks() const noexcept
|
||||||
|
{
|
||||||
|
return nTracks_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Define the orig parcel mappings
|
||||||
|
void reset(const labelUList& origParcelCounts)
|
||||||
|
{
|
||||||
|
origParcelAddr_.reset(origParcelCounts);
|
||||||
|
origParcelIds_.clear();
|
||||||
|
origProcIds_.clear();
|
||||||
|
trackIds_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Set the sampling stride, upper limits
|
||||||
|
// \return Number of tracks to generate
|
||||||
|
label setSampleRate
|
||||||
|
(
|
||||||
|
const label sampleFreq,
|
||||||
|
const label maxPositions,
|
||||||
|
const label maxTracks = -1
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// numTracks = numParticles/stride
|
||||||
|
|
||||||
|
stride_ = max(1, sampleFreq);
|
||||||
|
maxPositions_ = maxPositions;
|
||||||
|
nTracks_ = (origParcelAddr_.totalSize()/stride_);
|
||||||
|
|
||||||
|
if (maxTracks > 0)
|
||||||
|
{
|
||||||
|
nTracks_ = min(nTracks_, maxTracks);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nTracks_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetCloud(const label localCloudSize)
|
||||||
|
{
|
||||||
|
cloudGather_.reset(localCloudSize, globalIndex::gatherOnly{});
|
||||||
|
origParcelIds_.resize_nocopy(localCloudSize);
|
||||||
|
origProcIds_.resize_nocopy(localCloudSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void gatherInplace(List<Type>& fld) const
|
||||||
|
{
|
||||||
|
cloudGather_.gatherInplace(fld);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void createTrackField
|
||||||
|
(
|
||||||
|
const UList<Type>& values,
|
||||||
|
List<DynamicList<Type>>& trackValues
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
label setTrackFields
|
||||||
|
(
|
||||||
|
const objectRegistry& obr,
|
||||||
|
HashTable<List<DynamicList<Type>>>& fieldTable
|
||||||
|
) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "particleTracksSamplerTemplates.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,108 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "objectRegistry.H"
|
||||||
|
#include "ListOps.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::particleTracksSampler::createTrackField
|
||||||
|
(
|
||||||
|
const UList<Type>& values,
|
||||||
|
List<DynamicList<Type>>& trackValues
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
List<Type> allValues(cloudGather_.gather(values));
|
||||||
|
|
||||||
|
const label nTracks = trackValues.size();
|
||||||
|
|
||||||
|
forAll(allValues, i)
|
||||||
|
{
|
||||||
|
const label globalId =
|
||||||
|
origParcelAddr_.toGlobal(origProcIds_[i], origParcelIds_[i]);
|
||||||
|
|
||||||
|
if (globalId % stride_ == 0)
|
||||||
|
{
|
||||||
|
const label trackId = globalId/stride_;
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
trackId < nTracks
|
||||||
|
&& trackValues[trackId].size() < maxPositions_
|
||||||
|
)
|
||||||
|
{
|
||||||
|
trackValues[trackId].append(allValues[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::label Foam::particleTracksSampler::setTrackFields
|
||||||
|
(
|
||||||
|
const objectRegistry& obr,
|
||||||
|
HashTable<List<DynamicList<Type>>>& fieldTable
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// First time - obtain field names and populate storage locations
|
||||||
|
if (fieldTable.empty())
|
||||||
|
{
|
||||||
|
wordList fieldNames = obr.names<IOField<Type>>();
|
||||||
|
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
Pstream::combineGather(fieldNames, ListOps::uniqueEqOp<word>());
|
||||||
|
Pstream::combineScatter(fieldNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const word& fieldName : fieldNames)
|
||||||
|
{
|
||||||
|
fieldTable(fieldName).resize(nTracks());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process in parallel-consistent order
|
||||||
|
for (const word& fieldName : fieldTable.sortedToc())
|
||||||
|
{
|
||||||
|
auto& output = fieldTable[fieldName];
|
||||||
|
|
||||||
|
const auto* ptr = obr.cfindObject<IOField<Type>>(fieldName);
|
||||||
|
|
||||||
|
this->createTrackField
|
||||||
|
(
|
||||||
|
ptr ? static_cast<const UList<Type>&>(*ptr) : UList<Type>::null(),
|
||||||
|
output
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fieldTable.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -8,7 +8,12 @@ IOdictionary propsDict(dictIO);
|
|||||||
|
|
||||||
const word cloudName(propsDict.get<word>("cloud"));
|
const word cloudName(propsDict.get<word>("cloud"));
|
||||||
|
|
||||||
List<word> userFields(propsDict.lookup("fields"));
|
// Mandatory - if empty, select none
|
||||||
|
wordRes acceptFields(propsDict.get<wordRes>("fields"));
|
||||||
|
|
||||||
|
// Optional
|
||||||
|
wordRes excludeFields;
|
||||||
|
propsDict.readIfPresent("exclude", excludeFields);
|
||||||
|
|
||||||
const dictionary formatOptions
|
const dictionary formatOptions
|
||||||
(
|
(
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -45,73 +46,112 @@ Description
|
|||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "timeSelector.H"
|
#include "timeSelector.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
#include "passiveParticleCloud.H"
|
|
||||||
#include "labelPairHashes.H"
|
#include "labelPairHashes.H"
|
||||||
#include "SortableList.H"
|
#include "IOField.H"
|
||||||
#include "IOobjectList.H"
|
#include "IOobjectList.H"
|
||||||
#include "PtrList.H"
|
#include "SortableList.H"
|
||||||
#include "Field.H"
|
#include "passiveParticleCloud.H"
|
||||||
#include "steadyParticleTracksTemplates.H"
|
#include "steadyParticleTracksTemplates.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
using namespace Foam;
|
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
label validateFields
|
// Extract list of IOobjects, modifying the input IOobjectList in the
|
||||||
|
// process
|
||||||
|
IOobjectList preFilterFields
|
||||||
(
|
(
|
||||||
const List<word>& userFields,
|
IOobjectList& cloudObjects,
|
||||||
const IOobjectList& cloudObjs
|
const wordRes& acceptFields,
|
||||||
|
const wordRes& excludeFields
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
List<bool> ok(userFields.size(), false);
|
IOobjectList filteredObjects(cloudObjects.capacity());
|
||||||
|
DynamicList<label> missed(acceptFields.size());
|
||||||
|
|
||||||
forAll(userFields, i)
|
// Selection here is slighly different than usual
|
||||||
{
|
// - an empty accept filter means "ignore everything"
|
||||||
ok[i] = ok[i] || fieldOk<label>(cloudObjs, userFields[i]);
|
|
||||||
ok[i] = ok[i] || fieldOk<scalar>(cloudObjs, userFields[i]);
|
|
||||||
ok[i] = ok[i] || fieldOk<vector>(cloudObjs, userFields[i]);
|
|
||||||
ok[i] = ok[i] || fieldOk<sphericalTensor>(cloudObjs, userFields[i]);
|
|
||||||
ok[i] = ok[i] || fieldOk<symmTensor>(cloudObjs, userFields[i]);
|
|
||||||
ok[i] = ok[i] || fieldOk<tensor>(cloudObjs, userFields[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
label nOk = 0;
|
if (!acceptFields.empty())
|
||||||
forAll(ok, i)
|
|
||||||
{
|
{
|
||||||
if (ok[i])
|
const wordRes::filter pred(acceptFields, excludeFields);
|
||||||
|
|
||||||
|
const wordList allNames(cloudObjects.sortedNames());
|
||||||
|
|
||||||
|
// Detect missing fields
|
||||||
|
forAll(acceptFields, i)
|
||||||
{
|
{
|
||||||
++nOk;
|
if
|
||||||
|
(
|
||||||
|
acceptFields[i].isLiteral()
|
||||||
|
&& !allNames.found(acceptFields[i])
|
||||||
|
)
|
||||||
|
{
|
||||||
|
missed.append(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
for (const word& fldName : allNames)
|
||||||
{
|
{
|
||||||
Info << "\n*** Warning: user specified field '" << userFields[i]
|
const auto iter = cloudObjects.cfind(fldName);
|
||||||
<< "' unavailable" << endl;
|
if (!pred(fldName) || !iter.found())
|
||||||
|
{
|
||||||
|
continue; // reject
|
||||||
|
}
|
||||||
|
|
||||||
|
const IOobject& io = *(iter.val());
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
//OR: fieldTypes::basic.found(io.headerClassName())
|
||||||
|
io.headerClassName() == IOField<label>::typeName
|
||||||
|
|| io.headerClassName() == IOField<scalar>::typeName
|
||||||
|
|| io.headerClassName() == IOField<vector>::typeName
|
||||||
|
|| io.headerClassName() == IOField<sphericalTensor>::typeName
|
||||||
|
|| io.headerClassName() == IOField<symmTensor>::typeName
|
||||||
|
|| io.headerClassName() == IOField<tensor>::typeName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Transfer from cloudObjects -> filteredObjects
|
||||||
|
filteredObjects.add(cloudObjects.remove(fldName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nOk;
|
if (missed.size())
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< nl
|
||||||
|
<< "Cannot find field file matching "
|
||||||
|
<< UIndirectList<wordRe>(acceptFields, missed) << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return filteredObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<>
|
void readFieldsAndWriteVTK
|
||||||
void writeVTK(OFstream& os, const label& value)
|
(
|
||||||
|
OFstream& os,
|
||||||
|
const List<labelList>& particleMap,
|
||||||
|
const IOobjectList& filteredObjects
|
||||||
|
)
|
||||||
{
|
{
|
||||||
os << value;
|
processFields<label>(os, particleMap, filteredObjects);
|
||||||
|
processFields<scalar>(os, particleMap, filteredObjects);
|
||||||
|
processFields<vector>(os, particleMap, filteredObjects);
|
||||||
|
processFields<sphericalTensor>(os, particleMap, filteredObjects);
|
||||||
|
processFields<symmTensor>(os, particleMap, filteredObjects);
|
||||||
|
processFields<tensor>(os, particleMap, filteredObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
template<>
|
|
||||||
void writeVTK(OFstream& os, const scalar& value)
|
|
||||||
{
|
|
||||||
os << value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
using namespace Foam;
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -153,37 +193,31 @@ int main(int argc, char *argv[])
|
|||||||
const fileName vtkTimePath(vtkPath/runTime.timeName());
|
const fileName vtkTimePath(vtkPath/runTime.timeName());
|
||||||
mkDir(vtkTimePath);
|
mkDir(vtkTimePath);
|
||||||
|
|
||||||
Info<< " Reading particle positions" << endl;
|
pointField particlePosition;
|
||||||
|
labelList particleToTrack;
|
||||||
PtrList<passiveParticle> particles(0);
|
label nTracks = 0;
|
||||||
|
|
||||||
// Transfer particles to (more convenient) list
|
// Transfer particles to (more convenient) list
|
||||||
{
|
{
|
||||||
passiveParticleCloud ppc(mesh, cloudName);
|
Info<< " Reading particle positions" << endl;
|
||||||
Info<< "\n Read " << returnReduce(ppc.size(), sumOp<label>())
|
|
||||||
|
passiveParticleCloud myCloud(mesh, cloudName);
|
||||||
|
Info<< "\n Read " << returnReduce(myCloud.size(), sumOp<label>())
|
||||||
<< " particles" << endl;
|
<< " particles" << endl;
|
||||||
|
|
||||||
particles.setSize(ppc.size());
|
const label nParticles = myCloud.size();
|
||||||
|
|
||||||
label i = 0;
|
particlePosition.resize(nParticles);
|
||||||
forAllIters(ppc, iter)
|
particleToTrack.resize(nParticles);
|
||||||
|
|
||||||
|
LabelPairMap<label> trackTable;
|
||||||
|
|
||||||
|
label np = 0;
|
||||||
|
for (const passiveParticle& p : myCloud)
|
||||||
{
|
{
|
||||||
particles.set(i++, ppc.remove(&iter()));
|
const label origId = p.origId();
|
||||||
}
|
const label origProc = p.origProc();
|
||||||
|
particlePosition[np] = p.position();
|
||||||
// myCloud should now be empty
|
|
||||||
}
|
|
||||||
|
|
||||||
List<label> particleToTrack(particles.size());
|
|
||||||
label nTracks = 0;
|
|
||||||
|
|
||||||
{
|
|
||||||
labelPairLookup trackTable;
|
|
||||||
|
|
||||||
forAll(particles, i)
|
|
||||||
{
|
|
||||||
const label origProc = particles[i].origProc();
|
|
||||||
const label origId = particles[i].origId();
|
|
||||||
|
|
||||||
const labelPair key(origProc, origId);
|
const labelPair key(origProc, origId);
|
||||||
|
|
||||||
@ -191,17 +225,19 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (iter.found())
|
if (iter.found())
|
||||||
{
|
{
|
||||||
particleToTrack[i] = *iter;
|
particleToTrack[np] = *iter;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
particleToTrack[i] = nTracks;
|
particleToTrack[np] = trackTable.size();
|
||||||
trackTable.insert(key, nTracks);
|
trackTable.insert(key, trackTable.size());
|
||||||
++nTracks;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
++np;
|
||||||
|
}
|
||||||
|
|
||||||
|
nTracks = trackTable.size();
|
||||||
|
}
|
||||||
|
|
||||||
if (nTracks == 0)
|
if (nTracks == 0)
|
||||||
{
|
{
|
||||||
@ -230,7 +266,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store the particle age per track
|
// Store the particle age per track
|
||||||
IOobjectList cloudObjs
|
IOobjectList cloudObjects
|
||||||
(
|
(
|
||||||
mesh,
|
mesh,
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
@ -239,25 +275,30 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// TODO: gather age across all procs
|
// TODO: gather age across all procs
|
||||||
{
|
{
|
||||||
tmp<scalarField> tage =
|
tmp<IOField<scalar>> tage =
|
||||||
readParticleField<scalar>("age", cloudObjs);
|
readParticleField<scalar>("age", cloudObjects);
|
||||||
|
|
||||||
const scalarField& age = tage();
|
const auto& age = tage();
|
||||||
|
|
||||||
labelList trackSamples(nTracks, Zero);
|
labelList trackSamples(nTracks, Zero);
|
||||||
|
|
||||||
forAll(particleToTrack, i)
|
forAll(particleToTrack, i)
|
||||||
{
|
{
|
||||||
const label trackI = particleToTrack[i];
|
const label tracki = particleToTrack[i];
|
||||||
const label sampleI = trackSamples[trackI];
|
const label samplei = trackSamples[tracki];
|
||||||
agePerTrack[trackI][sampleI] = age[i];
|
agePerTrack[tracki][samplei] = age[i];
|
||||||
particleMap[trackI][sampleI] = i;
|
particleMap[tracki][samplei] = i;
|
||||||
trackSamples[trackI]++;
|
++trackSamples[tracki];
|
||||||
}
|
}
|
||||||
tage.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const IOobjectList filteredObjects
|
||||||
|
(
|
||||||
|
preFilterFields(cloudObjects, acceptFields, excludeFields)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
OFstream os(vtkTimePath/"particleTracks.vtk");
|
OFstream os(vtkTimePath/"particleTracks.vtk");
|
||||||
@ -295,7 +336,7 @@ int main(int argc, char *argv[])
|
|||||||
forAll(ids, j)
|
forAll(ids, j)
|
||||||
{
|
{
|
||||||
const label localId = particleIds[j];
|
const label localId = particleIds[j];
|
||||||
const vector pos(particles[localId].position());
|
const point& pos = particlePosition[localId];
|
||||||
os << pos.x() << ' ' << pos.y() << ' ' << pos.z()
|
os << pos.x() << ' ' << pos.y() << ' ' << pos.z()
|
||||||
<< nl;
|
<< nl;
|
||||||
}
|
}
|
||||||
@ -330,22 +371,14 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const label nFields = validateFields(userFields, cloudObjs);
|
const label nFields = filteredObjects.size();
|
||||||
|
|
||||||
os << "POINT_DATA " << nPoints << nl
|
os << "POINT_DATA " << nPoints << nl
|
||||||
<< "FIELD attributes " << nFields << nl;
|
<< "FIELD attributes " << nFields << nl;
|
||||||
|
|
||||||
Info<< "\n Processing fields" << nl << endl;
|
Info<< "\n Processing fields" << nl << endl;
|
||||||
|
|
||||||
processFields<label>(os, particleMap, userFields, cloudObjs);
|
readFieldsAndWriteVTK(os, particleMap, filteredObjects);
|
||||||
processFields<scalar>(os, particleMap, userFields, cloudObjs);
|
|
||||||
processFields<vector>(os, particleMap, userFields, cloudObjs);
|
|
||||||
processFields<sphericalTensor>
|
|
||||||
(os, particleMap, userFields, cloudObjs);
|
|
||||||
processFields<symmTensor>
|
|
||||||
(os, particleMap, userFields, cloudObjs);
|
|
||||||
processFields<tensor>(os, particleMap, userFields, cloudObjs);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Info<< endl;
|
Info<< endl;
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -31,113 +31,71 @@ License
|
|||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
bool Foam::fieldOk(const IOobjectList& cloudObjs, const word& name)
|
Foam::tmp<Foam::IOField<Type>> Foam::readParticleField
|
||||||
{
|
|
||||||
return cloudObjs.cfindObject<IOField<Type>>(name) != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::tmp<Foam::Field<Type>> Foam::readParticleField
|
|
||||||
(
|
(
|
||||||
const word& name,
|
const word& fieldName,
|
||||||
const IOobjectList cloudObjs
|
const IOobjectList& cloudObjects
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const IOobject* obj = cloudObjs.cfindObject<IOField<Type>>(name);
|
const IOobject* io = cloudObjects.cfindObject<IOField<Type>>(fieldName);
|
||||||
if (obj != nullptr)
|
if (io)
|
||||||
{
|
{
|
||||||
IOField<Type> newField(*obj);
|
return tmp<IOField<Type>>::New(*io);
|
||||||
return tmp<Field<Type>>::New(std::move(newField));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Error: cloud field name " << name
|
<< "Cloud field name " << fieldName
|
||||||
<< " not found or the wrong type"
|
<< " not found or the incorrect type"
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
|
|
||||||
return Field<Type>::null();
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::readFields
|
|
||||||
(
|
|
||||||
PtrList<List<Type>>& values,
|
|
||||||
const List<word>& fieldNames,
|
|
||||||
const IOobjectList& cloudObjs
|
|
||||||
)
|
|
||||||
{
|
|
||||||
forAll(fieldNames, fieldi)
|
|
||||||
{
|
|
||||||
const word& fieldName = fieldNames[fieldi];
|
|
||||||
|
|
||||||
const IOobject* obj = cloudObjs.cfindObject<IOField<Type>>(fieldName);
|
|
||||||
if (obj != nullptr)
|
|
||||||
{
|
|
||||||
Info<< " reading field " << fieldName << endl;
|
|
||||||
IOField<Type> newField(*obj);
|
|
||||||
values.set(fieldi, new List<Type>(std::move(newField)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Unable to read field " << fieldName
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::writeVTK(OFstream& os, const Type& value)
|
void Foam::writeVTK(OFstream& os, const Type& value)
|
||||||
{
|
{
|
||||||
os << value.component(0);
|
os << component(value, 0);
|
||||||
for (label i=1; i<pTraits<Type>::nComponents; i++)
|
for (label d=1; d < pTraits<Type>::nComponents; ++d)
|
||||||
{
|
{
|
||||||
os << ' ' << value.component(i);
|
os << ' ' << component(value, d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::writeVTKFields
|
void Foam::writeVTKField
|
||||||
(
|
(
|
||||||
OFstream& os,
|
OFstream& os,
|
||||||
const PtrList<List<Type>>& values,
|
const IOField<Type>& field,
|
||||||
const List<List<label>>& addr,
|
const List<labelList>& addr
|
||||||
const List<word>& fieldNames
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
label step = max(floor(8/pTraits<Type>::nComponents), 1);
|
const label step = max(1, floor(8/pTraits<Type>::nComponents));
|
||||||
|
|
||||||
forAll(values, fieldi)
|
Info<< " writing field " << field.name() << endl;
|
||||||
|
os << nl << field.name() << ' '
|
||||||
|
<< int(pTraits<Type>::nComponents) << ' '
|
||||||
|
<< field.size() << " float" << nl;
|
||||||
|
|
||||||
|
///label offset = 0;
|
||||||
|
for (const labelList& ids : addr)
|
||||||
{
|
{
|
||||||
Info<< " writing field " << fieldNames[fieldi] << endl;
|
List<Type> data(UIndirectList<Type>(field, ids));
|
||||||
os << nl << fieldNames[fieldi] << ' '
|
label nData = data.size() - 1;
|
||||||
<< int(pTraits<Type>::nComponents) << ' '
|
forAll(data, i)
|
||||||
<< values[fieldi].size() << " float" << nl;
|
|
||||||
label offset = 0;
|
|
||||||
forAll(addr, tracki)
|
|
||||||
{
|
{
|
||||||
const List<label> ids(addr[tracki]);
|
writeVTK<Type>(os, data[i]);
|
||||||
|
if (((i + 1) % step == 0) || (i == nData))
|
||||||
List<Type> data(UIndirectList<Type>(values[fieldi], ids));
|
|
||||||
label nData = data.size() - 1;
|
|
||||||
forAll(data, i)
|
|
||||||
{
|
{
|
||||||
writeVTK<Type>(os, data[i]);
|
os << nl;
|
||||||
if (((i + 1) % step == 0) || (i == nData))
|
}
|
||||||
{
|
else
|
||||||
os << nl;
|
{
|
||||||
}
|
os << ' ';
|
||||||
else
|
|
||||||
{
|
|
||||||
os << ' ';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
offset += ids.size();
|
|
||||||
}
|
}
|
||||||
|
/// offset += ids.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,36 +104,28 @@ template<class Type>
|
|||||||
void Foam::processFields
|
void Foam::processFields
|
||||||
(
|
(
|
||||||
OFstream& os,
|
OFstream& os,
|
||||||
const List<List<label>>& addr,
|
const List<labelList>& addr,
|
||||||
const List<word>& userFieldNames,
|
const IOobjectList& cloudObjects
|
||||||
const IOobjectList& cloudObjs
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
IOobjectList objects(cloudObjs.lookupClass(IOField<Type>::typeName));
|
for (const word& fldName : cloudObjects.sortedNames<IOField<Type>>())
|
||||||
|
|
||||||
if (objects.size())
|
|
||||||
{
|
{
|
||||||
DynamicList<word> fieldNames(objects.size());
|
const IOobject* io = cloudObjects.cfindObject<IOField<Type>>(fldName);
|
||||||
forAll(userFieldNames, i)
|
|
||||||
|
if (!io)
|
||||||
{
|
{
|
||||||
const IOobject* obj = objects.findObject(userFieldNames[i]);
|
FatalErrorInFunction
|
||||||
if (obj != nullptr)
|
<< "Could not read field:" << fldName
|
||||||
{
|
<< " type:" << IOField<Type>::typeName
|
||||||
fieldNames.append(obj->name());
|
<< abort(FatalError);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fieldNames.shrink();
|
else
|
||||||
|
{
|
||||||
|
Info<< " reading field " << fldName << endl;
|
||||||
|
IOField<Type> field(*io);
|
||||||
|
|
||||||
PtrList<List<Type>> values(fieldNames.size());
|
writeVTKField<Type>(os, field, addr);
|
||||||
readFields<Type>(values, fieldNames, cloudObjs);
|
}
|
||||||
|
|
||||||
writeVTKFields<Type>
|
|
||||||
(
|
|
||||||
os,
|
|
||||||
values,
|
|
||||||
addr,
|
|
||||||
fieldNames
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -25,13 +26,12 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef steadyParticleTracksTemplates_H
|
#ifndef Foam_steadyParticleTracksTemplates_H
|
||||||
#define steadyParticleTracksTemplates_H
|
#define Foam_steadyParticleTracksTemplates_H
|
||||||
|
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
#include "IOobjectList.H"
|
#include "IOobjectList.H"
|
||||||
#include "PtrList.H"
|
#include "IOField.H"
|
||||||
#include "Field.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -41,42 +41,29 @@ namespace Foam
|
|||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
bool fieldOk(const IOobjectList& cloudObjs, const word& name);
|
tmp<IOField<Type>> readParticleField
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
tmp<Field<Type>> readParticleField
|
|
||||||
(
|
(
|
||||||
const word& name,
|
const word& fieldName,
|
||||||
const IOobjectList cloudObjs
|
const IOobjectList& cloudObjects
|
||||||
);
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void readFields
|
|
||||||
(
|
|
||||||
PtrList<List<Type>>& values,
|
|
||||||
const List<word>& fields,
|
|
||||||
const IOobjectList& cloudObjs
|
|
||||||
);
|
);
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void writeVTK(OFstream& os, const Type& value);
|
void writeVTK(OFstream& os, const Type& value);
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void writeVTKFields
|
void writeVTKField
|
||||||
(
|
(
|
||||||
OFstream& os,
|
OFstream& os,
|
||||||
const PtrList<List<Type>>& values,
|
const IOField<Type>& field,
|
||||||
const List<List<label>>& addr,
|
const List<labelList>& addr
|
||||||
const List<word>& fieldNames
|
|
||||||
);
|
);
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void processFields
|
void processFields
|
||||||
(
|
(
|
||||||
OFstream& os,
|
OFstream& os,
|
||||||
const List<List<label>>& addr,
|
const List<labelList>& addr,
|
||||||
const List<word>& userFieldNames,
|
const IOobjectList& cloudObjects
|
||||||
const IOobjectList& cloudObjs
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -482,6 +482,7 @@ DebugSwitches
|
|||||||
constantAbsorptionEmission 0;
|
constantAbsorptionEmission 0;
|
||||||
constantAlphaContactAngle 0;
|
constantAlphaContactAngle 0;
|
||||||
constantScatter 0;
|
constantScatter 0;
|
||||||
|
coordSetWriter 0;
|
||||||
coordinateSystem 0;
|
coordinateSystem 0;
|
||||||
corrected 0;
|
corrected 0;
|
||||||
coupled 0;
|
coupled 0;
|
||||||
@ -983,7 +984,6 @@ DebugSwitches
|
|||||||
wedge 0;
|
wedge 0;
|
||||||
weighted 0;
|
weighted 0;
|
||||||
word 0;
|
word 0;
|
||||||
writer 0;
|
|
||||||
xmgr 0;
|
xmgr 0;
|
||||||
zeroGradient 0;
|
zeroGradient 0;
|
||||||
zoneToCell 0;
|
zoneToCell 0;
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2016 OpenFOAM Foundation
|
Copyright (C) 2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -28,6 +28,7 @@ License
|
|||||||
|
|
||||||
#include "histogram.H"
|
#include "histogram.H"
|
||||||
#include "volFields.H"
|
#include "volFields.H"
|
||||||
|
#include "ListOps.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
@ -42,41 +43,6 @@ namespace functionObjects
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
void Foam::functionObjects::histogram::writeGraph
|
|
||||||
(
|
|
||||||
const coordSet& coords,
|
|
||||||
const word& fieldName,
|
|
||||||
const scalarField& normalizedValues,
|
|
||||||
const scalarField& absoluteValues
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
fileName outputPath = baseTimeDir();
|
|
||||||
mkDir(outputPath);
|
|
||||||
OFstream graphFile
|
|
||||||
(
|
|
||||||
outputPath
|
|
||||||
/formatterPtr_().getFileName
|
|
||||||
(
|
|
||||||
coords,
|
|
||||||
wordList(1, fieldName)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Log << " Writing histogram of " << fieldName
|
|
||||||
<< " to " << graphFile.name() << endl;
|
|
||||||
|
|
||||||
wordList fieldNames(2);
|
|
||||||
fieldNames[0] = fieldName;
|
|
||||||
fieldNames[1] = fieldName + "Count";
|
|
||||||
List<const scalarField*> yPtrs(2);
|
|
||||||
yPtrs[0] = &normalizedValues;
|
|
||||||
yPtrs[1] = &absoluteValues;
|
|
||||||
formatterPtr_().write(coords, fieldNames, yPtrs, graphFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::functionObjects::histogram::histogram
|
Foam::functionObjects::histogram::histogram
|
||||||
@ -86,10 +52,11 @@ Foam::functionObjects::histogram::histogram
|
|||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
fvMeshFunctionObject(name, runTime, dict),
|
functionObjects::fvMeshFunctionObject(name, runTime, dict),
|
||||||
writeFile(obr_, name),
|
functionObjects::writeFile(obr_, name),
|
||||||
max_(-GREAT),
|
max_(-GREAT),
|
||||||
min_(GREAT)
|
min_(GREAT),
|
||||||
|
setWriterPtr_(nullptr)
|
||||||
{
|
{
|
||||||
read(dict);
|
read(dict);
|
||||||
}
|
}
|
||||||
@ -116,8 +83,13 @@ bool Foam::functionObjects::histogram::read(const dictionary& dict)
|
|||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
const word format(dict.get<word>("setFormat"));
|
const word writeType(dict.get<word>("setFormat"));
|
||||||
formatterPtr_ = writer<scalar>::New(format);
|
|
||||||
|
setWriterPtr_ = coordSetWriter::New
|
||||||
|
(
|
||||||
|
writeType,
|
||||||
|
dict.subOrEmptyDict("formatOptions").optionalSubDict(writeType)
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -133,38 +105,30 @@ bool Foam::functionObjects::histogram::write()
|
|||||||
{
|
{
|
||||||
Log << type() << " " << name() << " write:" << nl;
|
Log << type() << " " << name() << " write:" << nl;
|
||||||
|
|
||||||
autoPtr<volScalarField> fieldPtr;
|
tmp<volScalarField> tfield;
|
||||||
if (obr_.foundObject<volScalarField>(fieldName_))
|
tfield.cref(obr_.cfindObject<volScalarField>(fieldName_));
|
||||||
|
|
||||||
|
if (tfield)
|
||||||
{
|
{
|
||||||
Log << " Looking up field " << fieldName_ << endl;
|
Log << " Looking up field " << fieldName_ << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log << " Reading field " << fieldName_ << endl;
|
Log << " Reading field " << fieldName_ << endl;
|
||||||
fieldPtr.reset
|
tfield = tmp<volScalarField>::New
|
||||||
(
|
(
|
||||||
new volScalarField
|
IOobject
|
||||||
(
|
(
|
||||||
IOobject
|
fieldName_,
|
||||||
(
|
mesh_.time().timeName(),
|
||||||
fieldName_,
|
mesh_,
|
||||||
mesh_.time().timeName(),
|
IOobject::MUST_READ,
|
||||||
mesh_,
|
IOobject::NO_WRITE
|
||||||
IOobject::MUST_READ,
|
),
|
||||||
IOobject::NO_WRITE
|
mesh_
|
||||||
),
|
|
||||||
mesh_
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const auto& field = tfield();
|
||||||
const volScalarField& field =
|
|
||||||
(
|
|
||||||
fieldPtr
|
|
||||||
? fieldPtr()
|
|
||||||
: obr_.lookupObject<volScalarField>(fieldName_)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
scalar histMax = max_;
|
scalar histMax = max_;
|
||||||
scalar histMin = min_;
|
scalar histMin = min_;
|
||||||
@ -188,14 +152,16 @@ bool Foam::functionObjects::histogram::write()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the mid-points of bins for the graph axis
|
// Calculate the mid-points of bins for the graph axis
|
||||||
pointField xBin(nBins_);
|
pointField xBin(nBins_, Zero);
|
||||||
const scalar delta = (histMax- histMin)/nBins_;
|
const scalar delta = (histMax - histMin)/nBins_;
|
||||||
|
|
||||||
scalar x = histMin + 0.5*delta;
|
|
||||||
forAll(xBin, i)
|
|
||||||
{
|
{
|
||||||
xBin[i] = point(x, 0, 0);
|
scalar x = histMin + 0.5*delta;
|
||||||
x += delta;
|
for (point& p : xBin)
|
||||||
|
{
|
||||||
|
p.x() = x;
|
||||||
|
x += delta;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scalarField dataNormalized(nBins_, Zero);
|
scalarField dataNormalized(nBins_, Zero);
|
||||||
@ -223,23 +189,27 @@ bool Foam::functionObjects::histogram::write()
|
|||||||
{
|
{
|
||||||
dataNormalized /= sumData;
|
dataNormalized /= sumData;
|
||||||
|
|
||||||
const coordSet coords
|
const coordSet coords(fieldName_, "x", xBin, mag(xBin));
|
||||||
|
|
||||||
|
auto& writer = *setWriterPtr_;
|
||||||
|
|
||||||
|
writer.open
|
||||||
(
|
(
|
||||||
fieldName_,
|
coords,
|
||||||
"x",
|
(
|
||||||
xBin,
|
writeFile::baseTimeDir()
|
||||||
mag(xBin)
|
/ (coords.name() + coordSetWriter::suffix(fieldName_))
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Log << " Writing histogram of " << fieldName_
|
||||||
|
<< " to " << writer.path() << endl;
|
||||||
|
|
||||||
// Convert count field from labelField to scalarField
|
writer.nFields(2);
|
||||||
scalarField count(dataCount.size());
|
writer.write(fieldName_, dataNormalized);
|
||||||
forAll(count, i)
|
writer.write(fieldName_ + "Count", dataCount);
|
||||||
{
|
|
||||||
count[i] = 1.0*dataCount[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
writeGraph(coords, fieldName_, dataNormalized, count);
|
writer.close(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2016 OpenFOAM Foundation
|
Copyright (C) 2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
Copyright (C) 2017-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -100,12 +100,12 @@ SourceFiles
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef functionObjects_histogram_H
|
#ifndef Foam_functionObjects_histogram_H
|
||||||
#define functionObjects_histogram_H
|
#define Foam_functionObjects_histogram_H
|
||||||
|
|
||||||
#include "fvMeshFunctionObject.H"
|
#include "fvMeshFunctionObject.H"
|
||||||
#include "writeFile.H"
|
#include "writeFile.H"
|
||||||
#include "writer.H"
|
#include "coordSetWriter.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -120,8 +120,8 @@ namespace functionObjects
|
|||||||
|
|
||||||
class histogram
|
class histogram
|
||||||
:
|
:
|
||||||
public fvMeshFunctionObject,
|
public functionObjects::fvMeshFunctionObject,
|
||||||
public writeFile
|
public functionObjects::writeFile
|
||||||
{
|
{
|
||||||
// Private Data
|
// Private Data
|
||||||
|
|
||||||
@ -138,18 +138,7 @@ class histogram
|
|||||||
scalar min_;
|
scalar min_;
|
||||||
|
|
||||||
//- Output formatter to write
|
//- Output formatter to write
|
||||||
autoPtr<writer<scalar>> formatterPtr_;
|
mutable autoPtr<coordSetWriter> setWriterPtr_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
void writeGraph
|
|
||||||
(
|
|
||||||
const coordSet& coords,
|
|
||||||
const word& valueName,
|
|
||||||
const scalarField& normalizedValues,
|
|
||||||
const scalarField& absoluteValues
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -78,8 +78,13 @@ bool Foam::functionObjects::particleDistribution::read(const dictionary& dict)
|
|||||||
dict.readEntry("cloud", cloudName_);
|
dict.readEntry("cloud", cloudName_);
|
||||||
dict.readIfPresent("tagField", tagFieldName_);
|
dict.readIfPresent("tagField", tagFieldName_);
|
||||||
dict.readEntry("nameVsBinWidth", nameVsBinWidth_);
|
dict.readEntry("nameVsBinWidth", nameVsBinWidth_);
|
||||||
const word format(dict.get<word>("setFormat"));
|
|
||||||
writerPtr_ = writer<scalar>::New(format);
|
const word setFormat(dict.get<word>("setFormat"));
|
||||||
|
writerPtr_ = coordSetWriter::New
|
||||||
|
(
|
||||||
|
setFormat,
|
||||||
|
dict.subOrEmptyDict("formatOptions").optionalSubDict(setFormat)
|
||||||
|
);
|
||||||
|
|
||||||
Info<< type() << " " << name() << " output:" << nl
|
Info<< type() << " " << name() << " output:" << nl
|
||||||
<< " Processing cloud : " << cloudName_ << nl
|
<< " Processing cloud : " << cloudName_ << nl
|
||||||
@ -104,12 +109,10 @@ bool Foam::functionObjects::particleDistribution::write()
|
|||||||
|
|
||||||
if (!mesh_.foundObject<cloud>(cloudName_))
|
if (!mesh_.foundObject<cloud>(cloudName_))
|
||||||
{
|
{
|
||||||
wordList cloudNames(mesh_.names<cloud>());
|
|
||||||
|
|
||||||
WarningInFunction
|
WarningInFunction
|
||||||
<< "Unable to find cloud " << cloudName_
|
<< "Unable to find cloud " << cloudName_
|
||||||
<< " in the mesh database. Available clouds include:"
|
<< " in the mesh database. Available clouds include:"
|
||||||
<< cloudNames << endl;
|
<< flatOutput(mesh_.sortedNames<cloud>()) << endl;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -153,16 +156,17 @@ bool Foam::functionObjects::particleDistribution::write()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ok = false;
|
|
||||||
forAll(nameVsBinWidth_, i)
|
forAll(nameVsBinWidth_, i)
|
||||||
{
|
{
|
||||||
ok = false;
|
const bool ok
|
||||||
ok = ok || processField<scalar>(cloudObr, i, tagAddr);
|
(
|
||||||
ok = ok || processField<vector>(cloudObr, i, tagAddr);
|
processField<scalar>(cloudObr, i, tagAddr)
|
||||||
ok = ok || processField<tensor>(cloudObr, i, tagAddr);
|
|| processField<vector>(cloudObr, i, tagAddr)
|
||||||
ok = ok || processField<sphericalTensor>(cloudObr, i, tagAddr);
|
|| processField<tensor>(cloudObr, i, tagAddr)
|
||||||
ok = ok || processField<symmTensor>(cloudObr, i, tagAddr);
|
|| processField<sphericalTensor>(cloudObr, i, tagAddr)
|
||||||
ok = ok || processField<tensor>(cloudObr, i, tagAddr);
|
|| processField<symmTensor>(cloudObr, i, tagAddr)
|
||||||
|
|| processField<tensor>(cloudObr, i, tagAddr)
|
||||||
|
);
|
||||||
|
|
||||||
if (log && !ok)
|
if (log && !ok)
|
||||||
{
|
{
|
||||||
@ -189,10 +193,10 @@ void Foam::functionObjects::particleDistribution::generateDistribution
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
word fName(fieldName);
|
word fldName(fieldName);
|
||||||
if (tag != -1)
|
if (tag != -1)
|
||||||
{
|
{
|
||||||
fName = fName + '_' + Foam::name(tag);
|
fldName += '_' + Foam::name(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
distributionModels::general distribution
|
distributionModels::general distribution
|
||||||
@ -202,31 +206,20 @@ void Foam::functionObjects::particleDistribution::generateDistribution
|
|||||||
rndGen_
|
rndGen_
|
||||||
);
|
);
|
||||||
|
|
||||||
const Field<scalar> distX(distribution.x());
|
Field<scalar> distX(distribution.x());
|
||||||
const Field<scalar> distY(distribution.y());
|
Field<scalar> distY(distribution.y());
|
||||||
|
|
||||||
pointField xBin(distX.size(), Zero);
|
pointField xBin(distX.size(), Zero);
|
||||||
xBin.replace(0, distX);
|
xBin.replace(vector::X, distX);
|
||||||
const coordSet coords
|
|
||||||
(
|
|
||||||
fName,
|
|
||||||
"x",
|
|
||||||
xBin,
|
|
||||||
distX
|
|
||||||
);
|
|
||||||
|
|
||||||
const wordList fieldNames(1, fName);
|
const coordSet coords(fldName, "x", std::move(xBin), std::move(distX));
|
||||||
|
|
||||||
fileName outputPath(baseTimeDir());
|
writerPtr_->open(coords, baseTimeDir() / fldName);
|
||||||
mkDir(outputPath);
|
fileName outFile = writerPtr_->write(fldName, distY);
|
||||||
OFstream graphFile(outputPath/writerPtr_->getFileName(coords, fieldNames));
|
writerPtr_->close(true);
|
||||||
|
|
||||||
Log << " Writing distribution of " << fieldName
|
Log << " Wrote distribution of " << fieldName
|
||||||
<< " to " << graphFile.name() << endl;
|
<< " to " << time_.relativePath(outFile) << endl;
|
||||||
|
|
||||||
List<const scalarField*> yPtrs(1);
|
|
||||||
yPtrs[0] = &distY;
|
|
||||||
writerPtr_->write(coords, fieldNames, yPtrs, graphFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -103,7 +103,7 @@ SourceFiles
|
|||||||
#include "scalarField.H"
|
#include "scalarField.H"
|
||||||
#include "Random.H"
|
#include "Random.H"
|
||||||
#include "Tuple2.H"
|
#include "Tuple2.H"
|
||||||
#include "writer.H"
|
#include "coordSetWriter.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ namespace functionObjects
|
|||||||
|
|
||||||
class particleDistribution
|
class particleDistribution
|
||||||
:
|
:
|
||||||
public fvMeshFunctionObject,
|
public functionObjects::fvMeshFunctionObject,
|
||||||
public writeFile
|
public writeFile
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@ -138,7 +138,7 @@ protected:
|
|||||||
List<Tuple2<word, scalar>> nameVsBinWidth_;
|
List<Tuple2<word, scalar>> nameVsBinWidth_;
|
||||||
|
|
||||||
//- Writer
|
//- Writer
|
||||||
autoPtr<writer<scalar>> writerPtr_;
|
mutable autoPtr<coordSetWriter> writerPtr_;
|
||||||
|
|
||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2013-2016 OpenFOAM Foundation
|
Copyright (C) 2013-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -27,6 +27,8 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "regionSizeDistribution.H"
|
#include "regionSizeDistribution.H"
|
||||||
|
#include "regionSplit.H"
|
||||||
|
#include "volFields.H"
|
||||||
#include "fvcVolumeIntegrate.H"
|
#include "fvcVolumeIntegrate.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
@ -47,31 +49,47 @@ namespace Foam
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::functionObjects::regionSizeDistribution::writeGraph
|
namespace Foam
|
||||||
(
|
|
||||||
const coordSet& coords,
|
|
||||||
const word& valueName,
|
|
||||||
const scalarField& values
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
const wordList valNames(1, valueName);
|
|
||||||
|
|
||||||
fileName outputPath = baseTimeDir();
|
template<class Type>
|
||||||
mkDir(outputPath);
|
static Map<Type> regionSum(const regionSplit& regions, const Field<Type>& fld)
|
||||||
|
{
|
||||||
|
// Per region the sum of fld
|
||||||
|
Map<Type> regionToSum(regions.nRegions()/Pstream::nProcs());
|
||||||
|
|
||||||
OFstream str(outputPath/formatterPtr_().getFileName(coords, valNames));
|
forAll(fld, celli)
|
||||||
|
{
|
||||||
|
const label regioni = regions[celli];
|
||||||
|
regionToSum(regioni, Type(Zero)) += fld[celli];
|
||||||
|
}
|
||||||
|
|
||||||
Log << " Writing distribution of " << valueName << " to " << str.name()
|
Pstream::mapCombineGather(regionToSum, plusEqOp<Type>());
|
||||||
<< endl;
|
Pstream::mapCombineScatter(regionToSum);
|
||||||
|
|
||||||
List<const scalarField*> valPtrs(1);
|
return regionToSum;
|
||||||
valPtrs[0] = &values;
|
|
||||||
formatterPtr_().write(coords, valNames, valPtrs, str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
static List<Type> extractData(const labelUList& keys, const Map<Type>& regionData)
|
||||||
|
{
|
||||||
|
List<Type> sortedData(keys.size());
|
||||||
|
|
||||||
|
forAll(keys, i)
|
||||||
|
{
|
||||||
|
sortedData[i] = regionData[keys[i]];
|
||||||
|
}
|
||||||
|
return sortedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::functionObjects::regionSizeDistribution::writeAlphaFields
|
void Foam::functionObjects::regionSizeDistribution::writeAlphaFields
|
||||||
(
|
(
|
||||||
const regionSplit& regions,
|
const regionSplit& regions,
|
||||||
@ -222,7 +240,7 @@ Foam::functionObjects::regionSizeDistribution::divide
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result[i] = 0.0;
|
result[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tresult;
|
return tresult;
|
||||||
@ -232,8 +250,9 @@ Foam::functionObjects::regionSizeDistribution::divide
|
|||||||
void Foam::functionObjects::regionSizeDistribution::writeGraphs
|
void Foam::functionObjects::regionSizeDistribution::writeGraphs
|
||||||
(
|
(
|
||||||
const word& fieldName, // name of field
|
const word& fieldName, // name of field
|
||||||
const labelList& indices, // index of bin for each region
|
|
||||||
const scalarField& sortedField, // per region field data
|
const scalarField& sortedField, // per region field data
|
||||||
|
|
||||||
|
const labelList& indices, // index of bin for each region
|
||||||
const scalarField& binCount, // per bin number of regions
|
const scalarField& binCount, // per bin number of regions
|
||||||
const coordSet& coords // graph data for bins
|
const coordSet& coords // graph data for bins
|
||||||
) const
|
) const
|
||||||
@ -260,12 +279,44 @@ void Foam::functionObjects::regionSizeDistribution::writeGraphs
|
|||||||
sqrt(divide(binSqrSum, binCount) - Foam::sqr(binAvg))
|
sqrt(divide(binSqrSum, binCount) - Foam::sqr(binAvg))
|
||||||
);
|
);
|
||||||
|
|
||||||
// Write average
|
|
||||||
writeGraph(coords, fieldName + "_sum", binSum);
|
auto& writer = formatterPtr_();
|
||||||
// Write average
|
|
||||||
writeGraph(coords, fieldName + "_avg", binAvg);
|
word outputName;
|
||||||
// Write deviation
|
if (writer.buffering())
|
||||||
writeGraph(coords, fieldName + "_dev", binDev);
|
{
|
||||||
|
outputName =
|
||||||
|
(
|
||||||
|
coords.name()
|
||||||
|
+ coordSetWriter::suffix
|
||||||
|
(
|
||||||
|
wordList
|
||||||
|
({
|
||||||
|
fieldName + "_sum",
|
||||||
|
fieldName + "_avg",
|
||||||
|
fieldName + "_dev"
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outputName = coords.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.open
|
||||||
|
(
|
||||||
|
coords,
|
||||||
|
(baseTimeDir() / outputName)
|
||||||
|
);
|
||||||
|
|
||||||
|
Log << " Writing distribution of "
|
||||||
|
<< fieldName << " to " << writer.path() << endl;
|
||||||
|
|
||||||
|
writer.write(fieldName + "_sum", binSum);
|
||||||
|
writer.write(fieldName + "_avg", binAvg);
|
||||||
|
writer.write(fieldName + "_dev", binDev);
|
||||||
|
writer.close(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,18 +341,15 @@ void Foam::functionObjects::regionSizeDistribution::writeGraphs
|
|||||||
scalarField sortedField
|
scalarField sortedField
|
||||||
(
|
(
|
||||||
sortedNormalisation
|
sortedNormalisation
|
||||||
* extractData
|
* extractData(sortedRegions, regionField)
|
||||||
(
|
|
||||||
sortedRegions,
|
|
||||||
regionField
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
writeGraphs
|
writeGraphs
|
||||||
(
|
(
|
||||||
fieldName, // name of field
|
fieldName, // name of field
|
||||||
indices, // index of bin for each region
|
|
||||||
sortedField, // per region field data
|
sortedField, // per region field data
|
||||||
|
|
||||||
|
indices, // index of bin for each region
|
||||||
binCount, // per bin number of regions
|
binCount, // per bin number of regions
|
||||||
coords // graph data for bins
|
coords // graph data for bins
|
||||||
);
|
);
|
||||||
@ -343,8 +391,12 @@ bool Foam::functionObjects::regionSizeDistribution::read(const dictionary& dict)
|
|||||||
dict.readEntry("patches", patchNames_);
|
dict.readEntry("patches", patchNames_);
|
||||||
dict.readEntry("fields", fields_);
|
dict.readEntry("fields", fields_);
|
||||||
|
|
||||||
const word format(dict.get<word>("setFormat"));
|
const word setFormat(dict.get<word>("setFormat"));
|
||||||
formatterPtr_ = writer<scalar>::New(format);
|
formatterPtr_ = coordSetWriter::New
|
||||||
|
(
|
||||||
|
setFormat,
|
||||||
|
dict.subOrEmptyDict("formatOptions").optionalSubDict(setFormat)
|
||||||
|
);
|
||||||
|
|
||||||
if (dict.found(coordinateSystem::typeName_()))
|
if (dict.found(coordinateSystem::typeName_()))
|
||||||
{
|
{
|
||||||
@ -385,15 +437,16 @@ bool Foam::functionObjects::regionSizeDistribution::write()
|
|||||||
{
|
{
|
||||||
Log << type() << " " << name() << " write:" << nl;
|
Log << type() << " " << name() << " write:" << nl;
|
||||||
|
|
||||||
autoPtr<volScalarField> alphaPtr;
|
tmp<volScalarField> talpha;
|
||||||
if (obr_.foundObject<volScalarField>(alphaName_))
|
talpha.cref(obr_.cfindObject<volScalarField>(alphaName_));
|
||||||
|
if (talpha)
|
||||||
{
|
{
|
||||||
Log << " Looking up field " << alphaName_ << endl;
|
Log << " Looking up field " << alphaName_ << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Info<< " Reading field " << alphaName_ << endl;
|
Info<< " Reading field " << alphaName_ << endl;
|
||||||
alphaPtr.reset
|
talpha.reset
|
||||||
(
|
(
|
||||||
new volScalarField
|
new volScalarField
|
||||||
(
|
(
|
||||||
@ -409,14 +462,7 @@ bool Foam::functionObjects::regionSizeDistribution::write()
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const auto& alpha = talpha();
|
||||||
|
|
||||||
const volScalarField& alpha =
|
|
||||||
(
|
|
||||||
alphaPtr
|
|
||||||
? *alphaPtr
|
|
||||||
: obr_.lookupObject<volScalarField>(alphaName_)
|
|
||||||
);
|
|
||||||
|
|
||||||
Log << " Volume of alpha = "
|
Log << " Volume of alpha = "
|
||||||
<< fvc::domainIntegrate(alpha).value()
|
<< fvc::domainIntegrate(alpha).value()
|
||||||
@ -460,10 +506,9 @@ bool Foam::functionObjects::regionSizeDistribution::write()
|
|||||||
if (fvp.coupled())
|
if (fvp.coupled())
|
||||||
{
|
{
|
||||||
tmp<scalarField> townFld(fvp.patchInternalField());
|
tmp<scalarField> townFld(fvp.patchInternalField());
|
||||||
const scalarField& ownFld = townFld();
|
|
||||||
|
|
||||||
tmp<scalarField> tnbrFld(fvp.patchNeighbourField());
|
tmp<scalarField> tnbrFld(fvp.patchNeighbourField());
|
||||||
const scalarField& nbrFld = tnbrFld();
|
const auto& ownFld = townFld();
|
||||||
|
const auto& nbrFld = tnbrFld();
|
||||||
|
|
||||||
label start = fvp.patch().patch().start();
|
label start = fvp.patch().patch().start();
|
||||||
|
|
||||||
@ -663,13 +708,15 @@ bool Foam::functionObjects::regionSizeDistribution::write()
|
|||||||
if (allRegionVolume.size())
|
if (allRegionVolume.size())
|
||||||
{
|
{
|
||||||
// Construct mids of bins for plotting
|
// Construct mids of bins for plotting
|
||||||
pointField xBin(nBins_);
|
pointField xBin(nBins_, Zero);
|
||||||
|
|
||||||
scalar x = 0.5*delta;
|
|
||||||
forAll(xBin, i)
|
|
||||||
{
|
{
|
||||||
xBin[i] = point(x, 0, 0);
|
scalar x = 0.5*delta;
|
||||||
x += delta;
|
for (point& p : xBin)
|
||||||
|
{
|
||||||
|
p.x() = x;
|
||||||
|
x += delta;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const coordSet coords("diameter", "x", xBin, mag(xBin));
|
const coordSet coords("diameter", "x", xBin, mag(xBin));
|
||||||
@ -682,11 +729,7 @@ bool Foam::functionObjects::regionSizeDistribution::write()
|
|||||||
|
|
||||||
scalarField sortedVols
|
scalarField sortedVols
|
||||||
(
|
(
|
||||||
extractData
|
extractData(sortedRegions, allRegionAlphaVolume)
|
||||||
(
|
|
||||||
sortedRegions,
|
|
||||||
allRegionAlphaVolume
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
vectorField centroids(sortedVols.size(), Zero);
|
vectorField centroids(sortedVols.size(), Zero);
|
||||||
@ -712,11 +755,7 @@ bool Foam::functionObjects::regionSizeDistribution::write()
|
|||||||
// 2. centroid
|
// 2. centroid
|
||||||
vectorField sortedMoment
|
vectorField sortedMoment
|
||||||
(
|
(
|
||||||
extractData
|
extractData(sortedRegions, allRegionAlphaDistance)
|
||||||
(
|
|
||||||
sortedRegions,
|
|
||||||
allRegionAlphaDistance
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
centroids = sortedMoment/sortedVols + origin_;
|
centroids = sortedMoment/sortedVols + origin_;
|
||||||
@ -756,17 +795,30 @@ bool Foam::functionObjects::regionSizeDistribution::write()
|
|||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
// Construct mids of bins for plotting
|
// Construct mids of bins for plotting
|
||||||
pointField xBin(nDownstreamBins_);
|
pointField xBin(nDownstreamBins_, Zero);
|
||||||
|
|
||||||
scalar x = 0.5*deltaX;
|
|
||||||
forAll(xBin, i)
|
|
||||||
{
|
{
|
||||||
xBin[i] = point(x, 0, 0);
|
scalar x = 0.5*deltaX;
|
||||||
x += deltaX;
|
for (point& p : xBin)
|
||||||
|
{
|
||||||
|
p.x() = x;
|
||||||
|
x += deltaX;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const coordSet coords("distance", "x", xBin, mag(xBin));
|
const coordSet coords("distance", "x", xBin, mag(xBin));
|
||||||
writeGraph(coords, "isoPlanes", binDownCount);
|
|
||||||
|
auto& writer = formatterPtr_();
|
||||||
|
writer.nFields(1);
|
||||||
|
|
||||||
|
writer.open
|
||||||
|
(
|
||||||
|
coords,
|
||||||
|
writeFile::baseTimeDir() / (coords.name() + "_isoPlanes")
|
||||||
|
);
|
||||||
|
|
||||||
|
writer.write("isoPlanes", binDownCount);
|
||||||
|
writer.close(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write to log
|
// Write to log
|
||||||
@ -819,7 +871,17 @@ bool Foam::functionObjects::regionSizeDistribution::write()
|
|||||||
// Write counts
|
// Write counts
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
writeGraph(coords, "count", binCount);
|
auto& writer = formatterPtr_();
|
||||||
|
writer.nFields(1);
|
||||||
|
|
||||||
|
writer.open
|
||||||
|
(
|
||||||
|
coords,
|
||||||
|
writeFile::baseTimeDir() / (coords.name() + "_count")
|
||||||
|
);
|
||||||
|
|
||||||
|
writer.write("count", binCount);
|
||||||
|
writer.close(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write to log
|
// Write to log
|
||||||
@ -849,28 +911,28 @@ bool Foam::functionObjects::regionSizeDistribution::write()
|
|||||||
writeGraphs
|
writeGraphs
|
||||||
(
|
(
|
||||||
"volume", // name of field
|
"volume", // name of field
|
||||||
indices, // per region the bin index
|
|
||||||
sortedVols, // per region field data
|
sortedVols, // per region field data
|
||||||
|
|
||||||
|
indices, // per region the bin index
|
||||||
binCount, // per bin number of regions
|
binCount, // per bin number of regions
|
||||||
coords // graph data for bins
|
coords // graph data for bins
|
||||||
);
|
);
|
||||||
|
|
||||||
// Collect some more field
|
// Collect some more fields
|
||||||
{
|
{
|
||||||
wordList scalarNames(obr_.names(volScalarField::typeName));
|
for
|
||||||
|
(
|
||||||
const labelList selected(fields_.matching(scalarNames));
|
const word& fldName
|
||||||
|
: obr_.sortedNames<volScalarField>(fields_)
|
||||||
for (const label fieldi : selected)
|
)
|
||||||
{
|
{
|
||||||
const word& fldName = scalarNames[fieldi];
|
|
||||||
|
|
||||||
Log << " Scalar field " << fldName << endl;
|
Log << " Scalar field " << fldName << endl;
|
||||||
|
|
||||||
const scalarField& fld = obr_.lookupObject
|
tmp<Field<scalar>> tfld
|
||||||
<
|
(
|
||||||
volScalarField
|
obr_.lookupObject<volScalarField>(fldName).primitiveField()
|
||||||
>(fldName).primitiveField();
|
);
|
||||||
|
const auto& fld = tfld();
|
||||||
|
|
||||||
writeGraphs
|
writeGraphs
|
||||||
(
|
(
|
||||||
@ -887,21 +949,20 @@ bool Foam::functionObjects::regionSizeDistribution::write()
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
wordList vectorNames(obr_.names(volVectorField::typeName));
|
for
|
||||||
|
(
|
||||||
const labelList selected(fields_.matching(vectorNames));
|
const word& fldName
|
||||||
|
: obr_.sortedNames<volVectorField>(fields_)
|
||||||
for (const label fieldi : selected)
|
)
|
||||||
{
|
{
|
||||||
const word& fldName = vectorNames[fieldi];
|
|
||||||
|
|
||||||
Log << " Vector field " << fldName << endl;
|
Log << " Vector field " << fldName << endl;
|
||||||
|
|
||||||
vectorField fld = obr_.lookupObject
|
tmp<Field<vector>> tfld
|
||||||
<
|
(
|
||||||
volVectorField
|
obr_.lookupObject<volVectorField>(fldName).primitiveField()
|
||||||
>(fldName).primitiveField();
|
);
|
||||||
|
|
||||||
if (csysPtr_)
|
if (csysPtr_)
|
||||||
{
|
{
|
||||||
@ -910,18 +971,18 @@ bool Foam::functionObjects::regionSizeDistribution::write()
|
|||||||
<< csysPtr_->name()
|
<< csysPtr_->name()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
fld = csysPtr_->localVector(fld);
|
tfld = csysPtr_->localVector(tfld());
|
||||||
}
|
}
|
||||||
|
const auto& fld = tfld();
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
|
|
||||||
for (direction cmp = 0; cmp < vector::nComponents; cmp++)
|
for (direction cmpt = 0; cmpt < vector::nComponents; ++cmpt)
|
||||||
{
|
{
|
||||||
writeGraphs
|
writeGraphs
|
||||||
(
|
(
|
||||||
fldName + vector::componentNames[cmp],
|
fldName + vector::componentNames[cmpt],
|
||||||
alphaVol*fld.component(cmp),// per cell field data
|
alphaVol*fld.component(cmpt),// per cell field data
|
||||||
|
|
||||||
regions, // per cell the region(=droplet)
|
regions, // per cell the region(=droplet)
|
||||||
sortedRegions, // valid regions in sorted order
|
sortedRegions, // valid regions in sorted order
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2013-2016 OpenFOAM Foundation
|
Copyright (C) 2013-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -169,17 +169,16 @@ SourceFiles
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef functionObjects_regionSizeDistribution_H
|
#ifndef Foam_functionObjects_regionSizeDistribution_H
|
||||||
#define functionObjects_regionSizeDistribution_H
|
#define Foam_functionObjects_regionSizeDistribution_H
|
||||||
|
|
||||||
#include "fvMeshFunctionObject.H"
|
#include "fvMeshFunctionObject.H"
|
||||||
#include "writeFile.H"
|
#include "writeFile.H"
|
||||||
#include "writer.H"
|
#include "coordSetWriter.H"
|
||||||
#include "Map.H"
|
#include "Map.H"
|
||||||
#include "volFieldsFwd.H"
|
#include "volFieldsFwd.H"
|
||||||
#include "wordRes.H"
|
#include "wordRes.H"
|
||||||
#include "coordinateSystem.H"
|
#include "coordinateSystem.H"
|
||||||
#include "Switch.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -197,7 +196,7 @@ namespace functionObjects
|
|||||||
|
|
||||||
class regionSizeDistribution
|
class regionSizeDistribution
|
||||||
:
|
:
|
||||||
public fvMeshFunctionObject,
|
public functionObjects::fvMeshFunctionObject,
|
||||||
public writeFile
|
public writeFile
|
||||||
{
|
{
|
||||||
// Private Data
|
// Private Data
|
||||||
@ -224,7 +223,7 @@ class regionSizeDistribution
|
|||||||
wordRes fields_;
|
wordRes fields_;
|
||||||
|
|
||||||
//- Output formatter to write
|
//- Output formatter to write
|
||||||
autoPtr<writer<scalar>> formatterPtr_;
|
mutable autoPtr<coordSetWriter> formatterPtr_;
|
||||||
|
|
||||||
//- Optional coordinate system
|
//- Optional coordinate system
|
||||||
autoPtr<coordinateSystem> csysPtr_;
|
autoPtr<coordinateSystem> csysPtr_;
|
||||||
@ -253,20 +252,6 @@ class regionSizeDistribution
|
|||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Map<Type> regionSum(const regionSplit&, const Field<Type>&) const;
|
|
||||||
|
|
||||||
//- Get data in order
|
|
||||||
template<class Type>
|
|
||||||
List<Type> extractData(const labelUList& keys, const Map<Type>&) const;
|
|
||||||
|
|
||||||
void writeGraph
|
|
||||||
(
|
|
||||||
const coordSet& coords,
|
|
||||||
const word& valueName,
|
|
||||||
const scalarField& values
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Write volfields with the parts of alpha which are not
|
//- Write volfields with the parts of alpha which are not
|
||||||
//- droplets (liquidCore, backGround)
|
//- droplets (liquidCore, backGround)
|
||||||
void writeAlphaFields
|
void writeAlphaFields
|
||||||
@ -287,8 +272,9 @@ class regionSizeDistribution
|
|||||||
void writeGraphs
|
void writeGraphs
|
||||||
(
|
(
|
||||||
const word& fieldName, // name of field
|
const word& fieldName, // name of field
|
||||||
const labelList& indices, // index of bin for each region
|
|
||||||
const scalarField& sortedField, // per region field data
|
const scalarField& sortedField, // per region field data
|
||||||
|
|
||||||
|
const labelList& indices, // index of bin for each region
|
||||||
const scalarField& binCount, // per bin number of regions
|
const scalarField& binCount, // per bin number of regions
|
||||||
const coordSet& coords // graph data for bins
|
const coordSet& coords // graph data for bins
|
||||||
) const;
|
) const;
|
||||||
@ -301,6 +287,7 @@ class regionSizeDistribution
|
|||||||
const regionSplit& regions, // per cell the region(=droplet)
|
const regionSplit& regions, // per cell the region(=droplet)
|
||||||
const labelList& sortedRegions, // valid regions in sorted order
|
const labelList& sortedRegions, // valid regions in sorted order
|
||||||
const scalarField& sortedNormalisation,
|
const scalarField& sortedNormalisation,
|
||||||
|
|
||||||
const labelList& indices, // index of bin for each region
|
const labelList& indices, // index of bin for each region
|
||||||
const scalarField& binCount, // per bin number of regions
|
const scalarField& binCount, // per bin number of regions
|
||||||
const coordSet& coords // graph data for bins
|
const coordSet& coords // graph data for bins
|
||||||
@ -355,12 +342,6 @@ public:
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
#include "regionSizeDistributionTemplates.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2015 OpenFOAM Foundation
|
Copyright (C) 2015 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -29,6 +29,7 @@ License
|
|||||||
#include "streamLineBase.H"
|
#include "streamLineBase.H"
|
||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
#include "ReadFields.H"
|
#include "ReadFields.H"
|
||||||
|
#include "OFstream.H"
|
||||||
#include "sampledSet.H"
|
#include "sampledSet.H"
|
||||||
#include "globalIndex.H"
|
#include "globalIndex.H"
|
||||||
#include "mapDistribute.H"
|
#include "mapDistribute.H"
|
||||||
@ -626,8 +627,7 @@ bool Foam::functionObjects::streamLineBase::writeToFile()
|
|||||||
|
|
||||||
|
|
||||||
// Note: filenames scattered below since used in global call
|
// Note: filenames scattered below since used in global call
|
||||||
fileName scalarVtkFile;
|
HashTable<fileName> outputFileNames;
|
||||||
fileName vectorVtkFile;
|
|
||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
@ -706,117 +706,112 @@ bool Foam::functionObjects::streamLineBase::writeToFile()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert scalar values
|
|
||||||
|
|
||||||
if (!allScalars_.empty() && !tracks.empty())
|
const bool canWrite =
|
||||||
|
(
|
||||||
|
!tracks.empty()
|
||||||
|
&& trackWriterPtr_
|
||||||
|
&& trackWriterPtr_->enabled()
|
||||||
|
&& (!allScalars_.empty() || !allVectors_.empty())
|
||||||
|
);
|
||||||
|
|
||||||
|
if (canWrite)
|
||||||
{
|
{
|
||||||
List<List<scalarField>> scalarValues(allScalars_.size());
|
auto& writer = trackWriterPtr_();
|
||||||
|
|
||||||
forAll(allScalars_, scalari)
|
writer.nFields(allScalars_.size() + allVectors_.size());
|
||||||
|
|
||||||
|
writer.open
|
||||||
|
(
|
||||||
|
tracks,
|
||||||
|
(vtkPath / tracks[0].name())
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Temporary measure
|
||||||
|
if (!allScalars_.empty())
|
||||||
{
|
{
|
||||||
DynamicList<scalarList>& allTrackVals = allScalars_[scalari];
|
List<List<scalarField>> scalarValues(allScalars_.size());
|
||||||
scalarValues[scalari].setSize(nTracks);
|
|
||||||
|
|
||||||
forAll(allTrackVals, tracki)
|
forAll(allScalars_, scalari)
|
||||||
{
|
{
|
||||||
scalarList& vals = allTrackVals[tracki];
|
DynamicList<scalarList>& allTrackVals = allScalars_[scalari];
|
||||||
if (vals.size())
|
scalarValues[scalari].resize(nTracks);
|
||||||
|
|
||||||
|
forAll(allTrackVals, tracki)
|
||||||
{
|
{
|
||||||
const label newTracki = oldToNewTrack[tracki];
|
scalarList& vals = allTrackVals[tracki];
|
||||||
scalarValues[scalari][newTracki].transfer(vals);
|
if (vals.size())
|
||||||
|
{
|
||||||
|
const label newTracki = oldToNewTrack[tracki];
|
||||||
|
scalarValues[scalari][newTracki].transfer(vals);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forAll(scalarNames_, i)
|
||||||
|
{
|
||||||
|
fileName outFile =
|
||||||
|
writer.write(scalarNames_[i], scalarValues[i]);
|
||||||
|
|
||||||
|
outputFileNames.insert
|
||||||
|
(
|
||||||
|
scalarNames_[i],
|
||||||
|
time_.relativePath(outFile, true)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scalarVtkFile = fileName
|
if (!allVectors_.empty())
|
||||||
(
|
|
||||||
vtkPath
|
|
||||||
/ scalarFormatterPtr_().getFileName
|
|
||||||
(
|
|
||||||
tracks[0],
|
|
||||||
scalarNames_
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Log << " Writing data to " << scalarVtkFile.path() << endl;
|
|
||||||
|
|
||||||
scalarFormatterPtr_().write
|
|
||||||
(
|
|
||||||
true, // writeTracks
|
|
||||||
List<scalarField>(), // times
|
|
||||||
tracks,
|
|
||||||
scalarNames_,
|
|
||||||
scalarValues,
|
|
||||||
OFstream(scalarVtkFile)()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert vector values
|
|
||||||
|
|
||||||
if (!allVectors_.empty() && !tracks.empty())
|
|
||||||
{
|
|
||||||
List<List<vectorField>> vectorValues(allVectors_.size());
|
|
||||||
|
|
||||||
forAll(allVectors_, vectori)
|
|
||||||
{
|
{
|
||||||
DynamicList<vectorList>& allTrackVals = allVectors_[vectori];
|
List<List<vectorField>> vectorValues(allVectors_.size());
|
||||||
vectorValues[vectori].setSize(nTracks);
|
|
||||||
|
|
||||||
forAll(allTrackVals, tracki)
|
forAll(allVectors_, vectori)
|
||||||
{
|
{
|
||||||
vectorList& vals = allTrackVals[tracki];
|
DynamicList<vectorList>& allTrackVals = allVectors_[vectori];
|
||||||
if (vals.size())
|
vectorValues[vectori].setSize(nTracks);
|
||||||
|
|
||||||
|
forAll(allTrackVals, tracki)
|
||||||
{
|
{
|
||||||
const label newTracki = oldToNewTrack[tracki];
|
vectorList& vals = allTrackVals[tracki];
|
||||||
vectorValues[vectori][newTracki].transfer(vals);
|
if (vals.size())
|
||||||
|
{
|
||||||
|
const label newTracki = oldToNewTrack[tracki];
|
||||||
|
vectorValues[vectori][newTracki].transfer(vals);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forAll(vectorNames_, i)
|
||||||
|
{
|
||||||
|
fileName outFile =
|
||||||
|
writer.write(vectorNames_[i], vectorValues[i]);
|
||||||
|
|
||||||
|
outputFileNames.insert
|
||||||
|
(
|
||||||
|
scalarNames_[i],
|
||||||
|
time_.relativePath(outFile, true)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vectorVtkFile = fileName
|
writer.close(true);
|
||||||
(
|
|
||||||
vtkPath
|
|
||||||
/ vectorFormatterPtr_().getFileName(tracks[0], vectorNames_)
|
|
||||||
);
|
|
||||||
|
|
||||||
//Info<< " Writing vector data to " << vectorVtkFile << endl;
|
|
||||||
|
|
||||||
vectorFormatterPtr_().write
|
|
||||||
(
|
|
||||||
true, // writeTracks
|
|
||||||
List<scalarField>(), // times
|
|
||||||
tracks,
|
|
||||||
vectorNames_,
|
|
||||||
vectorValues,
|
|
||||||
OFstream(vectorVtkFile)()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log << " Writing data to " << scalarVtkFile.path() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// File names are generated on the master but setProperty needs to
|
// File names generated on the master but setProperty needed everywher
|
||||||
// be across all procs
|
Pstream::scatter(outputFileNames);
|
||||||
Pstream::scatter(scalarVtkFile);
|
|
||||||
for (const word& fieldName : scalarNames_)
|
|
||||||
{
|
|
||||||
dictionary propsDict;
|
|
||||||
propsDict.add
|
|
||||||
(
|
|
||||||
"file",
|
|
||||||
time_.relativePath(scalarVtkFile, true)
|
|
||||||
);
|
|
||||||
setProperty(fieldName, propsDict);
|
|
||||||
}
|
|
||||||
|
|
||||||
Pstream::scatter(vectorVtkFile);
|
forAllConstIters(outputFileNames, iter)
|
||||||
for (const word& fieldName : vectorNames_)
|
|
||||||
{
|
{
|
||||||
|
const word& fieldName = iter.key();
|
||||||
|
const fileName& outputName = iter.val();
|
||||||
|
|
||||||
dictionary propsDict;
|
dictionary propsDict;
|
||||||
propsDict.add
|
propsDict.add("file", outputName);
|
||||||
(
|
|
||||||
"file",
|
|
||||||
time_.relativePath(vectorVtkFile, true)
|
|
||||||
);
|
|
||||||
setProperty(fieldName, propsDict);
|
setProperty(fieldName, propsDict);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -844,7 +839,7 @@ Foam::functionObjects::streamLineBase::streamLineBase
|
|||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
fvMeshFunctionObject(name, runTime, dict),
|
functionObjects::fvMeshFunctionObject(name, runTime, dict),
|
||||||
dict_(dict),
|
dict_(dict),
|
||||||
fields_()
|
fields_()
|
||||||
{}
|
{}
|
||||||
@ -858,7 +853,7 @@ Foam::functionObjects::streamLineBase::streamLineBase
|
|||||||
const wordList& fieldNames
|
const wordList& fieldNames
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
fvMeshFunctionObject(name, runTime, dict),
|
functionObjects::fvMeshFunctionObject(name, runTime, dict),
|
||||||
dict_(dict),
|
dict_(dict),
|
||||||
fields_(fieldNames)
|
fields_(fieldNames)
|
||||||
{}
|
{}
|
||||||
@ -959,8 +954,13 @@ bool Foam::functionObjects::streamLineBase::read(const dictionary& dict)
|
|||||||
sampledSetPtr_.clear();
|
sampledSetPtr_.clear();
|
||||||
sampledSetAxis_.clear();
|
sampledSetAxis_.clear();
|
||||||
|
|
||||||
scalarFormatterPtr_ = writer<scalar>::New(dict.get<word>("setFormat"));
|
const word setFormat(dict.get<word>("setFormat"));
|
||||||
vectorFormatterPtr_ = writer<vector>::New(dict.get<word>("setFormat"));
|
|
||||||
|
trackWriterPtr_ = coordSetWriter::New
|
||||||
|
(
|
||||||
|
setFormat,
|
||||||
|
dict.subOrEmptyDict("formatOptions").optionalSubDict(setFormat)
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2015 OpenFOAM Foundation
|
Copyright (C) 2015 OpenFOAM Foundation
|
||||||
Copyright (C) 2016 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -36,14 +36,14 @@ SourceFiles
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef streamLineBase_H
|
#ifndef Foam_functionObjects_streamLineBase_H
|
||||||
#define streamLineBase_H
|
#define Foam_functionObjects_streamLineBase_H
|
||||||
|
|
||||||
#include "fvMeshFunctionObject.H"
|
#include "fvMeshFunctionObject.H"
|
||||||
#include "DynamicList.H"
|
#include "DynamicList.H"
|
||||||
#include "scalarList.H"
|
#include "scalarList.H"
|
||||||
#include "vectorList.H"
|
#include "vectorList.H"
|
||||||
#include "writer.H"
|
#include "coordSetWriter.H"
|
||||||
#include "indirectPrimitivePatch.H"
|
#include "indirectPrimitivePatch.H"
|
||||||
#include "interpolation.H"
|
#include "interpolation.H"
|
||||||
#include "Enum.H"
|
#include "Enum.H"
|
||||||
@ -53,6 +53,7 @@ SourceFiles
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
class meshSearch;
|
class meshSearch;
|
||||||
class sampledSet;
|
class sampledSet;
|
||||||
|
|
||||||
@ -65,7 +66,7 @@ namespace functionObjects
|
|||||||
|
|
||||||
class streamLineBase
|
class streamLineBase
|
||||||
:
|
:
|
||||||
public fvMeshFunctionObject
|
public functionObjects::fvMeshFunctionObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -128,16 +129,13 @@ protected:
|
|||||||
wordList vectorNames_;
|
wordList vectorNames_;
|
||||||
|
|
||||||
|
|
||||||
// Demand driven
|
// Demand driven
|
||||||
|
|
||||||
//- File writer for scalar data
|
//- File writer for tracks data
|
||||||
autoPtr<writer<scalar>> scalarFormatterPtr_;
|
mutable autoPtr<coordSetWriter> trackWriterPtr_;
|
||||||
|
|
||||||
//- File writer for vector data
|
|
||||||
autoPtr<writer<vector>> vectorFormatterPtr_;
|
|
||||||
|
|
||||||
|
|
||||||
// Generated data
|
// Generated Data
|
||||||
|
|
||||||
//- All tracks. Per track the points it passed through
|
//- All tracks. Per track the points it passed through
|
||||||
DynamicList<List<point>> allTracks_;
|
DynamicList<List<point>> allTracks_;
|
||||||
|
|||||||
@ -2808,23 +2808,19 @@ Foam::fileName Foam::meshRefinement::writeLeakPath
|
|||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const writer<scalar>& leakPathFormatter,
|
const boolList& blockedFace,
|
||||||
const boolList& blockedFace
|
coordSetWriter& writer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
|
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
|
||||||
|
|
||||||
fileName outputDir;
|
fileName outputDir
|
||||||
if (Pstream::master())
|
(
|
||||||
{
|
mesh.time().globalPath()
|
||||||
outputDir =
|
/ functionObject::outputPrefix
|
||||||
mesh.time().globalPath()
|
/ mesh.pointsInstance()
|
||||||
/ functionObject::outputPrefix
|
);
|
||||||
/ mesh.pointsInstance();
|
outputDir.clean(); // Remove unneeded ".."
|
||||||
outputDir.clean();
|
|
||||||
mkDir(outputDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Write the leak path
|
// Write the leak path
|
||||||
|
|
||||||
@ -2877,7 +2873,7 @@ Foam::fileName Foam::meshRefinement::writeLeakPath
|
|||||||
label& n = nElemsPerSegment[segmenti];
|
label& n = nElemsPerSegment[segmenti];
|
||||||
|
|
||||||
points[n] = leakPath[elemi];
|
points[n] = leakPath[elemi];
|
||||||
dist[n] = leakPath.curveDist()[elemi];
|
dist[n] = leakPath.distance()[elemi];
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2887,13 +2883,11 @@ Foam::fileName Foam::meshRefinement::writeLeakPath
|
|||||||
{
|
{
|
||||||
// Collect data from all processors
|
// Collect data from all processors
|
||||||
List<pointList> gatheredPts(Pstream::nProcs());
|
List<pointList> gatheredPts(Pstream::nProcs());
|
||||||
gatheredPts[Pstream::myProcNo()] =
|
gatheredPts[Pstream::myProcNo()] = std::move(segmentPoints[segmenti]);
|
||||||
std::move(segmentPoints[segmenti]);
|
|
||||||
Pstream::gatherList(gatheredPts);
|
Pstream::gatherList(gatheredPts);
|
||||||
|
|
||||||
List<scalarList> gatheredDist(Pstream::nProcs());
|
List<scalarList> gatheredDist(Pstream::nProcs());
|
||||||
gatheredDist[Pstream::myProcNo()] =
|
gatheredDist[Pstream::myProcNo()] = std::move(segmentDist[segmenti]);
|
||||||
std::move(segmentDist[segmenti]);
|
|
||||||
Pstream::gatherList(gatheredDist);
|
Pstream::gatherList(gatheredDist);
|
||||||
|
|
||||||
// Combine processor lists into one big list.
|
// Combine processor lists into one big list.
|
||||||
@ -2912,7 +2906,7 @@ Foam::fileName Foam::meshRefinement::writeLeakPath
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Sort according to curveDist
|
// Sort according to distance
|
||||||
labelList indexSet(Foam::sortedOrder(allDist));
|
labelList indexSet(Foam::sortedOrder(allDist));
|
||||||
|
|
||||||
allLeakPaths.set
|
allLeakPaths.set
|
||||||
@ -2932,42 +2926,28 @@ Foam::fileName Foam::meshRefinement::writeLeakPath
|
|||||||
fileName fName;
|
fileName fName;
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
List<List<scalarField>> allLeakData(1);
|
List<scalarField> allLeakData(allLeakPaths.size());
|
||||||
List<scalarField>& varData = allLeakData[0];
|
|
||||||
varData.setSize(allLeakPaths.size());
|
|
||||||
forAll(allLeakPaths, segmenti)
|
forAll(allLeakPaths, segmenti)
|
||||||
{
|
{
|
||||||
varData[segmenti] = allLeakPaths[segmenti].curveDist();
|
allLeakData[segmenti] = allLeakPaths[segmenti].distance();
|
||||||
}
|
}
|
||||||
|
|
||||||
const wordList valueSetNames(1, "leakPath");
|
writer.nFields(1);
|
||||||
|
|
||||||
fName =
|
writer.open
|
||||||
outputDir
|
(
|
||||||
/leakPathFormatter.getFileName
|
allLeakPaths,
|
||||||
(
|
(outputDir / allLeakPaths[0].name())
|
||||||
allLeakPaths[0],
|
);
|
||||||
valueSetNames
|
|
||||||
);
|
|
||||||
|
|
||||||
// Note scope to force writing to finish before
|
fName = writer.write("leakPath", allLeakData);
|
||||||
// FatalError exit
|
|
||||||
OFstream ofs(fName);
|
// Force writing to finish before FatalError exit
|
||||||
if (ofs.opened())
|
writer.close(true);
|
||||||
{
|
|
||||||
leakPathFormatter.write
|
|
||||||
(
|
|
||||||
true, // write tracks
|
|
||||||
List<scalarField>(), // times
|
|
||||||
allLeakPaths,
|
|
||||||
valueSetNames,
|
|
||||||
allLeakData,
|
|
||||||
ofs
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pstream::scatter(fName);
|
// Probably do not need to broadcast name (only written on master anyhow)
|
||||||
|
UPstream::broadcast(fName);
|
||||||
|
|
||||||
return fName;
|
return fName;
|
||||||
}
|
}
|
||||||
@ -2982,11 +2962,12 @@ Foam::label Foam::meshRefinement::findRegions
|
|||||||
const vector& perturbVec,
|
const vector& perturbVec,
|
||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const bool exitIfLeakPath,
|
|
||||||
const refPtr<writer<scalar>>& leakPathFormatter,
|
|
||||||
const label nRegions,
|
const label nRegions,
|
||||||
labelList& cellRegion,
|
labelList& cellRegion,
|
||||||
const boolList& blockedFace
|
const boolList& blockedFace,
|
||||||
|
// Leak-path
|
||||||
|
const bool exitIfLeakPath,
|
||||||
|
const refPtr<coordSetWriter>& leakPathFormatter
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
bitSet insideCell(mesh.nCells());
|
bitSet insideCell(mesh.nCells());
|
||||||
@ -3022,7 +3003,10 @@ Foam::label Foam::meshRefinement::findRegions
|
|||||||
// mesh do not conflict with those inside
|
// mesh do not conflict with those inside
|
||||||
forAll(locationsOutsideMesh, i)
|
forAll(locationsOutsideMesh, i)
|
||||||
{
|
{
|
||||||
// Find the region containing the point
|
// Find the region containing the point,
|
||||||
|
// and the corresponding inside region index
|
||||||
|
|
||||||
|
label indexi;
|
||||||
label regioni = findRegion
|
label regioni = findRegion
|
||||||
(
|
(
|
||||||
mesh,
|
mesh,
|
||||||
@ -3031,46 +3015,39 @@ Foam::label Foam::meshRefinement::findRegions
|
|||||||
locationsOutsideMesh[i]
|
locationsOutsideMesh[i]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (regioni != -1)
|
if (regioni == -1 && (indexi = insideRegions.find(regioni)) != -1)
|
||||||
{
|
{
|
||||||
// Do a quick check for locationsOutsideMesh overlapping with
|
if (leakPathFormatter)
|
||||||
// inside ones.
|
|
||||||
label index = insideRegions.find(regioni);
|
|
||||||
if (index != -1)
|
|
||||||
{
|
{
|
||||||
if (leakPathFormatter.valid())
|
const fileName fName
|
||||||
{
|
(
|
||||||
const fileName fName
|
writeLeakPath
|
||||||
(
|
(
|
||||||
writeLeakPath
|
mesh,
|
||||||
(
|
locationsInMesh,
|
||||||
mesh,
|
locationsOutsideMesh,
|
||||||
locationsInMesh,
|
blockedFace,
|
||||||
locationsOutsideMesh,
|
leakPathFormatter.constCast()
|
||||||
leakPathFormatter,
|
)
|
||||||
blockedFace
|
);
|
||||||
)
|
Info<< "Dumped leak path to " << fName << endl;
|
||||||
);
|
}
|
||||||
Info<< "Dumped leak path to " << fName << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exitIfLeakPath)
|
auto& err =
|
||||||
{
|
(
|
||||||
FatalErrorInFunction
|
exitIfLeakPath
|
||||||
<< "Location in mesh " << locationsInMesh[index]
|
? FatalErrorInFunction
|
||||||
<< " is inside same mesh region " << regioni
|
: WarningInFunction
|
||||||
<< " as one of the locations outside mesh "
|
);
|
||||||
<< locationsOutsideMesh
|
|
||||||
<< exit(FatalError);
|
err << "Location in mesh " << locationsInMesh[indexi]
|
||||||
}
|
<< " is inside same mesh region " << regioni
|
||||||
else
|
<< " as one of the locations outside mesh "
|
||||||
{
|
<< locationsOutsideMesh << endl;
|
||||||
WarningInFunction
|
|
||||||
<< "Location in mesh " << locationsInMesh[index]
|
if (exitIfLeakPath)
|
||||||
<< " is inside same mesh region " << regioni
|
{
|
||||||
<< " as one of the locations outside mesh "
|
FatalError << exit(FatalError);
|
||||||
<< locationsOutsideMesh << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3103,7 +3080,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::splitMeshRegions
|
|||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const bool exitIfLeakPath,
|
const bool exitIfLeakPath,
|
||||||
const refPtr<writer<scalar>>& leakPathFormatter
|
const refPtr<coordSetWriter>& leakPathFormatter
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Force calculation of face decomposition (used in findCell)
|
// Force calculation of face decomposition (used in findCell)
|
||||||
@ -3120,14 +3097,15 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::splitMeshRegions
|
|||||||
label nRemove = findRegions
|
label nRemove = findRegions
|
||||||
(
|
(
|
||||||
mesh_,
|
mesh_,
|
||||||
mergeDistance_ * vector::one, // perturbVec
|
vector::uniform(mergeDistance_), // perturbVec
|
||||||
locationsInMesh,
|
locationsInMesh,
|
||||||
locationsOutsideMesh,
|
locationsOutsideMesh,
|
||||||
exitIfLeakPath,
|
|
||||||
leakPathFormatter,
|
|
||||||
cellRegion.nRegions(),
|
cellRegion.nRegions(),
|
||||||
cellRegion,
|
cellRegion,
|
||||||
blockedFace
|
blockedFace,
|
||||||
|
// Leak-path
|
||||||
|
exitIfLeakPath,
|
||||||
|
leakPathFormatter
|
||||||
);
|
);
|
||||||
|
|
||||||
// Subset
|
// Subset
|
||||||
|
|||||||
@ -60,7 +60,7 @@ SourceFiles
|
|||||||
#include "surfaceZonesInfo.H"
|
#include "surfaceZonesInfo.H"
|
||||||
#include "volumeType.H"
|
#include "volumeType.H"
|
||||||
#include "DynamicField.H"
|
#include "DynamicField.H"
|
||||||
#include "writer.H"
|
#include "coordSetWriter.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -587,7 +587,7 @@ private:
|
|||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const wordList& regionsInMesh,
|
const wordList& regionsInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const refPtr<writer<scalar>>& leakPathFormatter,
|
const refPtr<coordSetWriter>& leakPathFormatter,
|
||||||
|
|
||||||
const labelList& neiLevel,
|
const labelList& neiLevel,
|
||||||
const pointField& neiCc,
|
const pointField& neiCc,
|
||||||
@ -622,8 +622,8 @@ private:
|
|||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const writer<scalar>& leakPathFormatter,
|
const boolList& blockedFace,
|
||||||
const boolList& blockedFace
|
coordSetWriter& leakPathWriter
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -846,7 +846,7 @@ private:
|
|||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const wordList& zonesInMesh,
|
const wordList& zonesInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const refPtr<writer<scalar>>& leakPathFormatter,
|
const refPtr<coordSetWriter>& leakPathFormatter,
|
||||||
|
|
||||||
labelList& cellToZone,
|
labelList& cellToZone,
|
||||||
labelList& unnamedRegion1,
|
labelList& unnamedRegion1,
|
||||||
@ -1303,7 +1303,7 @@ public:
|
|||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const wordList& regionsInMesh,
|
const wordList& regionsInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const refPtr<writer<scalar>>& leakPathFormatter
|
const refPtr<coordSetWriter>& leakPathFormatter
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Merge free-standing baffles
|
//- Merge free-standing baffles
|
||||||
@ -1334,7 +1334,7 @@ public:
|
|||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const wordList& regionsInMesh,
|
const wordList& regionsInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const writer<scalar>& leakPathFormatter
|
const refPtr<coordSetWriter>& leakPathFormatter
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Remove cells from limitRegions if level -1
|
//- Remove cells from limitRegions if level -1
|
||||||
@ -1436,7 +1436,7 @@ public:
|
|||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const wordList& regionsInMesh,
|
const wordList& regionsInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const refPtr<writer<scalar>>& leakPathFormatter,
|
const refPtr<coordSetWriter>& leakPathFormatter,
|
||||||
wordPairHashTable& zonesToFaceZone
|
wordPairHashTable& zonesToFaceZone
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1543,11 +1543,12 @@ public:
|
|||||||
const vector& perturbVec,
|
const vector& perturbVec,
|
||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const bool exitIfLeakPath,
|
|
||||||
const refPtr<writer<scalar>>& leakPathFormatter,
|
|
||||||
const label nRegions,
|
const label nRegions,
|
||||||
labelList& cellRegion,
|
labelList& cellRegion,
|
||||||
const boolList& blockedFace
|
const boolList& blockedFace,
|
||||||
|
// Leak-path
|
||||||
|
const bool exitIfLeakPath,
|
||||||
|
const refPtr<coordSetWriter>& leakPathFormatter
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Split mesh. Keep part containing point. Return empty map if
|
//- Split mesh. Keep part containing point. Return empty map if
|
||||||
@ -1558,8 +1559,9 @@ public:
|
|||||||
const labelList& globalToSlavePatch,
|
const labelList& globalToSlavePatch,
|
||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
|
// Leak-path
|
||||||
const bool exitIfLeakPath,
|
const bool exitIfLeakPath,
|
||||||
const refPtr<writer<scalar>>& leakPathFormatter
|
const refPtr<coordSetWriter>& leakPathFormatter
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Split faces into two
|
//- Split faces into two
|
||||||
|
|||||||
@ -292,7 +292,7 @@ void Foam::meshRefinement::getBafflePatches
|
|||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const wordList& zonesInMesh,
|
const wordList& zonesInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const refPtr<writer<scalar>>& leakPathFormatter,
|
const refPtr<coordSetWriter>& leakPathFormatter,
|
||||||
const labelList& neiLevel,
|
const labelList& neiLevel,
|
||||||
const pointField& neiCc,
|
const pointField& neiCc,
|
||||||
|
|
||||||
@ -1688,7 +1688,7 @@ void Foam::meshRefinement::findCellZoneInsideWalk
|
|||||||
(
|
(
|
||||||
mesh_,
|
mesh_,
|
||||||
cellRegion,
|
cellRegion,
|
||||||
mergeDistance_ * vector::one,
|
vector::uniform(mergeDistance_),
|
||||||
insidePoint
|
insidePoint
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1959,7 +1959,7 @@ void Foam::meshRefinement::findCellZoneTopo
|
|||||||
(
|
(
|
||||||
mesh_,
|
mesh_,
|
||||||
cellRegion,
|
cellRegion,
|
||||||
mergeDistance_ * vector::one,
|
vector::uniform(mergeDistance_),
|
||||||
keepPoint
|
keepPoint
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -2843,7 +2843,7 @@ void Foam::meshRefinement::zonify
|
|||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const wordList& zonesInMesh,
|
const wordList& zonesInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const refPtr<writer<scalar>>& leakPathFormatter,
|
const refPtr<coordSetWriter>& leakPathFormatter,
|
||||||
|
|
||||||
labelList& cellToZone,
|
labelList& cellToZone,
|
||||||
labelList& unnamedRegion1,
|
labelList& unnamedRegion1,
|
||||||
@ -2961,7 +2961,7 @@ void Foam::meshRefinement::zonify
|
|||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
// Dump leak path
|
// Dump leak path
|
||||||
if (leakPathFormatter.valid())
|
if (leakPathFormatter)
|
||||||
{
|
{
|
||||||
boolList blockedFace(mesh_.nFaces(), false);
|
boolList blockedFace(mesh_.nFaces(), false);
|
||||||
UIndirectList<bool>(blockedFace, unnamedFaces) = true;
|
UIndirectList<bool>(blockedFace, unnamedFaces) = true;
|
||||||
@ -2972,8 +2972,8 @@ void Foam::meshRefinement::zonify
|
|||||||
mesh_,
|
mesh_,
|
||||||
locationsInMesh,
|
locationsInMesh,
|
||||||
locationsOutsideMesh,
|
locationsOutsideMesh,
|
||||||
leakPathFormatter(),
|
blockedFace,
|
||||||
blockedFace
|
leakPathFormatter.constCast()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
Info<< "Dumped leak path to " << fName << endl;
|
Info<< "Dumped leak path to " << fName << endl;
|
||||||
@ -3065,7 +3065,7 @@ void Foam::meshRefinement::zonify
|
|||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
// Dump leak path
|
// Dump leak path
|
||||||
if (leakPathFormatter.valid())
|
if (leakPathFormatter)
|
||||||
{
|
{
|
||||||
boolList blockedFace(mesh_.nFaces(), false);
|
boolList blockedFace(mesh_.nFaces(), false);
|
||||||
UIndirectList<bool>(blockedFace, unnamedFaces) = true;
|
UIndirectList<bool>(blockedFace, unnamedFaces) = true;
|
||||||
@ -3077,8 +3077,8 @@ void Foam::meshRefinement::zonify
|
|||||||
mesh_,
|
mesh_,
|
||||||
locationsInMesh,
|
locationsInMesh,
|
||||||
locationsOutsideMesh,
|
locationsOutsideMesh,
|
||||||
leakPathFormatter(),
|
blockedFace,
|
||||||
blockedFace
|
leakPathFormatter.constCast()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
Info<< "Dumped leak path to " << fName << endl;
|
Info<< "Dumped leak path to " << fName << endl;
|
||||||
@ -4509,7 +4509,7 @@ void Foam::meshRefinement::baffleAndSplitMesh
|
|||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const wordList& zonesInMesh,
|
const wordList& zonesInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const refPtr<writer<scalar>>& leakPathFormatter
|
const refPtr<coordSetWriter>& leakPathFormatter
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Introduce baffles
|
// Introduce baffles
|
||||||
@ -4536,7 +4536,7 @@ void Foam::meshRefinement::baffleAndSplitMesh
|
|||||||
locationsInMesh,
|
locationsInMesh,
|
||||||
zonesInMesh,
|
zonesInMesh,
|
||||||
locationsOutsideMesh,
|
locationsOutsideMesh,
|
||||||
refPtr<writer<scalar>>(nullptr),
|
refPtr<coordSetWriter>(nullptr),
|
||||||
|
|
||||||
neiLevel,
|
neiLevel,
|
||||||
neiCc,
|
neiCc,
|
||||||
@ -4610,7 +4610,7 @@ void Foam::meshRefinement::baffleAndSplitMesh
|
|||||||
locationsInMesh,
|
locationsInMesh,
|
||||||
zonesInMesh,
|
zonesInMesh,
|
||||||
locationsOutsideMesh,
|
locationsOutsideMesh,
|
||||||
refPtr<writer<scalar>>(nullptr),
|
refPtr<coordSetWriter>(nullptr),
|
||||||
|
|
||||||
neiLevel,
|
neiLevel,
|
||||||
neiCc,
|
neiCc,
|
||||||
@ -4760,7 +4760,7 @@ void Foam::meshRefinement::mergeFreeStandingBaffles
|
|||||||
locationsInMesh,
|
locationsInMesh,
|
||||||
locationsOutsideMesh,
|
locationsOutsideMesh,
|
||||||
true, // Exit if any connection between inside and outside
|
true, // Exit if any connection between inside and outside
|
||||||
refPtr<writer<scalar>>(nullptr) //leakPathFormatter
|
refPtr<coordSetWriter>(nullptr) // leakPathFormatter
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -4785,7 +4785,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::splitMesh
|
|||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const wordList& zonesInMesh,
|
const wordList& zonesInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const writer<scalar>& leakPathFormatter
|
const refPtr<coordSetWriter>& leakPathFormatter
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Determine patches to put intersections into
|
// Determine patches to put intersections into
|
||||||
@ -4834,14 +4834,15 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::splitMesh
|
|||||||
findRegions
|
findRegions
|
||||||
(
|
(
|
||||||
mesh_,
|
mesh_,
|
||||||
mergeDistance_ * vector::one, // perturbVec
|
vector::uniform(mergeDistance_), // perturbVec
|
||||||
locationsInMesh,
|
locationsInMesh,
|
||||||
locationsOutsideMesh,
|
locationsOutsideMesh,
|
||||||
false, // do not exit if outside location found
|
|
||||||
leakPathFormatter,
|
|
||||||
cellRegion.nRegions(),
|
cellRegion.nRegions(),
|
||||||
cellRegion,
|
cellRegion,
|
||||||
blockedFace
|
blockedFace,
|
||||||
|
// Leak-path
|
||||||
|
false, // do not exit if outside location found
|
||||||
|
leakPathFormatter
|
||||||
);
|
);
|
||||||
|
|
||||||
return splitMesh
|
return splitMesh
|
||||||
@ -5272,7 +5273,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::removeLimitShells
|
|||||||
locationsInMesh,
|
locationsInMesh,
|
||||||
zonesInMesh,
|
zonesInMesh,
|
||||||
locationsOutsideMesh,
|
locationsOutsideMesh,
|
||||||
refPtr<writer<scalar>>(nullptr),
|
refPtr<coordSetWriter>(nullptr),
|
||||||
|
|
||||||
neiLevel,
|
neiLevel,
|
||||||
neiCc,
|
neiCc,
|
||||||
@ -5574,7 +5575,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
|
|||||||
const pointField& locationsInMesh,
|
const pointField& locationsInMesh,
|
||||||
const wordList& zonesInMesh,
|
const wordList& zonesInMesh,
|
||||||
const pointField& locationsOutsideMesh,
|
const pointField& locationsOutsideMesh,
|
||||||
const refPtr<writer<scalar>>& leakPathFormatter,
|
const refPtr<coordSetWriter>& leakPathFormatter,
|
||||||
wordPairHashTable& zonesToFaceZone
|
wordPairHashTable& zonesToFaceZone
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -67,7 +67,7 @@ Foam::snappyRefineDriver::snappyRefineDriver
|
|||||||
fvMeshDistribute& distributor,
|
fvMeshDistribute& distributor,
|
||||||
const labelUList& globalToMasterPatch,
|
const labelUList& globalToMasterPatch,
|
||||||
const labelUList& globalToSlavePatch,
|
const labelUList& globalToSlavePatch,
|
||||||
const writer<scalar>& setFormatter,
|
coordSetWriter& setFormatter,
|
||||||
const bool dryRun
|
const bool dryRun
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
|
|||||||
@ -41,7 +41,7 @@ SourceFiles
|
|||||||
#include "labelList.H"
|
#include "labelList.H"
|
||||||
#include "scalarField.H"
|
#include "scalarField.H"
|
||||||
#include "Tuple2.H"
|
#include "Tuple2.H"
|
||||||
#include "writer.H"
|
#include "coordSetWriter.H"
|
||||||
#include "DynamicList.H"
|
#include "DynamicList.H"
|
||||||
#include "labelVector.H"
|
#include "labelVector.H"
|
||||||
#include "meshRefinement.H"
|
#include "meshRefinement.H"
|
||||||
@ -83,7 +83,7 @@ class snappyRefineDriver
|
|||||||
const labelList globalToSlavePatch_;
|
const labelList globalToSlavePatch_;
|
||||||
|
|
||||||
//- How to write lines. Used e.g. when writing leak-paths
|
//- How to write lines. Used e.g. when writing leak-paths
|
||||||
const writer<scalar>& setFormatter_;
|
coordSetWriter& setFormatter_;
|
||||||
|
|
||||||
//- Are we operating in test mode?
|
//- Are we operating in test mode?
|
||||||
const bool dryRun_;
|
const bool dryRun_;
|
||||||
@ -275,7 +275,7 @@ public:
|
|||||||
fvMeshDistribute& distributor,
|
fvMeshDistribute& distributor,
|
||||||
const labelUList& globalToMasterPatch,
|
const labelUList& globalToMasterPatch,
|
||||||
const labelUList& globalToSlavePatch,
|
const labelUList& globalToSlavePatch,
|
||||||
const writer<scalar>& setFormatter,
|
coordSetWriter& setFormatter,
|
||||||
const bool dryRun = false
|
const bool dryRun = false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -136,16 +136,19 @@ coordSet/coordSet.C
|
|||||||
|
|
||||||
setWriters = coordSet/writers
|
setWriters = coordSet/writers
|
||||||
|
|
||||||
$(setWriters)/common/writers.C
|
$(setWriters)/common/coordSetWriter.C
|
||||||
$(setWriters)/csv/csvSetWriterRunTime.C
|
$(setWriters)/common/coordSetWriterBuffers.C
|
||||||
$(setWriters)/ensight/ensightSetWriterRunTime.C
|
$(setWriters)/common/coordSetWriterNew.C
|
||||||
$(setWriters)/gltf/gltfSetWriterRunTime.C
|
$(setWriters)/csv/csvCoordSetWriter.C
|
||||||
$(setWriters)/gnuplot/gnuplotSetWriterRunTime.C
|
$(setWriters)/ensight/ensightCoordSetWriter.C
|
||||||
$(setWriters)/nastran/nastranSetWriterRunTime.C
|
$(setWriters)/gltf/gltfCoordSetWriter.C
|
||||||
$(setWriters)/raw/rawSetWriterRunTime.C
|
$(setWriters)/gnuplot/gnuplotCoordSetWriter.C
|
||||||
|
$(setWriters)/nastran/nastranCoordSetWriter.C
|
||||||
|
$(setWriters)/null/nullCoordSetWriter.C
|
||||||
|
$(setWriters)/raw/rawCoordSetWriter.C
|
||||||
$(setWriters)/vtk/foamVtkCoordSetWriter.C
|
$(setWriters)/vtk/foamVtkCoordSetWriter.C
|
||||||
$(setWriters)/vtk/vtkSetWriterRunTime.C
|
$(setWriters)/vtk/vtkCoordSetWriter.C
|
||||||
$(setWriters)/xmgrace/xmgraceSetWriterRunTime.C
|
$(setWriters)/xmgrace/xmgraceCoordSetWriter.C
|
||||||
|
|
||||||
graph/curve.C
|
graph/curve.C
|
||||||
graph/graph.C
|
graph/graph.C
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2018 OpenCFD Ltd.
|
Copyright (C) 2017-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -27,6 +27,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "coordSet.H"
|
#include "coordSet.H"
|
||||||
|
#include "globalIndex.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -36,11 +37,13 @@ const Foam::Enum
|
|||||||
>
|
>
|
||||||
Foam::coordSet::coordFormatNames
|
Foam::coordSet::coordFormatNames
|
||||||
({
|
({
|
||||||
{ coordFormat::XYZ, "xyz" },
|
|
||||||
{ coordFormat::X, "x" },
|
{ coordFormat::X, "x" },
|
||||||
{ coordFormat::Y, "y" },
|
{ coordFormat::Y, "y" },
|
||||||
{ coordFormat::Z, "z" },
|
{ coordFormat::Z, "z" },
|
||||||
|
{ coordFormat::RADIUS, "radius" },
|
||||||
{ coordFormat::DISTANCE, "distance" },
|
{ coordFormat::DISTANCE, "distance" },
|
||||||
|
{ coordFormat::XYZ, "xyz" },
|
||||||
|
/// { coordFormat::DEFAULT, "default" },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -48,12 +51,12 @@ Foam::coordSet::coordFormatNames
|
|||||||
|
|
||||||
void Foam::coordSet::checkDimensions() const
|
void Foam::coordSet::checkDimensions() const
|
||||||
{
|
{
|
||||||
if (size() != curveDist_.size())
|
if (points().size() != distance().size())
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Size of points and curve distance must be the same" << nl
|
<< "Size not equal :" << nl
|
||||||
<< " points size : " << size()
|
<< " points:" << points().size()
|
||||||
<< " curve size : " << curveDist_.size()
|
<< " distance:" << distance().size()
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,6 +64,15 @@ void Foam::coordSet::checkDimensions() const
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Foam::coordSet::coordSet()
|
||||||
|
// :
|
||||||
|
// pointField(),
|
||||||
|
// name_(),
|
||||||
|
// distance_(),
|
||||||
|
// axis_(coordFormat::DEFAULT)
|
||||||
|
// {}
|
||||||
|
|
||||||
|
|
||||||
Foam::coordSet::coordSet
|
Foam::coordSet::coordSet
|
||||||
(
|
(
|
||||||
const word& name,
|
const word& name,
|
||||||
@ -69,8 +81,8 @@ Foam::coordSet::coordSet
|
|||||||
:
|
:
|
||||||
pointField(),
|
pointField(),
|
||||||
name_(name),
|
name_(name),
|
||||||
axis_(axisType),
|
distance_(),
|
||||||
curveDist_()
|
axis_(axisType)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -80,10 +92,7 @@ Foam::coordSet::coordSet
|
|||||||
const word& axis
|
const word& axis
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
pointField(),
|
coordSet(name, coordFormatNames.get(axis))
|
||||||
name_(name),
|
|
||||||
axis_(coordFormatNames[axis]),
|
|
||||||
curveDist_()
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -92,13 +101,13 @@ Foam::coordSet::coordSet
|
|||||||
const word& name,
|
const word& name,
|
||||||
const word& axis,
|
const word& axis,
|
||||||
const List<point>& points,
|
const List<point>& points,
|
||||||
const scalarList& curveDist
|
const scalarList& dist
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
pointField(points),
|
pointField(points),
|
||||||
name_(name),
|
name_(name),
|
||||||
axis_(coordFormatNames[axis]),
|
distance_(dist),
|
||||||
curveDist_(curveDist)
|
axis_(coordFormatNames[axis])
|
||||||
{
|
{
|
||||||
checkDimensions();
|
checkDimensions();
|
||||||
}
|
}
|
||||||
@ -109,13 +118,13 @@ Foam::coordSet::coordSet
|
|||||||
const word& name,
|
const word& name,
|
||||||
const word& axis,
|
const word& axis,
|
||||||
List<point>&& points,
|
List<point>&& points,
|
||||||
scalarList&& curveDist
|
scalarList&& dist
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
pointField(std::move(points)),
|
pointField(std::move(points)),
|
||||||
name_(name),
|
name_(name),
|
||||||
axis_(coordFormatNames[axis]),
|
distance_(std::move(dist)),
|
||||||
curveDist_(std::move(curveDist))
|
axis_(coordFormatNames.get(axis))
|
||||||
{
|
{
|
||||||
checkDimensions();
|
checkDimensions();
|
||||||
}
|
}
|
||||||
@ -123,7 +132,7 @@ Foam::coordSet::coordSet
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
bool Foam::coordSet::hasVectorAxis() const
|
bool Foam::coordSet::hasVectorAxis() const noexcept
|
||||||
{
|
{
|
||||||
return axis_ == coordFormat::XYZ;
|
return axis_ == coordFormat::XYZ;
|
||||||
}
|
}
|
||||||
@ -131,72 +140,105 @@ bool Foam::coordSet::hasVectorAxis() const
|
|||||||
|
|
||||||
Foam::scalar Foam::coordSet::scalarCoord(const label index) const
|
Foam::scalar Foam::coordSet::scalarCoord(const label index) const
|
||||||
{
|
{
|
||||||
const point& p = operator[](index);
|
|
||||||
|
|
||||||
switch (axis_)
|
switch (axis_)
|
||||||
{
|
{
|
||||||
case coordFormat::X:
|
case coordFormat::X:
|
||||||
{
|
{
|
||||||
return p.x();
|
return points()[index].x();
|
||||||
}
|
}
|
||||||
case coordFormat::Y:
|
case coordFormat::Y:
|
||||||
{
|
{
|
||||||
return p.y();
|
return points()[index].y();
|
||||||
}
|
}
|
||||||
case coordFormat::Z:
|
case coordFormat::Z:
|
||||||
{
|
{
|
||||||
return p.z();
|
return points()[index].z();
|
||||||
|
}
|
||||||
|
case coordFormat::RADIUS:
|
||||||
|
{
|
||||||
|
return mag(points()[index]);
|
||||||
}
|
}
|
||||||
case coordFormat::DISTANCE:
|
case coordFormat::DISTANCE:
|
||||||
{
|
{
|
||||||
// Note: If this has been constructed from the 'name' and 'axis'
|
// Note: the distance will unset it constructed from
|
||||||
// constructor the curveDist list will not have been set
|
// 'name' and 'axis' only
|
||||||
|
|
||||||
if (curveDist_.empty())
|
if (distance().empty())
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Axis type '" << coordFormatNames[axis_]
|
<< "Axis type '" << coordFormatNames[axis_]
|
||||||
<< "' requested but curve distance has not been set"
|
<< "' requested but curve distance has not been set"
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
return distance()[index];
|
||||||
return curveDist_[index];
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Illegal axis specification '" << coordFormatNames[axis_]
|
<< "Illegal axis specification '" << coordFormatNames[axis_]
|
||||||
<< "' for sampling line " << name_
|
<< "' for sampling " << name_
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::point Foam::coordSet::vectorCoord(const label index) const
|
const Foam::point& Foam::coordSet::vectorCoord(const label index) const
|
||||||
{
|
{
|
||||||
const point& p = operator[](index);
|
return points()[index];
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::coordSet::write(Ostream& os) const
|
Foam::Ostream& Foam::coordSet::write(Ostream& os) const
|
||||||
{
|
{
|
||||||
os << "name:" << name_ << " axis:" << coordFormatNames[axis_]
|
os << "name:" << name_ << " axis:" << coordFormatNames[axis_] << nl
|
||||||
<< nl
|
<< nl
|
||||||
<< nl << "\t(coord)"
|
<< "\t(coord)" << nl;
|
||||||
<< endl;
|
|
||||||
|
|
||||||
for (const point& pt : *this)
|
for (const point& p : *this)
|
||||||
{
|
{
|
||||||
os << '\t' << pt << endl;
|
os << '\t' << p << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::coordSet> Foam::coordSet::gatherSort
|
||||||
|
(
|
||||||
|
labelList& sortOrder
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Combine sampleSet from processors. Sort by distance.
|
||||||
|
// Return ordering in indexSet.
|
||||||
|
// Note: only master results are valid
|
||||||
|
|
||||||
|
List<point> allPoints(globalIndex::gatherOp(points()));
|
||||||
|
List<scalar> allDistance(globalIndex::gatherOp(distance()));
|
||||||
|
|
||||||
|
if (Pstream::master() && allDistance.empty())
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "Gathered empty coordSet: " << name() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort according to distance
|
||||||
|
Foam::sortedOrder(allDistance, sortOrder); // uses stable sort
|
||||||
|
|
||||||
|
// Repopulate gathered points/distances in the correct order
|
||||||
|
allPoints = List<point>(allPoints, sortOrder);
|
||||||
|
allDistance = List<scalar>(allDistance, sortOrder);
|
||||||
|
|
||||||
|
return autoPtr<coordSet>::New
|
||||||
|
(
|
||||||
|
name(),
|
||||||
|
axis(),
|
||||||
|
std::move(allPoints),
|
||||||
|
std::move(allDistance)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2012 OpenFOAM Foundation
|
Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2018 OpenCFD Ltd.
|
Copyright (C) 2017-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -35,11 +35,11 @@ SourceFiles
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef coordSet_H
|
#ifndef Foam_coordSet_H
|
||||||
#define coordSet_H
|
#define Foam_coordSet_H
|
||||||
|
|
||||||
#include "pointField.H"
|
#include "pointField.H"
|
||||||
#include "word.H"
|
#include "scalarList.H"
|
||||||
#include "Enum.H"
|
#include "Enum.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
@ -57,49 +57,55 @@ class coordSet
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Public data types
|
// Public Data Types
|
||||||
|
|
||||||
//- Enumeration defining the output format for coordinates
|
//- Enumeration defining the output format for coordinates
|
||||||
enum class coordFormat
|
enum class coordFormat
|
||||||
{
|
{
|
||||||
XYZ,
|
X, //!< Use 'x' component of points for (scalar) axis
|
||||||
X,
|
Y, //!< Use 'y' component of points for (scalar) axis
|
||||||
Y,
|
Z, //!< Use 'z' component of points for (scalar) axis
|
||||||
Z,
|
RADIUS, //!< Use mag of points for (scalar) axis
|
||||||
DISTANCE
|
DISTANCE, //!< Use additional distance field for (scalar) axis
|
||||||
|
XYZ, //!< Use x,y,z point values
|
||||||
|
/// DEFAULT
|
||||||
};
|
};
|
||||||
|
|
||||||
//- String representation of coordFormat enum
|
//- String representation of coordFormat enum
|
||||||
static const Enum<coordFormat> coordFormatNames;
|
static const Enum<coordFormat> coordFormatNames;
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//- Check for consistent dimensions of points and curve distance
|
|
||||||
void checkDimensions() const;
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
// Protected Data
|
||||||
|
|
||||||
//- Name
|
//- Name
|
||||||
const word name_;
|
word name_;
|
||||||
|
|
||||||
//- Axis write type
|
//- Cumulative distance for "distance" write specifier.
|
||||||
const coordFormat axis_;
|
scalarList distance_;
|
||||||
|
|
||||||
//- Cumulative distance "distance" write specifier.
|
//- Axis type
|
||||||
scalarList curveDist_;
|
coordFormat axis_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Check for consistent dimensions of points and curve distance
|
||||||
|
void checkDimensions() const;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct from components
|
/// //- Default construct
|
||||||
// Note: curveDist will be empty
|
/// coordSet();
|
||||||
|
|
||||||
|
//- Default construct with name and axis type
|
||||||
coordSet(const word& name, const coordFormat axisType);
|
coordSet(const word& name, const coordFormat axisType);
|
||||||
|
|
||||||
//- Construct from components
|
//- Default construct with name and axis type
|
||||||
// Note: curveDist will be empty
|
|
||||||
coordSet(const word& name, const word& axis);
|
coordSet(const word& name, const word& axis);
|
||||||
|
|
||||||
//- Copy construct from components
|
//- Copy construct from components
|
||||||
@ -108,7 +114,7 @@ public:
|
|||||||
const word& name,
|
const word& name,
|
||||||
const word& axis,
|
const word& axis,
|
||||||
const List<point>& points,
|
const List<point>& points,
|
||||||
const scalarList& curveDist
|
const scalarList& dist
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Move construct from components
|
//- Move construct from components
|
||||||
@ -117,66 +123,116 @@ public:
|
|||||||
const word& name,
|
const word& name,
|
||||||
const word& axis,
|
const word& axis,
|
||||||
List<point>&& points,
|
List<point>&& points,
|
||||||
scalarList&& curveDist
|
scalarList&& dist
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Member functions
|
// Member Functions
|
||||||
|
|
||||||
const word& name() const
|
// Access
|
||||||
|
|
||||||
|
//- The coord-set name
|
||||||
|
const word& name() const noexcept
|
||||||
{
|
{
|
||||||
return name_;
|
return name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
word axis() const
|
//- The sort axis name
|
||||||
|
const word& axis() const
|
||||||
{
|
{
|
||||||
return coordFormatNames[axis_];
|
return coordFormatNames[axis_];
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Set the points
|
//- Return the points
|
||||||
|
const pointField& points() const noexcept
|
||||||
|
{
|
||||||
|
return static_cast<const pointField&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Return the cumulative distance
|
||||||
|
const scalarList& distance() const noexcept
|
||||||
|
{
|
||||||
|
return distance_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Return the number of points
|
||||||
|
label nPoints() const noexcept
|
||||||
|
{
|
||||||
|
return pointField::size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Edit
|
||||||
|
|
||||||
|
//- Rename the coordinate set
|
||||||
|
void rename(const word& newName)
|
||||||
|
{
|
||||||
|
name_ = newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Copy assign new points
|
||||||
void setPoints(const List<point>& newPoints)
|
void setPoints(const List<point>& newPoints)
|
||||||
{
|
{
|
||||||
static_cast<pointField&>(*this) = newPoints;
|
static_cast<pointField&>(*this) = newPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Set the points
|
//- Move assign new points
|
||||||
void setPoints(List<point>&& newPoints)
|
void setPoints(List<point>&& newPoints)
|
||||||
{
|
{
|
||||||
static_cast<pointField&>(*this) = std::move(newPoints);
|
static_cast<pointField&>(*this) = std::move(newPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Return the cumulative distance
|
//- Copy assign the cumulative distance
|
||||||
const scalarList& curveDist() const
|
void setDistance(const scalarList& dist, const bool check=true)
|
||||||
{
|
{
|
||||||
return curveDist_;
|
distance_ = dist;
|
||||||
|
if (check) checkDimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Set the cumulative distance
|
//- Move assign the cumulative distance
|
||||||
void setCurveDist(const scalarList& curveDist)
|
void setDistance(scalarList&& dist, const bool check=true)
|
||||||
{
|
{
|
||||||
curveDist_ = curveDist;
|
distance_ = std::move(dist);
|
||||||
checkDimensions();
|
if (check) checkDimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Set the cumulative distance
|
|
||||||
void setCurveDist(scalarList&& curveDist)
|
|
||||||
{
|
|
||||||
curveDist_ = std::move(curveDist);
|
|
||||||
checkDimensions();
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Is axis specification a vector
|
// Output-related
|
||||||
bool hasVectorAxis() const;
|
|
||||||
|
//- True if axis specification is a vector
|
||||||
|
bool hasVectorAxis() const noexcept;
|
||||||
|
|
||||||
//- Get coordinate of point according to axis specification.
|
//- Get coordinate of point according to axis specification.
|
||||||
// If axis="distance" is the curveDist[index]
|
// If axis="distance" is the distance[index]
|
||||||
scalar scalarCoord(const label index) const;
|
scalar scalarCoord(const label index) const;
|
||||||
|
|
||||||
//- Get point according to axis="xyz" specification
|
//- Get point according to axis="xyz" specification
|
||||||
vector vectorCoord(const label index) const;
|
const vector& vectorCoord(const label index) const;
|
||||||
|
|
||||||
//- Write to stream
|
//- Write to stream
|
||||||
Ostream& write(Ostream& os) const;
|
Ostream& write(Ostream& os) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Other
|
||||||
|
|
||||||
|
//- Gather and sort.
|
||||||
|
// \return (on master) gathered set and overall sort order
|
||||||
|
autoPtr<coordSet> gatherSort(labelList& sortOrder) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Housekeeping
|
||||||
|
|
||||||
|
//- Return the cumulative distance
|
||||||
|
const scalarList& curveDist() const noexcept
|
||||||
|
{
|
||||||
|
return distance_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Copy assign the cumulative distance
|
||||||
|
void setCurveDist(const scalarList& dist)
|
||||||
|
{
|
||||||
|
setDistance(dist);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
455
src/meshTools/coordSet/writers/common/coordSetWriter.C
Normal file
455
src/meshTools/coordSet/writers/common/coordSetWriter.C
Normal file
@ -0,0 +1,455 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "coordSet.H"
|
||||||
|
#include "coordSetWriter.H"
|
||||||
|
#include "Time.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(coordSetWriter, 0);
|
||||||
|
defineRunTimeSelectionTable(coordSetWriter, word);
|
||||||
|
defineRunTimeSelectionTable(coordSetWriter, wordDict);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::word Foam::coordSetWriter::suffix
|
||||||
|
(
|
||||||
|
const word& fldName,
|
||||||
|
const word& fileExt
|
||||||
|
)
|
||||||
|
{
|
||||||
|
word result;
|
||||||
|
|
||||||
|
if (!fldName.empty())
|
||||||
|
{
|
||||||
|
result += '_' + fldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ext(fileExt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::word Foam::coordSetWriter::suffix
|
||||||
|
(
|
||||||
|
const wordList& fieldNames,
|
||||||
|
const word& fileExt
|
||||||
|
)
|
||||||
|
{
|
||||||
|
word result;
|
||||||
|
|
||||||
|
for (const word& fldName : fieldNames)
|
||||||
|
{
|
||||||
|
if (!fldName.empty())
|
||||||
|
{
|
||||||
|
result += '_' + fldName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ext(fileExt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::coordSetWriter::coordSetWriter()
|
||||||
|
:
|
||||||
|
coords_(),
|
||||||
|
trackTimes_(),
|
||||||
|
upToDate_(false),
|
||||||
|
wroteGeom_(false),
|
||||||
|
/// parallel_(true),
|
||||||
|
buffering_(false),
|
||||||
|
useTracks_(false),
|
||||||
|
useTimeDir_(false),
|
||||||
|
verbose_(false),
|
||||||
|
nFields_(0),
|
||||||
|
currTime_(),
|
||||||
|
outputPath_()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriter::coordSetWriter(const dictionary& options)
|
||||||
|
:
|
||||||
|
coordSetWriter()
|
||||||
|
{
|
||||||
|
options.readIfPresent("verbose", verbose_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::coordSetWriter::~coordSetWriter()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * Controls * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::setTime(const instant& inst)
|
||||||
|
{
|
||||||
|
currTime_ = inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::setTime(scalar timeValue)
|
||||||
|
{
|
||||||
|
currTime_ = instant(timeValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::setTime(scalar timeValue, const word& timeName)
|
||||||
|
{
|
||||||
|
currTime_.value() = timeValue;
|
||||||
|
currTime_.name() = timeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::unsetTime()
|
||||||
|
{
|
||||||
|
currTime_.value() = 0;
|
||||||
|
currTime_.name().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::beginTime(const Time& t)
|
||||||
|
{
|
||||||
|
setTime(t.value(), t.timeName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::beginTime(const instant& inst)
|
||||||
|
{
|
||||||
|
setTime(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::endTime()
|
||||||
|
{
|
||||||
|
// Flush bufferred data
|
||||||
|
if (nDataColumns())
|
||||||
|
{
|
||||||
|
writeBuffered();
|
||||||
|
}
|
||||||
|
clearBuffers();
|
||||||
|
|
||||||
|
unsetTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::open(const fileName& outputPath)
|
||||||
|
{
|
||||||
|
outputPath_ = outputPath;
|
||||||
|
wroteGeom_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::open
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
setCoordinates(coords);
|
||||||
|
open(outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::open
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
setTracks(tracks);
|
||||||
|
open(outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::close(bool force)
|
||||||
|
{
|
||||||
|
if (nDataColumns())
|
||||||
|
{
|
||||||
|
if (verbose_) Info<< "Flush buffered data:" << nl;
|
||||||
|
writeBuffered();
|
||||||
|
}
|
||||||
|
clearBuffers();
|
||||||
|
|
||||||
|
outputPath_.clear();
|
||||||
|
wroteGeom_ = false;
|
||||||
|
|
||||||
|
if (force)
|
||||||
|
{
|
||||||
|
coords_.clear();
|
||||||
|
trackTimes_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::clear()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
expire();
|
||||||
|
coords_.clear();
|
||||||
|
trackTimes_.clear();
|
||||||
|
clearBuffers(); // Reset any buffering
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::setCoordinates(const coordSet* coords)
|
||||||
|
{
|
||||||
|
expire();
|
||||||
|
clearBuffers(); // Reset any buffering
|
||||||
|
|
||||||
|
if (coords)
|
||||||
|
{
|
||||||
|
coords_.resize(1);
|
||||||
|
coords_.set(0, coords);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
coords_.clear();
|
||||||
|
}
|
||||||
|
trackTimes_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::setCoordinates(const coordSet& coords)
|
||||||
|
{
|
||||||
|
setCoordinates(&coords);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::setTracks(const UPtrList<coordSet>& tracks)
|
||||||
|
{
|
||||||
|
expire();
|
||||||
|
clearBuffers(); // Reset any buffering
|
||||||
|
|
||||||
|
// Shallow copy (pointers)
|
||||||
|
|
||||||
|
coords_.resize(tracks.size());
|
||||||
|
forAll(coords_, tracki)
|
||||||
|
{
|
||||||
|
coords_.set(tracki, tracks.get(tracki));
|
||||||
|
}
|
||||||
|
trackTimes_.clear();
|
||||||
|
useTracks_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::setTrackTimes(const UList<scalarField>& times)
|
||||||
|
{
|
||||||
|
if (times.size() == coords_.size())
|
||||||
|
{
|
||||||
|
trackTimes_ = times;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trackTimes_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::coordSetWriter::numPoints() const
|
||||||
|
{
|
||||||
|
label nTotal = 0;
|
||||||
|
|
||||||
|
forAll(coords_, tracki)
|
||||||
|
{
|
||||||
|
const auto* ptr = coords_.get(tracki);
|
||||||
|
if (ptr) nTotal += ptr->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::coordSetWriter::numTracks() const
|
||||||
|
{
|
||||||
|
return coords_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::coordSetWriter::needsUpdate() const
|
||||||
|
{
|
||||||
|
return !upToDate_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::coordSetWriter::wroteData() const
|
||||||
|
{
|
||||||
|
return wroteGeom_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::coordSetWriter::expire()
|
||||||
|
{
|
||||||
|
const bool changed = upToDate_;
|
||||||
|
|
||||||
|
upToDate_ = false;
|
||||||
|
wroteGeom_ = false;
|
||||||
|
coords_.clear();
|
||||||
|
trackTimes_.clear();
|
||||||
|
|
||||||
|
// Field count (nFields_) is a different type of accounting
|
||||||
|
// and is unaffected by geometry changes
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::coordSetWriter::hasCoords() const
|
||||||
|
{
|
||||||
|
return !coords_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::coordSetWriter::empty() const
|
||||||
|
{
|
||||||
|
return coords_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
Foam::fileName Foam::coordSetWriter::getExpectedPath
|
||||||
|
(
|
||||||
|
const word& fileExt
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
fileName file;
|
||||||
|
|
||||||
|
if (!outputPath_.empty())
|
||||||
|
{
|
||||||
|
if (useTimeDir() && !timeName().empty())
|
||||||
|
{
|
||||||
|
// Splice in time-directory
|
||||||
|
file = outputPath_.path() / timeName() / outputPath_.name();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file = outputPath_;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.ext(fileExt); // Append extension - can also be empty
|
||||||
|
}
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fileName Foam::coordSetWriter::getFieldPrefixedPath
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const word& fileExt
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (outputPath_.empty() || fieldName.empty())
|
||||||
|
{
|
||||||
|
return getExpectedPath(fileExt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Field: rootdir/<TIME>/<field>_NAME.ext
|
||||||
|
|
||||||
|
fileName file;
|
||||||
|
if (useTimeDir() && !timeName().empty())
|
||||||
|
{
|
||||||
|
// Splice in time-directory
|
||||||
|
file = outputPath_.path() / timeName();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file = outputPath_.path();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append <field>_NAME.EXT
|
||||||
|
file /= (fieldName + '_' + outputPath_.name());
|
||||||
|
file.ext(fileExt); // Append extension - can also be empty
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::checkOpen() const
|
||||||
|
{
|
||||||
|
if (!is_open())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< type() << " : Attempted to write without a path" << nl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::coordSetWriter::merge() const
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
// Possible future requirement...
|
||||||
|
//
|
||||||
|
// if (parallel_ && Pstream::parRun() && !upToDate_)
|
||||||
|
// {
|
||||||
|
// changed = merged_.merge(coords_, mergeDim_);
|
||||||
|
// }
|
||||||
|
upToDate_ = true;
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
wroteGeom_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::Ostream& Foam::operator<<
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const InfoProxy<coordSetWriter>& ip
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const coordSetWriter& w = ip.t_;
|
||||||
|
|
||||||
|
os << "coordSetWriter:"
|
||||||
|
<< " upToDate: " << w.upToDate_
|
||||||
|
<< " nFields: " << w.nFields_
|
||||||
|
<< " time: " << w.currTime_
|
||||||
|
<< " path: " << w.outputPath_ << endl;
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
597
src/meshTools/coordSet/writers/common/coordSetWriter.H
Normal file
597
src/meshTools/coordSet/writers/common/coordSetWriter.H
Normal file
@ -0,0 +1,597 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::coordSetWriter
|
||||||
|
|
||||||
|
Description
|
||||||
|
Base class for writing coordSet(s) and tracks with fields.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
\verbatim
|
||||||
|
coordSet coords(...);
|
||||||
|
|
||||||
|
// Construct writer of xmgr type
|
||||||
|
autoPtr<coordSetWriter> writer(coordSetWriter::New("vtk"));
|
||||||
|
|
||||||
|
writer.open(coords, path/name);
|
||||||
|
|
||||||
|
writer.write("density", rho);
|
||||||
|
writer.write("velocity", U);
|
||||||
|
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
coordSetWriterI.H
|
||||||
|
coordSetWriter.C
|
||||||
|
coordSetWriterBuffers.C
|
||||||
|
coordSetWriterNew.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_coordSetWriter_H
|
||||||
|
#define Foam_coordSetWriter_H
|
||||||
|
|
||||||
|
#include "coordSet.H"
|
||||||
|
#include "typeInfo.H"
|
||||||
|
#include "vector.H"
|
||||||
|
#include "tensor.H"
|
||||||
|
#include "fileName.H"
|
||||||
|
#include "wordList.H"
|
||||||
|
#include "Field.H"
|
||||||
|
#include "DynamicList.H"
|
||||||
|
#include "PtrDynList.H"
|
||||||
|
#include "UPtrList.H"
|
||||||
|
#include "instant.H"
|
||||||
|
#include "InfoProxy.H"
|
||||||
|
#include "runTimeSelectionTables.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
class coordSetWriter;
|
||||||
|
class Time;
|
||||||
|
|
||||||
|
Ostream& operator<<(Ostream& os, const InfoProxy<coordSetWriter>&);
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class coordSetWriter Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class coordSetWriter
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Data
|
||||||
|
|
||||||
|
//- Reference to coordinate set(s)
|
||||||
|
UPtrList<const coordSet> coords_;
|
||||||
|
|
||||||
|
//- Track times (eg, streamlines), one per coords_ entry
|
||||||
|
List<scalarField> trackTimes_;
|
||||||
|
|
||||||
|
//- The content is up-to-date?
|
||||||
|
mutable bool upToDate_;
|
||||||
|
|
||||||
|
//- Track if geometry has been written since the last open
|
||||||
|
mutable bool wroteGeom_;
|
||||||
|
|
||||||
|
/// //- Writing in parallel (via master)
|
||||||
|
/// bool parallel_;
|
||||||
|
|
||||||
|
//- Writer with buffering output
|
||||||
|
mutable bool buffering_;
|
||||||
|
|
||||||
|
//- Prefer tracks to points during single set writing
|
||||||
|
bool useTracks_;
|
||||||
|
|
||||||
|
//- Insert additional time sub-directory in the output path
|
||||||
|
bool useTimeDir_;
|
||||||
|
|
||||||
|
//- Additional output verbosity
|
||||||
|
bool verbose_;
|
||||||
|
|
||||||
|
//- The number of fields
|
||||||
|
label nFields_;
|
||||||
|
|
||||||
|
//- The current time value/name
|
||||||
|
instant currTime_;
|
||||||
|
|
||||||
|
//- The full output directory and file (coords) name
|
||||||
|
fileName outputPath_;
|
||||||
|
|
||||||
|
|
||||||
|
// Buffering
|
||||||
|
|
||||||
|
#undef defineBufferMethod
|
||||||
|
#define defineBufferMethod(Type) \
|
||||||
|
\
|
||||||
|
/* Names of Type fields */ \
|
||||||
|
DynamicList<word> Type##Names_; \
|
||||||
|
\
|
||||||
|
/* Values of Type fields */ \
|
||||||
|
PtrDynList<Field<Type>> Type##Fields_; \
|
||||||
|
\
|
||||||
|
/* Add named Type field to buffering */ \
|
||||||
|
void appendField(const word& fieldName, const Field<Type>& vals) \
|
||||||
|
{ \
|
||||||
|
Type##Names_.append(fieldName); \
|
||||||
|
Type##Fields_.append(vals.clone()); \
|
||||||
|
}
|
||||||
|
|
||||||
|
defineBufferMethod(label);
|
||||||
|
defineBufferMethod(scalar);
|
||||||
|
defineBufferMethod(vector);
|
||||||
|
defineBufferMethod(sphericalTensor);
|
||||||
|
defineBufferMethod(symmTensor);
|
||||||
|
defineBufferMethod(tensor);
|
||||||
|
|
||||||
|
#undef defineBufferMethod
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
// Buffering
|
||||||
|
|
||||||
|
//- Write line contents (eg, buffered)
|
||||||
|
static void writeLine(Ostream&, const UList<word>&, const char* sep);
|
||||||
|
|
||||||
|
//- Write line contents (eg, buffered)
|
||||||
|
static void writeLine(Ostream&, const UList<scalar>&, const char* sep);
|
||||||
|
|
||||||
|
//- Clear out buffering
|
||||||
|
void clearBuffers();
|
||||||
|
|
||||||
|
//- The number of buffer data columns, after splitting into components
|
||||||
|
label nDataColumns() const;
|
||||||
|
|
||||||
|
//- Write buffered data
|
||||||
|
virtual bool writeBuffered();
|
||||||
|
|
||||||
|
//- Write buffered data
|
||||||
|
void writeBufferContents
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const coordSet& coords,
|
||||||
|
const char* sep
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Get buffered data line (components)
|
||||||
|
void getBufferLine
|
||||||
|
(
|
||||||
|
DynamicList<scalar>& buf,
|
||||||
|
const coordSet& coords,
|
||||||
|
const label pointi
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
// File Operations
|
||||||
|
|
||||||
|
//- Get expected (characteristic) output file name - information only
|
||||||
|
fileName getExpectedPath(const word& fileExt = word::null) const;
|
||||||
|
|
||||||
|
//- Get field-prefixed output file name.
|
||||||
|
// Eg, dir/U_name.raw
|
||||||
|
fileName getFieldPrefixedPath
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const word& fileExt = word::null
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Verify that the outputPath_ has been set or FatalError
|
||||||
|
void checkOpen() const;
|
||||||
|
|
||||||
|
//- Perform any merging if not already upToDate (parallel)
|
||||||
|
//- or simply mark as being up-to-date
|
||||||
|
virtual bool merge() const;
|
||||||
|
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
|
||||||
|
//- Repackage field into a UPtrList
|
||||||
|
template<class Type>
|
||||||
|
static UPtrList<const Field<Type>>
|
||||||
|
repackageFields
|
||||||
|
(
|
||||||
|
const Field<Type>& field
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Repackage multiple fields into a UPtrList
|
||||||
|
template<class Type>
|
||||||
|
static UPtrList<const Field<Type>>
|
||||||
|
repackageFields
|
||||||
|
(
|
||||||
|
const UList<Field<Type>>& fieldValues
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Write coordinates and values
|
||||||
|
template<class Type>
|
||||||
|
static void writeTable
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const coordSet& coords,
|
||||||
|
const UList<Type>& values,
|
||||||
|
const char* sep
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Normal write templates
|
||||||
|
|
||||||
|
//- Dummy templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName, //!< Name of field
|
||||||
|
const Field<Type>& values //!< Local field values to write
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/// if (!wroteGeom_)
|
||||||
|
/// {
|
||||||
|
/// return this->write();
|
||||||
|
/// }
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Dummy templated write operation. Multiple tracks
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- No copy construct
|
||||||
|
coordSetWriter(const coordSetWriter&) = delete;
|
||||||
|
|
||||||
|
//- No copy assignment
|
||||||
|
void operator=(const coordSetWriter&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("coordSetWriter");
|
||||||
|
|
||||||
|
// Declare run-time constructor selection table
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
coordSetWriter,
|
||||||
|
word,
|
||||||
|
(),
|
||||||
|
()
|
||||||
|
);
|
||||||
|
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
coordSetWriter,
|
||||||
|
wordDict,
|
||||||
|
(
|
||||||
|
const dictionary& writeOptions
|
||||||
|
),
|
||||||
|
(writeOptions)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- True if New is likely to succeed for this writeType
|
||||||
|
static bool supportedType(const word& writeType);
|
||||||
|
|
||||||
|
//- Return a reference to the selected writer
|
||||||
|
static autoPtr<coordSetWriter> New(const word& writeFormat);
|
||||||
|
|
||||||
|
//- Return a reference to the selected writer
|
||||||
|
// Select with extra write option
|
||||||
|
static autoPtr<coordSetWriter> New
|
||||||
|
(
|
||||||
|
const word& writeFormat,
|
||||||
|
const dictionary& writeOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Default construct
|
||||||
|
coordSetWriter();
|
||||||
|
|
||||||
|
//- Default construct with specified options
|
||||||
|
explicit coordSetWriter(const dictionary& options);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor. Calls close()
|
||||||
|
virtual ~coordSetWriter();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
|
||||||
|
//- Name suffix based on fieldName (underscore separator)
|
||||||
|
static word suffix
|
||||||
|
(
|
||||||
|
const word& fldName,
|
||||||
|
const word& fileExt = word::null
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Name suffix based on fieldNames (underscore separator)
|
||||||
|
static word suffix
|
||||||
|
(
|
||||||
|
const wordList& fieldNames,
|
||||||
|
const word& fileExt = word::null
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Capability
|
||||||
|
|
||||||
|
//- True if the format uses internal buffering (eg, column output)
|
||||||
|
virtual bool buffering() const;
|
||||||
|
|
||||||
|
//- Turn internal buffering on/off (only if supported by the writer)
|
||||||
|
virtual bool buffering(const bool on);
|
||||||
|
|
||||||
|
//- 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Bookkeeping
|
||||||
|
|
||||||
|
//- Does the writer need an update (eg, lagging behind other changes)
|
||||||
|
virtual bool needsUpdate() const;
|
||||||
|
|
||||||
|
//- Geometry or fields written since the last open?
|
||||||
|
virtual bool wroteData() const;
|
||||||
|
|
||||||
|
//- Mark that content 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 coordSet associations and
|
||||||
|
//- expire the writer.
|
||||||
|
virtual void clear();
|
||||||
|
|
||||||
|
|
||||||
|
// Content Association
|
||||||
|
|
||||||
|
//- Set coordinates, can also be nullptr
|
||||||
|
virtual void setCoordinates(const coordSet* coords);
|
||||||
|
|
||||||
|
//- Set coordinates
|
||||||
|
virtual void setCoordinates(const coordSet& coords);
|
||||||
|
|
||||||
|
//- Set track coordinates
|
||||||
|
virtual void setTracks(const UPtrList<coordSet>& tracks);
|
||||||
|
|
||||||
|
//- Set track times
|
||||||
|
virtual void setTrackTimes(const UList<scalarField>& times);
|
||||||
|
|
||||||
|
|
||||||
|
// Queries, Access
|
||||||
|
|
||||||
|
//- The number of associated points (local processor)
|
||||||
|
label numPoints() const;
|
||||||
|
|
||||||
|
//- The number of coordinate tracks
|
||||||
|
label numTracks() const;
|
||||||
|
|
||||||
|
//- Writer is associated with content
|
||||||
|
bool hasCoords() const;
|
||||||
|
|
||||||
|
//- Writer is not associated with content
|
||||||
|
bool empty() const;
|
||||||
|
|
||||||
|
//- Test if outputPath has been set
|
||||||
|
inline bool is_open() const noexcept;
|
||||||
|
|
||||||
|
//- The number of expected output fields.
|
||||||
|
// Currently only used by the legacy VTK format.
|
||||||
|
inline label nFields() const noexcept;
|
||||||
|
|
||||||
|
//- Set the number of expected output fields
|
||||||
|
// Currently only used by the legacy VTK format.
|
||||||
|
// \return old value
|
||||||
|
inline label nFields(const label n) noexcept;
|
||||||
|
|
||||||
|
//- Prefer tracks to points during single set writing
|
||||||
|
inline bool useTracks() const noexcept;
|
||||||
|
|
||||||
|
//- Enable/disable tracks preference
|
||||||
|
// \return old value
|
||||||
|
inline bool useTracks(const bool on) noexcept;
|
||||||
|
|
||||||
|
//- Should a time directory be spliced into the output path?
|
||||||
|
inline bool useTimeDir() const noexcept;
|
||||||
|
|
||||||
|
//- Enable/disable use of spliced output path
|
||||||
|
// \return old value
|
||||||
|
inline bool useTimeDir(const bool on) noexcept;
|
||||||
|
|
||||||
|
//- Get output verbosity
|
||||||
|
inline bool verbose() const noexcept;
|
||||||
|
|
||||||
|
//- Enable/disable verbose output
|
||||||
|
// \return old value
|
||||||
|
inline bool verbose(bool on) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
//- Expected (characteristic) output file name - information only.
|
||||||
|
//- Return empty when is_open() is false.
|
||||||
|
virtual fileName path() const = 0;
|
||||||
|
|
||||||
|
//- Write separate geometry to file.
|
||||||
|
/// TBD: virtual fileName write() = 0;
|
||||||
|
|
||||||
|
//- Open for output on specified path, using existing content
|
||||||
|
virtual void open(const fileName& outputPath);
|
||||||
|
|
||||||
|
//- Open from components
|
||||||
|
virtual void open
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Open from components
|
||||||
|
virtual void open
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Finish output, performing any necessary cleanup
|
||||||
|
// Optional force disassociation with any coordSet(s)
|
||||||
|
virtual void close(bool force = false);
|
||||||
|
|
||||||
|
|
||||||
|
// Other
|
||||||
|
|
||||||
|
//- Return info proxy.
|
||||||
|
virtual InfoProxy<coordSetWriter> info() const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Output info proxy
|
||||||
|
friend Ostream& operator<<
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const InfoProxy<coordSetWriter>& ip
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Write methods
|
||||||
|
|
||||||
|
#undef declareCoordSetWriterWriteMethod
|
||||||
|
#define declareCoordSetWriterWriteMethod(Type) \
|
||||||
|
\
|
||||||
|
/*! \brief Write field of Type (point data) */ \
|
||||||
|
virtual fileName write \
|
||||||
|
( \
|
||||||
|
const word& fieldName, /*!< Name of field */ \
|
||||||
|
const Field<Type>& field /*!< Field values */ \
|
||||||
|
) = 0; \
|
||||||
|
\
|
||||||
|
/*! \brief Write track fields of Type (point data) */ \
|
||||||
|
virtual fileName write \
|
||||||
|
( \
|
||||||
|
const word& fieldName, /*!< Name of field */ \
|
||||||
|
const List<Field<Type>>& fieldValues /*!< Per-track values */ \
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
declareCoordSetWriterWriteMethod(label);
|
||||||
|
declareCoordSetWriterWriteMethod(scalar);
|
||||||
|
declareCoordSetWriterWriteMethod(vector);
|
||||||
|
declareCoordSetWriterWriteMethod(sphericalTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(symmTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(tensor);
|
||||||
|
|
||||||
|
|
||||||
|
#undef declareCoordSetWriterWriteMethod
|
||||||
|
#define declareCoordSetWriterWriteMethod(Type) \
|
||||||
|
\
|
||||||
|
/*! \brief Write field of Type (point data) */ \
|
||||||
|
virtual fileName write \
|
||||||
|
( \
|
||||||
|
const word& fieldName, /*!< Name of field */ \
|
||||||
|
const Field<Type>& values /*!< Field values */ \
|
||||||
|
); /* override */ \
|
||||||
|
\
|
||||||
|
/*! \brief Write track fields of Type (point data) */ \
|
||||||
|
virtual fileName write \
|
||||||
|
( \
|
||||||
|
const word& fieldName, /*!< Name of field */ \
|
||||||
|
const List<Field<Type>>& fieldValues /*!< Per-track values */ \
|
||||||
|
); /* override */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#include "coordSetWriterI.H"
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "coordSetWriterTemplates.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
197
src/meshTools/coordSet/writers/common/coordSetWriterBuffers.C
Normal file
197
src/meshTools/coordSet/writers/common/coordSetWriterBuffers.C
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "coordSetWriter.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::writeLine
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const UList<word>& values,
|
||||||
|
const char* sep
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!values.empty())
|
||||||
|
{
|
||||||
|
forAll(values, coli)
|
||||||
|
{
|
||||||
|
if (coli && sep) os << sep;
|
||||||
|
os << values[coli];
|
||||||
|
}
|
||||||
|
os << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::writeLine
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const UList<scalar>& values,
|
||||||
|
const char* sep
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!values.empty())
|
||||||
|
{
|
||||||
|
forAll(values, coli)
|
||||||
|
{
|
||||||
|
if (coli && sep) os << sep;
|
||||||
|
os << values[coli];
|
||||||
|
}
|
||||||
|
os << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::clearBuffers()
|
||||||
|
{
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(Type) \
|
||||||
|
{ \
|
||||||
|
Type##Names_.clear(); \
|
||||||
|
Type##Fields_.clear(); \
|
||||||
|
}
|
||||||
|
|
||||||
|
doLocalCode(label);
|
||||||
|
doLocalCode(scalar);
|
||||||
|
doLocalCode(vector);
|
||||||
|
doLocalCode(sphericalTensor);
|
||||||
|
doLocalCode(symmTensor);
|
||||||
|
doLocalCode(tensor);
|
||||||
|
#undef doLocalCode
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::coordSetWriter::nDataColumns() const
|
||||||
|
{
|
||||||
|
label ncol = 0;
|
||||||
|
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(Type) \
|
||||||
|
ncol += (Type##Fields_.size() * pTraits<Type>::nComponents);
|
||||||
|
|
||||||
|
doLocalCode(label);
|
||||||
|
doLocalCode(scalar);
|
||||||
|
doLocalCode(vector);
|
||||||
|
doLocalCode(sphericalTensor);
|
||||||
|
doLocalCode(symmTensor);
|
||||||
|
doLocalCode(tensor);
|
||||||
|
#undef doLocalCode
|
||||||
|
|
||||||
|
return ncol;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::getBufferLine
|
||||||
|
(
|
||||||
|
DynamicList<scalar>& buf,
|
||||||
|
const coordSet& coords,
|
||||||
|
const label pointi
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
buf.clear();
|
||||||
|
|
||||||
|
if (coords.hasVectorAxis())
|
||||||
|
{
|
||||||
|
const vector& p = coords.vectorCoord(pointi);
|
||||||
|
buf.append(p.x());
|
||||||
|
buf.append(p.y());
|
||||||
|
buf.append(p.z());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf.append(coords.scalarCoord(pointi));
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(Type) \
|
||||||
|
\
|
||||||
|
for (const auto& fld : Type##Fields_) \
|
||||||
|
{ \
|
||||||
|
const auto& val = fld[pointi]; \
|
||||||
|
for (direction d=0; d < pTraits<Type>::nComponents; ++d) \
|
||||||
|
{ \
|
||||||
|
buf.append(component(val, d)); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
doLocalCode(label);
|
||||||
|
doLocalCode(scalar);
|
||||||
|
doLocalCode(vector);
|
||||||
|
doLocalCode(sphericalTensor);
|
||||||
|
doLocalCode(symmTensor);
|
||||||
|
doLocalCode(tensor);
|
||||||
|
#undef doLocalCode
|
||||||
|
}
|
||||||
|
while (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::coordSetWriter::writeBuffered()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriter::writeBufferContents
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const coordSet& coords,
|
||||||
|
const char* sep
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const label npts = coords.size();
|
||||||
|
const label ncomp = nDataColumns();
|
||||||
|
|
||||||
|
DynamicList<scalar> compCols(3 + ncomp);
|
||||||
|
|
||||||
|
for (label pointi = 0; pointi < npts; ++pointi)
|
||||||
|
{
|
||||||
|
getBufferLine(compCols, coords, pointi);
|
||||||
|
writeLine(os, compCols, sep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * Controls * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::coordSetWriter::buffering() const
|
||||||
|
{
|
||||||
|
return buffering_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// disabled
|
||||||
|
bool Foam::coordSetWriter::buffering(const bool)
|
||||||
|
{
|
||||||
|
return buffering_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
110
src/meshTools/coordSet/writers/common/coordSetWriterI.H
Normal file
110
src/meshTools/coordSet/writers/common/coordSetWriterI.H
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline bool Foam::coordSetWriter::is_open() const noexcept
|
||||||
|
{
|
||||||
|
return !outputPath_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::label Foam::coordSetWriter::nFields() const noexcept
|
||||||
|
{
|
||||||
|
return nFields_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::label Foam::coordSetWriter::nFields(const label n) noexcept
|
||||||
|
{
|
||||||
|
label old(nFields_);
|
||||||
|
nFields_ = n;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::coordSetWriter::useTracks() const noexcept
|
||||||
|
{
|
||||||
|
return useTracks_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::coordSetWriter::useTracks(const bool on) noexcept
|
||||||
|
{
|
||||||
|
bool old(useTracks_);
|
||||||
|
useTracks_ = on;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::coordSetWriter::useTimeDir() const noexcept
|
||||||
|
{
|
||||||
|
return useTimeDir_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::coordSetWriter::useTimeDir(const bool on) noexcept
|
||||||
|
{
|
||||||
|
bool old(useTimeDir_);
|
||||||
|
useTimeDir_ = on;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::coordSetWriter::verbose() const noexcept
|
||||||
|
{
|
||||||
|
return verbose_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::coordSetWriter::verbose(bool on) noexcept
|
||||||
|
{
|
||||||
|
bool old(verbose_);
|
||||||
|
verbose_ = on;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::coordSetWriter::hasTime() const
|
||||||
|
{
|
||||||
|
return currTime_.name().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const Foam::word& Foam::coordSetWriter::timeName() const
|
||||||
|
{
|
||||||
|
return currTime_.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::scalar Foam::coordSetWriter::timeValue() const
|
||||||
|
{
|
||||||
|
return currTime_.name().empty() ? 0 : currTime_.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
InClass
|
||||||
|
Foam::coordSetWriterMethods
|
||||||
|
|
||||||
|
Description
|
||||||
|
Convenience macros for instantiating coordSetWriter methods.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_coordSetWriterMethods_H
|
||||||
|
#define Foam_coordSetWriterMethods_H
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Instantiate templated method for standard types
|
||||||
|
#define defineCoordSetWriterWriteField(ThisClass, ValueType) \
|
||||||
|
\
|
||||||
|
Foam::fileName ThisClass::write \
|
||||||
|
( \
|
||||||
|
const word& fieldName, \
|
||||||
|
const Field<ValueType>& values \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
return writeTemplate(fieldName, values); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
Foam::fileName ThisClass::write \
|
||||||
|
( \
|
||||||
|
const word& fieldName, \
|
||||||
|
const List<Field<ValueType>>& fieldValues \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
return writeTemplate(fieldName, fieldValues); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define defineCoordSetWriterWriteFields(ThisClass) \
|
||||||
|
defineCoordSetWriterWriteField(ThisClass, label); \
|
||||||
|
defineCoordSetWriterWriteField(ThisClass, scalar); \
|
||||||
|
defineCoordSetWriterWriteField(ThisClass, vector); \
|
||||||
|
defineCoordSetWriterWriteField(ThisClass, sphericalTensor); \
|
||||||
|
defineCoordSetWriterWriteField(ThisClass, symmTensor); \
|
||||||
|
defineCoordSetWriterWriteField(ThisClass, tensor)
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
98
src/meshTools/coordSet/writers/common/coordSetWriterNew.C
Normal file
98
src/meshTools/coordSet/writers/common/coordSetWriterNew.C
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "coordSet.H"
|
||||||
|
#include "coordSetWriter.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::coordSetWriter::supportedType(const word& writeType)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(
|
||||||
|
wordConstructorTablePtr_->found(writeType)
|
||||||
|
|| wordDictConstructorTablePtr_->found(writeType)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::coordSetWriter> Foam::coordSetWriter::New
|
||||||
|
(
|
||||||
|
const word& writeType
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto* ctorPtr = wordConstructorTable(writeType);
|
||||||
|
|
||||||
|
if (!ctorPtr)
|
||||||
|
{
|
||||||
|
FatalErrorInLookup
|
||||||
|
(
|
||||||
|
"setWriter",
|
||||||
|
writeType,
|
||||||
|
*wordConstructorTablePtr_
|
||||||
|
) << exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return autoPtr<coordSetWriter>(ctorPtr());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::coordSetWriter> Foam::coordSetWriter::New
|
||||||
|
(
|
||||||
|
const word& writeType,
|
||||||
|
const dictionary& writeOpts
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Constructors with dictionary options
|
||||||
|
{
|
||||||
|
auto* ctorPtr = wordDictConstructorTable(writeType);
|
||||||
|
|
||||||
|
if (ctorPtr)
|
||||||
|
{
|
||||||
|
return autoPtr<coordSetWriter>(ctorPtr(writeOpts));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors without dictionary options
|
||||||
|
auto* ctorPtr = wordConstructorTable(writeType);
|
||||||
|
|
||||||
|
if (!ctorPtr)
|
||||||
|
{
|
||||||
|
FatalErrorInLookup
|
||||||
|
(
|
||||||
|
"setWriter",
|
||||||
|
writeType,
|
||||||
|
*wordConstructorTablePtr_
|
||||||
|
) << exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return autoPtr<coordSetWriter>(ctorPtr());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -5,8 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2012-2016 OpenFOAM Foundation
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,49 +25,63 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "regionSizeDistribution.H"
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
#include "regionSplit.H"
|
|
||||||
#include "volFields.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::Map<Type> Foam::functionObjects::regionSizeDistribution::regionSum
|
Foam::UPtrList<const Foam::Field<Type>>
|
||||||
(
|
Foam::coordSetWriter::repackageFields(const Field<Type>& field)
|
||||||
const regionSplit& regions,
|
|
||||||
const Field<Type>& fld
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
// Per region the sum of fld
|
UPtrList<const Field<Type>> fieldPtrs(1);
|
||||||
Map<Type> regionToSum(regions.nRegions()/Pstream::nProcs());
|
fieldPtrs.set(0, &field);
|
||||||
|
|
||||||
forAll(fld, celli)
|
return fieldPtrs;
|
||||||
{
|
|
||||||
const label regioni = regions[celli];
|
|
||||||
regionToSum(regioni, Type(Zero)) += fld[celli];
|
|
||||||
}
|
|
||||||
|
|
||||||
Pstream::mapCombineGather(regionToSum, plusEqOp<Type>());
|
|
||||||
Pstream::mapCombineScatter(regionToSum);
|
|
||||||
|
|
||||||
return regionToSum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::List<Type> Foam::functionObjects::regionSizeDistribution::extractData
|
Foam::UPtrList<const Foam::Field<Type>>
|
||||||
(
|
Foam::coordSetWriter::repackageFields(const UList<Field<Type>>& fieldValues)
|
||||||
const labelUList& keys,
|
|
||||||
const Map<Type>& regionData
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
List<Type> sortedData(keys.size());
|
UPtrList<const Field<Type>> fieldPtrs(fieldValues.size());
|
||||||
|
forAll(fieldValues, i)
|
||||||
forAll(keys, i)
|
|
||||||
{
|
{
|
||||||
sortedData[i] = regionData[keys[i]];
|
fieldPtrs.set(i, &(fieldValues[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return fieldPtrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::coordSetWriter::writeTable
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const coordSet& coords,
|
||||||
|
const UList<Type>& values,
|
||||||
|
const char* sep
|
||||||
|
)
|
||||||
|
{
|
||||||
|
forAll(coords, pointi)
|
||||||
|
{
|
||||||
|
// Output coordinate (point or scalar) with separator
|
||||||
|
if (coords.hasVectorAxis())
|
||||||
|
{
|
||||||
|
const vector& p = coords.vectorCoord(pointi);
|
||||||
|
os << p.x() << sep << p.y() << sep << p.z();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << coords.scalarCoord(pointi);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output component values with separator
|
||||||
|
const auto& val = values[pointi];
|
||||||
|
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
|
||||||
|
{
|
||||||
|
os << sep << component(val, d);
|
||||||
|
}
|
||||||
|
os << nl;
|
||||||
}
|
}
|
||||||
return sortedData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1,280 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
||||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "writer.H"
|
|
||||||
#include "coordSet.H"
|
|
||||||
#include "OFstream.H"
|
|
||||||
#include "OSspecific.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::autoPtr<Foam::writer<Type>> Foam::writer<Type>::New
|
|
||||||
(
|
|
||||||
const word& writeType
|
|
||||||
)
|
|
||||||
{
|
|
||||||
auto* ctorPtr = wordConstructorTable(writeType);
|
|
||||||
|
|
||||||
if (!ctorPtr)
|
|
||||||
{
|
|
||||||
FatalErrorInLookup
|
|
||||||
(
|
|
||||||
"writer",
|
|
||||||
writeType,
|
|
||||||
*wordConstructorTablePtr_
|
|
||||||
) << exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return autoPtr<writer<Type>>(ctorPtr());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::autoPtr<Foam::writer<Type>> Foam::writer<Type>::New
|
|
||||||
(
|
|
||||||
const word& writeType,
|
|
||||||
const dictionary& formatOptions
|
|
||||||
)
|
|
||||||
{
|
|
||||||
auto* ctorPtr = dictConstructorTable(writeType);
|
|
||||||
|
|
||||||
if (!ctorPtr)
|
|
||||||
{
|
|
||||||
FatalErrorInLookup
|
|
||||||
(
|
|
||||||
"writer",
|
|
||||||
writeType,
|
|
||||||
*dictConstructorTablePtr_
|
|
||||||
) << exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return autoPtr<writer<Type>>(ctorPtr(formatOptions));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::fileName Foam::writer<Type>::getBaseName
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const wordList& valueSets
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
fileName fName(points.name());
|
|
||||||
|
|
||||||
forAll(valueSets, i)
|
|
||||||
{
|
|
||||||
fName += '_' + valueSets[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return fName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::writer<Type>::writeCoord
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const label pointi,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
if (points.hasVectorAxis())
|
|
||||||
{
|
|
||||||
write(points.vectorCoord(pointi), os);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
write(points.scalarCoord(pointi), os);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::writer<Type>::writeTable
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const List<Type>& values,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
forAll(points, pointi)
|
|
||||||
{
|
|
||||||
writeCoord(points, pointi, os);
|
|
||||||
writeSeparator(os);
|
|
||||||
write(values[pointi], os);
|
|
||||||
os << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::writer<Type>::writeTable
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const List<const List<Type>*>& valuesPtrList,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
forAll(points, pointi)
|
|
||||||
{
|
|
||||||
writeCoord(points, pointi, os);
|
|
||||||
|
|
||||||
forAll(valuesPtrList, i)
|
|
||||||
{
|
|
||||||
writeSeparator(os);
|
|
||||||
|
|
||||||
const List<Type>& values = *valuesPtrList[i];
|
|
||||||
write(values[pointi], os);
|
|
||||||
}
|
|
||||||
os << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::writer<Type>::writer()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::writer<Type>::writer(const dictionary& dict)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::writer<Type>::write
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<Field<Type>>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
List<const Field<Type>*> valueSetPtrs(valueSets.size());
|
|
||||||
forAll(valueSetPtrs, i)
|
|
||||||
{
|
|
||||||
valueSetPtrs[i] = &valueSets[i];
|
|
||||||
}
|
|
||||||
write(points, valueSetNames, valueSetPtrs, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::Ostream& Foam::writer<Type>::write
|
|
||||||
(
|
|
||||||
const scalar value,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return os << value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
template<class VSType>
|
|
||||||
Foam::Ostream& Foam::writer<Type>::writeVS
|
|
||||||
(
|
|
||||||
const VSType& value,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
for (direction d=0; d<VSType::nComponents; d++)
|
|
||||||
{
|
|
||||||
if (d > 0)
|
|
||||||
{
|
|
||||||
writeSeparator(os);
|
|
||||||
}
|
|
||||||
|
|
||||||
os << value.component(d);
|
|
||||||
}
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::writer<Type>::writeSeparator
|
|
||||||
(
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
os << token::SPACE << token::TAB;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::Ostream& Foam::writer<Type>::write
|
|
||||||
(
|
|
||||||
const vector& value,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return writeVS(value, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::Ostream& Foam::writer<Type>::write
|
|
||||||
(
|
|
||||||
const sphericalTensor& value,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return writeVS(value, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::Ostream& Foam::writer<Type>::write
|
|
||||||
(
|
|
||||||
const symmTensor& value,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return writeVS(value, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::Ostream& Foam::writer<Type>::write
|
|
||||||
(
|
|
||||||
const tensor& value,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return writeVS(value, os);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,244 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::writer
|
|
||||||
|
|
||||||
Description
|
|
||||||
Base class for graphics format writing. Entry points are
|
|
||||||
- write(..). \n
|
|
||||||
Write to an Ostream a table of points with corresponding values.
|
|
||||||
- write(scalar/vector/sphericalTensor/symmTensor/tensor). \n
|
|
||||||
Write single scalar/vector/sphericalTensor/symmTensor/tensor.
|
|
||||||
Default is to write space separated components.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
\verbatim
|
|
||||||
// Construct writer of xmgr type
|
|
||||||
autoPtr<writer<scalar>> scalarFormatter(writer<scalar>::New("xmgr"));
|
|
||||||
|
|
||||||
// Output list of points and corresponding values
|
|
||||||
scalarFormatter().write
|
|
||||||
(
|
|
||||||
coordSet(...)
|
|
||||||
"U.component(0)", // name of values
|
|
||||||
vals // values
|
|
||||||
);
|
|
||||||
\endverbatim
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
writer.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef writer_H
|
|
||||||
#define writer_H
|
|
||||||
|
|
||||||
#include "fileName.H"
|
|
||||||
#include "wordList.H"
|
|
||||||
#include "vector.H"
|
|
||||||
#include "tensor.H"
|
|
||||||
#include "typeInfo.H"
|
|
||||||
#include "runTimeSelectionTables.H"
|
|
||||||
#include "autoPtr.H"
|
|
||||||
#include "Field.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// Forward Declarations
|
|
||||||
class coordSet;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class writer Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
class writer
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
//- Generates filename from coordSet and sampled fields
|
|
||||||
fileName getBaseName(const coordSet&, const wordList&) const;
|
|
||||||
|
|
||||||
void writeCoord(const coordSet&, const label sampleI, Ostream&) const;
|
|
||||||
|
|
||||||
//- Writes single-column ascii write. Column 1 is coordSet coordinate,
|
|
||||||
// columns 2 is the value. Uses write() function
|
|
||||||
// to write coordinate in correct format.
|
|
||||||
void writeTable(const coordSet&, const List<Type>&, Ostream&) const;
|
|
||||||
|
|
||||||
//- Writes multi-column ascii write. Column 1 is coordSet coordinate,
|
|
||||||
// columns 2..n are the values. Uses write() function
|
|
||||||
// to write coordinate in correct format.
|
|
||||||
void writeTable
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const List<const List<Type>*>&,
|
|
||||||
Ostream& os
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Writes a separator. Used by write functions.
|
|
||||||
virtual void writeSeparator(Ostream& os) const;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("writer");
|
|
||||||
|
|
||||||
// Declare run-time constructor selection table
|
|
||||||
|
|
||||||
declareRunTimeSelectionTable
|
|
||||||
(
|
|
||||||
autoPtr,
|
|
||||||
writer,
|
|
||||||
word,
|
|
||||||
(),
|
|
||||||
()
|
|
||||||
);
|
|
||||||
|
|
||||||
declareRunTimeSelectionTable
|
|
||||||
(
|
|
||||||
autoPtr,
|
|
||||||
writer,
|
|
||||||
dict,
|
|
||||||
(
|
|
||||||
const dictionary& formatOptions
|
|
||||||
),
|
|
||||||
(formatOptions)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Selectors
|
|
||||||
|
|
||||||
//- Return a reference to the selected writer
|
|
||||||
static autoPtr<writer> New(const word& writeFormat);
|
|
||||||
|
|
||||||
//- Return a reference to the selected writer
|
|
||||||
static autoPtr<writer> New
|
|
||||||
(
|
|
||||||
const word& writeFormat,
|
|
||||||
const dictionary& formatOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Default construct
|
|
||||||
writer();
|
|
||||||
|
|
||||||
//- Construct with dictionary
|
|
||||||
explicit writer(const dictionary& dict);
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
virtual ~writer() = default;
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Generate file name with correct extension
|
|
||||||
virtual fileName getFileName
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&
|
|
||||||
) const = 0;
|
|
||||||
|
|
||||||
//- General entry point for writing.
|
|
||||||
// The data is organized in a set of point with one or more values
|
|
||||||
// per point
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&,
|
|
||||||
const List<const Field<Type>*>&,
|
|
||||||
Ostream&
|
|
||||||
) const = 0;
|
|
||||||
|
|
||||||
//- General entry point for writing.
|
|
||||||
// The data is organized in a set of point with one or more values
|
|
||||||
// per point
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&,
|
|
||||||
const List<Field<Type>>&,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- General entry point for writing of multiple coordSets.
|
|
||||||
// Each coordSet (track) has same data variables.
|
|
||||||
// The data is per variable, per track, per point of track.
|
|
||||||
// If writeTracks adds connecting lines (wherever applicable)
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream&
|
|
||||||
) const = 0;
|
|
||||||
|
|
||||||
//- Write scalar as ascii
|
|
||||||
virtual Ostream& write(const scalar, Ostream&) const;
|
|
||||||
|
|
||||||
template<class VSType>
|
|
||||||
Ostream& writeVS(const VSType&, Ostream&) const;
|
|
||||||
|
|
||||||
//- Write vector. Tab separated ascii
|
|
||||||
virtual Ostream& write(const vector&, Ostream&) const;
|
|
||||||
|
|
||||||
//- Write sphericalTensor. Tab separated ascii
|
|
||||||
virtual Ostream& write(const sphericalTensor&, Ostream&) const;
|
|
||||||
|
|
||||||
//- Write symmTensor. Tab separated ascii
|
|
||||||
virtual Ostream& write(const symmTensor&, Ostream&) const;
|
|
||||||
|
|
||||||
//- Write tensor. Tab separated ascii
|
|
||||||
virtual Ostream& write(const tensor&, Ostream&) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
#include "writer.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "writers.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#define defineSetWriterType(dataType) \
|
|
||||||
defineNamedTemplateTypeNameAndDebug(writer<dataType >, 0); \
|
|
||||||
defineTemplatedRunTimeSelectionTable(writer, word, dataType); \
|
|
||||||
defineTemplatedRunTimeSelectionTable(writer, dict, dataType);
|
|
||||||
|
|
||||||
defineSetWriterType(scalar);
|
|
||||||
defineSetWriterType(vector);
|
|
||||||
defineSetWriterType(sphericalTensor);
|
|
||||||
defineSetWriterType(symmTensor);
|
|
||||||
defineSetWriterType(tensor);
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,85 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ 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/>.
|
|
||||||
|
|
||||||
InClass
|
|
||||||
Foam::writer
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
writers.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef writers_H
|
|
||||||
#define writers_H
|
|
||||||
|
|
||||||
#include "writer.H"
|
|
||||||
#include "fieldTypes.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
// Only used internally
|
|
||||||
#define makeTypeSetWritersTypeName(typeWriter, dataType) \
|
|
||||||
\
|
|
||||||
defineNamedTemplateTypeNameAndDebug(typeWriter<dataType>, 0)
|
|
||||||
|
|
||||||
// Sometimes used externally
|
|
||||||
#define makeSetWritersTypeName(typeWriter) \
|
|
||||||
\
|
|
||||||
makeTypeSetWritersTypeName(typeWriter, scalar); \
|
|
||||||
makeTypeSetWritersTypeName(typeWriter, vector); \
|
|
||||||
makeTypeSetWritersTypeName(typeWriter, sphericalTensor); \
|
|
||||||
makeTypeSetWritersTypeName(typeWriter, symmTensor); \
|
|
||||||
makeTypeSetWritersTypeName(typeWriter, tensor)
|
|
||||||
|
|
||||||
// Define type info for single dataType template instantiation (eg, vector)
|
|
||||||
#define makeSetWriterType(typeWriter, dataType) \
|
|
||||||
\
|
|
||||||
defineNamedTemplateTypeNameAndDebug(typeWriter<dataType>, 0); \
|
|
||||||
addTemplatedToRunTimeSelectionTable \
|
|
||||||
( \
|
|
||||||
writer, typeWriter, dataType, word \
|
|
||||||
); \
|
|
||||||
addTemplatedToRunTimeSelectionTable \
|
|
||||||
( \
|
|
||||||
writer, typeWriter, dataType, dict \
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Define type info for scalar, vector etc. instantiations
|
|
||||||
#define makeSetWriters(typeWriter) \
|
|
||||||
\
|
|
||||||
makeSetWriterType(typeWriter, scalar); \
|
|
||||||
makeSetWriterType(typeWriter, vector); \
|
|
||||||
makeSetWriterType(typeWriter, sphericalTensor); \
|
|
||||||
makeSetWriterType(typeWriter, symmTensor); \
|
|
||||||
makeSetWriterType(typeWriter, tensor)
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -5,8 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,183 +25,242 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "csvSetWriter.H"
|
#include "csvCoordSetWriter.H"
|
||||||
#include "coordSet.H"
|
#include "coordSet.H"
|
||||||
#include "fileName.H"
|
#include "fileName.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
|
#include "coordSetWriterMethods.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
defineTypeName(csvWriter);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, csvWriter, word);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, csvWriter, wordDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
#include "csvCoordSetWriterImpl.C"
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::csvWriter::csvWriter()
|
||||||
Foam::csvSetWriter<Type>::csvSetWriter()
|
|
||||||
:
|
:
|
||||||
writer<Type>()
|
coordSetWriter(),
|
||||||
{}
|
streamOpt_(),
|
||||||
|
precision_(IOstream::defaultPrecision())
|
||||||
|
{
|
||||||
|
buffering_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::csvWriter::csvWriter(const dictionary& options)
|
||||||
Foam::csvSetWriter<Type>::csvSetWriter(const dictionary& dict)
|
|
||||||
:
|
:
|
||||||
writer<Type>(dict)
|
coordSetWriter(options),
|
||||||
{}
|
streamOpt_
|
||||||
|
(
|
||||||
|
IOstream::ASCII,
|
||||||
|
IOstream::compressionEnum("compression", options)
|
||||||
|
),
|
||||||
|
precision_
|
||||||
|
(
|
||||||
|
options.getOrDefault("precision", IOstream::defaultPrecision())
|
||||||
|
)
|
||||||
|
{
|
||||||
|
buffering_ = options.getOrDefault("buffer", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::csvWriter::csvWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
csvWriter(options)
|
||||||
|
{
|
||||||
|
open(coords, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::csvWriter::csvWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
csvWriter(options)
|
||||||
|
{
|
||||||
|
open(tracks, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::coordSetWriters::csvWriter::~csvWriter()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
bool Foam::coordSetWriters::csvWriter::buffering(const bool on)
|
||||||
Foam::fileName Foam::csvSetWriter<Type>::getFileName
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const wordList& valueSetNames
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
return this->getBaseName(points, valueSetNames) + ".csv";
|
const bool old(buffering_);
|
||||||
|
buffering_ = on;
|
||||||
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
Foam::fileName Foam::coordSetWriters::csvWriter::path() const
|
||||||
void Foam::csvSetWriter<Type>::write
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<const Field<Type>*>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
writeHeader(points,valueSetNames,os);
|
// Assume !useTracks_, otherwise too fragile
|
||||||
|
|
||||||
// Collect sets into columns
|
// 1) rootdir/<TIME>/setName.csv
|
||||||
List<const List<Type>*> columns(valueSets.size());
|
// 2) rootdir/setName.csv
|
||||||
|
|
||||||
forAll(valueSets, i)
|
return getExpectedPath("csv");
|
||||||
{
|
|
||||||
columns[i] = valueSets[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
this->writeTable(points, columns, os);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
bool Foam::coordSetWriters::csvWriter::writeBuffered()
|
||||||
void Foam::csvSetWriter<Type>::write
|
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
writeHeader(tracks[0],valueSetNames,os);
|
if (coords_.empty())
|
||||||
|
|
||||||
if (valueSets.size() != valueSetNames.size())
|
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
clearBuffers();
|
||||||
<< "Number of variables:" << valueSetNames.size() << endl
|
return false;
|
||||||
<< "Number of valueSets:" << valueSets.size()
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
}
|
||||||
|
const auto& coords = coords_[0];
|
||||||
|
|
||||||
List<const List<Type>*> columns(valueSets.size());
|
|
||||||
|
|
||||||
forAll(tracks, trackI)
|
DynamicList<word> headCols(3 + nDataColumns());
|
||||||
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
// Collect sets into columns
|
if (coords.hasVectorAxis())
|
||||||
forAll(valueSets, i)
|
|
||||||
{
|
{
|
||||||
columns[i] = &valueSets[i][trackI];
|
// x, y, z
|
||||||
|
headCols.append("x");
|
||||||
|
headCols.append("y");
|
||||||
|
headCols.append("z");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
headCols.append(coords.axis());
|
||||||
}
|
}
|
||||||
|
|
||||||
this->writeTable(tracks[trackI], columns, os);
|
// label, scalar
|
||||||
os << nl << nl;
|
headCols.append(labelNames_);
|
||||||
}
|
headCols.append(scalarNames_);
|
||||||
}
|
|
||||||
|
|
||||||
|
// vector space
|
||||||
template<class Type>
|
#undef doLocalCode
|
||||||
void Foam::csvSetWriter<Type>::writeSeparator(Ostream& os) const
|
#define doLocalCode(Type) \
|
||||||
{
|
\
|
||||||
os << token::COMMA;
|
for (const word& fldName : Type##Names_) \
|
||||||
}
|
{ \
|
||||||
|
for (direction d=0; d < pTraits<Type>::nComponents; ++d) \
|
||||||
|
{ \
|
||||||
namespace Foam
|
headCols.append(fldName + '_' + Foam::name(d)); \
|
||||||
{
|
} \
|
||||||
// otherwise compiler complains about specialization
|
|
||||||
template<>
|
|
||||||
void csvSetWriter<scalar>::writeHeader
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
writeCoordHeader(points, os);
|
|
||||||
|
|
||||||
forAll(valueSetNames, i)
|
|
||||||
{
|
|
||||||
if (i)
|
|
||||||
{
|
|
||||||
writeSeparator(os);
|
|
||||||
}
|
}
|
||||||
os << valueSetNames[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
os << nl;
|
doLocalCode(vector);
|
||||||
|
doLocalCode(sphericalTensor);
|
||||||
|
doLocalCode(symmTensor);
|
||||||
|
doLocalCode(tensor);
|
||||||
|
#undef doLocalCode
|
||||||
}
|
}
|
||||||
|
while (false);
|
||||||
|
|
||||||
|
|
||||||
|
// Field:
|
||||||
|
// 1) rootdir/<TIME>/setName.csv
|
||||||
|
// 2) rootdir/setName.csv
|
||||||
|
|
||||||
|
fileName outputFile = path();
|
||||||
|
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
OFstream os(outputFile, streamOpt_);
|
||||||
|
os.precision(precision_);
|
||||||
|
|
||||||
|
writeLine(os, headCols, ",");
|
||||||
|
|
||||||
|
writeBufferContents(os, coords, ",");
|
||||||
|
|
||||||
|
clearBuffers();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Implementation * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::csvWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const Field<Type>& values
|
||||||
|
)
|
||||||
|
{
|
||||||
|
checkOpen();
|
||||||
|
if (coords_.empty())
|
||||||
|
{
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useTracks_ || !buffering_)
|
||||||
|
{
|
||||||
|
UPtrList<const Field<Type>> fieldPtrs(repackageFields(values));
|
||||||
|
return writeTemplate(fieldName, fieldPtrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffering version
|
||||||
|
appendField(fieldName, values);
|
||||||
|
return path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::csvSetWriter<Type>::writeHeader
|
Foam::fileName Foam::coordSetWriters::csvWriter::writeTemplate
|
||||||
(
|
(
|
||||||
const coordSet& points,
|
const word& fieldName,
|
||||||
const wordList& valueSetNames,
|
const List<Field<Type>>& fieldValues
|
||||||
Ostream& os
|
)
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
writeCoordHeader(points, os);
|
checkOpen();
|
||||||
|
if (coords_.empty())
|
||||||
forAll(valueSetNames, i)
|
|
||||||
{
|
{
|
||||||
for (label j=0; j<Type::nComponents; j++)
|
return fileName::null;
|
||||||
{
|
|
||||||
if (i || j)
|
|
||||||
{
|
|
||||||
writeSeparator(os);
|
|
||||||
}
|
|
||||||
os << valueSetNames[i] << "_" << j;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
useTracks_ = true; // Extra safety
|
||||||
|
|
||||||
os << nl;
|
UPtrList<const Field<Type>> fieldPtrs(repackageFields(fieldValues));
|
||||||
|
return writeTemplate(fieldName, fieldPtrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
void Foam::csvSetWriter<Type>::writeCoordHeader
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const word axisName(points.axis());
|
|
||||||
|
|
||||||
if (points.hasVectorAxis())
|
// Field writing methods
|
||||||
{
|
defineCoordSetWriterWriteFields(Foam::coordSetWriters::csvWriter);
|
||||||
for (auto iter = axisName.cbegin(); iter != axisName.cend(); ++iter)
|
|
||||||
{
|
|
||||||
os << *iter;
|
|
||||||
writeSeparator(os);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
os << axisName;
|
|
||||||
writeSeparator(os);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
179
src/meshTools/coordSet/writers/csv/csvCoordSetWriter.H
Normal file
179
src/meshTools/coordSet/writers/csv/csvCoordSetWriter.H
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::coordSetWriters::csvWriter
|
||||||
|
|
||||||
|
Description
|
||||||
|
Write coordSet(s) in csv format
|
||||||
|
|
||||||
|
The formatOptions for csv:
|
||||||
|
\table
|
||||||
|
Property | Description | Required | Default
|
||||||
|
buffer | Use buffered output | no | true
|
||||||
|
compression | Use file compression | no | false
|
||||||
|
precision | Write precision in ascii | no | same as IOstream
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
When called with a single coordSet, will buffer the output of
|
||||||
|
all fields and output together in the order of label/scalar/vector/...
|
||||||
|
each of which is sorted alphabetically according to the field name.
|
||||||
|
|
||||||
|
When called as a track writer (eg, with multiple coordSets),
|
||||||
|
will emit one file per field.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
csvCoorSetWriter.C
|
||||||
|
csvCoorSetWriterImpl.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_coordSetWriters_csvWriter_H
|
||||||
|
#define Foam_coordSetWriters_csvWriter_H
|
||||||
|
|
||||||
|
#include "coordSetWriter.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class csvWriter Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class csvWriter
|
||||||
|
:
|
||||||
|
public coordSetWriter
|
||||||
|
{
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Output stream option
|
||||||
|
IOstreamOption streamOpt_;
|
||||||
|
|
||||||
|
//- ASCII write precision
|
||||||
|
unsigned precision_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName, //!< Name of field
|
||||||
|
const Field<Type>& vals //!< Local field values to write
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Write buffered data
|
||||||
|
virtual bool writeBuffered();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information (no debug)
|
||||||
|
TypeNameNoDebug("csv");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Default construct
|
||||||
|
csvWriter();
|
||||||
|
|
||||||
|
//- Default construct with specified options
|
||||||
|
explicit csvWriter(const dictionary& options);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
csvWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
csvWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor. Calls close()
|
||||||
|
virtual ~csvWriter();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Enable/disable internal buffering
|
||||||
|
virtual bool buffering(const bool on); // override
|
||||||
|
|
||||||
|
//- Characteristic output file name - information only
|
||||||
|
// \warning incorrect for unbuffered or track output!
|
||||||
|
virtual fileName path() const; // override
|
||||||
|
|
||||||
|
declareCoordSetWriterWriteMethod(label);
|
||||||
|
declareCoordSetWriterWriteMethod(scalar);
|
||||||
|
declareCoordSetWriterWriteMethod(vector);
|
||||||
|
declareCoordSetWriterWriteMethod(sphericalTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(symmTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(tensor);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace coordSetWriters
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
144
src/meshTools/coordSet/writers/csv/csvCoordSetWriterImpl.C
Normal file
144
src/meshTools/coordSet/writers/csv/csvCoordSetWriterImpl.C
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "IOmanip.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
// Output coordinate header
|
||||||
|
static void writeCoordHeader
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const coordSet& coords,
|
||||||
|
const label count /* (future?) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (coords.hasVectorAxis())
|
||||||
|
{
|
||||||
|
os << "x,y,z";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// axis name
|
||||||
|
// const word axisName(coords.axis());
|
||||||
|
os << word(coords.axis());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write field name, use named components for VectorSpace
|
||||||
|
template<class Type>
|
||||||
|
static inline void writeHeader(Ostream& os, const word& fieldName)
|
||||||
|
{
|
||||||
|
/// os << ' '; // Extra space
|
||||||
|
|
||||||
|
const auto nCmpts(pTraits<Type>::nComponents);
|
||||||
|
|
||||||
|
if (pTraits<Type>::rank || nCmpts > 1)
|
||||||
|
{
|
||||||
|
for (direction d = 0; d < nCmpts; ++d)
|
||||||
|
{
|
||||||
|
os << ',' << fieldName
|
||||||
|
<< '_' << pTraits<Type>::componentNames[d];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << ',' << fieldName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::csvWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (coords_.size() != fieldPtrs.size())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Attempted to write field: " << fieldName
|
||||||
|
<< " (" << fieldPtrs.size() << " entries) for "
|
||||||
|
<< coords_.size() << " sets" << nl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
label nPoints = 0;
|
||||||
|
for (const auto& pts : coords_)
|
||||||
|
{
|
||||||
|
nPoints += pts.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Field: rootdir/<TIME>/<field>_setName.csv
|
||||||
|
|
||||||
|
fileName outputFile = getFieldPrefixedPath(fieldName, "csv");
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing field " << fieldName;
|
||||||
|
Info<< " to " << outputFile << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Master only
|
||||||
|
{
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
OFstream os(outputFile, streamOpt_);
|
||||||
|
os.precision(precision_);
|
||||||
|
|
||||||
|
// Header
|
||||||
|
{
|
||||||
|
writeCoordHeader(os, coords_[0], nPoints);
|
||||||
|
writeHeader<Type>(os, fieldName);
|
||||||
|
os << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(coords_, tracki)
|
||||||
|
{
|
||||||
|
writeTable(os, coords_[tracki], fieldPtrs[tracki], ",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wroteGeom_ = true;
|
||||||
|
return outputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -1,131 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::csvSetWriter
|
|
||||||
|
|
||||||
Description
|
|
||||||
Write set in csv format
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
csvCoordSetWriter.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef Foam_coordSetWriters_csvWriter_H
|
|
||||||
#define Foam_coordSetWriters_csvWriter_H
|
|
||||||
|
|
||||||
#include "writer.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class csvSetWriter Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
class csvSetWriter
|
|
||||||
:
|
|
||||||
public writer<Type>
|
|
||||||
{
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
void writeCoordHeader(const coordSet&, Ostream&) const;
|
|
||||||
|
|
||||||
void writeHeader(const coordSet&, const wordList&, Ostream&) const;
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual void writeSeparator(Ostream&) const;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("csv");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Default construct
|
|
||||||
csvSetWriter();
|
|
||||||
|
|
||||||
//- Construct with dictionary
|
|
||||||
explicit csvSetWriter(const dictionary& dict);
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
virtual ~csvSetWriter() = default;
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
virtual fileName getFileName
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&,
|
|
||||||
const List<const Field<Type>*>&,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
#include "csvCoordSetWriter.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ 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/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "csvSetWriter.H"
|
|
||||||
#include "writers.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
makeSetWriters(csvSetWriter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,277 +26,321 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "ensightSetWriter.H"
|
#include "ensightCoordSetWriter.H"
|
||||||
#include "coordSet.H"
|
#include "coordSet.H"
|
||||||
#include "IOmanip.H"
|
#include "IOmanip.H"
|
||||||
#include "ensightCase.H"
|
#include "ensightCase.H"
|
||||||
#include "ensightGeoFile.H"
|
#include "ensightGeoFile.H"
|
||||||
|
#include "ensightOutput.H"
|
||||||
#include "ensightPTraits.H"
|
#include "ensightPTraits.H"
|
||||||
|
#include "coordSetWriterMethods.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
defineTypeName(ensightWriter);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, ensightWriter, word);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, ensightWriter, wordDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
static void writeTrackField
|
||||||
|
(
|
||||||
|
ensightFile& os,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Write field (serial only)
|
||||||
|
os.writeKeyword(ensightPTraits<Type>::typeName);
|
||||||
|
forAll(fieldPtrs, tracki)
|
||||||
|
{
|
||||||
|
// Write as point data
|
||||||
|
|
||||||
|
os.beginPart(tracki); // Part index (0-based)
|
||||||
|
ensightOutput::Detail::writeFieldComponents
|
||||||
|
(
|
||||||
|
os,
|
||||||
|
ensightFile::coordinates,
|
||||||
|
fieldPtrs[tracki],
|
||||||
|
false /* serial only! */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::ensightWriter::writeGeometry
|
||||||
|
(
|
||||||
|
ensightGeoFile& os,
|
||||||
|
elemOutputType elemOutput
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Writing tracks as x/y/z coordinates, optionally with points
|
||||||
|
// or points/lines as elements.
|
||||||
|
//
|
||||||
|
// The requirements are so basic that they do not warrant an
|
||||||
|
// ensightPart treatment at all.
|
||||||
|
|
||||||
|
forAll(coords_, tracki)
|
||||||
|
{
|
||||||
|
const auto& coords = coords_[tracki];
|
||||||
|
const label nPoints = coords.size();
|
||||||
|
|
||||||
|
word partName("track" + Foam::name(tracki));
|
||||||
|
if (coords_.size() == 1 && elemOutputType::WRITE_LINES != elemOutput)
|
||||||
|
{
|
||||||
|
partName = "sampled";
|
||||||
|
}
|
||||||
|
|
||||||
|
ensightOutput::Detail::writeCoordinates
|
||||||
|
(
|
||||||
|
os,
|
||||||
|
tracki, // Part index (0-based)
|
||||||
|
partName,
|
||||||
|
nPoints,
|
||||||
|
static_cast<const pointField&>(coords),
|
||||||
|
false /* serial only! */
|
||||||
|
);
|
||||||
|
|
||||||
|
if (elemOutputType::WRITE_POINTS == elemOutput)
|
||||||
|
{
|
||||||
|
if (nPoints)
|
||||||
|
{
|
||||||
|
os.writeKeyword("point");
|
||||||
|
os.write(nPoints);
|
||||||
|
os.newline();
|
||||||
|
for (label pointi = 0; pointi < nPoints; ++pointi)
|
||||||
|
{
|
||||||
|
os.write(pointi+1); // From 0-based to 1-based index
|
||||||
|
os.newline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (elemOutputType::WRITE_LINES == elemOutput)
|
||||||
|
{
|
||||||
|
const label nLines = (nPoints-1);
|
||||||
|
if (nPoints == 1)
|
||||||
|
{
|
||||||
|
os.writeKeyword("point");
|
||||||
|
os.write(nPoints);
|
||||||
|
os.newline();
|
||||||
|
for (label pointi = 0; pointi < nPoints; ++pointi)
|
||||||
|
{
|
||||||
|
os.write(pointi+1); // From 0-based to 1-based index
|
||||||
|
os.newline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (nLines > 0)
|
||||||
|
{
|
||||||
|
os.writeKeyword("bar2");
|
||||||
|
os.write(nLines);
|
||||||
|
os.newline();
|
||||||
|
for (label pointi = 0; pointi < nLines; ++pointi)
|
||||||
|
{
|
||||||
|
os.write(pointi+1); // From 0-based to 1-based index
|
||||||
|
os.write(pointi+2);
|
||||||
|
os.newline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::ensightWriter::ensightWriter()
|
||||||
Foam::ensightSetWriter<Type>::ensightSetWriter()
|
|
||||||
:
|
:
|
||||||
writer<Type>()
|
coordSetWriter(),
|
||||||
|
writeFormat_(IOstream::ASCII),
|
||||||
|
collateTimes_(true),
|
||||||
|
caching_("fieldsDict") // Historic name
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::ensightWriter::ensightWriter(const dictionary& options)
|
||||||
Foam::ensightSetWriter<Type>::ensightSetWriter(const dictionary& dict)
|
|
||||||
:
|
:
|
||||||
writer<Type>(dict)
|
coordSetWriter(options),
|
||||||
|
writeFormat_
|
||||||
|
(
|
||||||
|
IOstreamOption::formatEnum("format", options, IOstream::ASCII)
|
||||||
|
),
|
||||||
|
collateTimes_(options.getOrDefault("collateTimes", true)),
|
||||||
|
caching_("fieldsDict") // Historic name
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::ensightWriter::ensightWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
ensightWriter(options)
|
||||||
|
{
|
||||||
|
open(coords, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::ensightWriter::ensightWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
ensightWriter(options)
|
||||||
|
{
|
||||||
|
open(tracks, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::coordSetWriters::ensightWriter::~ensightWriter()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
Foam::fileName Foam::coordSetWriters::ensightWriter::path() const
|
||||||
Foam::fileName Foam::ensightSetWriter<Type>::getFileName
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const wordList& valueSetNames
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
return
|
// Assume collateTimes == true, otherwise too fragile
|
||||||
this->getBaseName(points, valueSetNames)
|
|
||||||
//+ '_'
|
// Collated
|
||||||
//+ ensightPTraits<Type>::typeName
|
// ========
|
||||||
+ ".case";
|
// CaseFile: rootdir/NAME/NAME.case
|
||||||
|
// Geometry: rootdir/NAME/data/<index>/geometry
|
||||||
|
// Field: rootdir/NAME/data/<index>/field
|
||||||
|
|
||||||
|
if (!outputPath_.empty())
|
||||||
|
{
|
||||||
|
return outputPath_ / (ensight::FileName(outputPath_.name()) + ".case");
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
void Foam::coordSetWriters::ensightWriter::close(const bool force)
|
||||||
void Foam::ensightSetWriter<Type>::write
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<const Field<Type>*>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
const fileName base(os.name().lessExt());
|
caching_.clear();
|
||||||
const fileName meshFile(base + ".mesh");
|
coordSetWriter::close(force);
|
||||||
|
}
|
||||||
|
|
||||||
// Write .case file
|
|
||||||
os << "FORMAT" << nl
|
|
||||||
<< "type: ensight gold" << nl
|
|
||||||
<< nl
|
|
||||||
<< "GEOMETRY" << nl
|
|
||||||
<< "model: 1 " << meshFile.name().c_str() << nl
|
|
||||||
<< nl
|
|
||||||
<< "VARIABLE"
|
|
||||||
<< nl;
|
|
||||||
|
|
||||||
for (const word& valueName : valueSetNames)
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
// Field writing implementations
|
||||||
|
|
||||||
|
#include "ensightCoordSetWriterCollated.C"
|
||||||
|
#include "ensightCoordSetWriterUncollated.C"
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::ensightWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const Field<Type>& values
|
||||||
|
)
|
||||||
|
{
|
||||||
|
checkOpen();
|
||||||
|
if (coords_.empty())
|
||||||
{
|
{
|
||||||
fileName dataFile(base + ".***." + valueName);
|
return fileName::null;
|
||||||
|
|
||||||
os.setf(ios_base::left);
|
|
||||||
os << ensightPTraits<Type>::typeName
|
|
||||||
<< " per node: 1 "
|
|
||||||
<< setw(15) << valueName
|
|
||||||
<< " " << dataFile.name().c_str()
|
|
||||||
<< nl;
|
|
||||||
}
|
}
|
||||||
os << nl
|
if (coords_.size() != 1)
|
||||||
<< "TIME" << nl
|
|
||||||
<< "time set: 1" << nl
|
|
||||||
<< "number of steps: 1" << nl
|
|
||||||
<< "filename start number: 0" << nl
|
|
||||||
<< "filename increment: 1" << nl
|
|
||||||
<< "time values:" << nl
|
|
||||||
<< "0.00000e+00" << nl;
|
|
||||||
|
|
||||||
// Write .mesh file
|
|
||||||
{
|
{
|
||||||
string desc("Written by OpenFOAM");
|
FatalErrorInFunction
|
||||||
OFstream os(meshFile);
|
<< "Attempted to write field: " << fieldName
|
||||||
os.setf(ios_base::scientific, ios_base::floatfield);
|
<< " (" << 1 << " entries) for "
|
||||||
os.precision(5);
|
<< coords_.size() << " sets" << nl
|
||||||
|
<< exit(FatalError);
|
||||||
os << "Ensight Geometry File" << nl
|
|
||||||
<< desc.c_str() << nl
|
|
||||||
<< "node id assign" << nl
|
|
||||||
<< "element id assign" << nl
|
|
||||||
<< "part" << nl
|
|
||||||
<< setw(10) << 1 << nl
|
|
||||||
<< "internalMesh" << nl
|
|
||||||
<< "coordinates" << nl
|
|
||||||
<< setw(10) << points.size() << nl;
|
|
||||||
|
|
||||||
for (direction cmpt = 0; cmpt < vector::nComponents; ++cmpt)
|
|
||||||
{
|
|
||||||
for (const point& p : points)
|
|
||||||
{
|
|
||||||
const float comp = narrowFloat(p[cmpt]);
|
|
||||||
os << setw(12) << comp << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
os << "point" << nl
|
|
||||||
<< setw(10) << points.size() << nl;
|
|
||||||
forAll(points, pointi)
|
|
||||||
{
|
|
||||||
os << setw(10) << pointi+1 << nl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write data files
|
UPtrList<const Field<Type>> fieldPtrs(repackageFields(values));
|
||||||
forAll(valueSetNames, seti)
|
|
||||||
|
elemOutputType elemOutput =
|
||||||
|
(
|
||||||
|
useTracks_
|
||||||
|
? elemOutputType::WRITE_LINES
|
||||||
|
: elemOutputType::NO_ELEMENTS
|
||||||
|
);
|
||||||
|
|
||||||
|
if (collateTimes_)
|
||||||
{
|
{
|
||||||
const word& valueName = valueSetNames[seti];
|
return writeCollated(fieldName, fieldPtrs, elemOutput);
|
||||||
const Field<Type>& fld = *(valueSets[seti]);
|
}
|
||||||
|
else
|
||||||
fileName dataFile(base + ".000." + valueName);
|
{
|
||||||
OFstream os(dataFile);
|
return writeUncollated(fieldName, fieldPtrs, elemOutput);
|
||||||
os.setf(ios_base::scientific, ios_base::floatfield);
|
|
||||||
os.precision(5);
|
|
||||||
|
|
||||||
os << ensightPTraits<Type>::typeName << nl
|
|
||||||
<< "part" << nl
|
|
||||||
<< setw(10) << 1 << nl
|
|
||||||
<< "coordinates" << nl;
|
|
||||||
|
|
||||||
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
|
|
||||||
{
|
|
||||||
const direction cmpt = ensightPTraits<Type>::componentOrder[d];
|
|
||||||
|
|
||||||
for (const Type& val : fld)
|
|
||||||
{
|
|
||||||
const float comp = narrowFloat(component(val, cmpt));
|
|
||||||
os << setw(12) << comp << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::ensightSetWriter<Type>::write
|
Foam::fileName Foam::coordSetWriters::ensightWriter::writeTemplate
|
||||||
(
|
(
|
||||||
const bool writeTracks,
|
const word& fieldName,
|
||||||
const List<scalarField>& times,
|
const List<Field<Type>>& fieldValues
|
||||||
const PtrList<coordSet>& tracks,
|
)
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
const fileName base(os.name().lessExt());
|
checkOpen();
|
||||||
const fileName meshFile(base + ".mesh");
|
if (coords_.empty())
|
||||||
|
|
||||||
// Write .case file
|
|
||||||
os << "FORMAT" << nl
|
|
||||||
<< "type: ensight gold" << nl
|
|
||||||
<< nl
|
|
||||||
<< "GEOMETRY" << nl
|
|
||||||
<< "model: 1 " << meshFile.name().c_str() << nl
|
|
||||||
<< nl
|
|
||||||
<< "VARIABLE"
|
|
||||||
<< nl;
|
|
||||||
|
|
||||||
for (const word& valueName : valueSetNames)
|
|
||||||
{
|
{
|
||||||
fileName dataFile(base + ".***." + valueName);
|
return fileName::null;
|
||||||
|
|
||||||
os.setf(ios_base::left);
|
|
||||||
os << ensightPTraits<Type>::typeName
|
|
||||||
<< " per node: 1 "
|
|
||||||
<< setw(15) << valueName
|
|
||||||
<< " " << dataFile.name().c_str()
|
|
||||||
<< nl;
|
|
||||||
}
|
}
|
||||||
os << nl
|
if (coords_.size() != fieldValues.size())
|
||||||
<< "TIME" << nl
|
|
||||||
<< "time set: 1" << nl
|
|
||||||
<< "number of steps: 1" << nl
|
|
||||||
<< "filename start number: 0" << nl
|
|
||||||
<< "filename increment: 1" << nl
|
|
||||||
<< "time values:" << nl
|
|
||||||
<< "0.00000e+00" << nl;
|
|
||||||
|
|
||||||
// Write .mesh file
|
|
||||||
{
|
{
|
||||||
string desc("Written by OpenFOAM");
|
FatalErrorInFunction
|
||||||
OFstream os(meshFile);
|
<< "Attempted to write field: " << fieldName
|
||||||
os.setf(ios_base::scientific, ios_base::floatfield);
|
<< " (" << fieldValues.size() << " entries) for "
|
||||||
os.precision(5);
|
<< coords_.size() << " sets" << nl
|
||||||
os << "Ensight Geometry File" << nl
|
<< exit(FatalError);
|
||||||
<< desc.c_str() << nl
|
|
||||||
<< "node id assign" << nl
|
|
||||||
<< "element id assign" << nl;
|
|
||||||
|
|
||||||
forAll(tracks, tracki)
|
|
||||||
{
|
|
||||||
const coordSet& points = tracks[tracki];
|
|
||||||
|
|
||||||
os << "part" << nl
|
|
||||||
<< setw(10) << tracki+1 << nl
|
|
||||||
<< "internalMesh" << nl
|
|
||||||
<< "coordinates" << nl
|
|
||||||
<< setw(10) << points.size() << nl;
|
|
||||||
|
|
||||||
for (direction cmpt = 0; cmpt < vector::nComponents; ++cmpt)
|
|
||||||
{
|
|
||||||
for (const point& p : points)
|
|
||||||
{
|
|
||||||
const float comp = narrowFloat(p[cmpt]);
|
|
||||||
os << setw(12) << comp << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (writeTracks)
|
|
||||||
{
|
|
||||||
os << "bar2" << nl
|
|
||||||
<< setw(10) << points.size()-1 << nl;
|
|
||||||
for (label i = 0; i < points.size()-1; i++)
|
|
||||||
{
|
|
||||||
os << setw(10) << i+1
|
|
||||||
<< setw(10) << i+2
|
|
||||||
<< nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UPtrList<const Field<Type>> fieldPtrs(repackageFields(fieldValues));
|
||||||
|
|
||||||
// Write data files
|
if (collateTimes_)
|
||||||
forAll(valueSetNames, seti)
|
|
||||||
{
|
{
|
||||||
const word& valueName = valueSetNames[seti];
|
return writeCollated
|
||||||
const List<Field<Type>>& fieldVals = valueSets[seti];
|
(
|
||||||
|
fieldName,
|
||||||
fileName dataFile(base + ".000." + valueName);
|
fieldPtrs,
|
||||||
OFstream os(dataFile);
|
elemOutputType::WRITE_LINES
|
||||||
os.setf(ios_base::scientific, ios_base::floatfield);
|
);
|
||||||
os.precision(5);
|
}
|
||||||
{
|
else
|
||||||
os << ensightPTraits<Type>::typeName << nl;
|
{
|
||||||
|
return writeUncollated
|
||||||
forAll(fieldVals, tracki)
|
(
|
||||||
{
|
fieldName,
|
||||||
const Field<Type>& fld = fieldVals[tracki];
|
fieldPtrs,
|
||||||
|
elemOutputType::WRITE_LINES
|
||||||
os << "part" << nl
|
);
|
||||||
<< setw(10) << tracki+1 << nl
|
|
||||||
<< "coordinates" << nl;
|
|
||||||
|
|
||||||
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
|
|
||||||
{
|
|
||||||
const direction cmpt =
|
|
||||||
ensightPTraits<Type>::componentOrder[d];
|
|
||||||
|
|
||||||
for (const Type& val : fld)
|
|
||||||
{
|
|
||||||
const float comp = narrowFloat(component(val, cmpt));
|
|
||||||
os << setw(12) << comp << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Field writing methods
|
||||||
|
defineCoordSetWriterWriteFields(Foam::coordSetWriters::ensightWriter);
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
220
src/meshTools/coordSet/writers/ensight/ensightCoordSetWriter.H
Normal file
220
src/meshTools/coordSet/writers/ensight/ensightCoordSetWriter.H
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::coordSetWriters::ensightCoordSetWriter
|
||||||
|
|
||||||
|
Description
|
||||||
|
A coordSetWriter 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
|
||||||
|
ensightCoordSetWriter.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_coordSetWriters_ensightWriter_H
|
||||||
|
#define Foam_coordSetWriters_ensightWriter_H
|
||||||
|
|
||||||
|
#include "coordSetWriter.H"
|
||||||
|
#include "ensightWriterCaching.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
class ensightGeoFile;
|
||||||
|
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class ensightWriter Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class ensightWriter
|
||||||
|
:
|
||||||
|
public coordSetWriter
|
||||||
|
{
|
||||||
|
// Data Types
|
||||||
|
|
||||||
|
//- Types of element output
|
||||||
|
enum elemOutputType
|
||||||
|
{
|
||||||
|
NO_ELEMENTS = 0,
|
||||||
|
WRITE_POINTS = 1,
|
||||||
|
WRITE_LINES = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Output format option (default: IOstream::ASCII)
|
||||||
|
IOstreamOption::streamFormat writeFormat_;
|
||||||
|
|
||||||
|
//- Collate times (default: true)
|
||||||
|
bool collateTimes_;
|
||||||
|
|
||||||
|
//- Cached information for times, geometry, fields (collated)
|
||||||
|
ensightOutput::writerCaching caching_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Write geometry
|
||||||
|
void writeGeometry
|
||||||
|
(
|
||||||
|
ensightGeoFile& os,
|
||||||
|
elemOutputType elemOutput
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Write geometry
|
||||||
|
fileName writeCollated(const bool writeTracks);
|
||||||
|
|
||||||
|
//- Write geometry
|
||||||
|
fileName writeUncollated(const bool writeTracks);
|
||||||
|
|
||||||
|
//- Templated write operation - one file per timestep
|
||||||
|
template<class Type>
|
||||||
|
fileName writeCollated
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs,
|
||||||
|
elemOutputType elemOutput
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation - all time steps in single file
|
||||||
|
template<class Type>
|
||||||
|
fileName writeUncollated
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs,
|
||||||
|
elemOutputType elemOutput
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const Field<Type>& values
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information (no debug)
|
||||||
|
TypeNameNoDebug("ensight");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Default construct
|
||||||
|
ensightWriter();
|
||||||
|
|
||||||
|
//- Default construct with specified options
|
||||||
|
explicit ensightWriter(const dictionary& options);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
ensightWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
ensightWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor. Calls close()
|
||||||
|
virtual ~ensightWriter();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Finish output, clears output times.
|
||||||
|
// Later reuse will rebuild times from fieldsDict file cache.
|
||||||
|
virtual void close(bool force = false); // override
|
||||||
|
|
||||||
|
|
||||||
|
// Write
|
||||||
|
|
||||||
|
//- Expected (characteristic) output file name - information only
|
||||||
|
// \warning incorrect for uncollated output!
|
||||||
|
virtual fileName path() const; // override
|
||||||
|
|
||||||
|
declareCoordSetWriterWriteMethod(label);
|
||||||
|
declareCoordSetWriterWriteMethod(scalar);
|
||||||
|
declareCoordSetWriterWriteMethod(vector);
|
||||||
|
declareCoordSetWriterWriteMethod(sphericalTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(symmTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(tensor);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace coordSetWriters
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,280 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::fileName Foam::coordSetWriters::ensightWriter::writeCollated
|
||||||
|
(
|
||||||
|
const bool writeTracks
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Collated?
|
||||||
|
// ========
|
||||||
|
// CaseFile: rootdir/NAME/NAME.case
|
||||||
|
// Geometry: rootdir/NAME/NAME.mesh
|
||||||
|
|
||||||
|
wroteGeom_ = true;
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::ensightWriter::writeCollated
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs,
|
||||||
|
elemOutputType elemOutput
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Geometry changed since last output? Capture now
|
||||||
|
const bool geomChanged = (!upToDate_);
|
||||||
|
|
||||||
|
checkOpen();
|
||||||
|
|
||||||
|
const ensight::FileName baseName(outputPath_.name());
|
||||||
|
const ensight::VarName varName(fieldName);
|
||||||
|
|
||||||
|
|
||||||
|
// Collated
|
||||||
|
// ========
|
||||||
|
// CaseFile: rootdir/NAME/NAME.case
|
||||||
|
// Geometry: rootdir/NAME/data/<index>/geometry
|
||||||
|
// Field: rootdir/NAME/data/<index>/field
|
||||||
|
|
||||||
|
// Use geometry name as sub-directory for results. Eg,
|
||||||
|
// - NAME1/NAME1.case
|
||||||
|
// - NAME1/data/00000000/geometry
|
||||||
|
// - NAME1/data/00000000/VAR1
|
||||||
|
// - NAME1/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 / baseName + ".case";
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing case file to " << outputFile << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update geometry
|
||||||
|
merge();
|
||||||
|
|
||||||
|
{
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool stateChanged =
|
||||||
|
caching_.update
|
||||||
|
(
|
||||||
|
baseDir,
|
||||||
|
timeValue,
|
||||||
|
geomChanged,
|
||||||
|
fieldName,
|
||||||
|
ensightPTraits<Type>::typeName,
|
||||||
|
varName
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// The most current time and geometry indices
|
||||||
|
const label timeIndex = caching_.latestTimeIndex();
|
||||||
|
const label geomIndex = caching_.latestGeomIndex();
|
||||||
|
|
||||||
|
|
||||||
|
// This will be used for the name of a static geometry,
|
||||||
|
// or just the masking part for moving geometries.
|
||||||
|
const fileName geometryName
|
||||||
|
(
|
||||||
|
"data"/word::printf(fmt, geomIndex)/ensightCase::geometryName
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Do case file
|
||||||
|
if (stateChanged)
|
||||||
|
{
|
||||||
|
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 = caching_.geometryTimeset();
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
for (const entry& dEntry : caching_.fieldsDict())
|
||||||
|
{
|
||||||
|
const dictionary& subDict = dEntry.dict();
|
||||||
|
|
||||||
|
const word varType(subDict.get<word>("type"));
|
||||||
|
const word varName
|
||||||
|
(
|
||||||
|
subDict.getOrDefault<word>
|
||||||
|
(
|
||||||
|
"name",
|
||||||
|
dEntry.keyword() // fieldName as fallback
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
osCase
|
||||||
|
<< varType
|
||||||
|
<<
|
||||||
|
(
|
||||||
|
true // this->isPointData()
|
||||||
|
? " per node: 1 " // time-set 1
|
||||||
|
: " per element: 1 " // time-set 1
|
||||||
|
)
|
||||||
|
<< setw(15) << varName << ' '
|
||||||
|
<< mask << varName << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
osCase
|
||||||
|
<< nl
|
||||||
|
<< "TIME" << nl;
|
||||||
|
|
||||||
|
ensightCase::printTimeset(osCase, 1, caching_.times());
|
||||||
|
if (tsGeom == 2)
|
||||||
|
{
|
||||||
|
ensightCase::printTimeset
|
||||||
|
(
|
||||||
|
osCase,
|
||||||
|
tsGeom,
|
||||||
|
caching_.times(),
|
||||||
|
caching_.geometries()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 geomFile(baseDir/geometryName);
|
||||||
|
|
||||||
|
if (!exists(geomFile))
|
||||||
|
{
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing geometry to " << geomFile.name() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Two-argument form for path-name to avoid validating base-dir
|
||||||
|
ensightGeoFile osGeom
|
||||||
|
(
|
||||||
|
geomFile.path(),
|
||||||
|
geomFile.name(),
|
||||||
|
writeFormat_
|
||||||
|
);
|
||||||
|
|
||||||
|
writeGeometry(osGeom, elemOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Write field
|
||||||
|
ensightFile osField
|
||||||
|
(
|
||||||
|
dataDir,
|
||||||
|
varName,
|
||||||
|
writeFormat_
|
||||||
|
);
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing field file to " << osField.name() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Write field (serial only)
|
||||||
|
writeTrackField<Type>(osField, fieldPtrs);
|
||||||
|
|
||||||
|
|
||||||
|
// Timestamp in the directory for future reference
|
||||||
|
{
|
||||||
|
OFstream timeStamp(dataDir/"time");
|
||||||
|
timeStamp
|
||||||
|
<< "# timestep time" << nl
|
||||||
|
<< dataDir.name() << ' ' << timeValue << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wroteGeom_ = true;
|
||||||
|
return outputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,158 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::fileName Foam::coordSetWriters::ensightWriter::writeUncollated
|
||||||
|
(
|
||||||
|
const bool writeTracks
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::ensightWriter::writeUncollated
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs,
|
||||||
|
elemOutputType elemOutput
|
||||||
|
)
|
||||||
|
{
|
||||||
|
checkOpen();
|
||||||
|
|
||||||
|
const ensight::FileName baseName(outputPath_.name());
|
||||||
|
const ensight::VarName varName(fieldName);
|
||||||
|
|
||||||
|
|
||||||
|
// Uncollated
|
||||||
|
// ==========
|
||||||
|
// CaseFile: rootdir/time/<field>/NAME.case
|
||||||
|
// Geometry: rootdir/time/<field>/NAME.<index>.mesh
|
||||||
|
// Field: rootdir/time/<field>/NAME.<index>.<field>
|
||||||
|
|
||||||
|
// Variable name as sub-directory for results. Eg,
|
||||||
|
// - VAR1/NAME1.case
|
||||||
|
// - VAR1/NAME1.00000000.mesh
|
||||||
|
// - VAR1/NAME1.00000001.VAR1
|
||||||
|
// and
|
||||||
|
// - VAR2/NAME1.case
|
||||||
|
// - VAR2/NAME1.00000000.mesh
|
||||||
|
// - VAR2/NAME1.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 / baseName + ".case";
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing case file to " << outputFile << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
merge();
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Two-argument form for path-name to avoid validating base-dir
|
||||||
|
ensightGeoFile osGeom
|
||||||
|
(
|
||||||
|
baseDir,
|
||||||
|
baseName + ".00000000.mesh",
|
||||||
|
writeFormat_
|
||||||
|
);
|
||||||
|
ensightFile osField
|
||||||
|
(
|
||||||
|
baseDir,
|
||||||
|
baseName + ".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
|
||||||
|
<<
|
||||||
|
(
|
||||||
|
true // this->isPointData()
|
||||||
|
? " per node: 1 " // time-set 1
|
||||||
|
: " per element: 1 " // time-set 1
|
||||||
|
)
|
||||||
|
<< setw(15) << varName << ' '
|
||||||
|
<< baseName.c_str() << ".********." << varName << nl;
|
||||||
|
|
||||||
|
osCase
|
||||||
|
<< nl
|
||||||
|
<< "TIME" << nl;
|
||||||
|
|
||||||
|
ensightCase::printTimeset(osCase, 1, timeValue);
|
||||||
|
osCase << "# end" << nl;
|
||||||
|
|
||||||
|
|
||||||
|
writeGeometry(osGeom, elemOutput);
|
||||||
|
|
||||||
|
// Write field (serial only)
|
||||||
|
writeTrackField<Type>(osField, fieldPtrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
wroteGeom_ = true;
|
||||||
|
return outputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -1,118 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::ensightSetWriter
|
|
||||||
|
|
||||||
Description
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
ensightCoordSetWriter.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef Foam_coordSetWriters_ensightWriter_H
|
|
||||||
#define Foam_coordSetWriters_ensightWriter_H
|
|
||||||
|
|
||||||
#include "writer.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class ensightSetWriter Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
class ensightSetWriter
|
|
||||||
:
|
|
||||||
public writer<Type>
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("ensight");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Default construct
|
|
||||||
ensightSetWriter();
|
|
||||||
|
|
||||||
//- Construct with dictionary
|
|
||||||
explicit ensightSetWriter(const dictionary& dict);
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
virtual ~ensightSetWriter() = default;
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
virtual fileName getFileName
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&,
|
|
||||||
const List<const Field<Type>*>&,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
#include "ensightCoordSetWriter.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ 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/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "ensightSetWriter.H"
|
|
||||||
#include "writers.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
makeSetWriters(ensightSetWriter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -25,19 +25,30 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "gltfSetWriter.H"
|
#include "gltfCoordSetWriter.H"
|
||||||
#include "coordSet.H"
|
#include "coordSet.H"
|
||||||
#include "fileName.H"
|
#include "fileName.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
#include "floatVector.H"
|
#include "OSspecific.H"
|
||||||
#include "foamGltfScene.H"
|
#include "foamGltfScene.H"
|
||||||
|
#include "foamGltfSceneWriter.H"
|
||||||
|
#include "coordSetWriterMethods.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
namespace Foam
|
||||||
const Foam::Enum<typename Foam::gltfSetWriter<Type>::fieldOption>
|
{
|
||||||
Foam::gltfSetWriter<Type>::fieldOptionNames_
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
defineTypeName(gltfWriter);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, gltfWriter, word);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, gltfWriter, wordDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Foam::Enum<Foam::coordSetWriters::gltfWriter::fieldOption>
|
||||||
|
Foam::coordSetWriters::gltfWriter::fieldOptionNames_
|
||||||
({
|
({
|
||||||
// No naming for NONE
|
// No naming for NONE
|
||||||
{ fieldOption::UNIFORM, "uniform" },
|
{ fieldOption::UNIFORM, "uniform" },
|
||||||
@ -45,10 +56,90 @@ Foam::gltfSetWriter<Type>::fieldOptionNames_
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::word Foam::gltfSetWriter<Type>::getColourMap
|
static tmp<vectorField> getBoundedColours
|
||||||
|
(
|
||||||
|
const colourTable& colours,
|
||||||
|
const Field<Type>& field,
|
||||||
|
const scalar boundMin,
|
||||||
|
const scalar boundMax
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label boundDelta = (boundMax - boundMin + ROOTVSMALL);
|
||||||
|
|
||||||
|
auto tresult = tmp<vectorField>::New(field.size());
|
||||||
|
auto& result = tresult.ref();
|
||||||
|
|
||||||
|
forAll(field, i)
|
||||||
|
{
|
||||||
|
const Type& val = field[i];
|
||||||
|
|
||||||
|
const scalar f =
|
||||||
|
(
|
||||||
|
pTraits<Type>::nComponents == 1
|
||||||
|
? scalar(component(val, 0))
|
||||||
|
: scalar(mag(val))
|
||||||
|
);
|
||||||
|
|
||||||
|
// 0-1 clipped by value()
|
||||||
|
result[i] = colours.value((f - boundMin)/boundDelta);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
static vector getAnimationColour
|
||||||
|
(
|
||||||
|
const dictionary& dict,
|
||||||
|
const colourTable& colours,
|
||||||
|
const Field<Type>& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
scalar refValue(0);
|
||||||
|
scalarMinMax valLimits;
|
||||||
|
|
||||||
|
if (pTraits<Type>::nComponents == 1)
|
||||||
|
{
|
||||||
|
MinMax<Type> scanned(minMax(field));
|
||||||
|
|
||||||
|
refValue = scalar(component(field[0], 0));
|
||||||
|
valLimits.min() = scalar(component(scanned.min(), 0));
|
||||||
|
valLimits.max() = scalar(component(scanned.max(), 0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use mag() for multiple components
|
||||||
|
refValue = mag(field[0]);
|
||||||
|
valLimits = minMaxMag(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
dict.readIfPresent("min", valLimits.min());
|
||||||
|
dict.readIfPresent("max", valLimits.max());
|
||||||
|
|
||||||
|
const scalar fraction =
|
||||||
|
(
|
||||||
|
(refValue - valLimits.min())
|
||||||
|
/ (valLimits.max() - valLimits.min() + ROOTVSMALL)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 0-1 clipped by value()
|
||||||
|
return colours.value(fraction);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::word Foam::coordSetWriters::gltfWriter::getColourMap
|
||||||
(
|
(
|
||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
) const
|
) const
|
||||||
@ -60,8 +151,7 @@ Foam::word Foam::gltfSetWriter<Type>::getColourMap
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
const Foam::colourTable& Foam::coordSetWriters::gltfWriter::getColourTable
|
||||||
const Foam::colourTable& Foam::gltfSetWriter<Type>::getColourTable
|
|
||||||
(
|
(
|
||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
) const
|
) const
|
||||||
@ -70,8 +160,7 @@ const Foam::colourTable& Foam::gltfSetWriter<Type>::getColourTable
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
Foam::scalarMinMax Foam::coordSetWriters::gltfWriter::getFieldLimits
|
||||||
Foam::scalarMinMax Foam::gltfSetWriter<Type>::getFieldLimits
|
|
||||||
(
|
(
|
||||||
const word& fieldName
|
const word& fieldName
|
||||||
) const
|
) const
|
||||||
@ -87,8 +176,8 @@ Foam::scalarMinMax Foam::gltfSetWriter<Type>::getFieldLimits
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
Foam::tmp<Foam::scalarField>
|
||||||
Foam::tmp<Foam::scalarField> Foam::gltfSetWriter<Type>::getAlphaField
|
Foam::coordSetWriters::gltfWriter::getAlphaField
|
||||||
(
|
(
|
||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
) const
|
) const
|
||||||
@ -141,27 +230,10 @@ Foam::tmp<Foam::scalarField> Foam::gltfSetWriter<Type>::getAlphaField
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
void Foam::coordSetWriters::gltfWriter::setupAnimationColour()
|
||||||
Foam::vector Foam::gltfSetWriter<Type>::getTrackAnimationColour
|
|
||||||
(
|
|
||||||
const colourTable& colours,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
const label tracki
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
if (!colour_)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Attempting to get colour when colour option is off"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
const dictionary& dict = animationDict_;
|
const dictionary& dict = animationDict_;
|
||||||
|
|
||||||
// Fallback value
|
|
||||||
vector colourValue(Zero);
|
|
||||||
|
|
||||||
const entry* eptr = dict.findEntry("colour", keyType::LITERAL);
|
const entry* eptr = dict.findEntry("colour", keyType::LITERAL);
|
||||||
|
|
||||||
if (!eptr || !eptr->isStream())
|
if (!eptr || !eptr->isStream())
|
||||||
@ -175,8 +247,11 @@ Foam::vector Foam::gltfSetWriter<Type>::getTrackAnimationColour
|
|||||||
// Value specified
|
// Value specified
|
||||||
|
|
||||||
ITstream& is = eptr->stream();
|
ITstream& is = eptr->stream();
|
||||||
is >> colourValue;
|
is >> animateColourValue_;
|
||||||
dict.checkITstream(is, "colour");
|
dict.checkITstream(is, "colour");
|
||||||
|
|
||||||
|
// Has uniform value
|
||||||
|
animateColourOption_ = fieldOption::UNIFORM;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -188,85 +263,59 @@ Foam::vector Foam::gltfSetWriter<Type>::getTrackAnimationColour
|
|||||||
{
|
{
|
||||||
case fieldOption::NONE:
|
case fieldOption::NONE:
|
||||||
{
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Cannot select 'none' for colour entry!" << nl
|
||||||
|
<< "... possible programming error"
|
||||||
|
<< exit(FatalError);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case fieldOption::UNIFORM:
|
case fieldOption::UNIFORM:
|
||||||
{
|
{
|
||||||
dict.readEntry("colourValue", colourValue);
|
dict.readEntry("colourValue", animateColourValue_);
|
||||||
|
|
||||||
|
// Has uniform value
|
||||||
|
animateColourOption_ = fieldOption::UNIFORM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case fieldOption::FIELD:
|
case fieldOption::FIELD:
|
||||||
{
|
{
|
||||||
const word fieldName = dict.get<word>("colourField");
|
// Needs named field...
|
||||||
const label fieldi = valueSetNames.find(fieldName);
|
animateColourName_ = dict.get<word>("colourField");
|
||||||
if (fieldi == -1)
|
animateColourOption_ = fieldOption::FIELD;
|
||||||
{
|
break;
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Unable to find field " << fieldName
|
|
||||||
<< ". Valid field names are:" << valueSetNames
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Field<Type>& colourFld = valueSets[fieldi][tracki];
|
|
||||||
|
|
||||||
|
|
||||||
scalar refValue(0);
|
|
||||||
scalarMinMax valLimits;
|
|
||||||
|
|
||||||
if (pTraits<Type>::nComponents == 1)
|
|
||||||
{
|
|
||||||
MinMax<Type> scanned(minMax(colourFld));
|
|
||||||
|
|
||||||
refValue = scalar(component(colourFld[0], 0));
|
|
||||||
valLimits.min() = scalar(component(scanned.min(), 0));
|
|
||||||
valLimits.max() = scalar(component(scanned.max(), 0));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Use mag() for multiple components
|
|
||||||
refValue = mag(colourFld[0]);
|
|
||||||
valLimits = minMaxMag(colourFld);
|
|
||||||
}
|
|
||||||
|
|
||||||
dict.readIfPresent("min", valLimits.min());
|
|
||||||
dict.readIfPresent("max", valLimits.max());
|
|
||||||
|
|
||||||
const scalar fraction =
|
|
||||||
(
|
|
||||||
(refValue - valLimits.min())
|
|
||||||
/ (valLimits.max() - valLimits.min() + ROOTVSMALL)
|
|
||||||
);
|
|
||||||
|
|
||||||
return colours.value(fraction); // 0-1 clipped by value()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return colourValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::gltfWriter::gltfWriter()
|
||||||
Foam::gltfSetWriter<Type>::gltfSetWriter()
|
|
||||||
:
|
:
|
||||||
writer<Type>(),
|
coordSetWriter(),
|
||||||
|
writer_(nullptr),
|
||||||
animate_(false),
|
animate_(false),
|
||||||
colour_(false),
|
colour_(false),
|
||||||
|
animateColourOption_(fieldOption::NONE),
|
||||||
|
animateColourName_(),
|
||||||
|
animateColourValue_(Zero),
|
||||||
fieldInfoDict_(),
|
fieldInfoDict_(),
|
||||||
animationDict_()
|
animationDict_()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::gltfWriter::gltfWriter(const dictionary& options)
|
||||||
Foam::gltfSetWriter<Type>::gltfSetWriter(const dictionary& dict)
|
|
||||||
:
|
:
|
||||||
writer<Type>(dict),
|
coordSetWriter(options),
|
||||||
animate_(dict.getOrDefault("animate", false)),
|
writer_(nullptr),
|
||||||
colour_(dict.getOrDefault("colour", false)),
|
animate_(options.getOrDefault("animate", false)),
|
||||||
fieldInfoDict_(dict.subOrEmptyDict("fieldInfo")),
|
colour_(options.getOrDefault("colour", false)),
|
||||||
animationDict_(dict.subOrEmptyDict("animationInfo"))
|
animateColourOption_(fieldOption::NONE),
|
||||||
|
animateColourName_(),
|
||||||
|
animateColourValue_(Zero),
|
||||||
|
fieldInfoDict_(options.subOrEmptyDict("fieldInfo")),
|
||||||
|
animationDict_(options.subOrEmptyDict("animationInfo"))
|
||||||
{
|
{
|
||||||
// fieldInfo
|
// fieldInfo
|
||||||
// {
|
// {
|
||||||
@ -281,50 +330,139 @@ Foam::gltfSetWriter<Type>::gltfSetWriter(const dictionary& dict)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
Foam::coordSetWriters::gltfWriter::gltfWriter
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::fileName Foam::gltfSetWriter<Type>::getFileName
|
|
||||||
(
|
(
|
||||||
const coordSet& points,
|
const coordSet& coords,
|
||||||
const wordList& valueSetNames
|
const fileName& outputPath,
|
||||||
) const
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
gltfWriter(options)
|
||||||
{
|
{
|
||||||
return this->getBaseName(points, valueSetNames) + ".gltf";
|
open(coords, outputPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::gltfWriter::gltfWriter
|
||||||
void Foam::gltfSetWriter<Type>::write
|
|
||||||
(
|
(
|
||||||
const coordSet& points,
|
const UPtrList<coordSet>& tracks,
|
||||||
const wordList& valueSetNames,
|
const fileName& outputPath,
|
||||||
const List<const Field<Type>*>& valueSets,
|
const dictionary& options
|
||||||
Ostream& os
|
)
|
||||||
) const
|
:
|
||||||
|
gltfWriter(options)
|
||||||
{
|
{
|
||||||
if (valueSets.size() != valueSetNames.size())
|
open(tracks, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::coordSetWriters::gltfWriter::~gltfWriter()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::fileName Foam::coordSetWriters::gltfWriter::path() const
|
||||||
|
{
|
||||||
|
// 1) rootdir/<TIME>/setName.gltf
|
||||||
|
// 2) rootdir/setName.gltf
|
||||||
|
|
||||||
|
return getExpectedPath("gltf");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::gltfWriter::close(bool force)
|
||||||
|
{
|
||||||
|
writer_.reset(nullptr);
|
||||||
|
coordSetWriter::close(force);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::gltfWriter::beginTime(const Time& t)
|
||||||
|
{
|
||||||
|
writer_.reset(nullptr);
|
||||||
|
coordSetWriter::beginTime(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::gltfWriter::beginTime(const instant& inst)
|
||||||
|
{
|
||||||
|
writer_.reset(nullptr);
|
||||||
|
coordSetWriter::beginTime(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::gltfWriter::endTime()
|
||||||
|
{
|
||||||
|
writer_.reset(nullptr);
|
||||||
|
coordSetWriter::endTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Implementation * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::gltfWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (coords_.size() != fieldPtrs.size())
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Number of variables:" << valueSetNames.size() << endl
|
<< "Attempted to write field: " << fieldName
|
||||||
<< "Number of valueSets:" << valueSets.size()
|
<< " (" << fieldPtrs.size() << " entries) for "
|
||||||
|
<< coords_.size() << " sets" << nl
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
glTF::scene scene;
|
const auto& tracks = coords_;
|
||||||
const label meshi = scene.addMesh(points, "points");
|
|
||||||
forAll(valueSetNames, i)
|
// const auto& times = trackTimes_;
|
||||||
|
|
||||||
|
if (!writer_)
|
||||||
{
|
{
|
||||||
scene.addFieldToMesh(*valueSets[i], valueSetNames[i], meshi);
|
// Field:
|
||||||
|
// 1) rootdir/<TIME>/setName.gltf
|
||||||
|
// 2) rootdir/setName.gltf
|
||||||
|
|
||||||
|
fileName outputFile = path();
|
||||||
|
|
||||||
|
writer_.reset(new glTF::sceneWriter(outputFile));
|
||||||
|
|
||||||
|
auto& scene = writer_->getScene();
|
||||||
|
|
||||||
|
meshes_.resize(tracks.size());
|
||||||
|
|
||||||
|
forAll(tracks, tracki)
|
||||||
|
{
|
||||||
|
word meshName("track:" + Foam::name(tracki));
|
||||||
|
if (tracks.size() == 1)
|
||||||
|
{
|
||||||
|
meshName = "points";
|
||||||
|
}
|
||||||
|
|
||||||
|
meshes_[tracki] = scene.addMesh(tracks[tracki], meshName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colour_)
|
|
||||||
{
|
|
||||||
forAll(valueSets, fieldi)
|
|
||||||
{
|
|
||||||
const auto& field = *valueSets[fieldi];
|
|
||||||
const word& fieldName = valueSetNames[fieldi];
|
|
||||||
|
|
||||||
|
auto& scene = writer_->getScene();
|
||||||
|
|
||||||
|
forAll(tracks, tracki)
|
||||||
|
{
|
||||||
|
const label meshi = meshes_[tracki];
|
||||||
|
const auto& field = fieldPtrs[tracki];
|
||||||
|
|
||||||
|
scene.addFieldToMesh(field, fieldName, meshi);
|
||||||
|
|
||||||
|
if (colour_)
|
||||||
|
{
|
||||||
const dictionary dict = fieldInfoDict_.subOrEmptyDict(fieldName);
|
const dictionary dict = fieldInfoDict_.subOrEmptyDict(fieldName);
|
||||||
const auto& colours = getColourTable(dict);
|
const auto& colours = getColourTable(dict);
|
||||||
|
|
||||||
@ -333,11 +471,7 @@ void Foam::gltfSetWriter<Type>::write
|
|||||||
|
|
||||||
const scalarMinMax valLimits = getFieldLimits(fieldName);
|
const scalarMinMax valLimits = getFieldLimits(fieldName);
|
||||||
|
|
||||||
// Generated field colours
|
|
||||||
vectorField fieldColour(field.size());
|
|
||||||
|
|
||||||
scalarMinMax fldLimits;
|
scalarMinMax fldLimits;
|
||||||
|
|
||||||
if (pTraits<Type>::nComponents == 1)
|
if (pTraits<Type>::nComponents == 1)
|
||||||
{
|
{
|
||||||
MinMax<Type> scanned(minMax(field));
|
MinMax<Type> scanned(minMax(field));
|
||||||
@ -351,24 +485,17 @@ void Foam::gltfSetWriter<Type>::write
|
|||||||
fldLimits = minMaxMag(field);
|
fldLimits = minMaxMag(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
const scalar minf = max(fldLimits.min(), valLimits.min());
|
// Generated field colours
|
||||||
const scalar maxf = min(fldLimits.max(), valLimits.max());
|
vectorField fieldColour
|
||||||
const scalar deltaf = (maxf - minf + SMALL);
|
(
|
||||||
|
getBoundedColours
|
||||||
forAll(field, i)
|
|
||||||
{
|
|
||||||
const Type& val = field[i];
|
|
||||||
|
|
||||||
const scalar f =
|
|
||||||
(
|
(
|
||||||
pTraits<Type>::nComponents == 1
|
colours,
|
||||||
? scalar(component(val, 0))
|
field,
|
||||||
: scalar(mag(val))
|
max(fldLimits.min(), valLimits.min()), // boundMin
|
||||||
);
|
min(fldLimits.max(), valLimits.max()) // boundMax
|
||||||
|
)
|
||||||
// 0-1 clipped by value()
|
);
|
||||||
fieldColour[i] = colours.value((f - minf)/deltaf);
|
|
||||||
}
|
|
||||||
|
|
||||||
scene.addColourToMesh
|
scene.addColourToMesh
|
||||||
(
|
(
|
||||||
@ -380,226 +507,260 @@ void Foam::gltfSetWriter<Type>::write
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.write(os);
|
return writer_().path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::gltfSetWriter<Type>::write
|
Foam::fileName Foam::coordSetWriters::gltfWriter::writeTemplate_animate
|
||||||
(
|
(
|
||||||
const bool writeTracks,
|
const word& fieldName,
|
||||||
const List<scalarField>& times,
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
const PtrList<coordSet>& tracks,
|
)
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
if (valueSets.size() != valueSetNames.size())
|
if (coords_.size() != fieldPtrs.size())
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Number of variables:" << valueSetNames.size() << endl
|
<< "Attempted to write field: " << fieldName
|
||||||
<< "Number of valueSets:" << valueSets.size()
|
<< " (" << fieldPtrs.size() << " entries) for "
|
||||||
|
<< coords_.size() << " sets" << nl
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (animate_)
|
const auto& tracks = this->coords_;
|
||||||
{
|
const auto& times = this->trackTimes_;
|
||||||
writeAnimateTracks
|
|
||||||
(
|
|
||||||
writeTracks,
|
|
||||||
times,
|
|
||||||
tracks,
|
|
||||||
valueSetNames,
|
|
||||||
valueSets,
|
|
||||||
os
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
writeStaticTracks
|
|
||||||
(
|
|
||||||
writeTracks,
|
|
||||||
times,
|
|
||||||
tracks,
|
|
||||||
valueSetNames,
|
|
||||||
valueSets,
|
|
||||||
os
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!writer_)
|
||||||
template<class Type>
|
|
||||||
void Foam::gltfSetWriter<Type>::writeStaticTracks
|
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
glTF::scene scene;
|
|
||||||
forAll(tracks, tracki)
|
|
||||||
{
|
{
|
||||||
const vectorField& track = tracks[tracki];
|
// Field:
|
||||||
const label meshi = scene.addMesh(track, "track:" + Foam::name(tracki));
|
// 1) rootdir/<TIME>/setName.gltf
|
||||||
forAll(valueSetNames, fieldi)
|
// 2) rootdir/setName.gltf
|
||||||
|
|
||||||
|
fileName outputFile = path();
|
||||||
|
|
||||||
|
writer_.reset(new glTF::sceneWriter(outputFile));
|
||||||
|
|
||||||
|
auto& scene = writer_->getScene();
|
||||||
|
|
||||||
|
meshes_.resize(tracks.size());
|
||||||
|
|
||||||
|
const label animationi = scene.createAnimation("animation");
|
||||||
|
|
||||||
|
forAll(tracks, tracki)
|
||||||
{
|
{
|
||||||
const word& fieldName = valueSetNames[fieldi];
|
const auto& track = tracks[tracki];
|
||||||
const auto& field = valueSets[fieldi][tracki];
|
|
||||||
scene.addFieldToMesh(field, fieldName, meshi);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colour_)
|
if (track.empty())
|
||||||
{
|
|
||||||
forAll(valueSets, fieldi)
|
|
||||||
{
|
{
|
||||||
const auto& field = valueSets[fieldi][tracki];
|
meshes_[tracki] = -1;
|
||||||
const word& fieldName = valueSetNames[fieldi];
|
continue;
|
||||||
|
|
||||||
const dictionary dict =
|
|
||||||
fieldInfoDict_.subOrEmptyDict(fieldName);
|
|
||||||
const auto& colours = getColourTable(dict);
|
|
||||||
|
|
||||||
const auto talpha = getAlphaField(dict);
|
|
||||||
const scalarField& alpha = talpha();
|
|
||||||
|
|
||||||
const scalarMinMax valLimits = getFieldLimits(fieldName);
|
|
||||||
|
|
||||||
|
|
||||||
// Generated field colours
|
|
||||||
vectorField fieldColour(field.size());
|
|
||||||
|
|
||||||
scalarMinMax fldLimits;
|
|
||||||
|
|
||||||
if (pTraits<Type>::nComponents == 1)
|
|
||||||
{
|
|
||||||
MinMax<Type> scanned(minMax(field));
|
|
||||||
|
|
||||||
fldLimits.min() = scalar(component(scanned.min(), 0));
|
|
||||||
fldLimits.max() = scalar(component(scanned.max(), 0));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Use mag() for multiple components
|
|
||||||
fldLimits = minMaxMag(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
const scalar minf = max(fldLimits.min(), valLimits.min());
|
|
||||||
const scalar maxf = min(fldLimits.max(), valLimits.max());
|
|
||||||
const scalar deltaf = (maxf - minf + SMALL);
|
|
||||||
|
|
||||||
forAll(field, i)
|
|
||||||
{
|
|
||||||
const Type& val = field[i];
|
|
||||||
|
|
||||||
const scalar f =
|
|
||||||
(
|
|
||||||
pTraits<Type>::nComponents == 1
|
|
||||||
? scalar(component(val, 0))
|
|
||||||
: scalar(mag(val))
|
|
||||||
);
|
|
||||||
|
|
||||||
// 0-1 clipped by value()
|
|
||||||
fieldColour[i] = colours.value((f - minf)/deltaf);
|
|
||||||
}
|
|
||||||
|
|
||||||
scene.addColourToMesh
|
|
||||||
(
|
|
||||||
fieldColour,
|
|
||||||
"Colour:" + fieldName,
|
|
||||||
meshi,
|
|
||||||
alpha
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Seed starting position
|
||||||
|
|
||||||
|
meshes_[tracki] =
|
||||||
|
scene.addMesh
|
||||||
|
(
|
||||||
|
vectorField(1, track[0]),
|
||||||
|
"track:" + Foam::name(tracki)
|
||||||
|
);
|
||||||
|
|
||||||
|
const label meshi = meshes_[tracki];
|
||||||
|
|
||||||
|
// Time frames
|
||||||
|
const label timeId =
|
||||||
|
scene.addField(times[tracki], "time:" + Foam::name(tracki));
|
||||||
|
|
||||||
|
// Translations
|
||||||
|
const vectorField translation(track - track[0]);
|
||||||
|
const label translationId =
|
||||||
|
scene.addField(translation, "translation");
|
||||||
|
|
||||||
|
scene.addToAnimation(animationi, timeId, translationId, meshi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.write(os);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
auto& scene = writer_->getScene();
|
||||||
|
|
||||||
template<class Type>
|
// Seed starting field values
|
||||||
void Foam::gltfSetWriter<Type>::writeAnimateTracks
|
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const auto& colours = getColourTable(animationDict_);
|
|
||||||
|
|
||||||
glTF::scene scene;
|
|
||||||
const label animationi = scene.createAnimation("animation");
|
|
||||||
|
|
||||||
forAll(tracks, tracki)
|
forAll(tracks, tracki)
|
||||||
{
|
{
|
||||||
const auto& track = tracks[tracki];
|
const auto& track = tracks[tracki];
|
||||||
|
const label meshi = meshes_[tracki];
|
||||||
|
const Field<Type>& field = fieldPtrs[tracki];
|
||||||
|
|
||||||
if (track.empty())
|
if (track.empty() || meshi < 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seed starting positions and field values
|
// Seed starting field values
|
||||||
const label meshi =
|
scene.addFieldToMesh(Field<Type>(1, field[0]), fieldName, meshi);
|
||||||
scene.addMesh
|
}
|
||||||
(
|
|
||||||
vectorField(1, track[0]),
|
|
||||||
"track:" + Foam::name(tracki)
|
|
||||||
);
|
|
||||||
|
|
||||||
forAll(valueSetNames, fieldi)
|
|
||||||
|
// Note: colours cannot be animated... setting a fixed value.
|
||||||
|
// However, we need to wait until the field is actually seen
|
||||||
|
|
||||||
|
if (colour_)
|
||||||
|
{
|
||||||
|
if (animateColourOption_ == fieldOption::NONE)
|
||||||
{
|
{
|
||||||
const Field<Type>& field = valueSets[fieldi][tracki];
|
// First time - scan for information
|
||||||
const word& fieldName = valueSetNames[fieldi];
|
setupAnimationColour();
|
||||||
scene.addFieldToMesh(Field<Type>(1, field[0]), fieldName, meshi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time frames
|
switch (animateColourOption_)
|
||||||
const label timeId =
|
|
||||||
scene.addField(times[tracki], "time:" + Foam::name(tracki));
|
|
||||||
|
|
||||||
// Translations
|
|
||||||
const vectorField translation(track - track[0]);
|
|
||||||
const label translationId = scene.addField(translation, "translation");
|
|
||||||
|
|
||||||
scene.addToAnimation(animationi, timeId, translationId, meshi);
|
|
||||||
|
|
||||||
// Note: colours cannot be animated... setting a fixed value
|
|
||||||
if (colour_)
|
|
||||||
{
|
{
|
||||||
const vector colour =
|
case fieldOption::NONE:
|
||||||
getTrackAnimationColour
|
{
|
||||||
|
// Should not occur
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case fieldOption::UNIFORM:
|
||||||
|
{
|
||||||
|
// Colour value is known
|
||||||
|
|
||||||
|
vectorField fieldColour(1, animateColourValue_);
|
||||||
|
scalarField alphaChannel(1, 1.0);
|
||||||
|
|
||||||
|
const auto talpha = getAlphaField(animationDict_);
|
||||||
|
|
||||||
|
if (talpha && talpha().size())
|
||||||
|
{
|
||||||
|
alphaChannel[0] = talpha()[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(tracks, tracki)
|
||||||
|
{
|
||||||
|
const auto& track = tracks[tracki];
|
||||||
|
const label meshi = meshes_[tracki];
|
||||||
|
|
||||||
|
if (track.empty() || meshi < 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
scene.addColourToMesh
|
||||||
|
(
|
||||||
|
fieldColour,
|
||||||
|
"Colour:fixed", // ... or "Colour:constant"
|
||||||
|
meshi,
|
||||||
|
alphaChannel
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark as done
|
||||||
|
animateColourName_.clear();
|
||||||
|
animateColourOption_ = fieldOption::FIELD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case fieldOption::FIELD:
|
||||||
|
{
|
||||||
|
if
|
||||||
(
|
(
|
||||||
colours,
|
!animateColourName_.empty()
|
||||||
valueSetNames,
|
&& animateColourName_ == fieldName
|
||||||
valueSets,
|
)
|
||||||
tracki
|
{
|
||||||
);
|
// This is the desired colour field. Process now
|
||||||
|
|
||||||
const auto talpha = getAlphaField(animationDict_);
|
const auto& colours = getColourTable(animationDict_);
|
||||||
|
|
||||||
const scalarField& alpha = talpha();
|
vectorField fieldColour(1, Zero);
|
||||||
|
scalarField alphaChannel(1, 1.0);
|
||||||
|
|
||||||
scene.addColourToMesh
|
const auto talpha = getAlphaField(animationDict_);
|
||||||
(
|
|
||||||
vectorField(1, colour),
|
if (talpha && talpha().size())
|
||||||
"Colour:fixed", // ... or "Colour:constant"
|
{
|
||||||
meshi,
|
alphaChannel[0] = talpha()[0];
|
||||||
scalarField(1, alpha[0])
|
}
|
||||||
);
|
|
||||||
|
forAll(tracks, tracki)
|
||||||
|
{
|
||||||
|
const auto& track = tracks[tracki];
|
||||||
|
const label meshi = meshes_[tracki];
|
||||||
|
const Field<Type>& field = fieldPtrs[tracki];
|
||||||
|
|
||||||
|
if (track.empty() || meshi < 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldColour[0] =
|
||||||
|
getAnimationColour(animationDict_, colours, field);
|
||||||
|
|
||||||
|
scene.addColourToMesh
|
||||||
|
(
|
||||||
|
fieldColour,
|
||||||
|
"Colour:fixed", // ... or "Colour:constant"
|
||||||
|
meshi,
|
||||||
|
alphaChannel
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark colouring as done. Avoid retriggering
|
||||||
|
animateColourName_.clear();
|
||||||
|
animateColourOption_ = fieldOption::FIELD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.write(os);
|
return writer_().path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::gltfWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const Field<Type>& values
|
||||||
|
)
|
||||||
|
{
|
||||||
|
checkOpen();
|
||||||
|
if (coords_.empty())
|
||||||
|
{
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
UPtrList<const Field<Type>> fieldPtrs(repackageFields(values));
|
||||||
|
return writeTemplate(fieldName, fieldPtrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::gltfWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
)
|
||||||
|
{
|
||||||
|
checkOpen();
|
||||||
|
if (coords_.empty())
|
||||||
|
{
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
UPtrList<const Field<Type>> fieldPtrs(repackageFields(fieldValues));
|
||||||
|
|
||||||
|
if (animate_ && trackTimes_.size() >= coords_.size())
|
||||||
|
{
|
||||||
|
return writeTemplate_animate(fieldName, fieldPtrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return writeTemplate(fieldName, fieldPtrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Field writing methods
|
||||||
|
defineCoordSetWriterWriteFields(Foam::coordSetWriters::gltfWriter);
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -24,10 +24,11 @@ License
|
|||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Class
|
Class
|
||||||
Foam::gltfSetWriter
|
Foam::coordSetWriters::gltfWriter
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Writes point data in glTF v2 format
|
A coordSet(s) writer in glTF v2 format, which is particularly
|
||||||
|
useful for writing track data.
|
||||||
|
|
||||||
Two files are generated:
|
Two files are generated:
|
||||||
- filename.bin : a binary file containing all scene entities
|
- filename.bin : a binary file containing all scene entities
|
||||||
@ -121,23 +122,25 @@ SourceFiles
|
|||||||
#ifndef Foam_coordSetWriters_gltfWriter_H
|
#ifndef Foam_coordSetWriters_gltfWriter_H
|
||||||
#define Foam_coordSetWriters_gltfWriter_H
|
#define Foam_coordSetWriters_gltfWriter_H
|
||||||
|
|
||||||
#include "writer.H"
|
#include "coordSetWriter.H"
|
||||||
#include "colourTable.H"
|
#include "colourTable.H"
|
||||||
|
#include "foamGltfFwd.H"
|
||||||
#include "MinMax.H"
|
#include "MinMax.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class gltfSetWriter Declaration
|
Class gltfWriter Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
template<class Type>
|
class gltfWriter
|
||||||
class gltfSetWriter
|
|
||||||
:
|
:
|
||||||
public writer<Type>
|
public coordSetWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -160,18 +163,33 @@ private:
|
|||||||
|
|
||||||
// Private Data
|
// Private Data
|
||||||
|
|
||||||
|
//- Backend output
|
||||||
|
autoPtr<glTF::sceneWriter> writer_;
|
||||||
|
|
||||||
//- Flag to animate - for particle tracks only
|
//- Flag to animate - for particle tracks only
|
||||||
bool animate_;
|
bool animate_;
|
||||||
|
|
||||||
//- Flag to add field colours
|
//- Flag to add field colours
|
||||||
bool colour_;
|
bool colour_;
|
||||||
|
|
||||||
|
//- Animation colour option
|
||||||
|
fieldOption animateColourOption_;
|
||||||
|
|
||||||
|
//- Animation colour field name
|
||||||
|
word animateColourName_;
|
||||||
|
|
||||||
|
//- Animation colour value
|
||||||
|
vector animateColourValue_;
|
||||||
|
|
||||||
//- Local field information
|
//- Local field information
|
||||||
const dictionary fieldInfoDict_;
|
const dictionary fieldInfoDict_;
|
||||||
|
|
||||||
//- Animation information
|
//- Animation information
|
||||||
const dictionary animationDict_;
|
const dictionary animationDict_;
|
||||||
|
|
||||||
|
//- The mesh indices in glTF scene
|
||||||
|
labelList meshes_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
@ -184,103 +202,117 @@ private:
|
|||||||
//- Return the named min/max field limits (from sub-dictionary)
|
//- Return the named min/max field limits (from sub-dictionary)
|
||||||
scalarMinMax getFieldLimits(const word& fieldName) const;
|
scalarMinMax getFieldLimits(const word& fieldName) const;
|
||||||
|
|
||||||
|
//- Setup animation colour or field to search for
|
||||||
|
void setupAnimationColour();
|
||||||
|
|
||||||
//- Return the alpha field for mesh values
|
//- Return the alpha field for mesh values
|
||||||
tmp<scalarField> getAlphaField(const dictionary& dict) const;
|
tmp<scalarField> getAlphaField(const dictionary& dict) const;
|
||||||
|
|
||||||
//- Return the animation colour when animating tracks
|
|
||||||
vector getTrackAnimationColour
|
//- Templated write operation (static tracks)
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
(
|
(
|
||||||
const colourTable& colours,
|
const word& fieldName,
|
||||||
const wordList& valueSetNames,
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
const List<List<Field<Type>>>& valueSets,
|
);
|
||||||
const label tracki
|
|
||||||
) const;
|
//- Write animated tracks
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate_animate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName, //!< Name of field
|
||||||
|
const Field<Type>& vals //!< Local field values to write
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information (no debug)
|
||||||
TypeName("gltf");
|
TypeNameNoDebug("gltf");
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Default construct
|
//- Default construct
|
||||||
gltfSetWriter();
|
gltfWriter();
|
||||||
|
|
||||||
//- Construct from dictionary
|
//- Default construct with specified options
|
||||||
explicit gltfSetWriter(const dictionary& dict);
|
explicit gltfWriter(const dictionary& options);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
gltfWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
gltfWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
//- Destructor. Calls close()
|
||||||
virtual ~gltfSetWriter() = default;
|
virtual ~gltfWriter();
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Return the file name
|
//- Expected (characteristic) output file name - information only
|
||||||
virtual fileName getFileName
|
virtual fileName path() const; // override
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Write
|
//- Close and reset, clears backend.
|
||||||
virtual void write
|
virtual void close(bool force = false); // override
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&,
|
|
||||||
const List<const Field<Type>*>&,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Write tracks (main entry point)
|
//- Begin time step. Clears existing backend.
|
||||||
virtual void write
|
virtual void beginTime(const Time& t); // override
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>&,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>&,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Write animated tracks
|
//- Begin time step. Clears existing backend.
|
||||||
virtual void writeAnimateTracks
|
virtual void beginTime(const instant& inst); // override
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Write static tracks
|
//- End time step. Clears existing backend.
|
||||||
virtual void writeStaticTracks
|
virtual void endTime(); // override
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
// Write
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
declareCoordSetWriterWriteMethod(label);
|
||||||
const List<List<Field<Type>>>& valueSets,
|
declareCoordSetWriterWriteMethod(scalar);
|
||||||
Ostream&
|
declareCoordSetWriterWriteMethod(vector);
|
||||||
) const;
|
declareCoordSetWriterWriteMethod(sphericalTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(symmTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(tensor);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace coordSetWriters
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
#include "gltfCoordSetWriter.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
@ -1,39 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "gltfSetWriter.H"
|
|
||||||
#include "writers.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
makeSetWriters(gltfSetWriter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
Copyright (C) 2017-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,135 +26,239 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "gnuplotSetWriter.H"
|
#include "gnuplotCoordSetWriter.H"
|
||||||
#include "coordSet.H"
|
#include "coordSet.H"
|
||||||
#include "fileName.H"
|
#include "fileName.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
|
#include "coordSetWriterMethods.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
defineTypeName(gnuplotWriter);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, gnuplotWriter, word);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, gnuplotWriter, wordDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
#include "gnuplotCoordSetWriterImpl.C"
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::gnuplotWriter::gnuplotWriter()
|
||||||
Foam::gnuplotSetWriter<Type>::gnuplotSetWriter()
|
|
||||||
:
|
:
|
||||||
writer<Type>()
|
coordSetWriter(),
|
||||||
{}
|
streamOpt_(),
|
||||||
|
precision_(IOstream::defaultPrecision())
|
||||||
|
{
|
||||||
|
buffering_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::gnuplotWriter::gnuplotWriter(const dictionary& options)
|
||||||
Foam::gnuplotSetWriter<Type>::gnuplotSetWriter(const dictionary& dict)
|
|
||||||
:
|
:
|
||||||
writer<Type>(dict)
|
coordSetWriter(options),
|
||||||
{}
|
streamOpt_
|
||||||
|
(
|
||||||
|
IOstream::ASCII,
|
||||||
|
IOstream::compressionEnum("compression", options)
|
||||||
|
),
|
||||||
|
precision_
|
||||||
|
(
|
||||||
|
options.getOrDefault("precision", IOstream::defaultPrecision())
|
||||||
|
)
|
||||||
|
{
|
||||||
|
buffering_ = options.getOrDefault("buffer", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::gnuplotWriter::gnuplotWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
gnuplotWriter(options)
|
||||||
|
{
|
||||||
|
open(coords, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::gnuplotWriter::gnuplotWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
gnuplotWriter(options)
|
||||||
|
{
|
||||||
|
open(tracks, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::coordSetWriters::gnuplotWriter::~gnuplotWriter()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
bool Foam::coordSetWriters::gnuplotWriter::buffering(const bool on)
|
||||||
Foam::fileName Foam::gnuplotSetWriter<Type>::getFileName
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const wordList& valueSetNames
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
return this->getBaseName(points, valueSetNames) + ".gplt";
|
const bool old(buffering_);
|
||||||
|
buffering_ = on;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fileName Foam::coordSetWriters::gnuplotWriter::path() const
|
||||||
|
{
|
||||||
|
// 1) rootdir/<TIME>/setName.{gplt}
|
||||||
|
// 2) rootdir/setName.{gplt}
|
||||||
|
|
||||||
|
return getExpectedPath("gplt");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::coordSetWriters::gnuplotWriter::writeBuffered()
|
||||||
|
{
|
||||||
|
if (coords_.empty())
|
||||||
|
{
|
||||||
|
clearBuffers();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Field:
|
||||||
|
// 1) rootdir/<TIME>/setName.gplt
|
||||||
|
// 2) rootdir/setName.gplt
|
||||||
|
|
||||||
|
fileName outputFile = path();
|
||||||
|
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
OFstream os(outputFile, streamOpt_);
|
||||||
|
os.precision(precision_);
|
||||||
|
|
||||||
|
os << "set term pngcairo" << nl
|
||||||
|
<< "set output \"" << outputFile.nameLessExt() << ".png\"" << nl;
|
||||||
|
|
||||||
|
label nplots = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(Type) \
|
||||||
|
for (const word& fldName : Type##Names_) \
|
||||||
|
{ \
|
||||||
|
os << (nplots++ ? ", \\" : "plot \\") << nl; \
|
||||||
|
os << " '-' title \"" << fldName << "\" with lines"; \
|
||||||
|
}
|
||||||
|
|
||||||
|
doLocalCode(label);
|
||||||
|
doLocalCode(scalar);
|
||||||
|
doLocalCode(vector);
|
||||||
|
doLocalCode(sphericalTensor);
|
||||||
|
doLocalCode(symmTensor);
|
||||||
|
doLocalCode(tensor);
|
||||||
|
#undef doLocalCode
|
||||||
|
}
|
||||||
|
while (false);
|
||||||
|
|
||||||
|
os << nl << nl;
|
||||||
|
|
||||||
|
if (nplots)
|
||||||
|
{
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(Type) \
|
||||||
|
for (const Field<Type>& fld : Type##Fields_) \
|
||||||
|
{ \
|
||||||
|
writeTable(os, coords_[0], fld, " \t"); \
|
||||||
|
os << "end_data" << nl << nl; \
|
||||||
|
}
|
||||||
|
|
||||||
|
doLocalCode(label);
|
||||||
|
doLocalCode(scalar);
|
||||||
|
doLocalCode(vector);
|
||||||
|
doLocalCode(sphericalTensor);
|
||||||
|
doLocalCode(symmTensor);
|
||||||
|
doLocalCode(tensor);
|
||||||
|
#undef doLocalCode
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "# end plot" << nl;
|
||||||
|
|
||||||
|
clearBuffers();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::gnuplotSetWriter<Type>::write
|
Foam::fileName Foam::coordSetWriters::gnuplotWriter::writeTemplate
|
||||||
(
|
(
|
||||||
const coordSet& points,
|
const word& fieldName,
|
||||||
const wordList& valueSetNames,
|
const Field<Type>& values
|
||||||
const List<const Field<Type>*>& valueSets,
|
)
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
os << "set term postscript color" << nl
|
checkOpen();
|
||||||
<< "set output \"" << points.name() << ".ps\"" << nl;
|
if (coords_.empty())
|
||||||
|
|
||||||
// Set secondary Y axis if using two columns. Falls back to same
|
|
||||||
// values if both on same scale. However, ignore if more columns.
|
|
||||||
if (valueSetNames.size() == 2)
|
|
||||||
{
|
{
|
||||||
os << "set ylabel \"" << valueSetNames[0] << "\"" << nl
|
return fileName::null;
|
||||||
<< "set y2label \"" << valueSetNames[1] << "\"" << nl
|
|
||||||
<< "set ytics nomirror" << nl << "set y2tics" << nl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
os << "plot";
|
if (useTracks_ || !buffering_)
|
||||||
|
|
||||||
forAll(valueSets, i)
|
|
||||||
{
|
{
|
||||||
if (i)
|
UPtrList<const Field<Type>> fieldPtrs(repackageFields(values));
|
||||||
{
|
return writeTemplate(fieldName, fieldPtrs);
|
||||||
os << ',';
|
|
||||||
}
|
|
||||||
|
|
||||||
os << " \"-\" title \"" << valueSetNames[i] << "\" with lines";
|
|
||||||
|
|
||||||
if (valueSetNames.size() == 2)
|
|
||||||
{
|
|
||||||
os << " axes x1y" << (i+1) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
os << nl;
|
|
||||||
|
|
||||||
forAll(valueSets, i)
|
|
||||||
{
|
// Buffering version
|
||||||
this->writeTable(points, *valueSets[i], os);
|
appendField(fieldName, values);
|
||||||
os << "e" << nl;
|
|
||||||
}
|
return path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::gnuplotSetWriter<Type>::write
|
Foam::fileName Foam::coordSetWriters::gnuplotWriter::writeTemplate
|
||||||
(
|
(
|
||||||
const bool writeTracks,
|
const word& fieldName,
|
||||||
const List<scalarField>& times,
|
const List<Field<Type>>& fieldValues
|
||||||
const PtrList<coordSet>& tracks,
|
)
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
if (valueSets.size() != valueSetNames.size())
|
checkOpen();
|
||||||
|
if (coords_.empty())
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
return fileName::null;
|
||||||
<< "Number of variables:" << valueSetNames.size() << endl
|
|
||||||
<< "Number of valueSets:" << valueSets.size()
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
}
|
||||||
if (tracks.size() > 0)
|
|
||||||
{
|
|
||||||
os << "set term postscript color" << nl
|
|
||||||
<< "set output \"" << tracks[0].name() << ".ps\"" << nl;
|
|
||||||
|
|
||||||
forAll(tracks, trackI)
|
UPtrList<const Field<Type>> fieldPtrs(repackageFields(fieldValues));
|
||||||
{
|
return writeTemplate(fieldName, fieldPtrs);
|
||||||
os << "plot";
|
|
||||||
|
|
||||||
forAll(valueSets, i)
|
|
||||||
{
|
|
||||||
if (i != 0)
|
|
||||||
{
|
|
||||||
os << ',';
|
|
||||||
}
|
|
||||||
|
|
||||||
os << " \"-\" title \"" << valueSetNames[i] << "\" with lines";
|
|
||||||
}
|
|
||||||
os << nl;
|
|
||||||
|
|
||||||
forAll(valueSets, i)
|
|
||||||
{
|
|
||||||
this->writeTable(tracks[trackI], valueSets[i][trackI], os);
|
|
||||||
os << "e" << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Field writing methods
|
||||||
|
defineCoordSetWriterWriteFields(Foam::coordSetWriters::gnuplotWriter);
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
179
src/meshTools/coordSet/writers/gnuplot/gnuplotCoordSetWriter.H
Normal file
179
src/meshTools/coordSet/writers/gnuplot/gnuplotCoordSetWriter.H
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::coordSetWriters::gnuplotWriter
|
||||||
|
|
||||||
|
Description
|
||||||
|
A coordSet(s) writer in gnuplot format.
|
||||||
|
|
||||||
|
The formatOptions for gnuplot:
|
||||||
|
\table
|
||||||
|
Property | Description | Required | Default
|
||||||
|
buffer | Use buffered output | no | true
|
||||||
|
compression | Use file compression | no | false
|
||||||
|
precision | Write precision in ascii | no | same as IOstream
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
When called with a single coordSet, will buffer the output of
|
||||||
|
all fields and output together in the order of label/scalar/vector/...
|
||||||
|
each of which is sorted alphabetically according to the field name.
|
||||||
|
|
||||||
|
When called as a track writer (eg, with multiple coordSets),
|
||||||
|
will emit one file per field.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
gnuplotCoordSetWriter.C
|
||||||
|
gnuplotCoordSetWriterImpl.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_coordSetWriters_gnuplotWriter_H
|
||||||
|
#define Foam_coordSetWriters_gnuplotWriter_H
|
||||||
|
|
||||||
|
#include "coordSetWriter.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class gnuplotWriter Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class gnuplotWriter
|
||||||
|
:
|
||||||
|
public coordSetWriter
|
||||||
|
{
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Output stream option
|
||||||
|
IOstreamOption streamOpt_;
|
||||||
|
|
||||||
|
//- ASCII write precision
|
||||||
|
unsigned precision_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName, //!< Name of field
|
||||||
|
const Field<Type>& vals //!< Local field values to write
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Write buffered data
|
||||||
|
virtual bool writeBuffered();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information (no debug)
|
||||||
|
TypeNameNoDebug("gnuplot");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Default construct
|
||||||
|
gnuplotWriter();
|
||||||
|
|
||||||
|
//- Default construct with specified options
|
||||||
|
explicit gnuplotWriter(const dictionary& options);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
gnuplotWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
gnuplotWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor. Calls close()
|
||||||
|
virtual ~gnuplotWriter();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Enable/disable internal buffering
|
||||||
|
virtual bool buffering(const bool on); // override
|
||||||
|
|
||||||
|
//- Characteristic output file name - information only
|
||||||
|
virtual fileName path() const; // override
|
||||||
|
|
||||||
|
declareCoordSetWriterWriteMethod(label);
|
||||||
|
declareCoordSetWriterWriteMethod(scalar);
|
||||||
|
declareCoordSetWriterWriteMethod(vector);
|
||||||
|
declareCoordSetWriterWriteMethod(sphericalTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(symmTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(tensor);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // Endnamespace coordSetWriters
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "IOmanip.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::gnuplotWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (coords_.size() != fieldPtrs.size())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Attempted to write field: " << fieldName
|
||||||
|
<< " (" << fieldPtrs.size() << " entries) for "
|
||||||
|
<< coords_.size() << " sets" << nl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
///const label nPoints = numPoints();
|
||||||
|
|
||||||
|
|
||||||
|
// Field: rootdir/<TIME>/<field>_setName.gplt
|
||||||
|
|
||||||
|
fileName outputFile = getFieldPrefixedPath(fieldName, "gplt");
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing field " << fieldName;
|
||||||
|
Info<< " to " << outputFile << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Master only
|
||||||
|
{
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
OFstream os(outputFile, streamOpt_);
|
||||||
|
os.precision(precision_);
|
||||||
|
|
||||||
|
os << "set term pngcairo" << nl
|
||||||
|
<< "set output \"" << outputFile.nameLessExt() << ".png\"" << nl;
|
||||||
|
|
||||||
|
// Header
|
||||||
|
{
|
||||||
|
os << "plot \\" << nl;
|
||||||
|
os << " '-' title \"" << fieldName << "\" with lines";
|
||||||
|
os << nl << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(coords_, tracki)
|
||||||
|
{
|
||||||
|
writeTable(os, coords_[tracki], fieldPtrs[tracki], " \t");
|
||||||
|
}
|
||||||
|
os << "end_data" << nl << nl;
|
||||||
|
os << "# end plot" << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
wroteGeom_ = true;
|
||||||
|
return outputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -1,117 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::gnuplotSetWriter
|
|
||||||
|
|
||||||
Description
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
gnuplotCoordSetWriter.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef Foam_coordSetWriters_gnuplotWriter_H
|
|
||||||
#define Foam_coordSetWriters_gnuplotWriter_H
|
|
||||||
|
|
||||||
#include "writer.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class gnuplotSetWriter Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
class gnuplotSetWriter
|
|
||||||
:
|
|
||||||
public writer<Type>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("gnuplot");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Default construct
|
|
||||||
gnuplotSetWriter();
|
|
||||||
|
|
||||||
//- Construct with dictionary
|
|
||||||
explicit gnuplotSetWriter(const dictionary& dict);
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
virtual ~gnuplotSetWriter() = default;
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
virtual fileName getFileName
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&,
|
|
||||||
const List<const Field<Type>*>&,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
#include "gnuplotCoordSetWriter.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ 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/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "gnuplotSetWriter.H"
|
|
||||||
#include "writers.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
makeSetWriters(gnuplotSetWriter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2018-2021 OpenCFD Ltd.
|
Copyright (C) 2018-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -25,175 +25,198 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "nastranSetWriter.H"
|
#include "nastranCoordSetWriter.H"
|
||||||
#include "coordSet.H"
|
#include "coordSet.H"
|
||||||
#include "IOmanip.H"
|
#include "IOmanip.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
|
#include "coordSetWriterMethods.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
defineTypeName(nastranWriter);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, nastranWriter, word);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, nastranWriter, wordDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
static inline void putValue(Ostream& os, const Type& value, const int width)
|
||||||
|
{
|
||||||
|
if (width) os << setw(width);
|
||||||
|
os << value;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::Ostream& Foam::coordSetWriters::nastranWriter::writeKeyword
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const word& keyword
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return fileFormats::NASCore::writeKeyword(os, keyword, writeFormat_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::nastranWriter::nastranWriter()
|
||||||
Foam::nastranSetWriter<Type>::nastranSetWriter()
|
|
||||||
:
|
:
|
||||||
writer<Type>()
|
coordSetWriter(),
|
||||||
{}
|
writeFormat_(fieldFormat::FREE),
|
||||||
|
separator_()
|
||||||
|
{
|
||||||
|
if (writeFormat_ == fieldFormat::FREE)
|
||||||
|
{
|
||||||
|
separator_ = ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::nastranWriter::nastranWriter(const dictionary& options)
|
||||||
Foam::nastranSetWriter<Type>::nastranSetWriter(const dictionary& dict)
|
|
||||||
:
|
:
|
||||||
writer<Type>(dict)
|
coordSetWriter(options),
|
||||||
{}
|
writeFormat_
|
||||||
|
(
|
||||||
|
fileFormats::NASCore::fieldFormatNames.getOrDefault
|
||||||
|
(
|
||||||
|
"format",
|
||||||
|
options,
|
||||||
|
fieldFormat::FREE
|
||||||
|
)
|
||||||
|
),
|
||||||
|
separator_()
|
||||||
|
{
|
||||||
|
if (writeFormat_ == fieldFormat::FREE)
|
||||||
|
{
|
||||||
|
separator_ = ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::nastranWriter::nastranWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
nastranWriter(options)
|
||||||
|
{
|
||||||
|
open(coords, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::nastranWriter::nastranWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
nastranWriter(options)
|
||||||
|
{
|
||||||
|
open(tracks, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::coordSetWriters::nastranWriter::~nastranWriter()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
Foam::fileName Foam::coordSetWriters::nastranWriter::path() const
|
||||||
Foam::fileName Foam::nastranSetWriter<Type>::getFileName
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const wordList& valueSetNames
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
return this->getBaseName(points, valueSetNames) + ".nas";
|
// 1) rootdir/<TIME>/setName.{nas}
|
||||||
|
// 2) rootdir/setName.{nas}
|
||||||
|
|
||||||
|
return getExpectedPath("nas");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
void Foam::coordSetWriters::nastranWriter::writeGeometry
|
||||||
void Foam::nastranSetWriter<Type>::write
|
|
||||||
(
|
(
|
||||||
const coordSet& points,
|
Ostream& os,
|
||||||
const wordList& valueSetNames,
|
label nTracks
|
||||||
const List<const Field<Type>*>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
os << "TITLE=OpenFOAM "
|
if (coords_.empty())
|
||||||
<< this->getBaseName(points, valueSetNames).c_str()
|
|
||||||
<< nl
|
|
||||||
<< "$" << nl
|
|
||||||
<< "BEGIN BULK" << nl;
|
|
||||||
|
|
||||||
forAll(points, pointi)
|
|
||||||
{
|
|
||||||
fileFormats::NASCore::writeCoord
|
|
||||||
(
|
|
||||||
os, points[pointi], pointi, fieldFormat::FREE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (false)
|
|
||||||
{
|
|
||||||
// Single track with multiple segments
|
|
||||||
const label nEdges = points.size()-1;
|
|
||||||
for (label edgei = 0; edgei < nEdges; ++edgei)
|
|
||||||
{
|
|
||||||
fileFormats::NASCore::writeKeyword
|
|
||||||
(
|
|
||||||
os,
|
|
||||||
"PLOTEL",
|
|
||||||
fieldFormat::FREE
|
|
||||||
);
|
|
||||||
|
|
||||||
// fieldFormat::SHORT
|
|
||||||
//os.setf(std::ios_base::right);
|
|
||||||
//os << setw(8) << edgei+1
|
|
||||||
// << setw(8) << edgei+1
|
|
||||||
// << setw(8) << edgei+2
|
|
||||||
// << nl;
|
|
||||||
//os.unsetf(std::ios_base::right);
|
|
||||||
|
|
||||||
// fieldFormat::FREE
|
|
||||||
os << ',' << edgei+1
|
|
||||||
<< ',' << edgei+1
|
|
||||||
<< ',' << edgei+2
|
|
||||||
<< nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
os << "ENDDATA" << nl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::nastranSetWriter<Type>::write
|
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
if (valueSets.size() != valueSetNames.size())
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Number of variables:" << valueSetNames.size() << endl
|
|
||||||
<< "Number of valueSets:" << valueSets.size()
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
if (tracks.empty())
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
os << "TITLE=OpenFOAM "
|
// Field width (SHORT, LONG formats)
|
||||||
<< this->getBaseName(tracks[0], valueSetNames).c_str()
|
const int width =
|
||||||
<< nl
|
(
|
||||||
<< "$" << nl
|
writeFormat_ == fieldFormat::SHORT ? 8
|
||||||
<< "BEGIN BULK" << nl;
|
: writeFormat_ == fieldFormat::LONG ? 16
|
||||||
|
: 0
|
||||||
|
);
|
||||||
|
|
||||||
// label nTracks = tracks.size();
|
// Separator char (FREE format)
|
||||||
// label nPoints = 0;
|
const char sep = (writeFormat_ == fieldFormat::FREE ? ',' : '\0');
|
||||||
// forAll(tracks, i)
|
|
||||||
// {
|
// Write points
|
||||||
// nPoints += tracks[i].size();
|
os << '$' << nl
|
||||||
// }
|
<< "$ Points" << nl
|
||||||
|
<< '$' << nl;
|
||||||
|
|
||||||
label globalPointi = 0;
|
label globalPointi = 0;
|
||||||
for (const coordSet& points : tracks)
|
for (const coordSet& coords : coords_)
|
||||||
{
|
{
|
||||||
for (const point& p : points)
|
for (const point& p : coords)
|
||||||
{
|
{
|
||||||
fileFormats::NASCore::writeCoord
|
fileFormats::NASCore::writeCoord
|
||||||
(
|
(
|
||||||
os, p, globalPointi, fieldFormat::FREE
|
os, p, globalPointi, writeFormat_
|
||||||
);
|
);
|
||||||
++globalPointi;
|
++globalPointi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writeTracks)
|
if (nTracks)
|
||||||
{
|
{
|
||||||
// Write ids of track points to file
|
// Write ids of track points to file
|
||||||
|
globalPointi = 0;
|
||||||
label globalEdgei = 0;
|
label globalEdgei = 0;
|
||||||
label globalPointi = 0;
|
|
||||||
for (const coordSet& points : tracks)
|
for (label tracki = 0; tracki < nTracks; ++tracki)
|
||||||
{
|
{
|
||||||
const label nEdges = points.size()-1;
|
const label nEdges = (coords_[tracki].size() - 1);
|
||||||
|
|
||||||
for (label edgei = 0; edgei < nEdges; ++edgei)
|
for (label edgei = 0; edgei < nEdges; ++edgei)
|
||||||
{
|
{
|
||||||
fileFormats::NASCore::writeKeyword
|
writeKeyword(os, "PLOTEL");
|
||||||
(
|
if (sep) os << sep;
|
||||||
os,
|
|
||||||
"PLOTEL",
|
|
||||||
fieldFormat::FREE
|
|
||||||
);
|
|
||||||
|
|
||||||
// fieldFormat::SHORT
|
putValue(os, globalEdgei+1, width); // Edge id
|
||||||
//os.setf(std::ios_base::right);
|
if (sep) os << sep;
|
||||||
//os << setw(8) << globalEdgei+1
|
|
||||||
// << setw(8) << globalPointi+1
|
|
||||||
// << setw(8) << globalPointi+2
|
|
||||||
// << nl;
|
|
||||||
//os.unsetf(std::ios_base::right);
|
|
||||||
|
|
||||||
// fieldFormat::FREE
|
putValue(os, globalPointi+1, width);
|
||||||
os << ',' << globalEdgei+1
|
if (sep) os << sep;
|
||||||
<< ',' << globalPointi+1
|
|
||||||
<< ',' << globalPointi+2
|
putValue(os, globalPointi+2, width);
|
||||||
<< nl;
|
os << nl;
|
||||||
|
|
||||||
++globalEdgei;
|
++globalEdgei;
|
||||||
++globalPointi;
|
++globalPointi;
|
||||||
@ -201,8 +224,100 @@ void Foam::nastranSetWriter<Type>::write
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
os << "ENDDATA" << nl;
|
wroteGeom_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::nastranWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const Field<Type>& values
|
||||||
|
)
|
||||||
|
{
|
||||||
|
checkOpen();
|
||||||
|
if (coords_.empty())
|
||||||
|
{
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName outputFile = path();
|
||||||
|
|
||||||
|
if (!wroteGeom_)
|
||||||
|
{
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing nastran geometry to " << outputFile << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
OFstream os(outputFile);
|
||||||
|
fileFormats::NASCore::setPrecision(os, writeFormat_);
|
||||||
|
|
||||||
|
os << "TITLE=OpenFOAM " << outputFile.nameLessExt()
|
||||||
|
<< " geometry" << nl
|
||||||
|
<< "BEGIN BULK" << nl;
|
||||||
|
|
||||||
|
writeGeometry(os, (useTracks_ ? coords_.size() : 0));
|
||||||
|
|
||||||
|
os << "ENDDATA" << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::nastranWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
)
|
||||||
|
{
|
||||||
|
checkOpen();
|
||||||
|
if (coords_.empty())
|
||||||
|
{
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName outputFile = path();
|
||||||
|
|
||||||
|
if (!wroteGeom_)
|
||||||
|
{
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing nastran geometry to " << outputFile << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
OFstream os(outputFile);
|
||||||
|
fileFormats::NASCore::setPrecision(os, writeFormat_);
|
||||||
|
|
||||||
|
os << "TITLE=OpenFOAM " << outputFile.nameLessExt()
|
||||||
|
<< " geometry" << nl
|
||||||
|
<< "BEGIN BULK" << nl;
|
||||||
|
|
||||||
|
writeGeometry(os, coords_.size());
|
||||||
|
|
||||||
|
os << "ENDDATA" << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Field writing methods
|
||||||
|
defineCoordSetWriterWriteFields(Foam::coordSetWriters::nastranWriter);
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
178
src/meshTools/coordSet/writers/nastran/nastranCoordSetWriter.H
Normal file
178
src/meshTools/coordSet/writers/nastran/nastranCoordSetWriter.H
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2018-2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::coordSetWriters::nastranWriter
|
||||||
|
|
||||||
|
Description
|
||||||
|
Write coordSet(s) as Nastran plot lines. Does not do field data.
|
||||||
|
|
||||||
|
The formatOptions for nastran:
|
||||||
|
\table
|
||||||
|
Property | Description | Required | Default
|
||||||
|
format | short / long / free | no | free
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section Output file locations
|
||||||
|
|
||||||
|
The \c rootdir normally corresponds to something like
|
||||||
|
\c postProcessing/\<name\>
|
||||||
|
|
||||||
|
\subsection Geometry
|
||||||
|
\verbatim
|
||||||
|
rootdir
|
||||||
|
`-- <time>
|
||||||
|
|-- setName0.{nas}
|
||||||
|
`-- setName1.{nas}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
nastranCoordSetWriter.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_coordSetWriters_nastranWriter_H
|
||||||
|
#define Foam_coordSetWriters_nastranWriter_H
|
||||||
|
|
||||||
|
#include "coordSetWriter.H"
|
||||||
|
#include "NASCore.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class nastranWriter Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class nastranWriter
|
||||||
|
:
|
||||||
|
public coordSetWriter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- File field formats
|
||||||
|
using fieldFormat = Foam::fileFormats::NASCore::fieldFormat;
|
||||||
|
|
||||||
|
//- Output load format
|
||||||
|
using loadFormat = Foam::fileFormats::NASCore::loadFormat;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//- Field format (width and separator)
|
||||||
|
fieldFormat writeFormat_;
|
||||||
|
|
||||||
|
//- Separator used for free format
|
||||||
|
word separator_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Write the formatted keyword to the output stream
|
||||||
|
Ostream& writeKeyword(Ostream& os, const word& keyword) const;
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName, //!< Name of field
|
||||||
|
const Field<Type>& values //!< Local field values to write
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Write geometry to file.
|
||||||
|
void writeGeometry(Ostream& os, label nTracks) const;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information (no debug)
|
||||||
|
TypeNameNoDebug("nastran");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Default construct
|
||||||
|
nastranWriter();
|
||||||
|
|
||||||
|
//- Default construct with specified options
|
||||||
|
explicit nastranWriter(const dictionary& options);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
nastranWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
nastranWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor. Calls close()
|
||||||
|
virtual ~nastranWriter();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Characteristic output file name - information only
|
||||||
|
virtual fileName path() const; // override
|
||||||
|
|
||||||
|
declareCoordSetWriterWriteMethod(label);
|
||||||
|
declareCoordSetWriterWriteMethod(scalar);
|
||||||
|
declareCoordSetWriterWriteMethod(vector);
|
||||||
|
declareCoordSetWriterWriteMethod(sphericalTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(symmTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(tensor);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace coordSetWriters
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -1,134 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2018-2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::nastranSetWriter
|
|
||||||
|
|
||||||
Description
|
|
||||||
Line format in Nastran (currently hardcoded to 'free' format)
|
|
||||||
|
|
||||||
Does not do field data.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
nastranCoordSetWriter.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef Foam_coordSetWriters_nastranWriter_H
|
|
||||||
#define Foam_coordSetWriters_nastranWriter_H
|
|
||||||
|
|
||||||
#include "writer.H"
|
|
||||||
#include "NASCore.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class nastranSetWriter Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
class nastranSetWriter
|
|
||||||
:
|
|
||||||
public writer<Type>
|
|
||||||
{
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Write the formatted keyword to the output stream
|
|
||||||
Ostream& writeKeyword
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const word& keyword
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- File field formats
|
|
||||||
using fieldFormat = Foam::fileFormats::NASCore::fieldFormat;
|
|
||||||
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("nastran");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Default construct
|
|
||||||
nastranSetWriter();
|
|
||||||
|
|
||||||
//- Construct with dictionary
|
|
||||||
explicit nastranSetWriter(const dictionary& dict);
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
virtual ~nastranSetWriter() = default;
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
virtual fileName getFileName
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&,
|
|
||||||
const List<const Field<Type>*>&,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
#include "nastranCoordSetWriter.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2018 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "nastranSetWriter.H"
|
|
||||||
#include "writers.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
makeSetWriters(nastranSetWriter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
157
src/meshTools/coordSet/writers/null/nullCoordSetWriter.C
Normal file
157
src/meshTools/coordSet/writers/null/nullCoordSetWriter.C
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "nullCoordSetWriter.H"
|
||||||
|
#include "coordSetWriterMethods.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
defineTypeName(nullWriter);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, nullWriter, word);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, nullWriter, wordDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::coordSetWriters::nullWriter::nullWriter()
|
||||||
|
:
|
||||||
|
coordSetWriter()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::nullWriter::nullWriter(const dictionary& options)
|
||||||
|
:
|
||||||
|
nullWriter()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::nullWriter::nullWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
nullWriter()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::nullWriter::nullWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
nullWriter()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::coordSetWriters::nullWriter::~nullWriter()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::coordSetWriters::nullWriter::enabled() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::coordSetWriters::nullWriter::buffering() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::coordSetWriters::nullWriter::needsUpdate() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::coordSetWriters::nullWriter::wroteData() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::nullWriter::setCoordinates
|
||||||
|
(
|
||||||
|
const coordSet* coords
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::nullWriter::setCoordinates
|
||||||
|
(
|
||||||
|
const coordSet& coords
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::nullWriter::setTracks
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fileName Foam::coordSetWriters::nullWriter::path() const
|
||||||
|
{
|
||||||
|
return fileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::nullWriter::open(const fileName& outputPath)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// Foam::fileName Foam::coordSetWriters::nullWriter::write()
|
||||||
|
// {
|
||||||
|
// wroteGeom_ = true;
|
||||||
|
// return fileName::null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Field writing methods
|
||||||
|
defineCoordSetWriterWriteFields(Foam::coordSetWriters::nullWriter);
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
177
src/meshTools/coordSet/writers/null/nullCoordSetWriter.H
Normal file
177
src/meshTools/coordSet/writers/null/nullCoordSetWriter.H
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::coordSetWriters::nullWriter
|
||||||
|
|
||||||
|
Description
|
||||||
|
A coordSet(s) writer with suppressed output.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
nullCoordSetWriter.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_coordSetWriters_nullWriter_H
|
||||||
|
#define Foam_coordSetWriters_nullWriter_H
|
||||||
|
|
||||||
|
#include "coordSetWriter.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class nullWriter Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class nullWriter
|
||||||
|
:
|
||||||
|
public coordSetWriter
|
||||||
|
{
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName, //!< Name of field
|
||||||
|
const Field<Type>& values //!< Local field values to write
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return fileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return fileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information (no debug)
|
||||||
|
TypeNameNoDebug("none");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Default construct
|
||||||
|
nullWriter();
|
||||||
|
|
||||||
|
//- Construct with some output options
|
||||||
|
explicit nullWriter(const dictionary& options);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
nullWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
nullWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~nullWriter();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Capability
|
||||||
|
|
||||||
|
//- False: The null writer is never enabled, which lets the caller
|
||||||
|
//- skip various (possibly expensive) preparatory operations.
|
||||||
|
virtual bool enabled() const;
|
||||||
|
|
||||||
|
//- False: no internal buffering possible
|
||||||
|
virtual bool buffering() const; // override
|
||||||
|
|
||||||
|
//- False: never needs an update.
|
||||||
|
virtual bool needsUpdate() const;
|
||||||
|
|
||||||
|
//- True: like a /dev/null device.
|
||||||
|
virtual bool wroteData() const;
|
||||||
|
|
||||||
|
|
||||||
|
// Content Association
|
||||||
|
|
||||||
|
//- Set coordinates (no-op).
|
||||||
|
virtual void setCoordinates(const coordSet*); // override
|
||||||
|
|
||||||
|
//- Set coordinates (no-op).
|
||||||
|
virtual void setCoordinates(const coordSet&); // override
|
||||||
|
|
||||||
|
//- Set tracks (no-op).
|
||||||
|
virtual void setTracks(const UPtrList<coordSet>&); // override
|
||||||
|
|
||||||
|
|
||||||
|
// Output
|
||||||
|
|
||||||
|
//- Characteristic output file name - information only.
|
||||||
|
//- Always an empty fileName
|
||||||
|
virtual fileName path() const; // override
|
||||||
|
|
||||||
|
//- Open for output on specified path, using existing content (no-op)
|
||||||
|
virtual void open(const fileName& outputPath); // override
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
declareCoordSetWriterWriteMethod(label);
|
||||||
|
declareCoordSetWriterWriteMethod(scalar);
|
||||||
|
declareCoordSetWriterWriteMethod(vector);
|
||||||
|
declareCoordSetWriterWriteMethod(sphericalTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(symmTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(tensor);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace coordSetWriters
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,94 +26,199 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "rawSetWriter.H"
|
#include "rawCoordSetWriter.H"
|
||||||
#include "coordSet.H"
|
#include "coordSet.H"
|
||||||
#include "fileName.H"
|
#include "fileName.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
|
#include "stringOps.H"
|
||||||
|
#include "coordSetWriterMethods.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
defineTypeName(rawWriter);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, rawWriter, word);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, rawWriter, wordDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
#include "rawCoordSetWriterImpl.C"
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::rawWriter::rawWriter()
|
||||||
Foam::rawSetWriter<Type>::rawSetWriter()
|
|
||||||
:
|
:
|
||||||
writer<Type>()
|
coordSetWriter(),
|
||||||
{}
|
streamOpt_(),
|
||||||
|
precision_(IOstream::defaultPrecision())
|
||||||
|
{
|
||||||
|
buffering_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::rawWriter::rawWriter(const dictionary& options)
|
||||||
Foam::rawSetWriter<Type>::rawSetWriter(const dictionary& dict)
|
|
||||||
:
|
:
|
||||||
writer<Type>(dict)
|
coordSetWriter(options),
|
||||||
{}
|
streamOpt_
|
||||||
|
(
|
||||||
|
IOstream::ASCII,
|
||||||
|
IOstream::compressionEnum("compression", options)
|
||||||
|
),
|
||||||
|
precision_
|
||||||
|
(
|
||||||
|
options.getOrDefault("precision", IOstream::defaultPrecision())
|
||||||
|
)
|
||||||
|
{
|
||||||
|
buffering_ = options.getOrDefault("buffer", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::rawWriter::rawWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
rawWriter(options)
|
||||||
|
{
|
||||||
|
open(coords, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::rawWriter::rawWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
rawWriter(options)
|
||||||
|
{
|
||||||
|
open(tracks, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::coordSetWriters::rawWriter::~rawWriter()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * Controls * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::coordSetWriters::rawWriter::buffering(const bool on)
|
||||||
|
{
|
||||||
|
const bool old(buffering_);
|
||||||
|
buffering_ = on;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
Foam::fileName Foam::coordSetWriters::rawWriter::path() const
|
||||||
Foam::fileName Foam::rawSetWriter<Type>::getFileName
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const wordList& valueSetNames
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
return this->getBaseName(points, valueSetNames) + ".xy";
|
// Assume !useTracks_, otherwise too fragile
|
||||||
|
|
||||||
|
// 1) rootdir/<TIME>/setName.raw
|
||||||
|
// 2) rootdir/setName.raw
|
||||||
|
|
||||||
|
return getExpectedPath("xy"); // Traditionally 'xy', not 'raw'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::coordSetWriters::rawWriter::writeBuffered()
|
||||||
|
{
|
||||||
|
if (coords_.empty())
|
||||||
|
{
|
||||||
|
clearBuffers();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto& coords = coords_[0];
|
||||||
|
|
||||||
|
// Field:
|
||||||
|
// 1) rootdir/<TIME>/setName.raw
|
||||||
|
// 2) rootdir/setName.raw
|
||||||
|
|
||||||
|
fileName outputFile = path();
|
||||||
|
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
OFstream os(outputFile, streamOpt_);
|
||||||
|
os.precision(precision_);
|
||||||
|
|
||||||
|
writeBufferContents(os, coords, " \t");
|
||||||
|
|
||||||
|
clearBuffers();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::rawSetWriter<Type>::write
|
Foam::fileName Foam::coordSetWriters::rawWriter::writeTemplate
|
||||||
(
|
(
|
||||||
const coordSet& points,
|
const word& fieldName,
|
||||||
const wordList& valueSetNames,
|
const Field<Type>& values
|
||||||
const List<const Field<Type>*>& valueSets,
|
)
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
// Collect sets into columns
|
checkOpen();
|
||||||
List<const List<Type>*> columns(valueSets.size());
|
if (coords_.empty())
|
||||||
|
|
||||||
forAll(valueSets, i)
|
|
||||||
{
|
{
|
||||||
columns[i] = valueSets[i];
|
return fileName::null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->writeTable(points, columns, os);
|
if (useTracks_ || !buffering_)
|
||||||
|
{
|
||||||
|
UPtrList<const Field<Type>> fieldPtrs(repackageFields(values));
|
||||||
|
return writeTemplate(fieldName, fieldPtrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffering version
|
||||||
|
appendField(fieldName, values);
|
||||||
|
return path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::rawSetWriter<Type>::write
|
Foam::fileName Foam::coordSetWriters::rawWriter::writeTemplate
|
||||||
(
|
(
|
||||||
const bool writeTracks,
|
const word& fieldName,
|
||||||
const List<scalarField>& times,
|
const List<Field<Type>>& fieldValues
|
||||||
const PtrList<coordSet>& tracks,
|
)
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
if (valueSets.size() != valueSetNames.size())
|
checkOpen();
|
||||||
|
if (coords_.empty())
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
return fileName::null;
|
||||||
<< "Number of variables:" << valueSetNames.size() << endl
|
|
||||||
<< "Number of valueSets:" << valueSets.size()
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
}
|
||||||
|
useTracks_ = true; // Extra safety
|
||||||
|
|
||||||
List<const List<Type>*> columns(valueSets.size());
|
UPtrList<const Field<Type>> fieldPtrs(repackageFields(fieldValues));
|
||||||
|
return writeTemplate(fieldName, fieldPtrs);
|
||||||
forAll(tracks, trackI)
|
|
||||||
{
|
|
||||||
// Collect sets into columns
|
|
||||||
forAll(valueSets, i)
|
|
||||||
{
|
|
||||||
columns[i] = &valueSets[i][trackI];
|
|
||||||
}
|
|
||||||
|
|
||||||
this->writeTable(tracks[trackI], columns, os);
|
|
||||||
os << nl << nl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Field writing methods
|
||||||
|
defineCoordSetWriterWriteFields(Foam::coordSetWriters::rawWriter);
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
178
src/meshTools/coordSet/writers/raw/rawCoordSetWriter.H
Normal file
178
src/meshTools/coordSet/writers/raw/rawCoordSetWriter.H
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::coordSetWriters::rawWriter
|
||||||
|
|
||||||
|
Description
|
||||||
|
A coordSet(s) in raw format.
|
||||||
|
|
||||||
|
The formatOptions for raw:
|
||||||
|
\table
|
||||||
|
Property | Description | Required | Default
|
||||||
|
buffer | Use buffered output | no | true
|
||||||
|
compression | Use file compression | no | false
|
||||||
|
precision | Write precision in ascii | no | same as IOstream
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
When called with a single coordSet, will buffer the output of
|
||||||
|
all fields and output together in the order of label/scalar/vector/...
|
||||||
|
each of which is sorted alphabetically according to the field name.
|
||||||
|
|
||||||
|
When called as a track writer (eg, with multiple coordSets),
|
||||||
|
will emit one file per field.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
rawCoordSetWriter.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_coordSetWriters_rawWriter_H
|
||||||
|
#define Foam_coordSetWriters_rawWriter_H
|
||||||
|
|
||||||
|
#include "coordSetWriter.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class rawWriter Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class rawWriter
|
||||||
|
:
|
||||||
|
public coordSetWriter
|
||||||
|
{
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Output stream option
|
||||||
|
IOstreamOption streamOpt_;
|
||||||
|
|
||||||
|
//- ASCII write precision
|
||||||
|
unsigned precision_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName, //!< Name of field
|
||||||
|
const Field<Type>& vals //!< Local field values to write
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName, //!< Name of field
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Write buffered data
|
||||||
|
virtual bool writeBuffered();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information (no debug)
|
||||||
|
TypeNameNoDebug("raw");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Default construct
|
||||||
|
rawWriter();
|
||||||
|
|
||||||
|
//- Default construct with specified options
|
||||||
|
explicit rawWriter(const dictionary& options);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
rawWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
rawWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor. Calls close()
|
||||||
|
virtual ~rawWriter();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Enable/disable internal buffering
|
||||||
|
virtual bool buffering(const bool on); // override
|
||||||
|
|
||||||
|
//- Characteristic output file name - information only
|
||||||
|
// \warning incorrect for unbuffered or track output!
|
||||||
|
virtual fileName path() const; // override
|
||||||
|
|
||||||
|
declareCoordSetWriterWriteMethod(label);
|
||||||
|
declareCoordSetWriterWriteMethod(scalar);
|
||||||
|
declareCoordSetWriterWriteMethod(vector);
|
||||||
|
declareCoordSetWriterWriteMethod(sphericalTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(symmTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(tensor);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace coordSetWriters
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
149
src/meshTools/coordSet/writers/raw/rawCoordSetWriterImpl.C
Normal file
149
src/meshTools/coordSet/writers/raw/rawCoordSetWriterImpl.C
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "IOmanip.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
// Output coordinate header
|
||||||
|
static void writeCoordHeader
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const coordSet& coords,
|
||||||
|
const label count
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (coords.hasVectorAxis())
|
||||||
|
{
|
||||||
|
os << "POINT_DATA" << ' ' << count << nl;
|
||||||
|
os << "# x y z";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
word axisName(coords.axis());
|
||||||
|
word dataName(stringOps::upper(axisName) + "_DATA");
|
||||||
|
|
||||||
|
os << dataName << ' ' << count << nl;
|
||||||
|
os << "# " << axisName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write field name, use named components for VectorSpace
|
||||||
|
template<class Type>
|
||||||
|
static inline void writeHeader(Ostream& os, const word& fieldName)
|
||||||
|
{
|
||||||
|
os << ' '; // Extra space
|
||||||
|
|
||||||
|
const auto nCmpts(pTraits<Type>::nComponents);
|
||||||
|
|
||||||
|
if (pTraits<Type>::rank || nCmpts > 1)
|
||||||
|
{
|
||||||
|
for (direction d = 0; d < nCmpts; ++d)
|
||||||
|
{
|
||||||
|
os << ' ' << fieldName
|
||||||
|
<< '_' << pTraits<Type>::componentNames[d];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << ' ' << fieldName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::rawWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (coords_.size() != fieldPtrs.size())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Attempted to write field: " << fieldName
|
||||||
|
<< " (" << fieldPtrs.size() << " entries) for "
|
||||||
|
<< coords_.size() << " sets" << nl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
label nPoints = 0;
|
||||||
|
for (const auto& pts : coords_)
|
||||||
|
{
|
||||||
|
nPoints += pts.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Field: rootdir/<TIME>/<field>_setName.raw
|
||||||
|
|
||||||
|
fileName outputFile = getFieldPrefixedPath(fieldName, "raw");
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing field " << fieldName;
|
||||||
|
Info<< " to " << outputFile << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Master only
|
||||||
|
{
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
OFstream os(outputFile, streamOpt_);
|
||||||
|
os.precision(precision_);
|
||||||
|
|
||||||
|
// Header
|
||||||
|
{
|
||||||
|
os << "# " << fieldName << " ";
|
||||||
|
|
||||||
|
writeCoordHeader(os, coords_[0], nPoints);
|
||||||
|
writeHeader<Type>(os, fieldName);
|
||||||
|
os << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(coords_, tracki)
|
||||||
|
{
|
||||||
|
writeTable(os, coords_[tracki], fieldPtrs[tracki], " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wroteGeom_ = true;
|
||||||
|
return outputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -1,117 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::rawSetWriter
|
|
||||||
|
|
||||||
Description
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
rawCoordSetWriter.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef Foam_coordSetWriters_rawWriter_H
|
|
||||||
#define Foam_coordSetWriters_rawWriter_H
|
|
||||||
|
|
||||||
#include "writer.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class rawSetWriter Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
class rawSetWriter
|
|
||||||
:
|
|
||||||
public writer<Type>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("raw");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Default construct
|
|
||||||
rawSetWriter();
|
|
||||||
|
|
||||||
//- Construct with dictionary
|
|
||||||
explicit rawSetWriter(const dictionary& dict);
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
virtual ~rawSetWriter() = default;
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
virtual fileName getFileName
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&,
|
|
||||||
const List<const Field<Type>*>&,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
#include "rawCoordSetWriter.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ 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/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "rawSetWriter.H"
|
|
||||||
#include "writers.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
makeSetWriters(rawSetWriter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -5,8 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,177 +25,310 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "vtkSetWriter.H"
|
#include "vtkCoordSetWriter.H"
|
||||||
#include "coordSet.H"
|
#include "coordSet.H"
|
||||||
#include "fileName.H"
|
#include "fileName.H"
|
||||||
#include "OFstream.H"
|
#include "foamVtkCoordSetWriter.H"
|
||||||
|
#include "coordSetWriterMethods.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
defineTypeName(vtkWriter);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, vtkWriter, word);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, vtkWriter, wordDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::vtkWriter::vtkWriter()
|
||||||
Foam::vtkSetWriter<Type>::vtkSetWriter()
|
|
||||||
:
|
:
|
||||||
writer<Type>()
|
coordSetWriter(),
|
||||||
|
fmtType_(static_cast<unsigned>(vtk::formatType::INLINE_BASE64)),
|
||||||
|
precision_(IOstream::defaultPrecision()),
|
||||||
|
writer_(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::vtkWriter::vtkWriter
|
||||||
Foam::vtkSetWriter<Type>::vtkSetWriter(const dictionary& dict)
|
(
|
||||||
|
const vtk::outputOptions& opts
|
||||||
|
)
|
||||||
:
|
:
|
||||||
writer<Type>(dict)
|
coordSetWriter(),
|
||||||
|
fmtType_(static_cast<unsigned>(opts.fmt())),
|
||||||
|
precision_(opts.precision()),
|
||||||
|
writer_(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::vtkWriter::vtkWriter(const dictionary& options)
|
||||||
|
:
|
||||||
|
coordSetWriter(options),
|
||||||
|
fmtType_(static_cast<unsigned>(vtk::formatType::INLINE_BASE64)),
|
||||||
|
precision_
|
||||||
|
(
|
||||||
|
options.getOrDefault("precision", IOstream::defaultPrecision())
|
||||||
|
),
|
||||||
|
writer_(nullptr)
|
||||||
|
{
|
||||||
|
// format: ascii | binary
|
||||||
|
// legacy: true | false
|
||||||
|
|
||||||
|
vtk::outputOptions opts(vtk::formatType::INLINE_BASE64);
|
||||||
|
opts.ascii
|
||||||
|
(
|
||||||
|
IOstream::ASCII
|
||||||
|
== IOstream::formatEnum("format", options, IOstream::BINARY)
|
||||||
|
);
|
||||||
|
|
||||||
|
opts.legacy(options.getOrDefault("legacy", false));
|
||||||
|
|
||||||
|
// Convert back to raw data type
|
||||||
|
fmtType_ = static_cast<unsigned>(opts.fmt());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::vtkWriter::vtkWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
vtkWriter(options)
|
||||||
|
{
|
||||||
|
open(coords, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::vtkWriter::vtkWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
vtkWriter(options)
|
||||||
|
{
|
||||||
|
open(tracks, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::coordSetWriters::vtkWriter::~vtkWriter()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
Foam::fileName Foam::coordSetWriters::vtkWriter::path() const
|
||||||
Foam::fileName Foam::vtkSetWriter<Type>::getFileName
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const wordList& valueSetNames
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
return this->getBaseName(points, valueSetNames) + ".vtk";
|
// 1) rootdir/<TIME>/setName.{vtk|vtp}
|
||||||
|
// 2) rootdir/setName.{vtk|vtp}
|
||||||
|
|
||||||
|
// From raw unsigned value to vtk::outputOptions
|
||||||
|
vtk::outputOptions opts(static_cast<vtk::formatType>(fmtType_));
|
||||||
|
|
||||||
|
return getExpectedPath(vtk::polyWriter::ext(opts));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
void Foam::coordSetWriters::vtkWriter::close(bool force)
|
||||||
void Foam::vtkSetWriter<Type>::write
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<const Field<Type>*>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
os << "# vtk DataFile Version 2.0" << nl
|
writer_.clear();
|
||||||
<< points.name() << nl
|
coordSetWriter::close(force);
|
||||||
<< "ASCII" << nl
|
}
|
||||||
<< "DATASET POLYDATA" << nl
|
|
||||||
<< "POINTS " << points.size() << " double" << nl;
|
|
||||||
|
|
||||||
for (const point& pt : points)
|
|
||||||
|
void Foam::coordSetWriters::vtkWriter::beginTime(const Time& t)
|
||||||
|
{
|
||||||
|
writer_.clear();
|
||||||
|
coordSetWriter::beginTime(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::vtkWriter::beginTime(const instant& inst)
|
||||||
|
{
|
||||||
|
writer_.clear();
|
||||||
|
coordSetWriter::beginTime(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::vtkWriter::endTime()
|
||||||
|
{
|
||||||
|
writer_.clear();
|
||||||
|
coordSetWriter::endTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fileName Foam::coordSetWriters::vtkWriter::write()
|
||||||
|
{
|
||||||
|
checkOpen();
|
||||||
|
if (needsUpdate())
|
||||||
{
|
{
|
||||||
os << float(pt.x()) << ' '
|
writer_.clear();
|
||||||
<< float(pt.y()) << ' '
|
}
|
||||||
<< float(pt.z()) << nl;
|
merge();
|
||||||
|
|
||||||
|
if (coords_.empty())
|
||||||
|
{
|
||||||
|
return fileName::null;
|
||||||
}
|
}
|
||||||
|
|
||||||
os << "POINT_DATA " << points.size() << nl
|
// From raw unsigned values to vtk::outputOptions
|
||||||
<< " FIELD attributes " << valueSetNames.size() << nl;
|
vtk::outputOptions opts(static_cast<vtk::formatType>(fmtType_), precision_);
|
||||||
|
|
||||||
forAll(valueSetNames, setI)
|
|
||||||
|
// Geometry: rootdir/<TIME>/setName.{vtk|vtp}
|
||||||
|
|
||||||
|
fileName outputFile = getExpectedPath(vtk::polyWriter::ext(opts));
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
{
|
{
|
||||||
os << valueSetNames[setI] << ' '
|
Info<< "Writing geometry to " << outputFile << endl;
|
||||||
<< int(pTraits<Type>::nComponents) << ' '
|
}
|
||||||
<< points.size() << " float" << nl;
|
|
||||||
|
|
||||||
const Field<Type>& fld = *valueSets[setI];
|
if (!writer_ && true) // always (non-parallel)
|
||||||
|
{
|
||||||
forAll(fld, pointi)
|
UPtrList<const pointField> points(coords_.size());
|
||||||
|
forAll(coords_, tracki)
|
||||||
{
|
{
|
||||||
if (pointi)
|
points.set(tracki, coords_.get(tracki));
|
||||||
{
|
|
||||||
os << ' ';
|
|
||||||
}
|
|
||||||
writer<Type>::write(fld[pointi], os);
|
|
||||||
}
|
}
|
||||||
os << nl;
|
|
||||||
|
writer_.reset
|
||||||
|
(
|
||||||
|
new vtk::coordSetWriter
|
||||||
|
(
|
||||||
|
points,
|
||||||
|
opts,
|
||||||
|
outputFile,
|
||||||
|
false // serial!
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (useTracks_ || coords_.size() > 1)
|
||||||
|
{
|
||||||
|
writer_->setElementType(vtk::coordSetWriter::LINE_ELEMENTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->hasTime())
|
||||||
|
{
|
||||||
|
// Time name in title
|
||||||
|
writer_->setTime(currTime_);
|
||||||
|
writer_->writeTimeValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Set name in title
|
||||||
|
writer_->beginFile(outputPath_.nameLessExt());
|
||||||
|
}
|
||||||
|
|
||||||
|
writer_->writeGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wroteGeom_ = true;
|
||||||
|
return outputFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Implementation * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::vtkSetWriter<Type>::write
|
Foam::fileName Foam::coordSetWriters::vtkWriter::writeTemplate
|
||||||
(
|
(
|
||||||
const bool writeTracks,
|
const word& fieldName,
|
||||||
const List<scalarField>& times,
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
const PtrList<coordSet>& tracks,
|
)
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
if (valueSets.size() != valueSetNames.size())
|
if (coords_.size() != fieldPtrs.size())
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Number of variables:" << valueSetNames.size() << endl
|
<< "Attempted to write field: " << fieldName
|
||||||
<< "Number of valueSets:" << valueSets.size()
|
<< " (" << fieldPtrs.size() << " entries) for "
|
||||||
|
<< coords_.size() << " sets" << nl
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
label nTracks = tracks.size();
|
// Open file, writing geometry (if required)
|
||||||
label nPoints = 0;
|
fileName outputFile = this->write();
|
||||||
forAll(tracks, i)
|
|
||||||
|
if (!nFields_ && writer_->legacy())
|
||||||
{
|
{
|
||||||
nPoints += tracks[i].size();
|
// Emit error message, but attempt to recover anyhow
|
||||||
|
nFields_ = 1;
|
||||||
|
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Using VTK legacy format, but did not define nFields!"
|
||||||
|
<< nl
|
||||||
|
<< "Assuming nFields=1 (may be incorrect) and continuing..."
|
||||||
|
<< nl
|
||||||
|
<< " Field " << fieldName << " to " << outputFile << nl;
|
||||||
|
|
||||||
|
Info<< FatalError;
|
||||||
|
Info<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
os << "# vtk DataFile Version 2.0" << nl
|
writer_->beginPointData(nFields_);
|
||||||
<< tracks[0].name() << nl
|
|
||||||
<< "ASCII" << nl
|
|
||||||
<< "DATASET POLYDATA" << nl
|
|
||||||
<< "POINTS " << nPoints << " double" << nl;
|
|
||||||
|
|
||||||
for (const coordSet& points : tracks)
|
writer_->writePointData(fieldName, fieldPtrs);
|
||||||
{
|
|
||||||
for (const point& pt : points)
|
|
||||||
{
|
|
||||||
os << float(pt.x()) << ' '
|
|
||||||
<< float(pt.y()) << ' '
|
|
||||||
<< float(pt.z()) << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (writeTracks)
|
wroteGeom_ = true;
|
||||||
{
|
return outputFile;
|
||||||
os << "LINES " << nTracks << ' ' << nPoints+nTracks << nl;
|
|
||||||
|
|
||||||
// Write ids of track points to file
|
|
||||||
label globalPtI = 0;
|
|
||||||
forAll(tracks, trackI)
|
|
||||||
{
|
|
||||||
const coordSet& points = tracks[trackI];
|
|
||||||
|
|
||||||
const label len = points.size();
|
|
||||||
|
|
||||||
os << len;
|
|
||||||
for (label i = 0; i < len; ++i)
|
|
||||||
{
|
|
||||||
os << ' ' << globalPtI;
|
|
||||||
++globalPtI;
|
|
||||||
}
|
|
||||||
os << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
os << "POINT_DATA " << nPoints << nl
|
|
||||||
<< " FIELD attributes " << valueSetNames.size() << nl;
|
|
||||||
|
|
||||||
forAll(valueSetNames, setI)
|
|
||||||
{
|
|
||||||
os << valueSetNames[setI] << ' '
|
|
||||||
<< int(pTraits<Type>::nComponents) << ' '
|
|
||||||
<< nPoints << " float" << nl;
|
|
||||||
|
|
||||||
const List<Field<Type>>& fieldVals = valueSets[setI];
|
|
||||||
|
|
||||||
for (const Field<Type>& vals : fieldVals)
|
|
||||||
{
|
|
||||||
forAll(vals, j)
|
|
||||||
{
|
|
||||||
if (j)
|
|
||||||
{
|
|
||||||
os << ' ';
|
|
||||||
}
|
|
||||||
writer<Type>::write(vals[j], os);
|
|
||||||
}
|
|
||||||
os << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::vtkWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const Field<Type>& values
|
||||||
|
)
|
||||||
|
{
|
||||||
|
checkOpen();
|
||||||
|
if (coords_.empty())
|
||||||
|
{
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
UPtrList<const Field<Type>> fieldPtrs(repackageFields(values));
|
||||||
|
return writeTemplate(fieldName, fieldPtrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::vtkWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
)
|
||||||
|
{
|
||||||
|
checkOpen();
|
||||||
|
if (coords_.empty())
|
||||||
|
{
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
useTracks_ = true; // Extra safety
|
||||||
|
|
||||||
|
UPtrList<const Field<Type>> fieldPtrs(repackageFields(fieldValues));
|
||||||
|
return writeTemplate(fieldName, fieldPtrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Field writing methods
|
||||||
|
defineCoordSetWriterWriteFields(Foam::coordSetWriters::vtkWriter);
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
185
src/meshTools/coordSet/writers/vtk/vtkCoordSetWriter.H
Normal file
185
src/meshTools/coordSet/writers/vtk/vtkCoordSetWriter.H
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::coordSetWriters::vtkWriter
|
||||||
|
|
||||||
|
Description
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
vtkCoordSetWriter.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_coordSetWriters_vtkWriter_H
|
||||||
|
#define Foam_coordSetWriters_vtkWriter_H
|
||||||
|
|
||||||
|
#include "coordSetWriter.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
class OFstream;
|
||||||
|
|
||||||
|
namespace vtk
|
||||||
|
{
|
||||||
|
// Forward Declarations
|
||||||
|
class outputOptions;
|
||||||
|
class coordSetWriter;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class vtkCoordSetWriter Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class vtkWriter
|
||||||
|
:
|
||||||
|
public coordSetWriter
|
||||||
|
{
|
||||||
|
// 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::coordSetWriter> writer_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName, //!< Name of field
|
||||||
|
const Field<Type>& vals //!< Local field values to write
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information (no debug)
|
||||||
|
TypeNameNoDebug("vtk");
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Default construct
|
||||||
|
vtkWriter();
|
||||||
|
|
||||||
|
//- Construct with some output options
|
||||||
|
explicit vtkWriter(const vtk::outputOptions& opts);
|
||||||
|
|
||||||
|
//- Default construct with specified options
|
||||||
|
explicit vtkWriter(const dictionary& options);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
vtkWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
vtkWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor. Calls close()
|
||||||
|
virtual ~vtkWriter();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Expected (characteristic) output file name - information only
|
||||||
|
virtual fileName path() const; // override
|
||||||
|
|
||||||
|
//- Close and reset, clears backend.
|
||||||
|
virtual void close(bool force = false); // 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 geometry to file.
|
||||||
|
virtual fileName write(); // override
|
||||||
|
|
||||||
|
declareCoordSetWriterWriteMethod(label);
|
||||||
|
declareCoordSetWriterWriteMethod(scalar);
|
||||||
|
declareCoordSetWriterWriteMethod(vector);
|
||||||
|
declareCoordSetWriterWriteMethod(sphericalTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(symmTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(tensor);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace coordSetWriters
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -1,120 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::vtkSetWriter
|
|
||||||
|
|
||||||
Description
|
|
||||||
|
|
||||||
Note
|
|
||||||
The output order of symmTensor is incorrect.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
vtkCoordSetWriter.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef Foam_coordSetWriters_vtkWriter_H
|
|
||||||
#define Foam_coordSetWriters_vtkWriter_H
|
|
||||||
|
|
||||||
#include "writer.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class vtkSetWriter Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
class vtkSetWriter
|
|
||||||
:
|
|
||||||
public writer<Type>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("vtk");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Default construct
|
|
||||||
vtkSetWriter();
|
|
||||||
|
|
||||||
//- Construct with dictionary
|
|
||||||
explicit vtkSetWriter(const dictionary& dict);
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
virtual ~vtkSetWriter() = default;
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
virtual fileName getFileName
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&,
|
|
||||||
const List<const Field<Type>*>&,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
#include "vtkCoordSetWriter.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ 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/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "vtkSetWriter.H"
|
|
||||||
#include "writers.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
makeSetWriters(vtkSetWriter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,110 +26,244 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "xmgraceSetWriter.H"
|
#include "xmgraceCoordSetWriter.H"
|
||||||
#include "coordSet.H"
|
#include "coordSet.H"
|
||||||
#include "fileName.H"
|
#include "fileName.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
|
#include "coordSetWriterMethods.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
defineTypeName(xmgraceWriter);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, xmgraceWriter, word);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, xmgraceWriter, wordDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
#include "xmgraceCoordSetWriterImpl.C"
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::xmgraceWriter::xmgraceWriter()
|
||||||
Foam::xmgraceSetWriter<Type>::xmgraceSetWriter()
|
|
||||||
:
|
:
|
||||||
writer<Type>()
|
coordSetWriter(),
|
||||||
{}
|
streamOpt_(),
|
||||||
|
precision_(IOstream::defaultPrecision()),
|
||||||
|
ofile_(nullptr),
|
||||||
|
nWritten_(0)
|
||||||
|
{
|
||||||
|
buffering_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
Foam::coordSetWriters::xmgraceWriter::xmgraceWriter(const dictionary& options)
|
||||||
Foam::xmgraceSetWriter<Type>::xmgraceSetWriter(const dictionary& dict)
|
|
||||||
:
|
:
|
||||||
writer<Type>(dict)
|
coordSetWriter(options),
|
||||||
{}
|
streamOpt_
|
||||||
|
(
|
||||||
|
IOstream::ASCII,
|
||||||
|
IOstream::compressionEnum("compression", options)
|
||||||
|
),
|
||||||
|
precision_
|
||||||
|
(
|
||||||
|
options.getOrDefault("precision", IOstream::defaultPrecision())
|
||||||
|
),
|
||||||
|
ofile_(nullptr),
|
||||||
|
nWritten_(0)
|
||||||
|
{
|
||||||
|
buffering_ = options.getOrDefault("buffer", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::xmgraceWriter::xmgraceWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
xmgraceWriter(options)
|
||||||
|
{
|
||||||
|
open(coords, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::xmgraceWriter::xmgraceWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
xmgraceWriter(options)
|
||||||
|
{
|
||||||
|
open(tracks, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::coordSetWriters::xmgraceWriter::~xmgraceWriter()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
bool Foam::coordSetWriters::xmgraceWriter::buffering(const bool on)
|
||||||
Foam::fileName Foam::xmgraceSetWriter<Type>::getFileName
|
|
||||||
(
|
|
||||||
const coordSet& points,
|
|
||||||
const wordList& valueSetNames
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
return this->getBaseName(points, valueSetNames) + ".agr";
|
const bool old(buffering_);
|
||||||
|
buffering_ = on;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fileName Foam::coordSetWriters::xmgraceWriter::path() const
|
||||||
|
{
|
||||||
|
// Assume !useTracks_, otherwise too fragile
|
||||||
|
|
||||||
|
// 1) rootdir/<TIME>/setName.agr
|
||||||
|
// 2) rootdir/setName.agr
|
||||||
|
|
||||||
|
return getExpectedPath("agr");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::xmgraceWriter::close(bool force)
|
||||||
|
{
|
||||||
|
ofile_.reset(nullptr);
|
||||||
|
nWritten_ = 0;
|
||||||
|
coordSetWriter::close(force);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::xmgraceWriter::beginTime(const Time& t)
|
||||||
|
{
|
||||||
|
ofile_.reset(nullptr);
|
||||||
|
nWritten_ = 0;
|
||||||
|
coordSetWriter::beginTime(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::xmgraceWriter::beginTime(const instant& inst)
|
||||||
|
{
|
||||||
|
ofile_.reset(nullptr);
|
||||||
|
nWritten_ = 0;
|
||||||
|
coordSetWriter::beginTime(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::xmgraceWriter::endTime()
|
||||||
|
{
|
||||||
|
ofile_.reset(nullptr);
|
||||||
|
nWritten_ = 0;
|
||||||
|
coordSetWriter::endTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::xmgraceSetWriter<Type>::write
|
Foam::fileName Foam::coordSetWriters::xmgraceWriter::writeTemplate
|
||||||
(
|
(
|
||||||
const coordSet& points,
|
const word& fieldName,
|
||||||
const wordList& valueSetNames,
|
const Field<Type>& values
|
||||||
const List<const Field<Type>*>& valueSets,
|
)
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
os << "@g0 on" << nl
|
checkOpen();
|
||||||
<< "@with g0" << nl
|
if (coords_.empty())
|
||||||
<< "@ title \"" << points.name() << '"' << nl
|
|
||||||
<< "@ xaxis label " << '"' << points.axis() << '"' << nl;
|
|
||||||
|
|
||||||
forAll(valueSets, i)
|
|
||||||
{
|
{
|
||||||
os << "@ s" << i << " legend " << '"'
|
return fileName::null;
|
||||||
<< valueSetNames[i] << '"' << nl
|
|
||||||
<< "@target G0.S" << i << nl;
|
|
||||||
|
|
||||||
this->writeTable(points, *valueSets[i], os);
|
|
||||||
|
|
||||||
os << '&' << nl;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if (useTracks_ || !buffering_)
|
||||||
template<class Type>
|
|
||||||
void Foam::xmgraceSetWriter<Type>::write
|
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
if (valueSets.size() != valueSetNames.size())
|
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
UPtrList<const Field<Type>> fieldPtrs(repackageFields(values));
|
||||||
<< "Number of variables:" << valueSetNames.size() << endl
|
return writeTemplate(fieldName, fieldPtrs);
|
||||||
<< "Number of valueSets:" << valueSets.size()
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
}
|
||||||
if (tracks.size() > 0)
|
|
||||||
|
|
||||||
|
// Regular version
|
||||||
|
|
||||||
|
const auto& coords = coords_[0];
|
||||||
|
|
||||||
|
if (!ofile_)
|
||||||
{
|
{
|
||||||
|
// Field:
|
||||||
|
// 1) rootdir/<TIME>/setName.agr
|
||||||
|
// 2) rootdir/setName.agr
|
||||||
|
|
||||||
|
const fileName outputFile = path();
|
||||||
|
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
ofile_.reset(new OFstream(outputFile, streamOpt_));
|
||||||
|
auto& os = ofile_();
|
||||||
|
os.precision(precision_);
|
||||||
|
|
||||||
|
// Preamble
|
||||||
os << "@g0 on" << nl
|
os << "@g0 on" << nl
|
||||||
<< "@with g0" << nl
|
<< "@with g0" << nl
|
||||||
<< "@ title \"" << tracks[0].name() << '"' << nl
|
<< "@ title \"" << coords.name() << '"' << nl
|
||||||
<< "@ xaxis label " << '"' << tracks[0].axis() << '"' << nl;
|
<< "@ xaxis label \"" << coords.axis() << '"' << nl;
|
||||||
|
|
||||||
// Data index.
|
nWritten_ = 0; // Restarted
|
||||||
label sI = 0;
|
|
||||||
|
|
||||||
forAll(tracks, trackI)
|
|
||||||
{
|
|
||||||
forAll(valueSets, i)
|
|
||||||
{
|
|
||||||
os << "@ s" << sI << " legend " << '"'
|
|
||||||
<< valueSetNames[i] << "_track" << i << '"' << nl
|
|
||||||
<< "@target G0.S" << sI << nl;
|
|
||||||
this->writeTable(tracks[trackI], valueSets[i][trackI], os);
|
|
||||||
os << '&' << nl;
|
|
||||||
|
|
||||||
sI++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
auto& os = ofile_();
|
||||||
|
|
||||||
|
// Plot entry
|
||||||
|
{
|
||||||
|
os << "@ s" << nWritten_
|
||||||
|
<< " legend \"" << fieldName << '"' << nl
|
||||||
|
<< "@target G0.S" << nWritten_ << nl;
|
||||||
|
|
||||||
|
writeTable(os, coords, values, " \t");
|
||||||
|
|
||||||
|
os << '&' << nl;
|
||||||
|
os << "# end_data" << nl;
|
||||||
|
++nWritten_;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ofile_().name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::xmgraceWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
)
|
||||||
|
{
|
||||||
|
checkOpen();
|
||||||
|
if (coords_.empty())
|
||||||
|
{
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
useTracks_ = true; // Extra safety
|
||||||
|
|
||||||
|
UPtrList<const Field<Type>> fieldPtrs(repackageFields(fieldValues));
|
||||||
|
return writeTemplate(fieldName, fieldPtrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Field writing methods
|
||||||
|
defineCoordSetWriterWriteFields(Foam::coordSetWriters::xmgraceWriter);
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
204
src/meshTools/coordSet/writers/xmgrace/xmgraceCoordSetWriter.H
Normal file
204
src/meshTools/coordSet/writers/xmgrace/xmgraceCoordSetWriter.H
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::coordSetWriters::xmgraceWriter
|
||||||
|
|
||||||
|
Description
|
||||||
|
Write coordSet(s) in xmgrace format
|
||||||
|
|
||||||
|
The formatOptions for xmgrace:
|
||||||
|
\table
|
||||||
|
Property | Description | Required | Default
|
||||||
|
buffer | Use buffered output | no | true
|
||||||
|
compression | Use file compression | no | false
|
||||||
|
precision | Write precision in ascii | no | same as IOstream
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
When called with a single coordSet, will combine all output fields
|
||||||
|
into a single file. Although it is nominally 'buffered', it actually
|
||||||
|
just keeps track of the number of fields written into the file.
|
||||||
|
|
||||||
|
When called as a track writer (eg, with multiple coordSets),
|
||||||
|
will emit one file per field.
|
||||||
|
|
||||||
|
\section Output file locations
|
||||||
|
|
||||||
|
The \c rootdir normally corresponds to something like
|
||||||
|
\c postProcessing/\<name\>
|
||||||
|
|
||||||
|
\subsection Geometry and Fields
|
||||||
|
\verbatim
|
||||||
|
rootdir
|
||||||
|
`-- timeName
|
||||||
|
`-- setName.{agr}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
xmgraceCoordSetWriter.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_coordSetWriters_xmgraceWriter_H
|
||||||
|
#define Foam_coordSetWriters_xmgraceWriter_H
|
||||||
|
|
||||||
|
#include "coordSetWriter.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
class OFstream;
|
||||||
|
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class xmgraceWriter Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class xmgraceWriter
|
||||||
|
:
|
||||||
|
public coordSetWriter
|
||||||
|
{
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Output stream option
|
||||||
|
IOstreamOption streamOpt_;
|
||||||
|
|
||||||
|
//- ASCII write precision
|
||||||
|
unsigned precision_;
|
||||||
|
|
||||||
|
//- Backend output file (when buffering)
|
||||||
|
autoPtr<Foam::OFstream> ofile_;
|
||||||
|
|
||||||
|
//- The number of fields written (when buffering)
|
||||||
|
label nWritten_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName, //!< Name of field
|
||||||
|
const Field<Type>& vals //!< Local field values to write
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information (no debug)
|
||||||
|
TypeNameNoDebug("xmgr");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Default construct
|
||||||
|
xmgraceWriter();
|
||||||
|
|
||||||
|
//- Default construct with specified options
|
||||||
|
explicit xmgraceWriter(const dictionary& options);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
xmgraceWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
xmgraceWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor. Calls close()
|
||||||
|
virtual ~xmgraceWriter();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Enable/disable internal buffering
|
||||||
|
virtual bool buffering(const bool on); // override
|
||||||
|
|
||||||
|
//- Characteristic output file name - information only
|
||||||
|
virtual fileName path() const; // override
|
||||||
|
|
||||||
|
//- Close and reset, clears backend.
|
||||||
|
virtual void close(bool force = false); // 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
|
||||||
|
|
||||||
|
|
||||||
|
declareCoordSetWriterWriteMethod(label);
|
||||||
|
declareCoordSetWriterWriteMethod(scalar);
|
||||||
|
declareCoordSetWriterWriteMethod(vector);
|
||||||
|
declareCoordSetWriterWriteMethod(sphericalTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(symmTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(tensor);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace coordSetWriters
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,102 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "IOmanip.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::xmgraceWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const UPtrList<const Field<Type>>& fieldPtrs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (coords_.size() != fieldPtrs.size())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Attempted to write field: " << fieldName
|
||||||
|
<< " (" << fieldPtrs.size() << " entries) for "
|
||||||
|
<< coords_.size() << " sets" << nl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Field: rootdir/<TIME>/<field>_setName.agr
|
||||||
|
|
||||||
|
fileName outputFile = getFieldPrefixedPath(fieldName, "agr");
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing field " << fieldName;
|
||||||
|
Info<< " to " << outputFile << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Master only
|
||||||
|
{
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
OFstream os(outputFile, streamOpt_);
|
||||||
|
os.precision(precision_);
|
||||||
|
|
||||||
|
// Preamble
|
||||||
|
{
|
||||||
|
const coordSet& coords = coords_[0];
|
||||||
|
|
||||||
|
os << "@g0 on" << nl
|
||||||
|
<< "@with g0" << nl
|
||||||
|
<< "@ title \"" << coords.name() << '"' << nl
|
||||||
|
<< "@ xaxis label \"" << coords.axis() << '"' << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
const label setNumber = 0;
|
||||||
|
|
||||||
|
// Plot entry
|
||||||
|
os << "@ s" << setNumber
|
||||||
|
<< " legend \"" << fieldName << '"' << nl
|
||||||
|
<< "@target G0.S" << setNumber << nl;
|
||||||
|
|
||||||
|
forAll(coords_, tracki)
|
||||||
|
{
|
||||||
|
writeTable(os, coords_[tracki], fieldPtrs[tracki], " \t");
|
||||||
|
}
|
||||||
|
|
||||||
|
os << '&' << nl;
|
||||||
|
os << "# end_data" << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
wroteGeom_ = true;
|
||||||
|
return outputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -1,117 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::xmgraceSetWriter
|
|
||||||
|
|
||||||
Description
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
xmgraceCoordSetWriter.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef Foam_coordSetWriters_xmgraceWriter_H
|
|
||||||
#define Foam_coordSetWriters_xmgraceWriter_H
|
|
||||||
|
|
||||||
#include "writer.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class xmgraceSetWriter Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
class xmgraceSetWriter
|
|
||||||
:
|
|
||||||
public writer<Type>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("xmgr");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Default construct
|
|
||||||
xmgraceSetWriter();
|
|
||||||
|
|
||||||
//- Construct with dictionary
|
|
||||||
explicit xmgraceSetWriter(const dictionary& dict);
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
virtual ~xmgraceSetWriter() = default;
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
virtual fileName getFileName
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const coordSet&,
|
|
||||||
const wordList&,
|
|
||||||
const List<const Field<Type>*>&,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
virtual void write
|
|
||||||
(
|
|
||||||
const bool writeTracks,
|
|
||||||
const List<scalarField>& times,
|
|
||||||
const PtrList<coordSet>& tracks,
|
|
||||||
const wordList& valueSetNames,
|
|
||||||
const List<List<Field<Type>>>& valueSets,
|
|
||||||
Ostream&
|
|
||||||
) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
#include "xmgraceCoordSetWriter.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ 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/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "xmgraceSetWriter.H"
|
|
||||||
#include "writers.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
makeSetWriters(xmgraceSetWriter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2020 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -32,7 +32,7 @@ License
|
|||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "DynamicField.H"
|
#include "DynamicField.H"
|
||||||
#include "PatchTools.H"
|
#include "PatchTools.H"
|
||||||
#include "writer.H"
|
#include "coordSetWriter.H"
|
||||||
#include "triSurfaceMesh.H"
|
#include "triSurfaceMesh.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
@ -611,7 +611,7 @@ bool Foam::searchableSurfaces::checkSizes
|
|||||||
bool Foam::searchableSurfaces::checkIntersection
|
bool Foam::searchableSurfaces::checkIntersection
|
||||||
(
|
(
|
||||||
const scalar tolerance,
|
const scalar tolerance,
|
||||||
const autoPtr<writer<scalar>>& setWriter,
|
autoPtr<coordSetWriter>& setWriter,
|
||||||
const bool report
|
const bool report
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
@ -669,7 +669,7 @@ bool Foam::searchableSurfaces::checkIntersection
|
|||||||
|
|
||||||
label nHits = 0;
|
label nHits = 0;
|
||||||
DynamicField<point> intersections(edges0.size()/100);
|
DynamicField<point> intersections(edges0.size()/100);
|
||||||
DynamicField<scalar> intersectionEdge(intersections.capacity());
|
DynamicField<label> intersectionEdge(intersections.capacity());
|
||||||
|
|
||||||
forAll(hits, edgeI)
|
forAll(hits, edgeI)
|
||||||
{
|
{
|
||||||
@ -680,7 +680,7 @@ bool Foam::searchableSurfaces::checkIntersection
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
intersections.append(hits[edgeI].hitPoint());
|
intersections.append(hits[edgeI].hitPoint());
|
||||||
intersectionEdge.append(1.0*edgeI);
|
intersectionEdge.append(edgeI);
|
||||||
nHits++;
|
nHits++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -698,7 +698,7 @@ bool Foam::searchableSurfaces::checkIntersection
|
|||||||
<< " locations."
|
<< " locations."
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
if (setWriter)
|
if (setWriter && setWriter->enabled())
|
||||||
{
|
{
|
||||||
scalarField dist(mag(intersections));
|
scalarField dist(mag(intersections));
|
||||||
coordSet track
|
coordSet track
|
||||||
@ -708,31 +708,27 @@ bool Foam::searchableSurfaces::checkIntersection
|
|||||||
std::move(intersections),
|
std::move(intersections),
|
||||||
std::move(dist)
|
std::move(dist)
|
||||||
);
|
);
|
||||||
wordList valueSetNames(1, "edgeIndex");
|
|
||||||
List<const scalarField*> valueSets
|
|
||||||
(
|
|
||||||
1,
|
|
||||||
&intersectionEdge
|
|
||||||
);
|
|
||||||
|
|
||||||
fileName fName
|
|
||||||
(
|
auto& writer = *setWriter;
|
||||||
setWriter().getFileName(track, valueSetNames)
|
writer.nFields(1);
|
||||||
);
|
|
||||||
Info<< " Writing intersection locations to "
|
writer.open
|
||||||
<< fName << endl;
|
|
||||||
OFstream os
|
|
||||||
(
|
|
||||||
s0.searchableSurface::time().path()
|
|
||||||
/fName
|
|
||||||
);
|
|
||||||
setWriter().write
|
|
||||||
(
|
(
|
||||||
track,
|
track,
|
||||||
valueSetNames,
|
(
|
||||||
valueSets,
|
s0.searchableSurface::time().path()
|
||||||
os
|
/ (track.name() + "_edgeIndex")
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
fileName fName =
|
||||||
|
writer.write("edgeIndex", intersectionEdge);
|
||||||
|
|
||||||
|
writer.close(true);
|
||||||
|
|
||||||
|
Info<< " Wrote intersection locations to "
|
||||||
|
<< fName << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -841,7 +837,7 @@ Foam::label Foam::searchableSurfaces::checkGeometry
|
|||||||
(
|
(
|
||||||
const scalar maxRatio,
|
const scalar maxRatio,
|
||||||
const scalar tol,
|
const scalar tol,
|
||||||
const autoPtr<writer<scalar>>& setWriter,
|
autoPtr<coordSetWriter>& setWriter,
|
||||||
const scalar minQuality,
|
const scalar minQuality,
|
||||||
const bool report
|
const bool report
|
||||||
) const
|
) const
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -68,7 +69,7 @@ namespace Foam
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
template<class T> class writer;
|
class coordSetWriter;
|
||||||
class triSurface;
|
class triSurface;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
@ -254,7 +255,7 @@ public:
|
|||||||
bool checkIntersection
|
bool checkIntersection
|
||||||
(
|
(
|
||||||
const scalar tol,
|
const scalar tol,
|
||||||
const autoPtr<writer<scalar>>&,
|
autoPtr<coordSetWriter>& setWriter,
|
||||||
const bool report
|
const bool report
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
@ -273,7 +274,7 @@ public:
|
|||||||
(
|
(
|
||||||
const scalar maxRatio,
|
const scalar maxRatio,
|
||||||
const scalar tolerance,
|
const scalar tolerance,
|
||||||
const autoPtr<writer<scalar>>& setWriter,
|
autoPtr<coordSetWriter>& setWriter,
|
||||||
const scalar minQuality,
|
const scalar minQuality,
|
||||||
const bool report
|
const bool report
|
||||||
) const;
|
) const;
|
||||||
|
|||||||
@ -13,7 +13,6 @@ sampledSet/patchSeed/patchSeedSet.C
|
|||||||
sampledSet/patchEdge/patchEdgeSet.C
|
sampledSet/patchEdge/patchEdgeSet.C
|
||||||
sampledSet/sampledSet/sampledSet.C
|
sampledSet/sampledSet/sampledSet.C
|
||||||
sampledSet/sampledSets/sampledSets.C
|
sampledSet/sampledSets/sampledSets.C
|
||||||
sampledSet/sampledSets/sampledSetsGrouping.C
|
|
||||||
sampledSet/triSurfaceMeshPointSet/triSurfaceMeshPointSet.C
|
sampledSet/triSurfaceMeshPointSet/triSurfaceMeshPointSet.C
|
||||||
sampledSet/uniform/uniformSet.C
|
sampledSet/uniform/uniformSet.C
|
||||||
sampledSet/array/arraySet.C
|
sampledSet/array/arraySet.C
|
||||||
|
|||||||
@ -57,11 +57,11 @@ void Foam::midPointAndFaceSet::genSamples()
|
|||||||
while (size() > 0)
|
while (size() > 0)
|
||||||
{
|
{
|
||||||
// Add first face
|
// Add first face
|
||||||
mpfSamplePoints[mpfSamplei] = operator[](samplei);
|
mpfSamplePoints[mpfSamplei] = points()[samplei];
|
||||||
mpfSampleCells[mpfSamplei] = cells_[samplei];
|
mpfSampleCells[mpfSamplei] = cells_[samplei];
|
||||||
mpfSampleFaces[mpfSamplei] = faces_[samplei];
|
mpfSampleFaces[mpfSamplei] = faces_[samplei];
|
||||||
mpfSampleSegments[mpfSamplei] = segments_[samplei];
|
mpfSampleSegments[mpfSamplei] = segments_[samplei];
|
||||||
mpfSampleCurveDist[mpfSamplei] = curveDist_[samplei];
|
mpfSampleCurveDist[mpfSamplei] = distance_[samplei];
|
||||||
++mpfSamplei;
|
++mpfSamplei;
|
||||||
|
|
||||||
while
|
while
|
||||||
@ -70,7 +70,7 @@ void Foam::midPointAndFaceSet::genSamples()
|
|||||||
&& (segments_[samplei] == segments_[samplei+1])
|
&& (segments_[samplei] == segments_[samplei+1])
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
point midPoint(0.5*(operator[](samplei) + operator[](samplei+1)));
|
point midPoint(0.5*(points()[samplei] + points()[samplei+1]));
|
||||||
label cellm = pointInCell(midPoint, samplei);
|
label cellm = pointInCell(midPoint, samplei);
|
||||||
|
|
||||||
if (cellm != -1)
|
if (cellm != -1)
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2018-2021 OpenCFD Ltd.
|
Copyright (C) 2018-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -30,7 +30,6 @@ License
|
|||||||
#include "polyMesh.H"
|
#include "polyMesh.H"
|
||||||
#include "primitiveMesh.H"
|
#include "primitiveMesh.H"
|
||||||
#include "meshSearch.H"
|
#include "meshSearch.H"
|
||||||
#include "writer.H"
|
|
||||||
#include "particle.H"
|
#include "particle.H"
|
||||||
#include "globalIndex.H"
|
#include "globalIndex.H"
|
||||||
|
|
||||||
@ -52,16 +51,16 @@ void Foam::sampledSet::checkDimensions() const
|
|||||||
(cells_.size() != size())
|
(cells_.size() != size())
|
||||||
|| (faces_.size() != size())
|
|| (faces_.size() != size())
|
||||||
|| (segments_.size() != size())
|
|| (segments_.size() != size())
|
||||||
|| (curveDist_.size() != size())
|
|| (distance_.size() != size())
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "sizes not equal : "
|
<< "Sizes not equal : "
|
||||||
<< " points:" << size()
|
<< " points:" << size()
|
||||||
<< " cells:" << cells_.size()
|
<< " cells:" << cells_.size()
|
||||||
<< " faces:" << faces_.size()
|
<< " faces:" << faces_.size()
|
||||||
<< " segments:" << segments_.size()
|
<< " segments:" << segments_.size()
|
||||||
<< " curveDist:" << curveDist_.size()
|
<< " distance:" << distance_.size()
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,14 +74,12 @@ Foam::label Foam::sampledSet::getBoundaryCell(const label facei) const
|
|||||||
|
|
||||||
Foam::label Foam::sampledSet::getNeighbourCell(const label facei) const
|
Foam::label Foam::sampledSet::getNeighbourCell(const label facei) const
|
||||||
{
|
{
|
||||||
if (facei >= mesh().nInternalFaces())
|
if (facei < mesh().nInternalFaces())
|
||||||
{
|
|
||||||
return mesh().faceOwner()[facei];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
return mesh().faceNeighbour()[facei];
|
return mesh().faceNeighbour()[facei];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return mesh().faceOwner()[facei];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -384,11 +381,11 @@ void Foam::sampledSet::setSamples
|
|||||||
const labelList& samplingCells,
|
const labelList& samplingCells,
|
||||||
const labelList& samplingFaces,
|
const labelList& samplingFaces,
|
||||||
const labelList& samplingSegments,
|
const labelList& samplingSegments,
|
||||||
const scalarList& samplingCurveDist
|
const scalarList& samplingDistance
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
setPoints(samplingPts);
|
setPoints(samplingPts);
|
||||||
curveDist_ = samplingCurveDist;
|
setDistance(samplingDistance, false); // check=false
|
||||||
|
|
||||||
segments_ = samplingSegments;
|
segments_ = samplingSegments;
|
||||||
cells_ = samplingCells;
|
cells_ = samplingCells;
|
||||||
@ -404,11 +401,11 @@ void Foam::sampledSet::setSamples
|
|||||||
labelList&& samplingCells,
|
labelList&& samplingCells,
|
||||||
labelList&& samplingFaces,
|
labelList&& samplingFaces,
|
||||||
labelList&& samplingSegments,
|
labelList&& samplingSegments,
|
||||||
scalarList&& samplingCurveDist
|
scalarList&& samplingDistance
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
setPoints(std::move(samplingPts));
|
setPoints(std::move(samplingPts));
|
||||||
curveDist_ = std::move(samplingCurveDist);
|
setDistance(std::move(samplingDistance), false); // check=false
|
||||||
|
|
||||||
segments_ = std::move(samplingSegments);
|
segments_ = std::move(samplingSegments);
|
||||||
cells_ = std::move(samplingCells);
|
cells_ = std::move(samplingCells);
|
||||||
@ -418,48 +415,6 @@ void Foam::sampledSet::setSamples
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::autoPtr<Foam::coordSet> Foam::sampledSet::gather
|
|
||||||
(
|
|
||||||
labelList& indexSet,
|
|
||||||
labelList& allSegments
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Combine sampleSet from processors. Sort by curveDist. Return
|
|
||||||
// ordering in indexSet.
|
|
||||||
// Note: only master results are valid
|
|
||||||
|
|
||||||
List<point> allPts;
|
|
||||||
globalIndex::gatherOp(*this, allPts);
|
|
||||||
|
|
||||||
globalIndex::gatherOp(segments(), allSegments);
|
|
||||||
|
|
||||||
scalarList allCurveDist;
|
|
||||||
globalIndex::gatherOp(curveDist(), allCurveDist);
|
|
||||||
|
|
||||||
|
|
||||||
if (Pstream::master() && allCurveDist.empty())
|
|
||||||
{
|
|
||||||
WarningInFunction
|
|
||||||
<< "Sample set " << name()
|
|
||||||
<< " has zero points." << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort curveDist and use to fill masterSamplePts
|
|
||||||
Foam::sortedOrder(allCurveDist, indexSet); // uses stable sort
|
|
||||||
scalarList sortedDist(allCurveDist, indexSet); // with indices for mapping
|
|
||||||
|
|
||||||
allSegments = UIndirectList<label>(allSegments, indexSet)();
|
|
||||||
|
|
||||||
return autoPtr<coordSet>::New
|
|
||||||
(
|
|
||||||
name(),
|
|
||||||
axis(),
|
|
||||||
List<point>(UIndirectList<point>(allPts, indexSet)),
|
|
||||||
sortedDist
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::sampledSet::sampledSet
|
Foam::sampledSet::sampledSet
|
||||||
@ -513,6 +468,25 @@ Foam::sampledSet::sampledSet
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// Foam::autoPtr<Foam::coordSet> Foam::sampledSet::gather
|
||||||
|
// (
|
||||||
|
// labelList& sortOrder,
|
||||||
|
// labelList& allSegments
|
||||||
|
// ) const
|
||||||
|
// {
|
||||||
|
// autoPtr<coordSet> result(coordSet::gatherSort(sortOrder));
|
||||||
|
//
|
||||||
|
// // Optional
|
||||||
|
// if (notNull(allSegments))
|
||||||
|
// {
|
||||||
|
// globalIndex::gatherOp(segments(), allSegments);
|
||||||
|
// allSegments = UIndirectList<label>(allSegments, sortOrder)();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::autoPtr<Foam::sampledSet> Foam::sampledSet::New
|
Foam::autoPtr<Foam::sampledSet> Foam::sampledSet::New
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2018 OpenCFD Ltd.
|
Copyright (C) 2017-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -50,20 +50,20 @@ SourceFiles
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef sampledSet_H
|
#ifndef Foam_sampledSet_H
|
||||||
#define sampledSet_H
|
#define Foam_sampledSet_H
|
||||||
|
|
||||||
#include "coordSet.H"
|
#include "coordSet.H"
|
||||||
|
#include "autoPtr.H"
|
||||||
#include "typeInfo.H"
|
#include "typeInfo.H"
|
||||||
#include "runTimeSelectionTables.H"
|
#include "runTimeSelectionTables.H"
|
||||||
#include "autoPtr.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
// Forward declarations
|
// Forward Declarations
|
||||||
class polyMesh;
|
class polyMesh;
|
||||||
class meshSearch;
|
class meshSearch;
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ class sampledSet
|
|||||||
:
|
:
|
||||||
public coordSet
|
public coordSet
|
||||||
{
|
{
|
||||||
// Private data
|
// Private Data
|
||||||
|
|
||||||
//- Reference to mesh
|
//- Reference to mesh
|
||||||
const polyMesh& mesh_;
|
const polyMesh& mesh_;
|
||||||
@ -86,6 +86,8 @@ class sampledSet
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
// Protected Data
|
||||||
|
|
||||||
//- Segment numbers
|
//- Segment numbers
|
||||||
labelList segments_;
|
labelList segments_;
|
||||||
|
|
||||||
@ -154,7 +156,7 @@ protected:
|
|||||||
const labelList& samplingCells,
|
const labelList& samplingCells,
|
||||||
const labelList& samplingFaces,
|
const labelList& samplingFaces,
|
||||||
const labelList& samplingSegments,
|
const labelList& samplingSegments,
|
||||||
const scalarList& samplingCurveDist
|
const scalarList& samplingDistance
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Set sample data. Move list contents.
|
//- Set sample data. Move list contents.
|
||||||
@ -164,7 +166,7 @@ protected:
|
|||||||
labelList&& samplingCells,
|
labelList&& samplingCells,
|
||||||
labelList&& samplingFaces,
|
labelList&& samplingFaces,
|
||||||
labelList&& samplingSegments,
|
labelList&& samplingSegments,
|
||||||
scalarList&& samplingCurveDist
|
scalarList&& samplingDistance
|
||||||
);
|
);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -194,22 +196,58 @@ public:
|
|||||||
// PtrLists of sampledSet
|
// PtrLists of sampledSet
|
||||||
class iNew
|
class iNew
|
||||||
{
|
{
|
||||||
|
//- Reference to the volume mesh
|
||||||
const polyMesh& mesh_;
|
const polyMesh& mesh_;
|
||||||
const meshSearch& searchEngine_;
|
const meshSearch& search_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
iNew(const polyMesh& mesh, const meshSearch& searchEngine)
|
iNew(const polyMesh& mesh, const meshSearch& searchEngine)
|
||||||
:
|
:
|
||||||
mesh_(mesh),
|
mesh_(mesh),
|
||||||
searchEngine_(searchEngine)
|
search_(searchEngine)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
autoPtr<sampledSet> operator()(Istream& is) const
|
autoPtr<sampledSet> operator()(Istream& is) const
|
||||||
{
|
{
|
||||||
word name(is);
|
word name(is);
|
||||||
dictionary dict(is);
|
dictionary dict(is);
|
||||||
return sampledSet::New(name, mesh_, searchEngine_, dict);
|
return sampledSet::New(name, mesh_, search_, dict);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//- PtrList read-construction helper that captures dictionaries used
|
||||||
|
//- during creation.
|
||||||
|
class iNewCapture
|
||||||
|
{
|
||||||
|
//- Reference to the volume mesh
|
||||||
|
const polyMesh& mesh_;
|
||||||
|
const meshSearch& search_;
|
||||||
|
|
||||||
|
//- Captured (recorded) dictionaries
|
||||||
|
DynamicList<dictionary>& capture_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
iNewCapture
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const meshSearch& searchEngine,
|
||||||
|
DynamicList<dictionary>& capture
|
||||||
|
)
|
||||||
|
:
|
||||||
|
mesh_(mesh),
|
||||||
|
search_(searchEngine),
|
||||||
|
capture_(capture)
|
||||||
|
{}
|
||||||
|
|
||||||
|
autoPtr<sampledSet> operator()(Istream& is) const
|
||||||
|
{
|
||||||
|
word name(is);
|
||||||
|
capture_.append(dictionary(is));
|
||||||
|
|
||||||
|
return sampledSet::New(name, mesh_, search_, capture_.last());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -269,27 +307,27 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
const polyMesh& mesh() const
|
const polyMesh& mesh() const noexcept
|
||||||
{
|
{
|
||||||
return mesh_;
|
return mesh_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const meshSearch& searchEngine() const
|
const meshSearch& searchEngine() const noexcept
|
||||||
{
|
{
|
||||||
return searchEngine_;
|
return searchEngine_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const labelList& segments() const
|
const labelList& segments() const noexcept
|
||||||
{
|
{
|
||||||
return segments_;
|
return segments_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const labelList& cells() const
|
const labelList& cells() const noexcept
|
||||||
{
|
{
|
||||||
return cells_;
|
return cells_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const labelList& faces() const
|
const labelList& faces() const noexcept
|
||||||
{
|
{
|
||||||
return faces_;
|
return faces_;
|
||||||
}
|
}
|
||||||
@ -297,13 +335,16 @@ public:
|
|||||||
//- Output for debugging
|
//- Output for debugging
|
||||||
Ostream& write(Ostream&) const;
|
Ostream& write(Ostream&) const;
|
||||||
|
|
||||||
//- Helper: gather onto master and sort.
|
|
||||||
// \return (on master) gathered set and overall sort order
|
// Other
|
||||||
autoPtr<coordSet> gather
|
|
||||||
(
|
/// //- Gather and sort.
|
||||||
labelList& indexSet,
|
/// \return (on master) gathered set and overall sort order
|
||||||
labelList& allSegments
|
/// autoPtr<coordSet> gather
|
||||||
) const;
|
/// (
|
||||||
|
/// labelList& sortOrder,
|
||||||
|
/// labelList& allSegments
|
||||||
|
/// ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2020 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -29,9 +29,12 @@ License
|
|||||||
#include "sampledSets.H"
|
#include "sampledSets.H"
|
||||||
#include "dictionary.H"
|
#include "dictionary.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
|
#include "globalIndex.H"
|
||||||
#include "volFields.H"
|
#include "volFields.H"
|
||||||
#include "volPointInterpolation.H"
|
|
||||||
#include "mapPolyMesh.H"
|
#include "mapPolyMesh.H"
|
||||||
|
#include "IOobjectList.H"
|
||||||
|
#include "UIndirectList.H"
|
||||||
|
#include "ListOps.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
@ -48,36 +51,287 @@ namespace Foam
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Foam::sampledSets::verbose_ = false;
|
#include "sampledSetsImpl.C"
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::sampledSets::combineSampledSets
|
Foam::autoPtr<Foam::coordSetWriter> Foam::sampledSets::newWriter
|
||||||
(
|
(
|
||||||
PtrList<coordSet>& masterSampledSets,
|
word writeType,
|
||||||
labelListList& indexSets
|
const dictionary& formatOptions,
|
||||||
|
const dictionary& setDict
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Combine sampleSets from processors. Sort by curveDist. Return
|
// Per-set adjustment
|
||||||
// ordering in indexSets.
|
setDict.readIfPresent<word>("setFormat", writeType);
|
||||||
// Note: only master results are valid
|
|
||||||
|
|
||||||
masterSampledSets_.clear();
|
dictionary options = formatOptions.subOrEmptyDict(writeType);
|
||||||
masterSampledSets_.setSize(size());
|
|
||||||
indexSets_.setSize(size());
|
|
||||||
|
|
||||||
const PtrList<sampledSet>& sampledSets = *this;
|
options.merge
|
||||||
|
(
|
||||||
|
setDict.subOrEmptyDict("formatOptions").subOrEmptyDict(writeType)
|
||||||
|
);
|
||||||
|
|
||||||
forAll(sampledSets, setI)
|
return coordSetWriter::New(writeType, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::sampledSets::gatherAllSets()
|
||||||
|
{
|
||||||
|
// Any writer references will become invalid
|
||||||
|
for (auto& writer : writers_)
|
||||||
{
|
{
|
||||||
labelList segments;
|
writer.expire();
|
||||||
masterSampledSets.set
|
|
||||||
(
|
|
||||||
setI,
|
|
||||||
sampledSets[setI].gather(indexSets[setI], segments)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PtrList<sampledSet>& localSets = *this;
|
||||||
|
|
||||||
|
gatheredSets_.clear();
|
||||||
|
gatheredSets_.resize(localSets.size());
|
||||||
|
gatheredSorting_.resize_nocopy(localSets.size());
|
||||||
|
globalIndices_.resize_nocopy(localSets.size());
|
||||||
|
|
||||||
|
forAll(localSets, seti)
|
||||||
|
{
|
||||||
|
const coordSet& coords = localSets[seti];
|
||||||
|
|
||||||
|
globalIndices_[seti].reset(coords.size(), globalIndex::gatherOnly{});
|
||||||
|
gatheredSets_.set(seti, coords.gatherSort(gatheredSorting_[seti]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::IOobjectList Foam::sampledSets::preCheckFields()
|
||||||
|
{
|
||||||
|
wordList allFields; // Just needed for warnings
|
||||||
|
HashTable<wordHashSet> selected;
|
||||||
|
|
||||||
|
IOobjectList objects(0);
|
||||||
|
|
||||||
|
if (loadFromFiles_)
|
||||||
|
{
|
||||||
|
// Check files for a particular time
|
||||||
|
objects = IOobjectList(mesh_, mesh_.time().timeName());
|
||||||
|
|
||||||
|
allFields = objects.names();
|
||||||
|
selected = objects.classes(fieldSelection_);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Check currently available fields
|
||||||
|
allFields = mesh_.names();
|
||||||
|
selected = mesh_.classes(fieldSelection_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Probably not needed...
|
||||||
|
// if (Pstream::parRun())
|
||||||
|
// {
|
||||||
|
// Pstream::mapCombineGather(selected, HashSetOps::plusEqOp<word>());
|
||||||
|
// Pstream::mapCombineScatter(selected);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
DynamicList<label> missed(fieldSelection_.size());
|
||||||
|
|
||||||
|
// Detect missing fields
|
||||||
|
forAll(fieldSelection_, i)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
fieldSelection_[i].isLiteral()
|
||||||
|
&& !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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The selected field names, ordered by (scalar, vector, ...)
|
||||||
|
// with internal sorting
|
||||||
|
|
||||||
|
selectedFieldNames_.clear();
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(InputType) \
|
||||||
|
{ \
|
||||||
|
const auto iter = selected.find(InputType::typeName); \
|
||||||
|
if (iter.found()) \
|
||||||
|
{ \
|
||||||
|
selectedFieldNames_.append(iter.val().sortedToc()); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
doLocalCode(volScalarField);
|
||||||
|
doLocalCode(volVectorField);
|
||||||
|
doLocalCode(volSphericalTensorField);
|
||||||
|
doLocalCode(volSymmTensorField);
|
||||||
|
doLocalCode(volTensorField);
|
||||||
|
#undef doLocalCode
|
||||||
|
}
|
||||||
|
while (false);
|
||||||
|
|
||||||
|
|
||||||
|
// Now propagate field counts (per surface)
|
||||||
|
// - can update writer even when not writing without problem
|
||||||
|
|
||||||
|
const label nFields = selectedFieldNames_.size();
|
||||||
|
|
||||||
|
forAll(writers_, seti)
|
||||||
|
{
|
||||||
|
coordSetWriter& writer = writers_[seti];
|
||||||
|
|
||||||
|
writer.nFields(nFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::sampledSets::initDict(const dictionary& dict, const bool initial)
|
||||||
|
{
|
||||||
|
PtrList<sampledSet>::clear();
|
||||||
|
if (initial)
|
||||||
|
{
|
||||||
|
writers_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const entry* eptr = dict.findEntry("sets");
|
||||||
|
|
||||||
|
if (eptr && eptr->isDict())
|
||||||
|
{
|
||||||
|
PtrList<sampledSet> sampSets(eptr->dict().size());
|
||||||
|
if (initial)
|
||||||
|
{
|
||||||
|
writers_.resize(sampSets.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
label seti = 0;
|
||||||
|
|
||||||
|
for (const entry& dEntry : eptr->dict())
|
||||||
|
{
|
||||||
|
if (!dEntry.isDict())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dictionary& subDict = dEntry.dict();
|
||||||
|
|
||||||
|
autoPtr<sampledSet> sampSet =
|
||||||
|
sampledSet::New
|
||||||
|
(
|
||||||
|
dEntry.keyword(),
|
||||||
|
mesh_,
|
||||||
|
searchEngine_,
|
||||||
|
subDict
|
||||||
|
);
|
||||||
|
|
||||||
|
// if (!sampSet || !sampSet->enabled())
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Define the set
|
||||||
|
sampSets.set(seti, sampSet);
|
||||||
|
|
||||||
|
// Define writer, but do not attached
|
||||||
|
if (initial)
|
||||||
|
{
|
||||||
|
writers_.set
|
||||||
|
(
|
||||||
|
seti,
|
||||||
|
newWriter(writeFormat_, writeFormatOptions_, subDict)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Use outputDir/TIME/set-name
|
||||||
|
writers_[seti].useTimeDir(true);
|
||||||
|
writers_[seti].verbose(verbose_);
|
||||||
|
}
|
||||||
|
++seti;
|
||||||
|
}
|
||||||
|
|
||||||
|
sampSets.resize(seti);
|
||||||
|
if (initial)
|
||||||
|
{
|
||||||
|
writers_.resize(seti);
|
||||||
|
}
|
||||||
|
static_cast<PtrList<sampledSet>&>(*this).transfer(sampSets);
|
||||||
|
}
|
||||||
|
else if (eptr)
|
||||||
|
{
|
||||||
|
// This is slightly trickier.
|
||||||
|
// We want access to the individual dictionaries used for construction
|
||||||
|
|
||||||
|
DynamicList<dictionary> capture;
|
||||||
|
|
||||||
|
PtrList<sampledSet> input
|
||||||
|
(
|
||||||
|
eptr->stream(),
|
||||||
|
sampledSet::iNewCapture(mesh_, searchEngine_, capture)
|
||||||
|
);
|
||||||
|
|
||||||
|
PtrList<sampledSet> sampSets(input.size());
|
||||||
|
if (initial)
|
||||||
|
{
|
||||||
|
writers_.resize(sampSets.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
label seti = 0;
|
||||||
|
|
||||||
|
forAll(input, inputi)
|
||||||
|
{
|
||||||
|
const dictionary& subDict = capture[inputi];
|
||||||
|
|
||||||
|
autoPtr<sampledSet> sampSet = input.release(inputi);
|
||||||
|
|
||||||
|
// if (!sampSet || !sampSet->enabled())
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Define the set
|
||||||
|
sampSets.set(seti, sampSet);
|
||||||
|
|
||||||
|
// Define writer, but do not attached
|
||||||
|
if (initial)
|
||||||
|
{
|
||||||
|
writers_.set
|
||||||
|
(
|
||||||
|
seti,
|
||||||
|
newWriter(writeFormat_, writeFormatOptions_, subDict)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Use outputDir/TIME/set-name
|
||||||
|
writers_[seti].useTimeDir(true);
|
||||||
|
writers_[seti].verbose(verbose_);
|
||||||
|
}
|
||||||
|
++seti;
|
||||||
|
}
|
||||||
|
|
||||||
|
sampSets.resize(seti);
|
||||||
|
if (initial)
|
||||||
|
{
|
||||||
|
writers_.resize(seti);
|
||||||
|
}
|
||||||
|
|
||||||
|
static_cast<PtrList<sampledSet>&>(*this).transfer(sampSets);
|
||||||
|
}
|
||||||
|
|
||||||
|
gatherAllSets();
|
||||||
|
|
||||||
|
needsCorrect_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -90,21 +344,27 @@ Foam::sampledSets::sampledSets
|
|||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
functionObjects::regionFunctionObject(name, runTime, dict),
|
functionObjects::fvMeshFunctionObject(name, runTime, dict),
|
||||||
PtrList<sampledSet>(),
|
PtrList<sampledSet>(),
|
||||||
mesh_(refCast<const fvMesh>(obr_)),
|
dict_(dict),
|
||||||
loadFromFiles_(false),
|
loadFromFiles_(false),
|
||||||
outputPath_(fileName::null),
|
verbose_(false),
|
||||||
searchEngine_(mesh_),
|
onExecute_(false),
|
||||||
interpolationScheme_(word::null),
|
needsCorrect_(false),
|
||||||
writeFormat_(word::null),
|
outputPath_
|
||||||
writeFormatOptions_(dict.subOrEmptyDict("formatOptions"))
|
|
||||||
{
|
|
||||||
outputPath_ =
|
|
||||||
(
|
(
|
||||||
mesh_.time().globalPath()/functionObject::outputPrefix/name
|
time_.globalPath()/functionObject::outputPrefix/name
|
||||||
);
|
),
|
||||||
|
searchEngine_(mesh_),
|
||||||
|
samplePointScheme_(),
|
||||||
|
writeFormat_(),
|
||||||
|
writeFormatOptions_(dict.subOrEmptyDict("formatOptions")),
|
||||||
|
writers_(),
|
||||||
|
selectedFieldNames_(),
|
||||||
|
gatheredSets_(),
|
||||||
|
gatheredSorting_(),
|
||||||
|
globalIndices_()
|
||||||
|
{
|
||||||
if (mesh_.name() != polyMesh::defaultRegion)
|
if (mesh_.name() != polyMesh::defaultRegion)
|
||||||
{
|
{
|
||||||
outputPath_ /= mesh_.name();
|
outputPath_ /= mesh_.name();
|
||||||
@ -124,26 +384,31 @@ Foam::sampledSets::sampledSets
|
|||||||
const bool loadFromFiles
|
const bool loadFromFiles
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
functionObjects::regionFunctionObject(name, obr, dict),
|
functionObjects::fvMeshFunctionObject(name, obr, dict),
|
||||||
PtrList<sampledSet>(),
|
PtrList<sampledSet>(),
|
||||||
mesh_(refCast<const fvMesh>(obr)),
|
dict_(dict),
|
||||||
loadFromFiles_(loadFromFiles),
|
loadFromFiles_(loadFromFiles),
|
||||||
outputPath_(fileName::null),
|
verbose_(false),
|
||||||
searchEngine_(mesh_),
|
onExecute_(false),
|
||||||
interpolationScheme_(word::null),
|
needsCorrect_(false),
|
||||||
writeFormat_(word::null),
|
outputPath_
|
||||||
writeFormatOptions_(dict.subOrEmptyDict("formatOptions"))
|
|
||||||
{
|
|
||||||
outputPath_ =
|
|
||||||
(
|
(
|
||||||
mesh_.time().globalPath()/functionObject::outputPrefix/name
|
time_.globalPath()/functionObject::outputPrefix/name
|
||||||
);
|
),
|
||||||
|
searchEngine_(mesh_),
|
||||||
|
samplePointScheme_(),
|
||||||
|
writeFormat_(),
|
||||||
|
writeFormatOptions_(dict.subOrEmptyDict("formatOptions")),
|
||||||
|
writers_(),
|
||||||
|
selectedFieldNames_(),
|
||||||
|
gatheredSets_(),
|
||||||
|
gatheredSorting_(),
|
||||||
|
globalIndices_()
|
||||||
|
{
|
||||||
if (mesh_.name() != polyMesh::defaultRegion)
|
if (mesh_.name() != polyMesh::defaultRegion)
|
||||||
{
|
{
|
||||||
outputPath_ /= mesh_.name();
|
outputPath_ /= mesh_.name();
|
||||||
}
|
}
|
||||||
|
|
||||||
outputPath_.clean(); // Remove unneeded ".."
|
outputPath_.clean(); // Remove unneeded ".."
|
||||||
|
|
||||||
read(dict);
|
read(dict);
|
||||||
@ -152,7 +417,7 @@ Foam::sampledSets::sampledSets
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
bool Foam::sampledSets::verbose(const bool on)
|
bool Foam::sampledSets::verbose(const bool on) noexcept
|
||||||
{
|
{
|
||||||
bool old(verbose_);
|
bool old(verbose_);
|
||||||
verbose_ = on;
|
verbose_ = on;
|
||||||
@ -160,122 +425,205 @@ bool Foam::sampledSets::verbose(const bool on)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::sampledSets::read(const dictionary& dict)
|
||||||
|
{
|
||||||
|
if (&dict_ != &dict)
|
||||||
|
{
|
||||||
|
// Update local copy of dictionary
|
||||||
|
dict_ = dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
fvMeshFunctionObject::read(dict);
|
||||||
|
|
||||||
|
PtrList<sampledSet>::clear();
|
||||||
|
writers_.clear();
|
||||||
|
fieldSelection_.clear();
|
||||||
|
selectedFieldNames_.clear();
|
||||||
|
|
||||||
|
gatheredSets_.clear();
|
||||||
|
gatheredSorting_.clear();
|
||||||
|
globalIndices_.clear();
|
||||||
|
|
||||||
|
verbose_ = dict.getOrDefault("verbose", false);
|
||||||
|
onExecute_ = dict.getOrDefault("sampleOnExecute", false);
|
||||||
|
|
||||||
|
samplePointScheme_ =
|
||||||
|
dict.getOrDefault<word>("interpolationScheme", "cellPoint");
|
||||||
|
|
||||||
|
const entry* eptr = dict.findEntry("sets");
|
||||||
|
|
||||||
|
if (eptr)
|
||||||
|
{
|
||||||
|
dict.readEntry("setFormat", writeFormat_);
|
||||||
|
}
|
||||||
|
// const dictionary formatOptions(dict.subOrEmptyDict("formatOptions"));
|
||||||
|
// Writer type and format options
|
||||||
|
// const word writerType =
|
||||||
|
// (eptr ? dict.get<word>("setFormat") : word::null);
|
||||||
|
// writerType_ = (eptr ? dict.get<word>("setFormat") : word::null);
|
||||||
|
|
||||||
|
initDict(dict, true);
|
||||||
|
|
||||||
|
// Have some sets, so sort out which fields are needed and report
|
||||||
|
|
||||||
|
if (this->size())
|
||||||
|
{
|
||||||
|
dict_.readEntry("fields", fieldSelection_);
|
||||||
|
fieldSelection_.uniq();
|
||||||
|
|
||||||
|
// Report
|
||||||
|
forAll(*this, seti)
|
||||||
|
{
|
||||||
|
const sampledSet& s = (*this)[seti];
|
||||||
|
|
||||||
|
if (!seti)
|
||||||
|
{
|
||||||
|
Info<< "Sampled set:" << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< " " << s.name() << " -> " << writers_[seti].type()
|
||||||
|
<< nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug && Pstream::master())
|
||||||
|
{
|
||||||
|
Pout<< "sample fields:" << flatOutput(fieldSelection_) << nl
|
||||||
|
<< "sample sets:" << nl << '(' << nl;
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
const sampledSet& s
|
||||||
|
: static_cast<const PtrList<sampledSet>&>(*this)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Pout<< " " << s << endl;
|
||||||
|
}
|
||||||
|
Pout<< ')' << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUTURE:
|
||||||
|
// Ensure all sets and merge information are expired
|
||||||
|
// expire(true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::sampledSets::performAction(unsigned request)
|
||||||
|
{
|
||||||
|
if (empty())
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (needsCorrect_)
|
||||||
|
{
|
||||||
|
searchEngine_.correct();
|
||||||
|
initDict(dict_, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUTURE:
|
||||||
|
// Update sets and store
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// Determine availability of fields.
|
||||||
|
// Count number of fields (only seems to be needed for VTK legacy)
|
||||||
|
|
||||||
|
IOobjectList objects = preCheckFields();
|
||||||
|
|
||||||
|
const label nFields = selectedFieldNames_.size();
|
||||||
|
|
||||||
|
if (!nFields)
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update writers
|
||||||
|
|
||||||
|
forAll(*this, seti)
|
||||||
|
{
|
||||||
|
const coordSet& s = gatheredSets_[seti];
|
||||||
|
|
||||||
|
if (request & ACTION_WRITE)
|
||||||
|
{
|
||||||
|
coordSetWriter& writer = writers_[seti];
|
||||||
|
|
||||||
|
if (writer.needsUpdate())
|
||||||
|
{
|
||||||
|
writer.setCoordinates(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (writer.buffering())
|
||||||
|
{
|
||||||
|
writer.open
|
||||||
|
(
|
||||||
|
outputPath_
|
||||||
|
/ word(s.name() + coordSetWriter::suffix(selectedFieldNames_))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.open(outputPath_/s.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.beginTime(mesh_.time());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sample fields
|
||||||
|
|
||||||
|
performAction<VolumeField<scalar>>(objects, request);
|
||||||
|
performAction<VolumeField<vector>>(objects, request);
|
||||||
|
performAction<VolumeField<sphericalTensor>>(objects, request);
|
||||||
|
performAction<VolumeField<symmTensor>>(objects, request);
|
||||||
|
performAction<VolumeField<tensor>>(objects, request);
|
||||||
|
|
||||||
|
|
||||||
|
// Finish this time step
|
||||||
|
forAll(writers_, seti)
|
||||||
|
{
|
||||||
|
// Write geometry if no fields were written so that we still
|
||||||
|
// can have something to look at
|
||||||
|
|
||||||
|
if (request & ACTION_WRITE)
|
||||||
|
{
|
||||||
|
/// if (!writers_[seti].wroteData())
|
||||||
|
/// {
|
||||||
|
/// writers_[seti].write();
|
||||||
|
/// }
|
||||||
|
|
||||||
|
writers_[seti].endTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::sampledSets::execute()
|
bool Foam::sampledSets::execute()
|
||||||
{
|
{
|
||||||
|
if (onExecute_)
|
||||||
|
{
|
||||||
|
return performAction(ACTION_ALL & ~ACTION_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::sampledSets::write()
|
bool Foam::sampledSets::write()
|
||||||
{
|
{
|
||||||
if (size())
|
return performAction(ACTION_ALL);
|
||||||
{
|
|
||||||
const label nFields = classifyFields();
|
|
||||||
|
|
||||||
if (Pstream::master())
|
|
||||||
{
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "timeName = " << mesh_.time().timeName() << nl
|
|
||||||
<< "scalarFields " << scalarFields_ << nl
|
|
||||||
<< "vectorFields " << vectorFields_ << nl
|
|
||||||
<< "sphTensorFields " << sphericalTensorFields_ << nl
|
|
||||||
<< "symTensorFields " << symmTensorFields_ <<nl
|
|
||||||
<< "tensorFields " << tensorFields_ <<nl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nFields)
|
|
||||||
{
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "Creating directory "
|
|
||||||
<< outputPath_/mesh_.time().timeName()
|
|
||||||
<< nl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
mkDir(outputPath_/mesh_.time().timeName());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Info<< "No fields to sample" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nFields)
|
|
||||||
{
|
|
||||||
sampleAndWrite(scalarFields_);
|
|
||||||
sampleAndWrite(vectorFields_);
|
|
||||||
sampleAndWrite(sphericalTensorFields_);
|
|
||||||
sampleAndWrite(symmTensorFields_);
|
|
||||||
sampleAndWrite(tensorFields_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::sampledSets::read(const dictionary& dict)
|
|
||||||
{
|
|
||||||
dict_ = dict;
|
|
||||||
|
|
||||||
if (dict_.found("sets"))
|
|
||||||
{
|
|
||||||
dict_.readEntry("fields", fieldSelection_);
|
|
||||||
clearFieldGroups();
|
|
||||||
|
|
||||||
dict.readEntry("interpolationScheme", interpolationScheme_);
|
|
||||||
dict.readEntry("setFormat", writeFormat_);
|
|
||||||
|
|
||||||
PtrList<sampledSet> newList
|
|
||||||
(
|
|
||||||
dict_.lookup("sets"),
|
|
||||||
sampledSet::iNew(mesh_, searchEngine_)
|
|
||||||
);
|
|
||||||
transfer(newList);
|
|
||||||
combineSampledSets(masterSampledSets_, indexSets_);
|
|
||||||
|
|
||||||
if (this->size())
|
|
||||||
{
|
|
||||||
Info<< "Reading set description:" << nl;
|
|
||||||
forAll(*this, setI)
|
|
||||||
{
|
|
||||||
Info<< " " << operator[](setI).name() << nl;
|
|
||||||
}
|
|
||||||
Info<< endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Pstream::master() && debug)
|
|
||||||
{
|
|
||||||
Pout<< "sample fields:" << fieldSelection_ << nl
|
|
||||||
<< "sample sets:" << nl << "(" << nl;
|
|
||||||
|
|
||||||
forAll(*this, setI)
|
|
||||||
{
|
|
||||||
Pout<< " " << operator[](setI) << endl;
|
|
||||||
}
|
|
||||||
Pout<< ")" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::sampledSets::correct()
|
void Foam::sampledSets::correct()
|
||||||
{
|
{
|
||||||
if (dict_.found("sets"))
|
needsCorrect_ = true;
|
||||||
{
|
|
||||||
searchEngine_.correct();
|
|
||||||
|
|
||||||
PtrList<sampledSet> newList
|
|
||||||
(
|
|
||||||
dict_.lookup("sets"),
|
|
||||||
sampledSet::iNew(mesh_, searchEngine_)
|
|
||||||
);
|
|
||||||
transfer(newList);
|
|
||||||
combineSampledSets(masterSampledSets_, indexSets_);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2018 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -29,24 +29,86 @@ Class
|
|||||||
|
|
||||||
Description
|
Description
|
||||||
Set of sets to sample.
|
Set of sets to sample.
|
||||||
Call sampledSets.write() to sample and write files.
|
|
||||||
|
The write() method is used to sample and write files.
|
||||||
|
|
||||||
|
Example of function object specification:
|
||||||
|
|
||||||
|
\verbatim
|
||||||
|
surfaces
|
||||||
|
{
|
||||||
|
type sets;
|
||||||
|
libs (sampling);
|
||||||
|
|
||||||
|
// Write at same frequency as fields
|
||||||
|
writeControl writeTime;
|
||||||
|
writeInterval 1;
|
||||||
|
|
||||||
|
// Fields to be sampled
|
||||||
|
fields (p U);
|
||||||
|
|
||||||
|
// Scheme to obtain values
|
||||||
|
interpolationScheme cellPoint;
|
||||||
|
|
||||||
|
// Output format
|
||||||
|
surfaceFormat vtk;
|
||||||
|
|
||||||
|
formatOptions
|
||||||
|
{
|
||||||
|
vtk
|
||||||
|
{
|
||||||
|
precision 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sets
|
||||||
|
{
|
||||||
|
Uref
|
||||||
|
{
|
||||||
|
type cloud;
|
||||||
|
axis xyz;
|
||||||
|
points ((-0.0508 0.0508 0.01));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
Entries:
|
||||||
|
\table
|
||||||
|
Property | Description | Required | Default
|
||||||
|
type | Type-name: sets | yes |
|
||||||
|
sets | Dictionary or list of sample sets | expected |
|
||||||
|
fields | word/regex list of fields to sample | yes |
|
||||||
|
interpolationScheme | scheme to obtain values | no | cellPoint
|
||||||
|
setFormat | output format | yes |
|
||||||
|
sampleOnExecute | Sample (store) on execution as well | no | false
|
||||||
|
formatOptions | dictionary of format options | no |
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
Additional per-set entries:
|
||||||
|
\table
|
||||||
|
Property | Description | Required | Default
|
||||||
|
store | Store surface/fields on registry | no |
|
||||||
|
setFormat | output format | no |
|
||||||
|
formatOptions | dictionary of format options | no |
|
||||||
|
\endtable
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
sampledSets.C
|
sampledSets.C
|
||||||
|
sampledSetsImpl.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef sampledSets_H
|
#ifndef Foam_sampledSets_H
|
||||||
#define sampledSets_H
|
#define Foam_sampledSets_H
|
||||||
|
|
||||||
#include "regionFunctionObject.H"
|
#include "fvMeshFunctionObject.H"
|
||||||
#include "sampledSet.H"
|
#include "sampledSet.H"
|
||||||
#include "volFieldsFwd.H"
|
|
||||||
#include "meshSearch.H"
|
#include "meshSearch.H"
|
||||||
#include "interpolation.H"
|
|
||||||
#include "coordSet.H"
|
#include "coordSet.H"
|
||||||
#include "writer.H"
|
#include "coordSetWriter.H"
|
||||||
#include "wordRes.H"
|
#include "volFieldsFwd.H"
|
||||||
|
#include "IOobjectList.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -55,9 +117,8 @@ namespace Foam
|
|||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
class Time;
|
class Time;
|
||||||
class objectRegistry;
|
|
||||||
class dictionary;
|
class dictionary;
|
||||||
class fvMesh;
|
class globalIndex;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class sampledSets Declaration
|
Class sampledSets Declaration
|
||||||
@ -65,97 +126,37 @@ class fvMesh;
|
|||||||
|
|
||||||
class sampledSets
|
class sampledSets
|
||||||
:
|
:
|
||||||
public functionObjects::regionFunctionObject,
|
public functionObjects::fvMeshFunctionObject,
|
||||||
public PtrList<sampledSet>
|
public PtrList<sampledSet>
|
||||||
{
|
{
|
||||||
// Private Classes
|
|
||||||
|
|
||||||
//- Class used for grouping field types
|
|
||||||
template<class Type>
|
|
||||||
class fieldGroup
|
|
||||||
:
|
|
||||||
public DynamicList<word>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- The set formatter
|
|
||||||
autoPtr<writer<Type>> formatter;
|
|
||||||
|
|
||||||
//- Construct null
|
|
||||||
fieldGroup() = default;
|
|
||||||
|
|
||||||
//- Reset format and field list
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
DynamicList<word>::clear();
|
|
||||||
formatter.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFormatter(const word& writeFormat, const dictionary& dict)
|
|
||||||
{
|
|
||||||
formatter = writer<Type>::New(writeFormat, dict);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//- Class used for sampling volFields
|
|
||||||
template<class Type>
|
|
||||||
class volFieldSampler
|
|
||||||
:
|
|
||||||
public List<Field<Type>>
|
|
||||||
{
|
|
||||||
//- Name of this collection of values
|
|
||||||
const word name_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Construct interpolating field to the sampleSets
|
|
||||||
volFieldSampler
|
|
||||||
(
|
|
||||||
const word& interpolationScheme,
|
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& field,
|
|
||||||
const PtrList<sampledSet>&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct mapping field to the sampleSets
|
|
||||||
volFieldSampler
|
|
||||||
(
|
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& field,
|
|
||||||
const PtrList<sampledSet>&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct from components
|
|
||||||
volFieldSampler
|
|
||||||
(
|
|
||||||
const List<Field<Type>>& values,
|
|
||||||
const word& name
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Return the field name
|
|
||||||
const word& name() const
|
|
||||||
{
|
|
||||||
return name_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Static Data Members
|
// Static Data Members
|
||||||
|
|
||||||
//- Output verbosity
|
//- Local control for sampling actions
|
||||||
static bool verbose_;
|
enum sampleActionType : unsigned
|
||||||
|
{
|
||||||
|
ACTION_NONE = 0,
|
||||||
|
ACTION_WRITE = 0x1,
|
||||||
|
ACTION_STORE = 0x2,
|
||||||
|
ACTION_ALL = 0xF
|
||||||
|
};
|
||||||
|
|
||||||
// Private Data
|
// Private Data
|
||||||
|
|
||||||
//- Const reference to fvMesh
|
|
||||||
const fvMesh& mesh_;
|
|
||||||
|
|
||||||
//- Keep the dictionary to recreate sets for moving mesh cases
|
//- Keep the dictionary to recreate sets for moving mesh cases
|
||||||
dictionary dict_;
|
dictionary dict_;
|
||||||
|
|
||||||
//- Load fields from files (not from objectRegistry)
|
//- Load fields from files (not from objectRegistry)
|
||||||
bool loadFromFiles_;
|
bool loadFromFiles_;
|
||||||
|
|
||||||
|
//- Output verbosity
|
||||||
|
bool verbose_;
|
||||||
|
|
||||||
|
//- Perform sample/store actions on execute as well
|
||||||
|
bool onExecute_;
|
||||||
|
|
||||||
|
//- Correct meshSearch and update sets
|
||||||
|
bool needsCorrect_;
|
||||||
|
|
||||||
//- Output path
|
//- Output path
|
||||||
fileName outputPath_;
|
fileName outputPath_;
|
||||||
|
|
||||||
@ -168,8 +169,8 @@ class sampledSets
|
|||||||
//- Names of fields to sample
|
//- Names of fields to sample
|
||||||
wordRes fieldSelection_;
|
wordRes fieldSelection_;
|
||||||
|
|
||||||
//- Interpolation scheme to use
|
//- Interpolation/sample scheme to obtain values at the points
|
||||||
word interpolationScheme_;
|
word samplePointScheme_;
|
||||||
|
|
||||||
//- Output format to use
|
//- Output format to use
|
||||||
word writeFormat_;
|
word writeFormat_;
|
||||||
@ -178,61 +179,76 @@ class sampledSets
|
|||||||
dictionary writeFormatOptions_;
|
dictionary writeFormatOptions_;
|
||||||
|
|
||||||
|
|
||||||
// Categorized scalar/vector/tensor fields
|
// Output control
|
||||||
|
|
||||||
fieldGroup<scalar> scalarFields_;
|
//- The coordSet writers (one per sampled set)
|
||||||
fieldGroup<vector> vectorFields_;
|
PtrList<coordSetWriter> writers_;
|
||||||
fieldGroup<sphericalTensor> sphericalTensorFields_;
|
|
||||||
fieldGroup<symmTensor> symmTensorFields_;
|
//- Current list of field names selected for sampling
|
||||||
fieldGroup<tensor> tensorFields_;
|
DynamicList<word> selectedFieldNames_;
|
||||||
|
|
||||||
|
|
||||||
// Merging structures
|
// Merging
|
||||||
|
|
||||||
PtrList<coordSet> masterSampledSets_;
|
//- Gathered coordSet. (Content only meaningful on master)
|
||||||
labelListList indexSets_;
|
PtrList<coordSet> gatheredSets_;
|
||||||
|
|
||||||
|
//- Indexed sort order for gathered coordSet.
|
||||||
|
// (Content only meaningful on master)
|
||||||
|
List<labelList> gatheredSorting_;
|
||||||
|
|
||||||
|
//- The globalIndex for gathering. (Content only meaningful on master)
|
||||||
|
List<globalIndex> globalIndices_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Clear old field groups
|
//- A new coordSet writer, with per-set formatOptions
|
||||||
void clearFieldGroups();
|
static autoPtr<coordSetWriter> newWriter
|
||||||
|
|
||||||
//- Classify field types, returns the number of fields
|
|
||||||
label classifyFields();
|
|
||||||
|
|
||||||
//- Combine points from all processors. Sort by curveDist and produce
|
|
||||||
//- index list. Valid result only on master processor.
|
|
||||||
void combineSampledSets
|
|
||||||
(
|
(
|
||||||
PtrList<coordSet>& masterSampledSets,
|
word writeType,
|
||||||
labelListList& indexSets
|
const dictionary& formatOptions,
|
||||||
|
const dictionary& surfDict
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Combine values from all processors.
|
//- Perform sampling action with store/write
|
||||||
// Valid result only on master processor.
|
bool performAction(unsigned request);
|
||||||
template<class T>
|
|
||||||
void combineSampledValues
|
|
||||||
(
|
|
||||||
const PtrList<volFieldSampler<T>>& sampledFields,
|
|
||||||
const labelListList& indexSets,
|
|
||||||
PtrList<volFieldSampler<T>>& masterFields
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Write set on master, return fileName
|
//- Count selected/sampled fields
|
||||||
|
// Returns empty IOobjectList if loadFromFiles_ is not active
|
||||||
|
//
|
||||||
|
// Adjusts selectedFieldNames_
|
||||||
|
IOobjectList preCheckFields();
|
||||||
|
|
||||||
|
//- Setup the sets (optional writers)
|
||||||
|
void initDict(const dictionary& dict, const bool initial);
|
||||||
|
|
||||||
|
//- Combine points from all processors.
|
||||||
|
//- Sort by curve distance and produce index list.
|
||||||
|
//- Valid result only on master processor.
|
||||||
|
void gatherAllSets();
|
||||||
|
|
||||||
|
//- Write sampled fieldName on coordSet and on outputDir path
|
||||||
template<class Type>
|
template<class Type>
|
||||||
fileName writeSampleFile
|
void writeCoordSet
|
||||||
(
|
(
|
||||||
const coordSet& masterSampleSet,
|
coordSetWriter& writer,
|
||||||
const PtrList<volFieldSampler<Type>>& masterFields,
|
const Field<Type>& values,
|
||||||
const label setI,
|
const word& fieldName
|
||||||
const fileName& timeDir,
|
|
||||||
const writer<Type>& formatter
|
|
||||||
);
|
);
|
||||||
|
|
||||||
template<class Type>
|
//- Get from registry or load from disk
|
||||||
void sampleAndWrite(fieldGroup<Type>& fields);
|
template<class GeoField>
|
||||||
|
tmp<GeoField> getOrLoadField(const word& fieldName) const;
|
||||||
|
|
||||||
|
//- Sample and store/write a specific volume field
|
||||||
|
template<class Type>
|
||||||
|
void performAction(const VolumeField<Type>& field, unsigned request);
|
||||||
|
|
||||||
|
//- Sample and write all applicable sampled fields
|
||||||
|
// Only uses IOobjectList when loadFromFiles_ is active
|
||||||
|
template<class GeoField>
|
||||||
|
void performAction(const IOobjectList& objects, unsigned request);
|
||||||
|
|
||||||
//- No copy construct
|
//- No copy construct
|
||||||
sampledSets(const sampledSets&) = delete;
|
sampledSets(const sampledSets&) = delete;
|
||||||
@ -253,7 +269,7 @@ public:
|
|||||||
sampledSets
|
sampledSets
|
||||||
(
|
(
|
||||||
const word& name,
|
const word& name,
|
||||||
const Time& time,
|
const Time& runTime,
|
||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -262,8 +278,8 @@ public:
|
|||||||
sampledSets
|
sampledSets
|
||||||
(
|
(
|
||||||
const word& name,
|
const word& name,
|
||||||
const objectRegistry&,
|
const objectRegistry& obr,
|
||||||
const dictionary&,
|
const dictionary& dict,
|
||||||
const bool loadFromFiles = false
|
const bool loadFromFiles = false
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -276,7 +292,7 @@ public:
|
|||||||
|
|
||||||
//- Enable/disable verbose output
|
//- Enable/disable verbose output
|
||||||
// \return old value
|
// \return old value
|
||||||
bool verbose(const bool on);
|
bool verbose(const bool on) noexcept;
|
||||||
|
|
||||||
//- Read the sampledSets
|
//- Read the sampledSets
|
||||||
virtual bool read(const dictionary&);
|
virtual bool read(const dictionary&);
|
||||||
@ -307,12 +323,6 @@ public:
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
#include "sampledSetsTemplates.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -1,129 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
||||||
Copyright (C) 2017 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "sampledSets.H"
|
|
||||||
#include "volFields.H"
|
|
||||||
#include "IOobjectList.H"
|
|
||||||
#include "UIndirectList.H"
|
|
||||||
#include "ListOps.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
void Foam::sampledSets::clearFieldGroups()
|
|
||||||
{
|
|
||||||
scalarFields_.clear();
|
|
||||||
vectorFields_.clear();
|
|
||||||
sphericalTensorFields_.clear();
|
|
||||||
symmTensorFields_.clear();
|
|
||||||
tensorFields_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::label Foam::sampledSets::classifyFields()
|
|
||||||
{
|
|
||||||
label nFields = 0;
|
|
||||||
clearFieldGroups();
|
|
||||||
|
|
||||||
wordList allFields; // Just needed for warnings
|
|
||||||
HashTable<wordHashSet> available;
|
|
||||||
|
|
||||||
if (loadFromFiles_)
|
|
||||||
{
|
|
||||||
// Check files for a particular time
|
|
||||||
IOobjectList objects(mesh_, mesh_.time().timeName());
|
|
||||||
|
|
||||||
allFields = objects.names();
|
|
||||||
available = objects.classes(fieldSelection_);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Check currently available fields
|
|
||||||
allFields = mesh_.names();
|
|
||||||
available = mesh_.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
forAllConstIters(available, iter)
|
|
||||||
{
|
|
||||||
const word& fieldType = iter.key();
|
|
||||||
const wordList fieldNames = iter.val().sortedToc();
|
|
||||||
|
|
||||||
const label count = fieldNames.size(); // pre-filtered, so non-empty
|
|
||||||
|
|
||||||
if (fieldType == volScalarField::typeName)
|
|
||||||
{
|
|
||||||
scalarFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
else if (fieldType == volVectorField::typeName)
|
|
||||||
{
|
|
||||||
vectorFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
else if (fieldType == volSphericalTensorField::typeName)
|
|
||||||
{
|
|
||||||
sphericalTensorFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
else if (fieldType == volSymmTensorField::typeName)
|
|
||||||
{
|
|
||||||
symmTensorFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
else if (fieldType == volTensorField::typeName)
|
|
||||||
{
|
|
||||||
tensorFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nFields;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
241
src/sampling/sampledSet/sampledSets/sampledSetsImpl.C
Normal file
241
src/sampling/sampledSet/sampledSets/sampledSetsImpl.C
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2011 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "sampledSets.H"
|
||||||
|
#include "globalIndex.H"
|
||||||
|
#include "interpolation.H"
|
||||||
|
#include "volFields.H"
|
||||||
|
#include "volPointInterpolation.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class GeoField>
|
||||||
|
Foam::tmp<GeoField>
|
||||||
|
Foam::sampledSets::getOrLoadField(const word& fieldName) const
|
||||||
|
{
|
||||||
|
tmp<GeoField> tfield;
|
||||||
|
|
||||||
|
if (loadFromFiles_)
|
||||||
|
{
|
||||||
|
tfield.reset
|
||||||
|
(
|
||||||
|
new GeoField
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
fieldName,
|
||||||
|
mesh_.time().timeName(),
|
||||||
|
mesh_,
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
mesh_
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Slightly paranoid here
|
||||||
|
tfield.cref(mesh_.cfindObject<GeoField>(fieldName));
|
||||||
|
}
|
||||||
|
|
||||||
|
return tfield;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::sampledSets::writeCoordSet
|
||||||
|
(
|
||||||
|
coordSetWriter& writer,
|
||||||
|
const Field<Type>& values,
|
||||||
|
const word& fieldName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
fileName outputName;
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
outputName = writer.write(fieldName, values);
|
||||||
|
}
|
||||||
|
Pstream::scatter(outputName);
|
||||||
|
|
||||||
|
if (outputName.size())
|
||||||
|
{
|
||||||
|
// Case-local file name with "<case>" to make relocatable
|
||||||
|
|
||||||
|
dictionary propsDict;
|
||||||
|
propsDict.add
|
||||||
|
(
|
||||||
|
"file",
|
||||||
|
time_.relativePath(outputName, true)
|
||||||
|
);
|
||||||
|
setProperty(fieldName, propsDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::sampledSets::performAction
|
||||||
|
(
|
||||||
|
const VolumeField<Type>& fld,
|
||||||
|
unsigned request
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const word& fieldName = fld.name();
|
||||||
|
|
||||||
|
// The interpolator for this field
|
||||||
|
autoPtr<interpolation<Type>> interpPtr;
|
||||||
|
|
||||||
|
if (!samplePointScheme_.empty() && samplePointScheme_ != "cell")
|
||||||
|
{
|
||||||
|
interpPtr.reset(interpolation<Type>::New(samplePointScheme_, fld));
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(*this, seti)
|
||||||
|
{
|
||||||
|
const sampledSet& s = (*this)[seti];
|
||||||
|
const globalIndex& globIdx = globalIndices_[seti];
|
||||||
|
const labelList& globOrder = gatheredSorting_[seti];
|
||||||
|
|
||||||
|
const word& setName = s.name();
|
||||||
|
Field<Type> values(s.size());
|
||||||
|
|
||||||
|
if (interpPtr)
|
||||||
|
{
|
||||||
|
forAll(s, samplei)
|
||||||
|
{
|
||||||
|
const point& p = s[samplei];
|
||||||
|
const label celli = s.cells()[samplei];
|
||||||
|
const label facei = s.faces()[samplei];
|
||||||
|
|
||||||
|
if (celli == -1 && facei == -1)
|
||||||
|
{
|
||||||
|
// Special condition for illegal sampling points
|
||||||
|
values[samplei] = pTraits<Type>::max;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
values[samplei] = interpPtr().interpolate(p, celli, facei);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
forAll(s, samplei)
|
||||||
|
{
|
||||||
|
const label celli = s.cells()[samplei];
|
||||||
|
|
||||||
|
if (celli == -1)
|
||||||
|
{
|
||||||
|
values[samplei] = pTraits<Type>::max;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
values[samplei] = fld[celli];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect data from all processors
|
||||||
|
globIdx.gatherInplace(values);
|
||||||
|
|
||||||
|
// Some values only available on master
|
||||||
|
Type avgValue, minValue, maxValue;
|
||||||
|
label sizeValue;
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
avgValue = average(values);
|
||||||
|
minValue = min(values);
|
||||||
|
maxValue = max(values);
|
||||||
|
sizeValue = values.size();
|
||||||
|
|
||||||
|
// Use sorted order
|
||||||
|
values = UIndirectList<Type>(values, globOrder)();
|
||||||
|
}
|
||||||
|
Pstream::scatter(avgValue);
|
||||||
|
Pstream::scatter(minValue);
|
||||||
|
Pstream::scatter(maxValue);
|
||||||
|
Pstream::scatter(sizeValue);
|
||||||
|
|
||||||
|
// Store results: min/max/average/size with the name of the set
|
||||||
|
// for scoping.
|
||||||
|
// Eg, average(lines,T) ...
|
||||||
|
const word resultArg('(' + setName + ',' + fieldName + ')');
|
||||||
|
|
||||||
|
this->setResult("average" + resultArg, avgValue);
|
||||||
|
this->setResult("min" + resultArg, minValue);
|
||||||
|
this->setResult("max" + resultArg, maxValue);
|
||||||
|
this->setResult("size" + resultArg, sizeValue);
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< name() << ' ' << setName << " : " << fieldName << nl
|
||||||
|
<< " avg: " << avgValue << nl
|
||||||
|
<< " min: " << minValue << nl
|
||||||
|
<< " max: " << maxValue << nl << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request & ACTION_WRITE)
|
||||||
|
{
|
||||||
|
writeCoordSet<Type>(writers_[seti], values, fieldName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class GeoField>
|
||||||
|
void Foam::sampledSets::performAction
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
unsigned request
|
||||||
|
)
|
||||||
|
{
|
||||||
|
wordList fieldNames;
|
||||||
|
if (loadFromFiles_)
|
||||||
|
{
|
||||||
|
fieldNames = objects.sortedNames<GeoField>(fieldSelection_);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fieldNames = mesh_.thisDb().sortedNames<GeoField>(fieldSelection_);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const word& fieldName : fieldNames)
|
||||||
|
{
|
||||||
|
tmp<GeoField> tfield = getOrLoadField<GeoField>(fieldName);
|
||||||
|
|
||||||
|
if (tfield)
|
||||||
|
{
|
||||||
|
performAction<typename GeoField::value_type>(tfield(), request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -1,376 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
||||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "sampledSets.H"
|
|
||||||
#include "volFields.H"
|
|
||||||
#include "globalIndex.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::sampledSets::volFieldSampler<Type>::volFieldSampler
|
|
||||||
(
|
|
||||||
const word& interpolationScheme,
|
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& field,
|
|
||||||
const PtrList<sampledSet>& samplers
|
|
||||||
)
|
|
||||||
:
|
|
||||||
List<Field<Type>>(samplers.size()),
|
|
||||||
name_(field.name())
|
|
||||||
{
|
|
||||||
autoPtr<interpolation<Type>> interpolator
|
|
||||||
(
|
|
||||||
interpolation<Type>::New(interpolationScheme, field)
|
|
||||||
);
|
|
||||||
|
|
||||||
forAll(samplers, setI)
|
|
||||||
{
|
|
||||||
Field<Type>& values = this->operator[](setI);
|
|
||||||
const sampledSet& samples = samplers[setI];
|
|
||||||
|
|
||||||
values.setSize(samples.size());
|
|
||||||
forAll(samples, sampleI)
|
|
||||||
{
|
|
||||||
const point& samplePt = samples[sampleI];
|
|
||||||
label celli = samples.cells()[sampleI];
|
|
||||||
label facei = samples.faces()[sampleI];
|
|
||||||
|
|
||||||
if (celli == -1 && facei == -1)
|
|
||||||
{
|
|
||||||
// Special condition for illegal sampling points
|
|
||||||
values[sampleI] = pTraits<Type>::max;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
values[sampleI] = interpolator().interpolate
|
|
||||||
(
|
|
||||||
samplePt,
|
|
||||||
celli,
|
|
||||||
facei
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::sampledSets::volFieldSampler<Type>::volFieldSampler
|
|
||||||
(
|
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& field,
|
|
||||||
const PtrList<sampledSet>& samplers
|
|
||||||
)
|
|
||||||
:
|
|
||||||
List<Field<Type>>(samplers.size()),
|
|
||||||
name_(field.name())
|
|
||||||
{
|
|
||||||
forAll(samplers, setI)
|
|
||||||
{
|
|
||||||
Field<Type>& values = this->operator[](setI);
|
|
||||||
const sampledSet& samples = samplers[setI];
|
|
||||||
|
|
||||||
values.setSize(samples.size());
|
|
||||||
forAll(samples, sampleI)
|
|
||||||
{
|
|
||||||
label celli = samples.cells()[sampleI];
|
|
||||||
|
|
||||||
if (celli ==-1)
|
|
||||||
{
|
|
||||||
values[sampleI] = pTraits<Type>::max;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
values[sampleI] = field[celli];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::sampledSets::volFieldSampler<Type>::volFieldSampler
|
|
||||||
(
|
|
||||||
const List<Field<Type>>& values,
|
|
||||||
const word& name
|
|
||||||
)
|
|
||||||
:
|
|
||||||
List<Field<Type>>(values),
|
|
||||||
name_(name)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::fileName Foam::sampledSets::writeSampleFile
|
|
||||||
(
|
|
||||||
const coordSet& masterSampleSet,
|
|
||||||
const PtrList<volFieldSampler<Type>>& masterFields,
|
|
||||||
const label setI,
|
|
||||||
const fileName& timeDir,
|
|
||||||
const writer<Type>& formatter
|
|
||||||
)
|
|
||||||
{
|
|
||||||
wordList valueSetNames(masterFields.size());
|
|
||||||
List<const Field<Type>*> valueSets(masterFields.size());
|
|
||||||
forAll(masterFields, fieldi)
|
|
||||||
{
|
|
||||||
const word& fieldName = masterFields[fieldi].name();
|
|
||||||
|
|
||||||
valueSetNames[fieldi] = fieldName;
|
|
||||||
|
|
||||||
// Values only available on master
|
|
||||||
Type averageValue, minValue, maxValue;
|
|
||||||
label sizeValue;
|
|
||||||
if (Pstream::master())
|
|
||||||
{
|
|
||||||
valueSets[fieldi] = &masterFields[fieldi][setI];
|
|
||||||
averageValue = average(*valueSets[fieldi]);
|
|
||||||
minValue = min(*valueSets[fieldi]);
|
|
||||||
maxValue = max(*valueSets[fieldi]);
|
|
||||||
sizeValue = valueSets[fieldi]->size();
|
|
||||||
}
|
|
||||||
Pstream::scatter(averageValue);
|
|
||||||
Pstream::scatter(minValue);
|
|
||||||
Pstream::scatter(maxValue);
|
|
||||||
Pstream::scatter(sizeValue);
|
|
||||||
|
|
||||||
// Set results
|
|
||||||
|
|
||||||
setResult("average(" + fieldName + ")", averageValue);
|
|
||||||
setResult("min(" + fieldName + ")", minValue);
|
|
||||||
setResult("max(" + fieldName + ")", maxValue);
|
|
||||||
setResult("size(" + fieldName + ")", sizeValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
fileName fName;
|
|
||||||
if (Pstream::master())
|
|
||||||
{
|
|
||||||
fName = timeDir/formatter.getFileName(masterSampleSet, valueSetNames);
|
|
||||||
|
|
||||||
OFstream ofs(fName);
|
|
||||||
if (ofs.opened())
|
|
||||||
{
|
|
||||||
formatter.write
|
|
||||||
(
|
|
||||||
masterSampleSet,
|
|
||||||
valueSetNames,
|
|
||||||
valueSets,
|
|
||||||
ofs
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WarningInFunction
|
|
||||||
<< "File " << ofs.name() << " could not be opened. "
|
|
||||||
<< "No data will be written" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Pstream::scatter(fName);
|
|
||||||
|
|
||||||
return fName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
void Foam::sampledSets::combineSampledValues
|
|
||||||
(
|
|
||||||
const PtrList<volFieldSampler<T>>& sampledFields,
|
|
||||||
const labelListList& indexSets,
|
|
||||||
PtrList<volFieldSampler<T>>& masterFields
|
|
||||||
)
|
|
||||||
{
|
|
||||||
forAll(sampledFields, fieldi)
|
|
||||||
{
|
|
||||||
List<Field<T>> masterValues(indexSets.size());
|
|
||||||
|
|
||||||
forAll(indexSets, setI)
|
|
||||||
{
|
|
||||||
// Collect data from all processors
|
|
||||||
|
|
||||||
Field<T> allData;
|
|
||||||
globalIndex::gatherOp(sampledFields[fieldi][setI], allData);
|
|
||||||
|
|
||||||
if (Pstream::master())
|
|
||||||
{
|
|
||||||
masterValues[setI] = UIndirectList<T>
|
|
||||||
(
|
|
||||||
allData,
|
|
||||||
indexSets[setI]
|
|
||||||
)();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
masterFields.set
|
|
||||||
(
|
|
||||||
fieldi,
|
|
||||||
new volFieldSampler<T>
|
|
||||||
(
|
|
||||||
masterValues,
|
|
||||||
sampledFields[fieldi].name()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::sampledSets::sampleAndWrite(fieldGroup<Type>& fields)
|
|
||||||
{
|
|
||||||
if (fields.size())
|
|
||||||
{
|
|
||||||
const bool interpolate = interpolationScheme_ != "cell";
|
|
||||||
|
|
||||||
// Create or use existing writer
|
|
||||||
if (!fields.formatter)
|
|
||||||
{
|
|
||||||
fields.setFormatter(writeFormat_, writeFormatOptions_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Storage for interpolated values
|
|
||||||
PtrList<volFieldSampler<Type>> sampledFields(fields.size());
|
|
||||||
|
|
||||||
forAll(fields, fieldi)
|
|
||||||
{
|
|
||||||
if (Pstream::master() && verbose_)
|
|
||||||
{
|
|
||||||
Pout<< "sampledSets::sampleAndWrite: "
|
|
||||||
<< fields[fieldi] << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loadFromFiles_)
|
|
||||||
{
|
|
||||||
GeometricField<Type, fvPatchField, volMesh> vf
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
fields[fieldi],
|
|
||||||
mesh_.time().timeName(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
false
|
|
||||||
),
|
|
||||||
mesh_
|
|
||||||
);
|
|
||||||
|
|
||||||
if (interpolate)
|
|
||||||
{
|
|
||||||
sampledFields.set
|
|
||||||
(
|
|
||||||
fieldi,
|
|
||||||
new volFieldSampler<Type>
|
|
||||||
(
|
|
||||||
interpolationScheme_,
|
|
||||||
vf,
|
|
||||||
*this
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sampledFields.set
|
|
||||||
(
|
|
||||||
fieldi,
|
|
||||||
new volFieldSampler<Type>(vf, *this)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (interpolate)
|
|
||||||
{
|
|
||||||
sampledFields.set
|
|
||||||
(
|
|
||||||
fieldi,
|
|
||||||
new volFieldSampler<Type>
|
|
||||||
(
|
|
||||||
interpolationScheme_,
|
|
||||||
mesh_.lookupObject
|
|
||||||
<GeometricField<Type, fvPatchField, volMesh>>
|
|
||||||
(fields[fieldi]),
|
|
||||||
*this
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sampledFields.set
|
|
||||||
(
|
|
||||||
fieldi,
|
|
||||||
new volFieldSampler<Type>
|
|
||||||
(
|
|
||||||
mesh_.lookupObject
|
|
||||||
<GeometricField<Type, fvPatchField, volMesh>>
|
|
||||||
(fields[fieldi]),
|
|
||||||
*this
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Combine sampled fields from processors.
|
|
||||||
// Note: only master results are valid
|
|
||||||
|
|
||||||
PtrList<volFieldSampler<Type>> masterFields(sampledFields.size());
|
|
||||||
combineSampledValues(sampledFields, indexSets_, masterFields);
|
|
||||||
|
|
||||||
forAll(masterSampledSets_, setI)
|
|
||||||
{
|
|
||||||
fileName sampleFile = writeSampleFile
|
|
||||||
(
|
|
||||||
masterSampledSets_[setI],
|
|
||||||
masterFields,
|
|
||||||
setI,
|
|
||||||
outputPath_/mesh_.time().timeName(),
|
|
||||||
fields.formatter()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (sampleFile.size())
|
|
||||||
{
|
|
||||||
// Case-local file name with "<case>" to make relocatable
|
|
||||||
|
|
||||||
forAll(masterFields, fieldi)
|
|
||||||
{
|
|
||||||
dictionary propsDict;
|
|
||||||
propsDict.add
|
|
||||||
(
|
|
||||||
"file",
|
|
||||||
time_.relativePath(sampleFile, true)
|
|
||||||
);
|
|
||||||
|
|
||||||
const word& fieldName = masterFields[fieldi].name();
|
|
||||||
setProperty(fieldName, propsDict);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -940,7 +940,7 @@ void Foam::shortestPathSet::genSamples
|
|||||||
// Get the target point
|
// Get the target point
|
||||||
const label outsideCelli = mesh.findCell(outsidePoint);
|
const label outsideCelli = mesh.findCell(outsidePoint);
|
||||||
|
|
||||||
// Maintain overall track length. Used to make curveDist continuous.
|
// Maintain overall track length. Used to make curve distance continuous.
|
||||||
scalar trackLength = 0;
|
scalar trackLength = 0;
|
||||||
|
|
||||||
List<topoDistanceData<label>> allFaceInfo(mesh.nFaces());
|
List<topoDistanceData<label>> allFaceInfo(mesh.nFaces());
|
||||||
|
|||||||
Reference in New Issue
Block a user