diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C b/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C index 5c8f4da2d7de4f7c34483ec0dcf0107970de619d..4f1f821681022aaafc0cee51a41dde3840976b90 100644 --- a/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C +++ b/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C @@ -8,7 +8,6 @@ #include "wedgePolyPatch.H" #include "unitConversion.H" #include "polyMeshTetDecomposition.H" -#include "surfaceWriter.H" #include "checkTools.H" #include "functionObject.H" @@ -482,7 +481,7 @@ Foam::label Foam::checkGeometry ( const polyMesh& mesh, const bool allGeometry, - const autoPtr<surfaceWriter>& surfWriter, + autoPtr<surfaceWriter>& surfWriter, const autoPtr<writer<scalar>>& setWriter ) { @@ -542,7 +541,7 @@ Foam::label Foam::checkGeometry nonAlignedPoints.write(); if (setWriter.valid()) { - mergeAndWrite(setWriter(), nonAlignedPoints); + mergeAndWrite(*setWriter, nonAlignedPoints); } } } @@ -576,7 +575,7 @@ Foam::label Foam::checkGeometry cells.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), cells); + mergeAndWrite(*surfWriter, cells); } } } @@ -592,7 +591,7 @@ Foam::label Foam::checkGeometry aspectCells.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), aspectCells); + mergeAndWrite(*surfWriter, aspectCells); } } } @@ -613,7 +612,7 @@ Foam::label Foam::checkGeometry faces.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), faces); + mergeAndWrite(*surfWriter, faces); } } } @@ -635,7 +634,7 @@ Foam::label Foam::checkGeometry cells.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), cells); + mergeAndWrite(*surfWriter, cells); } } } @@ -658,7 +657,7 @@ Foam::label Foam::checkGeometry faces.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), faces); + mergeAndWrite(*surfWriter, faces); } } } @@ -680,7 +679,7 @@ Foam::label Foam::checkGeometry faces.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), faces); + mergeAndWrite(*surfWriter, faces); } } } @@ -702,7 +701,7 @@ Foam::label Foam::checkGeometry faces.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), faces); + mergeAndWrite(*surfWriter, faces); } } } @@ -726,7 +725,7 @@ Foam::label Foam::checkGeometry faces.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), faces); + mergeAndWrite(*surfWriter, faces); } } } @@ -759,7 +758,7 @@ Foam::label Foam::checkGeometry faces.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), faces); + mergeAndWrite(*surfWriter, faces); } } } @@ -784,7 +783,7 @@ Foam::label Foam::checkGeometry points.write(); if (setWriter.valid()) { - mergeAndWrite(setWriter(), points); + mergeAndWrite(*setWriter, points); } } } @@ -807,7 +806,7 @@ Foam::label Foam::checkGeometry nearPoints.write(); if (setWriter.valid()) { - mergeAndWrite(setWriter(), nearPoints); + mergeAndWrite(*setWriter, nearPoints); } } } @@ -831,7 +830,7 @@ Foam::label Foam::checkGeometry faces.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), faces); + mergeAndWrite(*surfWriter, faces); } } } @@ -854,7 +853,7 @@ Foam::label Foam::checkGeometry faces.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), faces); + mergeAndWrite(*surfWriter, faces); } } } @@ -875,7 +874,7 @@ Foam::label Foam::checkGeometry cells.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), cells); + mergeAndWrite(*surfWriter, cells); } } } @@ -895,7 +894,7 @@ Foam::label Foam::checkGeometry cells.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), cells); + mergeAndWrite(*surfWriter, cells); } } } @@ -916,7 +915,7 @@ Foam::label Foam::checkGeometry faces.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), faces); + mergeAndWrite(*surfWriter, faces); } } } @@ -937,7 +936,7 @@ Foam::label Foam::checkGeometry faces.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), faces); + mergeAndWrite(*surfWriter, faces); } } } @@ -952,14 +951,10 @@ Foam::label Foam::checkGeometry autoPtr<surfaceWriter> patchWriter; if (!surfWriter.valid()) { - patchWriter.reset(new vtkSurfaceWriter()); + patchWriter.reset(new surfaceWriters::vtkWriter()); } - const surfaceWriter& wr = - ( - surfWriter.valid() - ? surfWriter() - : patchWriter() - ); + + surfaceWriter& wr = (surfWriter.valid() ? *surfWriter : *patchWriter); // Currently only do AMI checks @@ -1017,22 +1012,22 @@ Foam::label Foam::checkGeometry if (Pstream::master()) { - wr.write + const word fName ( - outputDir, - ( - "patch" + Foam::name(cpp.index()) - + "-src_" + tmName - ), - meshedSurfRef - ( - mergedPoints, - mergedFaces - ), - "weightsSum", - mergedWeights, - false + "patch" + Foam::name(cpp.index()) + + "-src_" + tmName + ); + + wr.open + ( + mergedPoints, + mergedFaces, + (outputDir / fName), + false // serial - already merged ); + + wr.write("weightsSum", mergedWeights); + wr.clear(); } if (isA<cyclicACMIPolyPatch>(pbm[patchi])) @@ -1049,22 +1044,22 @@ Foam::label Foam::checkGeometry if (Pstream::master()) { - wr.write + const word fName ( - outputDir, - ( - "patch" + Foam::name(cpp.index()) - + "-src_" + tmName - ), - meshedSurfRef - ( - mergedPoints, - mergedFaces - ), - "mask", - mergedMask, - false + "patch" + Foam::name(cpp.index()) + + "-src_" + tmName + ); + + wr.open + ( + mergedPoints, + mergedFaces, + (outputDir / fName), + false // serial - already merged ); + + wr.write("mask", mergedMask); + wr.clear(); } } } @@ -1101,22 +1096,22 @@ Foam::label Foam::checkGeometry if (Pstream::master()) { - wr.write + const word fName ( - outputDir, - ( - "patch" + Foam::name(cpp.index()) - + "-tgt_" + tmName - ), - meshedSurfRef - ( - mergedPoints, - mergedFaces - ), - "weightsSum", - mergedWeights, - false + "patch" + Foam::name(cpp.index()) + + "-tgt_" + tmName + ); + + wr.open + ( + mergedPoints, + mergedFaces, + (outputDir / fName), + false // serial - already merged ); + + wr.write("weightsSum", mergedWeights); + wr.clear(); } if (isA<cyclicACMIPolyPatch>(pbm[patchi])) @@ -1129,24 +1124,25 @@ Foam::label Foam::checkGeometry pp.neighbPatch().mask(), mergedMask ); + if (Pstream::master()) { - wr.write + const word fName ( - outputDir, - ( - "patch" + Foam::name(cpp.index()) - + "-tgt_" + tmName - ), - meshedSurfRef - ( - mergedPoints, - mergedFaces - ), - "mask", - mergedMask, - false + "patch" + Foam::name(cpp.index()) + + "-tgt_" + tmName ); + + wr.open + ( + mergedPoints, + mergedFaces, + (outputDir / fName), + false // serial - already merged + ); + + wr.write("mask", mergedMask); + wr.clear(); } } } diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.H b/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.H index d0111fd1e1972d6495ab0854cbfd5a2e843c39af..acd3d401be5c03c42fb1a7a36e42df7f0d383a77 100644 --- a/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.H +++ b/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.H @@ -27,7 +27,7 @@ namespace Foam ( const polyMesh& mesh, const bool allGeometry, - const autoPtr<surfaceWriter>&, - const autoPtr<writer<scalar>>& + autoPtr<surfaceWriter>& surfWriter, + const autoPtr<writer<scalar>>& setWriter ); } diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkMesh.C b/applications/utilities/mesh/manipulation/checkMesh/checkMesh.C index 8b3eb25cc72c64d3643c3efe80b3f6a917baabf4..fbd24180c46b35a6c3ae5751bc3718b3432c9db1 100644 --- a/applications/utilities/mesh/manipulation/checkMesh/checkMesh.C +++ b/applications/utilities/mesh/manipulation/checkMesh/checkMesh.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2017 OpenFOAM Foundation @@ -67,8 +67,8 @@ Usage #include "Time.H" #include "fvMesh.H" #include "globalMeshData.H" -#include "surfaceWriter.H" #include "vtkSetWriter.H" +#include "vtkSurfaceWriter.H" #include "IOdictionary.H" #include "checkTools.H" @@ -149,16 +149,19 @@ int main(int argc, char *argv[]) ); if (!writeFields && args.found("writeAllFields")) { - selectedFields.insert("nonOrthoAngle"); - selectedFields.insert("faceWeight"); - selectedFields.insert("skewness"); - selectedFields.insert("cellDeterminant"); - selectedFields.insert("aspectRatio"); - selectedFields.insert("cellShapes"); - selectedFields.insert("cellVolume"); - selectedFields.insert("cellVolumeRatio"); - selectedFields.insert("minTetVolume"); - selectedFields.insert("cellRegion"); + selectedFields.insert + ({ + "nonOrthoAngle", + "faceWeight", + "skewness", + "cellDeterminant", + "aspectRatio", + "cellShapes", + "cellVolume", + "cellVolumeRatio", + "minTetVolume", + "cellRegion" + }); } diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkMeshQuality.C b/applications/utilities/mesh/manipulation/checkMesh/checkMeshQuality.C index a6a01c7336144d40f1793381b6e4eda0ad5c942c..26dfbb6d20fd2725788052f3749e1e0cbb72dcb6 100644 --- a/applications/utilities/mesh/manipulation/checkMesh/checkMeshQuality.C +++ b/applications/utilities/mesh/manipulation/checkMesh/checkMeshQuality.C @@ -10,7 +10,7 @@ Foam::label Foam::checkMeshQuality ( const polyMesh& mesh, const dictionary& dict, - const autoPtr<surfaceWriter>& writer + autoPtr<surfaceWriter>& writer ) { label noFailedChecks = 0; @@ -29,9 +29,10 @@ Foam::label Foam::checkMeshQuality << " faces in error to set " << faces.name() << endl; faces.instance() = mesh.pointsInstance(); faces.write(); + if (writer.valid()) { - mergeAndWrite(writer(), faces); + mergeAndWrite(*writer, faces); } } } diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkMeshQuality.H b/applications/utilities/mesh/manipulation/checkMesh/checkMeshQuality.H index 52507986bf0bb68dd10b30afc2fce8e01beedf45..0ad3f7448792ac0421d7bbca69feffc0bbc24cdc 100644 --- a/applications/utilities/mesh/manipulation/checkMesh/checkMeshQuality.H +++ b/applications/utilities/mesh/manipulation/checkMesh/checkMeshQuality.H @@ -6,8 +6,8 @@ namespace Foam label checkMeshQuality ( - const polyMesh&, - const dictionary&, - const autoPtr<surfaceWriter>& + const polyMesh& mesh, + const dictionary& dict, + autoPtr<surfaceWriter>& writer ); } diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkTools.C b/applications/utilities/mesh/manipulation/checkMesh/checkTools.C index 060c60b0fc83eba7d3c89cfafb125f67b78d2bb6..4b530ee9efe29b223e51ab85e3d421d9bb6487a7 100644 --- a/applications/utilities/mesh/manipulation/checkMesh/checkTools.C +++ b/applications/utilities/mesh/manipulation/checkMesh/checkTools.C @@ -209,7 +209,7 @@ void Foam::printMeshStats(const polyMesh& mesh, const bool allTopology) void Foam::mergeAndWrite ( const polyMesh& mesh, - const surfaceWriter& writer, + surfaceWriter& writer, const word& name, const indirectPrimitivePatch& setPatch, const fileName& outputDir @@ -242,37 +242,37 @@ void Foam::mergeAndWrite // Write if (Pstream::master()) { - writer.write + writer.open ( - outputDir, - name, - meshedSurfRef - ( - mergedPoints, - mergedFaces - ) + mergedPoints, + mergedFaces, + (outputDir / name), + false // serial - already merged ); + + writer.writeGeometry(); + writer.clear(); } } else { - writer.write + writer.open ( - outputDir, - name, - meshedSurfRef - ( - setPatch.localPoints(), - setPatch.localFaces() - ) + setPatch.localPoints(), + setPatch.localFaces(), + (outputDir / name), + false // serial - already merged ); + + writer.writeGeometry(); + writer.clear(); } } void Foam::mergeAndWrite ( - const surfaceWriter& writer, + surfaceWriter& writer, const faceSet& set ) { @@ -299,7 +299,7 @@ void Foam::mergeAndWrite void Foam::mergeAndWrite ( - const surfaceWriter& writer, + surfaceWriter& writer, const cellSet& set ) { diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkTools.H b/applications/utilities/mesh/manipulation/checkMesh/checkTools.H index adb98089b5bc9af76daad422e42c5c58731d9765..79c68b6673a136130ba55a1c071e019f0fe094fd 100644 --- a/applications/utilities/mesh/manipulation/checkMesh/checkTools.H +++ b/applications/utilities/mesh/manipulation/checkMesh/checkTools.H @@ -5,12 +5,12 @@ namespace Foam { class polyMesh; - class surfaceWriter; class pointSet; class faceSet; class cellSet; class fileName; class polyMesh; + class surfaceWriter; void printMeshStats(const polyMesh& mesh, const bool allTopology); @@ -19,7 +19,7 @@ namespace Foam void mergeAndWrite ( const polyMesh& mesh, - const surfaceWriter& writer, + surfaceWriter& writer, const word& name, const indirectPrimitivePatch& setPatch, const fileName& outputDir @@ -27,15 +27,15 @@ namespace Foam //- Write vtk representation of (assembled) faceSet to surface file in // postProcessing/ directory - void mergeAndWrite(const surfaceWriter&, const faceSet&); + void mergeAndWrite(surfaceWriter& writer, const faceSet& set); //- Write vtk representation of (assembled) cellSet to surface file in // postProcessing/ directory - void mergeAndWrite(const surfaceWriter&, const cellSet&); + void mergeAndWrite(surfaceWriter& writer, const cellSet& set); //- Write vtk representation of (assembled) pointSet to 'set' file in // postProcessing/ directory - void mergeAndWrite(const writer<scalar>&, const pointSet&); + void mergeAndWrite(const writer<scalar>& writer, const pointSet& set); } diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C b/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C index fb0d1c6ccf53daa0f2b84c39f6a98e6e4c44b1b1..25c8e43de8b995e73f9d3c23b3f419b3298eb969 100644 --- a/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C +++ b/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2016 OpenFOAM Foundation @@ -35,7 +35,7 @@ License #include "IOmanip.H" #include "emptyPolyPatch.H" #include "processorPolyPatch.H" -#include "surfaceWriter.H" +#include "vtkSurfaceWriter.H" #include "checkTools.H" #include "treeBoundBox.H" @@ -114,7 +114,7 @@ Foam::label Foam::checkTopology const polyMesh& mesh, const bool allTopology, const bool allGeometry, - const autoPtr<surfaceWriter>& surfWriter, + autoPtr<surfaceWriter>& surfWriter, const autoPtr<writer<scalar>>& setWriter ) { @@ -203,7 +203,7 @@ Foam::label Foam::checkTopology cells.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), cells); + mergeAndWrite(*surfWriter, cells); } } else @@ -227,7 +227,7 @@ Foam::label Foam::checkTopology points.write(); if (setWriter.valid()) { - mergeAndWrite(setWriter(), points); + mergeAndWrite(*setWriter, points); } } } @@ -249,7 +249,7 @@ Foam::label Foam::checkTopology faces.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), faces); + mergeAndWrite(*surfWriter, faces); } } } @@ -269,7 +269,7 @@ Foam::label Foam::checkTopology faces.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), faces); + mergeAndWrite(*surfWriter, faces); } } } @@ -290,7 +290,7 @@ Foam::label Foam::checkTopology cells.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), cells); + mergeAndWrite(*surfWriter, cells); } } @@ -314,7 +314,7 @@ Foam::label Foam::checkTopology faces.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), faces); + mergeAndWrite(*surfWriter, faces); } } } @@ -369,7 +369,7 @@ Foam::label Foam::checkTopology oneCells.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), oneCells); + mergeAndWrite(*surfWriter, oneCells); } } @@ -385,7 +385,7 @@ Foam::label Foam::checkTopology twoCells.write(); if (surfWriter.valid()) { - mergeAndWrite(surfWriter(), twoCells); + mergeAndWrite(*surfWriter, twoCells); } } } @@ -530,7 +530,7 @@ Foam::label Foam::checkTopology points.write(); if (setWriter.valid()) { - mergeAndWrite(setWriter(), points); + mergeAndWrite(*setWriter, points); } } } @@ -641,7 +641,7 @@ Foam::label Foam::checkTopology points.write(); if (setWriter.valid()) { - mergeAndWrite(setWriter(), points); + mergeAndWrite(*setWriter, points); } } diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkTopology.H b/applications/utilities/mesh/manipulation/checkMesh/checkTopology.H index 7320cb0e563b1b436af88ae724f5d35d170c2d6e..bd93afc3dbe1dba9a310f101fd8abc639b030c26 100644 --- a/applications/utilities/mesh/manipulation/checkMesh/checkTopology.H +++ b/applications/utilities/mesh/manipulation/checkMesh/checkTopology.H @@ -5,8 +5,8 @@ namespace Foam { class polyMesh; - class surfaceWriter; class pointSet; + class surfaceWriter; template<class PatchType> void checkPatch @@ -19,10 +19,10 @@ namespace Foam label checkTopology ( - const polyMesh&, - const bool, - const bool, - const autoPtr<surfaceWriter>&, - const autoPtr<writer<scalar>>& + const polyMesh& mesh, + const bool allTopology, + const bool allGeometry, + autoPtr<surfaceWriter>& surfWriter, + const autoPtr<writer<scalar>>& setWriter ); } diff --git a/applications/utilities/surface/surfaceCheck/surfaceCheck.C b/applications/utilities/surface/surfaceCheck/surfaceCheck.C index 57afe5931faac00141417bf161d62da149c0f900..c42f3e3fe87e652e7abddd0f4590a98c2a9393f1 100644 --- a/applications/utilities/surface/surfaceCheck/surfaceCheck.C +++ b/applications/utilities/surface/surfaceCheck/surfaceCheck.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2016 OpenFOAM Foundation @@ -128,7 +128,7 @@ labelList countBins void writeZoning ( - const surfaceWriter& writer, + surfaceWriter& writer, const triSurface& surf, const labelList& faceZone, const word& fieldName, @@ -136,43 +136,23 @@ void writeZoning const fileName& surfFileNameBase ) { - Info<< "Writing zoning to " - << fileName - ( - surfFilePath - / fieldName - + '_' - + surfFileNameBase - + '.' - + writer.type() - ) - << " ..." << endl << endl; - - // Convert data - scalarField scalarFaceZone(faceZone.size()); - forAll(faceZone, i) - { - scalarFaceZone[i] = faceZone[i]; - } - faceList faces(surf.size()); - forAll(surf, i) - { - faces[i] = surf[i]; - } + // Transcribe faces + faceList faces; + surf.triFaceFaces(faces); - writer.write + writer.open ( - surfFilePath, - surfFileNameBase, - meshedSurfRef - ( - surf.points(), - faces - ), - fieldName, - scalarFaceZone, - false // face based data + surf.points(), + faces, + (surfFilePath / surfFileNameBase), + false // serial - already merged ); + + fileName outputName = writer.write(fieldName, labelField(faceZone)); + + writer.clear(); + + Info<< "Wrote zoning to " << outputName << nl << endl; } @@ -213,7 +193,7 @@ void writeParts fileName subName ( surfFilePath - /surfFileNameBase + "_" + name(zone) + ".obj" + / surfFileNameBase + "_" + name(zone) + ".obj" ); Info<< "writing part " << zone << " size " << subSurf.size() @@ -377,6 +357,7 @@ int main(int argc, char *argv[]) if (writeSets) { surfWriter = surfaceWriter::New(surfaceFormat); + // Option1: hard-coded format edgeFormat = "obj"; //// Option2: same type as surface format. Problem is e.g. .obj format @@ -514,38 +495,29 @@ int main(int argc, char *argv[]) ) ); - const fileName qualityName + + // Transcribe faces + faceList faces; + subSurf.triFaceFaces(faces); + + surfWriter->open ( - surfFilePath - / "illegal" - + '_' - + surfFileNameBase - + '.' - + surfWriter().type() + subSurf.points(), + faces, + (surfFilePath / surfFileNameBase), + false // serial - already merged ); - Info<< "Writing illegal triangles to " - << qualityName << " ..." << endl << endl; - - // Convert data - faceList faces(subSurf.size()); - forAll(subSurf, i) - { - faces[i] = subSurf[i]; - } - surfWriter().write + fileName outputName = surfWriter->write ( - surfFilePath, - surfFileNameBase, - meshedSurfRef - ( - subSurf.points(), - faces - ), "illegal", - scalarField(subSurf.size(), Zero), - false // face based data + scalarField(subSurf.size(), Zero) ); + + surfWriter->clear(); + + Info<< "Wrote illegal triangles to " + << outputName << nl << endl; } else if (outputThreshold > 0) { @@ -645,38 +617,24 @@ int main(int argc, char *argv[]) // Dump for subsetting if (surfWriter.valid()) { - const fileName qualityName - ( - surfFilePath - / "quality" - + '_' - + surfFileNameBase - + '.' - + surfWriter().type() - ); - Info<< "Writing triangle-quality to " - << qualityName << " ..." << endl << endl; - - // Convert data + // Transcribe faces faceList faces(surf.size()); - forAll(surf, i) - { - faces[i] = surf[i]; - } + surf.triFaceFaces(faces); - surfWriter().write + surfWriter->open ( - surfFilePath, - surfFileNameBase, - meshedSurfRef - ( - surf.points(), - faces - ), - "quality", - triQ, - false // face based data + surf.points(), + faces, + (surfFilePath / surfFileNameBase), + false // serial - already merged ); + + fileName outputName = surfWriter->write("quality", triQ); + + surfWriter->clear(); + + Info<< "Wrote triangle-quality to " + << outputName << nl << endl; } else if (outputThreshold > 0) { @@ -926,11 +884,12 @@ int main(int argc, char *argv[]) if (!surfWriter.valid()) { - surfWriter.reset(new vtkSurfaceWriter()); + surfWriter.reset(new surfaceWriters::vtkWriter()); } + writeZoning ( - surfWriter(), + *surfWriter, surf, faceZone, "zone", @@ -991,11 +950,12 @@ int main(int argc, char *argv[]) { if (!surfWriter.valid()) { - surfWriter.reset(new vtkSurfaceWriter()); + surfWriter.reset(new surfaceWriters::vtkWriter()); } + writeZoning ( - surfWriter(), + *surfWriter, surf, normalZone, "normal", diff --git a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C index 1df74fc79d1c5f8a6dee8060e9c110ae80f03a72..056b00a0c5b299006f5b21e7e1f0576df1760e4c 100644 --- a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C +++ b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C @@ -953,20 +953,23 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read { const word formatName(dict.get<word>("surfaceFormat")); - if (formatName != "none") - { - surfaceWriterPtr_.reset + surfaceWriterPtr_.reset + ( + surfaceWriter::New ( - surfaceWriter::New - ( - formatName, - dict.subOrEmptyDict("formatOptions") - .subOrEmptyDict(formatName) - ) - ); + formatName, + dict.subOrEmptyDict("formatOptions").subOrEmptyDict(formatName) + ) + ); + if (surfaceWriterPtr_->enabled()) + { Info<< " surfaceFormat = " << formatName << nl; } + else + { + surfaceWriterPtr_->clear(); + } } Info<< nl << endl; diff --git a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValueTemplates.C b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValueTemplates.C index 56c3bc8ed9e038346aff585adf5ad42926338eee..d665e74d5866ee48d18cb571f8f573c8f1c191d8 100644 --- a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValueTemplates.C +++ b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValueTemplates.C @@ -384,22 +384,26 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues Field<Type> values(getFieldValues<Type>(fieldName, true)); // Write raw values on surface if specified - if (surfaceWriterPtr_.valid()) + if (surfaceWriterPtr_.valid() && surfaceWriterPtr_->enabled()) { Field<Type> allValues(values); combineFields(allValues); if (Pstream::master()) { - surfaceWriterPtr_->write + surfaceWriterPtr_->open ( - outputDir(), - regionTypeNames_[regionType_] + ("_" + regionName_), surfToWrite, - fieldName, - allValues, - false + ( + outputDir() + / regionTypeNames_[regionType_] + ("_" + regionName_) + ), + false // serial - already merged ); + + surfaceWriterPtr_->write(fieldName, allValues); + + surfaceWriterPtr_->clear(); } } diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C index 5c228621bd27827f2d340a0293118137c35b92bb..4c859a885fb10a75ef5800d309cb1d71f3f3991f 100644 --- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C +++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2017 OpenFOAM Foundation @@ -28,8 +28,8 @@ License #include "FacePostProcessing.H" #include "Pstream.H" #include "ListListOps.H" -#include "surfaceWriter.H" #include "globalIndex.H" +#include "surfaceWriter.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -194,35 +194,26 @@ void Foam::FacePostProcessing<CloudType>::write() ) ); - autoPtr<surfaceWriter> writer + auto writer = surfaceWriter::New ( - surfaceWriter::New - ( - surfaceFormat_, - this->coeffDict().subOrEmptyDict("formatOptions"). - subOrEmptyDict(surfaceFormat_) - ) + surfaceFormat_, + this->coeffDict().subOrEmptyDict("formatOptions") + .subOrEmptyDict(surfaceFormat_) ); - writer->write + writer->open ( - this->writeTimeDir(), - fZone.name(), - meshedSurfRef(allPoints, allFaces), - "massTotal", - zoneMassTotal[zoneI], - false + allPoints, + allFaces, + (this->writeTimeDir() / fZone.name()), + false // serial - already merged ); - writer->write - ( - this->writeTimeDir(), - fZone.name(), - meshedSurfRef(allPoints, allFaces), - "massFlowRate", - zoneMassFlowRate[zoneI], - false - ); + writer->write("massTotal", zoneMassTotal[zoneI]); + + writer->write("massFlowRate", zoneMassFlowRate[zoneI]); + + writer->clear(); } } } diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleCollector/ParticleCollector.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleCollector/ParticleCollector.C index 381c36077b9bd3fe2b2f94550f38cfff09f90bcf..6f0eaf15c583a16dfc8f26533d3f0c9d7556a96e 100644 --- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleCollector/ParticleCollector.C +++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleCollector/ParticleCollector.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2012-2017 OpenFOAM Foundation @@ -462,40 +462,26 @@ void Foam::ParticleCollector<CloudType>::write() << endl; - if (surfaceFormat_ != "none") + if (surfaceFormat_ != "none" && Pstream::master()) { - if (Pstream::master()) - { - autoPtr<surfaceWriter> writer - ( - surfaceWriter::New - ( - surfaceFormat_, - this->coeffDict().subOrEmptyDict("formatOptions"). - subOrEmptyDict(surfaceFormat_) - ) - ); + auto writer = surfaceWriter::New + ( + surfaceFormat_, + this->coeffDict().subOrEmptyDict("formatOptions") + .subOrEmptyDict(surfaceFormat_) + ); - writer->write - ( - this->writeTimeDir(), - "collector", - meshedSurfRef(points_, faces_), - "massTotal", - faceMassTotal, - false - ); + writer->open + ( + points_, + faces_, + (this->writeTimeDir() / "collector"), + false // serial - already merged + ); - writer->write - ( - this->writeTimeDir(), - "collector", - meshedSurfRef(points_, faces_), - "massFlowRate", - faceMassFlowRate, - false - ); - } + writer->write("massFlowRate", faceMassFlowRate); + + writer->write("massTotal", faceMassTotal); } diff --git a/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.C b/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.C index bf53217d1a19b6fdf33727067f204b5c913a481f..b97622dd4ae65c4500c81849cbfcb4686ba9bca8 100644 --- a/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.C +++ b/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -275,22 +275,19 @@ Foam::scalar surfaceNoise::writeSurfaceData } } - // Could also have meshedSurface implement meshedSurf if (writeSurface) { - fileName outFileName = writerPtr_->write + writerPtr_->open ( - outDir, - fName, - meshedSurfRef - ( - surf.points(), - surf.surfFaces() - ), - title, - allData, - false + surf.points(), + surf.surfFaces(), + (outDir / fName), + false // serial - already merged ); + + writerPtr_->write(title, allData); + + writerPtr_->clear(); } // TO BE VERIFIED: area-averaged values @@ -305,22 +302,19 @@ Foam::scalar surfaceNoise::writeSurfaceData { const meshedSurface& surf = readerPtr_->geometry(); - // Could also have meshedSurface implement meshedSurf if (writeSurface) { - writerPtr_->write + writerPtr_->open ( - outDir, - fName, - meshedSurfRef - ( - surf.points(), - surf.surfFaces() - ), - title, - data, - false + surf.points(), + surf.surfFaces(), + (outDir / fName), + false // serial - already merged ); + + writerPtr_->write(title, data); + + writerPtr_->clear(); } // TO BE VERIFIED: area-averaged values @@ -442,13 +436,12 @@ bool surfaceNoise::read(const dictionary& dict) const word writerType(dict.get<word>("writer")); - dictionary optDict + writerPtr_ = surfaceWriter::New ( + writerType, dict.subOrEmptyDict("writeOptions").subOrEmptyDict(writerType) ); - writerPtr_ = surfaceWriter::New(writerType, optDict); - return true; } diff --git a/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.H b/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.H index 55d4e6e3348a7dc2d35a0e6e66f27c9a9e2ed438..38073c5f2b4d65a15888f2d046a7859a4157fde8 100644 --- a/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.H +++ b/src/randomProcesses/noise/noiseModels/surfaceNoise/surfaceNoise.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -111,7 +111,7 @@ SeeAlso namespace Foam { -// Forward declaration of classes +// Forward declarations class surfaceReader; class surfaceWriter; diff --git a/src/sampling/Make/files b/src/sampling/Make/files index dbef3b398732dd14b0e76791bc91b60c81ca2d62..83403b64a29d4f3ff468c2dd4893bb7ea472f1f8 100644 --- a/src/sampling/Make/files +++ b/src/sampling/Make/files @@ -50,8 +50,8 @@ sampledSurface/distanceSurface/sampledDistanceSurface.C sampledSurface/sampledCuttingPlane/sampledCuttingPlane.C sampledSurface/sampledCuttingSurface/sampledCuttingSurface.C sampledSurface/sampledSurface/sampledSurface.C +sampledSurface/sampledSurface/sampledSurfaceRegister.C sampledSurface/sampledSurfaces/sampledSurfaces.C -sampledSurface/sampledSurfaces/sampledSurfacesGrouping.C sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMeshNormal.C sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.C @@ -59,24 +59,11 @@ sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.C /* Proof-of-concept: */ /* sampledSurface/triSurfaceMesh/sampledDiscreteSurface.C */ +readers = sampledSurface/readers -surfWriters = sampledSurface/writers - -$(surfWriters)/surfaceWriter.C -$(surfWriters)/ensight/ensightSurfaceWriter.C -$(surfWriters)/foam/foamSurfaceWriter.C -$(surfWriters)/nastran/nastranSurfaceWriter.C -$(surfWriters)/proxy/proxySurfaceWriter.C -$(surfWriters)/raw/rawSurfaceWriter.C -$(surfWriters)/starcd/starcdSurfaceWriter.C -$(surfWriters)/vtk/vtkSurfaceWriter.C -$(surfWriters)/boundaryData/boundaryDataSurfaceWriter.C - -surfReaders = sampledSurface/readers - -$(surfReaders)/surfaceReader.C -$(surfReaders)/surfaceReaderNew.C -$(surfReaders)/ensight/ensightSurfaceReader.C +$(readers)/surfaceReader.C +$(readers)/surfaceReaderNew.C +$(readers)/ensight/ensightSurfaceReader.C graphField/writePatchGraph.C graphField/writeCellGraph.C diff --git a/src/sampling/sampledSurface/sampledSurface/sampledSurface.C b/src/sampling/sampledSurface/sampledSurface/sampledSurface.C index d326e7e3cab5f9c4e6e85bd75a1ee12e5071c365..ebb5048e53a3ee5a6bb1f1cca183631085b69cf7 100644 --- a/src/sampling/sampledSurface/sampledSurface/sampledSurface.C +++ b/src/sampling/sampledSurface/sampledSurface/sampledSurface.C @@ -38,6 +38,17 @@ namespace Foam } +const Foam::wordList Foam::sampledSurface::surfaceFieldTypes +({ + "surfaceScalarField", + "surfaceVectorField", + "surfaceSphericalTensorField", + "surfaceSymmTensorField", + "surfaceTensorField" +}); + + + // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // void Foam::sampledSurface::clearGeom() const @@ -57,10 +68,8 @@ Foam::autoPtr<Foam::sampledSurface> Foam::sampledSurface::New { const word sampleType(dict.get<word>("type")); - if (debug) - { - Info<< "Selecting sampledType " << sampleType << endl; - } + DebugInfo + << "Selecting sampledType " << sampleType << endl; auto cstrIter = wordConstructorTablePtr_->cfind(sampleType); diff --git a/src/sampling/sampledSurface/sampledSurface/sampledSurface.H b/src/sampling/sampledSurface/sampledSurface/sampledSurface.H index bf279805db750e72cab41356afd338978e4f4f0c..ba6a84a15f3d811b6f0aefa78c2a2c41fbf7ec07 100644 --- a/src/sampling/sampledSurface/sampledSurface/sampledSurface.H +++ b/src/sampling/sampledSurface/sampledSurface/sampledSurface.H @@ -65,17 +65,15 @@ SourceFiles #ifndef sampledSurface_H #define sampledSurface_H -#include "meshedSurf.H" -#include "word.H" -#include "labelList.H" -#include "faceList.H" +#include "polySurface.H" +#include "surfMesh.H" #include "typeInfo.H" #include "runTimeSelectionTables.H" #include "autoPtr.H" +#include "polyMesh.H" #include "volFieldsFwd.H" #include "surfaceFieldsFwd.H" #include "surfaceMesh.H" -#include "polyMesh.H" #include "interpolation.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -84,18 +82,26 @@ namespace Foam { /*---------------------------------------------------------------------------*\ - Class sampledSurface Declaration + Class sampledSurface Declaration \*---------------------------------------------------------------------------*/ class sampledSurface : public meshedSurf { +public: + + // Public Static Data + + //- Class names for surface field types + static const wordList surfaceFieldTypes; + + private: // Private Data - //- Name of sample surface + //- The name of the sample surface word name_; //- Reference to mesh @@ -104,15 +110,13 @@ private: //- Should surface sampling be enabled? bool enabled_; - //- Do we intend to interpolate the information? - const bool interpolate_; + //- Interpolate information to the nodes? + bool interpolate_; //- Total surface area (demand-driven) mutable scalar area_; - - protected: // Protected Member Functions @@ -163,9 +167,7 @@ public: ); - // iNew helper class - - //- Class for PtrList read-construction + //- PtrList read-construction helper class iNew { //- Reference to the volume mesh @@ -188,6 +190,34 @@ public: }; + //- PtrList read-construction helper that captures dictionaries used + //- during creation. + class iNewCapture + { + //- Reference to the volume mesh + const polyMesh& mesh_; + + //- Captured (recorded) dictionaries + DynamicList<dictionary>& capture_; + + public: + + iNewCapture(const polyMesh& mesh, DynamicList<dictionary>& capture) + : + mesh_(mesh), + capture_(capture) + {} + + autoPtr<sampledSurface> operator()(Istream& is) const + { + word name(is); + capture_.append(dictionary(is)); + + return sampledSurface::New(name, mesh_, capture_.last()); + } + }; + + // Constructors //- Construct from name, mesh @@ -245,13 +275,13 @@ public: return name_; } - //- Sampling is enabled + //- Surface is enabled bool enabled() const { return enabled_; } - //- Interpolation requested for surface + //- interpolation to nodes requested for surface bool interpolate() const { return interpolate_; @@ -301,6 +331,99 @@ public: } + // General registry storage (optional) + + //- Get surface from registry if available. + // \param obr The objectRegistry to use + // \param lookupName Optional lookup name, use surface name if empty + // \return surface or nullptr + polySurface* getRegistrySurface + ( + const objectRegistry& obr, + word lookupName = "" + ) const; + + //- Copy surface into registry. + // \param obr The objectRegistry to use + // \param lookupName Optional lookup name, use surface name if empty + // \return surface or nullptr it surface should not be stored + polySurface* storeRegistrySurface + ( + objectRegistry& obr, + word lookupName = "" + ) const; + + //- Remove surface from registry. + // \param obr The objectRegistry to use + // \param lookupName Optional lookup name, use surface name if empty + // \return True if surface existed and was removed + bool removeRegistrySurface + ( + objectRegistry& obr, + word lookupName = "" + ) const; + + //- Copy/store sampled field onto registered surface (if it exists) + template<class Type, class GeoMeshType> + bool storeRegistryField + ( + const objectRegistry& obr, + const word& fieldName, + const dimensionSet& dims, + const Field<Type>& values, + word lookupName = "" + ) const; + + //- Move/store sampled field onto registered surface (if it exists) + template<class Type, class GeoMeshType> + bool storeRegistryField + ( + const objectRegistry& obr, + const word& fieldName, + const dimensionSet& dims, + Field<Type>&& values, + word lookupName = "" + ) const; + + + // Specialized surfMesh storage (optional) + + //- Get surface from registry if available. + // \param lookupName Optional lookup name, use surface name if empty + // \return surface or nullptr + surfMesh* getSurfMesh(word lookupName = "") const; + + //- Copy surface into registry. + // \param lookupName Optional lookup name, use surface name if empty + // \return surface or nullptr it surface should not be stored + surfMesh* storeSurfMesh(word lookupName = "") const; + + //- Remove surface from registry. + // \param lookupName Optional lookup name, use surface name if empty + // \return True if surface existed and was removed + bool removeSurfMesh(word lookupName = "") const; + + //- Copy/store sampled Face field onto surfMesh (if it exists) + template<class Type, class GeoMeshType> + bool storeSurfMeshField + ( + const word& fieldName, + const dimensionSet& dims, + const Field<Type>& values, + word lookupName = "" + ) const; + + //- Move/store sampled Face field onto surfMesh (if it exists) + template<class Type, class GeoMeshType> + bool storeSurfMeshField + ( + const word& fieldName, + const dimensionSet& dims, + Field<Type>&& values, + word lookupName = "" + ) const; + + // Sample (faces) //- Sample volume field onto surface faces diff --git a/src/sampling/sampledSurface/sampledSurface/sampledSurfaceRegister.C b/src/sampling/sampledSurface/sampledSurface/sampledSurfaceRegister.C index c7fa0297d0ca15073c737b0824086f8da78057e4..ab2438fc643336589e1b02ac0bf13128b8ead249 100644 --- a/src/sampling/sampledSurface/sampledSurface/sampledSurfaceRegister.C +++ b/src/sampling/sampledSurface/sampledSurface/sampledSurfaceRegister.C @@ -2,10 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2004-2010, 2018-2019 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011-2016 OpenFOAM Foundation ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,269 +24,114 @@ License \*---------------------------------------------------------------------------*/ #include "sampledSurface.H" -#include "polyMesh.H" +#include "fvMesh.H" +#include "MeshedSurface.H" #include "demandDrivenData.H" -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -namespace Foam -{ - defineTypeNameAndDebug(sampledSurface, 0); - defineRunTimeSelectionTable(sampledSurface, word); -} - - -const Foam::wordList Foam::sampledSurface::surfaceFieldTypes -({ - "surfaceScalarField", - "surfaceVectorField", - "surfaceSphericalTensorField", - "surfaceSymmTensorField", - "surfaceTensorField" -}); - - - -// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // - -void Foam::sampledSurface::clearGeom() const -{ - area_ = -1; -} - - -// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -Foam::autoPtr<Foam::sampledSurface> Foam::sampledSurface::New +Foam::polySurface* Foam::sampledSurface::getRegistrySurface ( - const word& name, - const polyMesh& mesh, - const dictionary& dict -) + const objectRegistry& obr, + word lookupName +) const { - const word sampleType(dict.get<word>("type")); - - if (debug) - { - Info<< "Selecting sampledType " << sampleType << endl; - } - - auto cstrIter = wordConstructorTablePtr_->cfind(sampleType); - - if (!cstrIter.found()) + if (lookupName.empty()) { - FatalErrorInFunction - << "Unknown sample type " - << sampleType << nl << nl - << "Valid sample types :" << endl - << wordConstructorTablePtr_->sortedToc() - << exit(FatalError); + lookupName = this->name(); } - return autoPtr<sampledSurface>(cstrIter()(name, mesh, dict)); + return obr.getObjectPtr<polySurface>(lookupName); } -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::sampledSurface::sampledSurface(const word& name, std::nullptr_t) -: - name_(name), - mesh_(NullObjectRef<polyMesh>()), - enabled_(true), - interpolate_(false), - area_(-1), - writerType_(), - formatOptions_() -{} - - -Foam::sampledSurface::sampledSurface -( - const word& name, - const polyMesh& mesh, - const bool interpolate -) -: - name_(name), - mesh_(mesh), - enabled_(true), - interpolate_(interpolate), - area_(-1), - writerType_(), - formatOptions_() -{} - - -Foam::sampledSurface::sampledSurface +Foam::polySurface* Foam::sampledSurface::storeRegistrySurface ( - const word& name, - const polyMesh& mesh, - const dictionary& dict -) -: - name_(dict.lookupOrDefault<word>("name", name)), - mesh_(mesh), - enabled_(dict.lookupOrDefault("enabled", true)), - interpolate_(dict.lookupOrDefault("interpolate", false)), - area_(-1), - writerType_(dict.lookupOrDefault<word>("surfaceFormat", "")), - formatOptions_(dict.subOrEmptyDict("formatOptions")) -{} - - -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // - -Foam::sampledSurface::~sampledSurface() -{ - clearGeom(); -} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -Foam::scalar Foam::sampledSurface::area() const + objectRegistry& obr, + word lookupName +) const { - if (area_ < 0) + if (lookupName.empty()) { - area_ = gSum(magSf()); + lookupName = this->name(); } - return area_; -} - - -bool Foam::sampledSurface::withSurfaceFields() const -{ - return false; -} - - -Foam::tmp<Foam::scalarField> Foam::sampledSurface::sample -( - const surfaceScalarField& sField -) const -{ - NotImplemented; - return nullptr; -} - - -Foam::tmp<Foam::vectorField> Foam::sampledSurface::sample -( - const surfaceVectorField& sField -) const -{ - NotImplemented; - return nullptr; -} - + polySurface* surfptr = getRegistrySurface(obr, lookupName); -Foam::tmp<Foam::sphericalTensorField> Foam::sampledSurface::sample -( - const surfaceSphericalTensorField& sField -) const -{ - NotImplemented; - return nullptr; -} + if (!surfptr) + { + // Construct null and add to registry (owned by registry) + surfptr = new polySurface(lookupName, obr, true); + } + surfptr->copySurface(*this); // Copy in geometry (removes old fields) -Foam::tmp<Foam::symmTensorField> Foam::sampledSurface::sample -( - const surfaceSymmTensorField& sField -) const -{ - NotImplemented; - return nullptr; + return surfptr; } -Foam::tmp<Foam::tensorField> Foam::sampledSurface::sample +bool Foam::sampledSurface::removeRegistrySurface ( - const surfaceTensorField& sField + objectRegistry& obr, + word lookupName ) const { - NotImplemented; - return nullptr; -} + polySurface* surfptr = getRegistrySurface(obr, lookupName); + if (surfptr) + { + return obr.checkOut(*surfptr); + } -void Foam::sampledSurface::print(Ostream& os) const -{ - os << type(); + return false; } -Foam::polySurface* Foam::sampledSurface::getRegistrySurface -( - const objectRegistry& obr, - word lookupName -) const +Foam::surfMesh* Foam::sampledSurface::getSurfMesh(word lookupName) const { if (lookupName.empty()) { lookupName = this->name(); } - return obr.getObjectPtr<polySurface>(lookupName); + return mesh().getObjectPtr<surfMesh>(lookupName); } -Foam::polySurface* Foam::sampledSurface::storeRegistrySurface -( - objectRegistry& obr, - word lookupName -) const +Foam::surfMesh* Foam::sampledSurface::storeSurfMesh(word lookupName) const { if (lookupName.empty()) { lookupName = this->name(); } - polySurface* surfptr = getRegistrySurface(obr, lookupName); + surfMesh* surfptr = getSurfMesh(); if (!surfptr) { - surfptr = new polySurface - ( - lookupName, - obr, - true // Add to registry - owned by registry - ); + // Construct null and add owned by registry + surfptr = new surfMesh(lookupName, mesh()); + + surfptr->store(); // Add to registry - owned by registry } - surfptr->deepCopy(*this); // Copy in geometry (removes old fields) + surfptr->copySurface(*this); // Copy in geometry (removes old fields) return surfptr; } -bool Foam::sampledSurface::removeRegistrySurface -( - objectRegistry& obr, - word lookupName -) const +bool Foam::sampledSurface::removeSurfMesh(word lookupName) const { - polySurface* surfptr = getRegistrySurface(obr, lookupName); + surfMesh* surfptr = getSurfMesh(lookupName); if (surfptr) { - return obr.checkOut(*surfptr); + return mesh().checkOut(*surfptr); } return false; } -// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // - -Foam::Ostream& Foam::operator<<(Ostream& os, const sampledSurface& s) -{ - s.print(os); - os.check(FUNCTION_NAME); - return os; -} - - // ************************************************************************* // diff --git a/src/sampling/sampledSurface/sampledSurface/sampledSurfaceTemplates.C b/src/sampling/sampledSurface/sampledSurface/sampledSurfaceTemplates.C index 31794db89817464bf332593ba13c36759dc943ad..3d07a7a2ae30ece9a053b488d57327fd20852ecb 100644 --- a/src/sampling/sampledSurface/sampledSurface/sampledSurfaceTemplates.C +++ b/src/sampling/sampledSurface/sampledSurface/sampledSurfaceTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2016 OpenFOAM Foundation @@ -116,4 +116,100 @@ Foam::sampledSurface::pointAverage } +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class Type, class GeoMeshType> +bool Foam::sampledSurface::storeRegistryField +( + const objectRegistry& obr, + const word& fieldName, + const dimensionSet& dims, + const Field<Type>& values, + word lookupName +) const +{ + polySurface* surfptr = this->getRegistrySurface(obr, lookupName); + + if (surfptr) + { + surfptr->storeField<Type, GeoMeshType> + ( + fieldName, dims, values + ); + } + + return surfptr; +} + + +template<class Type, class GeoMeshType> +bool Foam::sampledSurface::storeRegistryField +( + const objectRegistry& obr, + const word& fieldName, + const dimensionSet& dims, + Field<Type>&& values, + word lookupName +) const +{ + polySurface* surfptr = this->getRegistrySurface(obr, lookupName); + + if (surfptr) + { + surfptr->storeField<Type, GeoMeshType> + ( + fieldName, dims, std::move(values) + ); + } + + return surfptr; +} + + +template<class Type, class GeoMeshType> +bool Foam::sampledSurface::storeSurfMeshField +( + const word& fieldName, + const dimensionSet& dims, + const Field<Type>& values, + word lookupName +) const +{ + surfMesh* surfptr = this->getSurfMesh(lookupName); + + if (surfptr) + { + surfptr->storeField<Type, GeoMeshType> + ( + fieldName, dims, values + ); + } + + return surfptr; +} + + +template<class Type, class GeoMeshType> +bool Foam::sampledSurface::storeSurfMeshField +( + const word& fieldName, + const dimensionSet& dims, + Field<Type>&& values, + word lookupName +) const +{ + surfMesh* surfptr = this->getSurfMesh(lookupName); + + if (surfptr) + { + surfptr->storeField<Type, GeoMeshType> + ( + fieldName, dims, std::move(values) + ); + } + + return surfptr; +} + + // ************************************************************************* // diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C index c72f0ce2eca7bfef5d4f997ea7012d48c7162973..5256a377ef2de7a03f7a39c69525a7450d01112c 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C @@ -26,15 +26,15 @@ License \*---------------------------------------------------------------------------*/ #include "sampledSurfaces.H" +#include "polySurface.H" + +#include "mapPolyMesh.H" +#include "stringListOps.H" #include "volFields.H" -#include "dictionary.H" +#include "HashOps.H" +#include "PstreamCombineReduceOps.H" #include "Time.H" -#include "IOmanip.H" -#include "interpolationCell.H" -#include "volPointInterpolation.H" -#include "PatchTools.H" -#include "mapPolyMesh.H" -#include "sampledTriSurfaceMesh.H" +#include "UIndirectList.H" #include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -51,69 +51,157 @@ namespace Foam ); } -bool Foam::sampledSurfaces::verbose_ = false; Foam::scalar Foam::sampledSurfaces::mergeTol_ = 1e-10; // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -void Foam::sampledSurfaces::writeGeometry() const +Foam::polySurface* Foam::sampledSurfaces::getRegistrySurface +( + const sampledSurface& s +) const { - // Write to time directory under outputPath_ - // Skip surfaces without faces (eg, a failed cut-plane) + return s.getRegistrySurface + ( + storedObjects(), + IOobject::groupName(name(), s.name()) + ); +} - const fileName outputDir = outputPath_/time_.timeName(); - forAll(*this, surfi) +Foam::polySurface* Foam::sampledSurfaces::storeRegistrySurface +( + const sampledSurface& s +) +{ + return s.storeRegistrySurface + ( + storedObjects(), + IOobject::groupName(name(), s.name()) + ); +} + + +bool Foam::sampledSurfaces::removeRegistrySurface +( + const sampledSurface& s +) +{ + return s.removeRegistrySurface + ( + storedObjects(), + IOobject::groupName(name(), s.name()) + ); +} + + +void Foam::sampledSurfaces::countFields() +{ + wordList allFields; // Just needed for warnings + HashTable<wordHashSet> selected; + + if (loadFromFiles_) { - const sampledSurface& s = operator[](surfi); + // Check files for a particular time + IOobjectList objects(obr_, obr_.time().timeName()); - if (Pstream::parRun()) - { - if (Pstream::master() && mergedList_[surfi].size()) - { - formatter_->write - ( - outputDir, - s.name(), - mergedList_[surfi] - ); - } - } - else if (s.faces().size()) + allFields = objects.names(); + selected = objects.classes(fieldSelection_); + } + else + { + // Check currently available fields + allFields = obr_.names(); + selected = obr_.classes(fieldSelection_); + } + + if (Pstream::parRun()) + { + Pstream::mapCombineGather(selected, HashSetOps::plusEqOp<word>()); + Pstream::mapCombineScatter(selected); + } + + + DynamicList<label> missed(fieldSelection_.size()); + + // Detect missing fields + forAll(fieldSelection_, i) + { + if (findStrings(fieldSelection_[i], allFields).empty()) { - formatter_->write(outputDir, s.name(), s); + missed.append(i); } } -} + if (missed.size()) + { + WarningInFunction + << nl + << "Cannot find " + << (loadFromFiles_ ? "field file" : "registered field") + << " matching " + << UIndirectList<wordRe>(fieldSelection_, missed) << endl; + } -void Foam::sampledSurfaces::writeOriginalIds() -{ - const word fieldName = "Ids"; - const fileName outputDir = outputPath_/time_.timeName(); - forAll(*this, surfi) + // Currently only support volume and surface field types + label nVolumeFields = 0; + label nSurfaceFields = 0; + + forAllConstIters(selected, iter) { - const sampledSurface& s = operator[](surfi); + const word& clsName = iter.key(); + const label n = iter.val().size(); - if (s.hasFaceIds()) + if (fieldTypes::volume.found(clsName)) + { + nVolumeFields += n; + } + else if (sampledSurface::surfaceFieldTypes.found(clsName)) { - const labelList& idLst = s.originalIds(); + nSurfaceFields += n; + } + } - // Transcribe from label to scalar - Field<scalar> ids(idLst.size()); - forAll(idLst, i) - { - ids[i] = idLst[i]; - } + // Now propagate field counts (per surface) - writeSurface(ids, surfi, fieldName, outputDir); - } + label surfi = 0; + + for (const sampledSurface& s : surfaces()) + { + writers_[surfi].nFields() = + ( + nVolumeFields + + (s.withSurfaceFields() ? nSurfaceFields : 0) + + ((s.hasFaceIds() && !s.interpolate()) ? 1 : 0) + ); + + ++surfi; } } +Foam::autoPtr<Foam::surfaceWriter> Foam::sampledSurfaces::newWriter +( + word writeType, + const dictionary& formatOptions, + const dictionary& surfDict +) +{ + // Per-surface adjustment + surfDict.readIfPresent<word>("surfaceFormat", writeType); + + dictionary options = formatOptions.subOrEmptyDict(writeType); + + options.merge + ( + surfDict.subOrEmptyDict("formatOptions").subOrEmptyDict(writeType) + ); + + return surfaceWriter::New(writeType, options); +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::sampledSurfaces::sampledSurfaces @@ -126,6 +214,8 @@ Foam::sampledSurfaces::sampledSurfaces functionObjects::fvMeshFunctionObject(name, runTime, dict), PtrList<sampledSurface>(), loadFromFiles_(false), + verbose_(false), + onExecute_(false), outputPath_ ( time_.globalPath()/functionObject::outputPrefix/name @@ -133,9 +223,9 @@ Foam::sampledSurfaces::sampledSurfaces fieldSelection_(), sampleFaceScheme_(), sampleNodeScheme_(), - mergedList_(), - changedGeom_(), - formatter_(nullptr) + writers_(), + actions_(), + nFaces_() { outputPath_.clean(); // Remove unneeded ".." @@ -154,6 +244,8 @@ Foam::sampledSurfaces::sampledSurfaces functionObjects::fvMeshFunctionObject(name, obr, dict), PtrList<sampledSurface>(), loadFromFiles_(loadFromFiles), + verbose_(false), + onExecute_(false), outputPath_ ( time_.globalPath()/functionObject::outputPrefix/name @@ -161,9 +253,9 @@ Foam::sampledSurfaces::sampledSurfaces fieldSelection_(), sampleFaceScheme_(), sampleNodeScheme_(), - mergedList_(), - changedGeom_(), - formatter_(nullptr) + writers_(), + actions_(), + nFaces_() { outputPath_.clean(); // Remove unneeded ".." @@ -179,60 +271,19 @@ void Foam::sampledSurfaces::verbose(const bool verbosity) } -bool Foam::sampledSurfaces::execute() -{ - return true; -} - - -bool Foam::sampledSurfaces::write() -{ - if (empty()) - { - return true; - } - - - // Finalize surfaces, merge points etc. - update(); - - const label nFields = classifyFields(); - - // Write geometry first if required, - // or when no fields would otherwise be written - if (formatter_->separateGeometry() || !nFields) - { - writeGeometry(); - changedGeom_ = false; - } - - const IOobjectList objects(obr_, obr_.time().timeName()); - - sampleAndWrite<volScalarField>(objects); - sampleAndWrite<volVectorField>(objects); - sampleAndWrite<volSphericalTensorField>(objects); - sampleAndWrite<volSymmTensorField>(objects); - sampleAndWrite<volTensorField>(objects); - - sampleAndWrite<surfaceScalarField>(objects); - sampleAndWrite<surfaceVectorField>(objects); - sampleAndWrite<surfaceSphericalTensorField>(objects); - sampleAndWrite<surfaceSymmTensorField>(objects); - sampleAndWrite<surfaceTensorField>(objects); - - return true; -} - - bool Foam::sampledSurfaces::read(const dictionary& dict) { fvMeshFunctionObject::read(dict); PtrList<sampledSurface>::clear(); - mergedList_.clear(); - changedGeom_.clear(); + writers_.clear(); + actions_.clear(); + nFaces_.clear(); fieldSelection_.clear(); + verbose_ = dict.lookupOrDefault("verbose", false); + onExecute_ = dict.lookupOrDefault("sampleOnExecute", false); + sampleFaceScheme_ = dict.lookupOrDefault<word>("sampleScheme", "cell"); @@ -241,82 +292,160 @@ bool Foam::sampledSurfaces::read(const dictionary& dict) const entry* eptr = dict.findEntry("surfaces"); + // Surface writer type and format options + const word writerType = + (eptr ? dict.get<word>("surfaceFormat") : word::null); + + const dictionary formatOptions(dict.subOrEmptyDict("formatOptions")); + + // Store on registry? + const bool dfltStore = dict.lookupOrDefault("store", false); + if (eptr && eptr->isDict()) { PtrList<sampledSurface> surfs(eptr->dict().size()); + actions_.resize(surfs.size(), ACTION_WRITE); // Default action + writers_.resize(surfs.size()); + nFaces_.resize(surfs.size(), Zero); + label surfi = 0; for (const entry& dEntry : eptr->dict()) { - if (dEntry.isDict()) + if (!dEntry.isDict()) + { + continue; + } + + const dictionary& surfDict = dEntry.dict(); + + autoPtr<sampledSurface> surf = + sampledSurface::New + ( + dEntry.keyword(), + mesh_, + surfDict + ); + + if (!surf.valid() || !surf->enabled()) { - autoPtr<sampledSurface> surf = - sampledSurface::New - ( - dEntry.keyword(), - mesh_, - dEntry.dict() - ); - - if (surf.valid() && surf->enabled()) - { - surfs.set(surfi, surf); - ++surfi; - } + continue; } + + // Define the surface + surfs.set(surfi, surf); + + // Define additional action(s) + if (surfDict.lookupOrDefault("store", dfltStore)) + { + actions_[surfi] |= ACTION_STORE; + } + if (surfDict.lookupOrDefault("surfMeshStore", false)) + { + actions_[surfi] |= ACTION_SURF_MESH; + } + + // Define surface writer, but do NOT yet attach a surface + writers_.set + ( + surfi, + newWriter(writerType, formatOptions, surfDict) + ); + + writers_[surfi].isPointData() = surfs[surfi].interpolate(); + + // Use outputDir/TIME/surface-name + writers_[surfi].useTimeDir() = true; + writers_[surfi].verbose() = verbose_; + + ++surfi; } surfs.resize(surfi); + actions_.resize(surfi); + writers_.resize(surfi); surfaces().transfer(surfs); } else if (eptr) { - PtrList<sampledSurface> surfs + // This is slightly trickier. + // We want access to the individual dictionaries used for construction + + DynamicList<dictionary> capture; + + PtrList<sampledSurface> input ( eptr->stream(), - sampledSurface::iNew(mesh_) + sampledSurface::iNewCapture(mesh_, capture) ); - forAll(surfs, surfi) + PtrList<sampledSurface> surfs(input.size()); + + actions_.resize(surfs.size(), ACTION_WRITE); // Default action + writers_.resize(surfs.size()); + nFaces_.resize(surfs.size(), Zero); + + label surfi = 0; + + forAll(input, inputi) { - if (!surfs[surfi].enabled()) + const dictionary& surfDict = capture[inputi]; + + autoPtr<sampledSurface> surf = input.set(inputi, nullptr); + + if (!surf.valid() || !surf->enabled()) { - surfs.set(surfi, nullptr); + continue; } - } - surfs.resize(surfs.squeezeNull()); + // Define the surface + surfs.set(surfi, surf); + // Define additional action(s) + if (surfDict.lookupOrDefault("store", dfltStore)) + { + actions_[surfi] |= ACTION_STORE; + } + if (surfDict.lookupOrDefault("surfMeshStore", false)) + { + actions_[surfi] |= ACTION_SURF_MESH; + } + + // Define surface writer, but do NOT yet attach a surface + writers_.set + ( + surfi, + newWriter(writerType, formatOptions, surfDict) + ); + + writers_[surfi].isPointData() = surfs[surfi].interpolate(); + + // Use outputDir/TIME/surface-name + writers_[surfi].useTimeDir() = true; + writers_[surfi].verbose() = verbose_; + + ++surfi; + } + + surfs.resize(surfi); + actions_.resize(surfi); + writers_.resize(surfi); surfaces().transfer(surfs); } const auto& surfs = surfaces(); + + // Have some surfaces, so sort out which fields are needed and report + if (surfs.size()) { + nFaces_.resize(surfs.size(), Zero); + dict.readEntry("fields", fieldSelection_); fieldSelection_.uniq(); - // The surface writer and format options - const word writerType(dict.get<word>("surfaceFormat")); - - // Define the surface formatter - // Optionally defined extra controls for the output formats - formatter_ = surfaceWriter::New - ( - writerType, - dict.subOrEmptyDict("formatOptions").subOrEmptyDict(writerType) - ); - - if (Pstream::parRun()) - { - mergedList_.resize(size()); - } - - // Ensure all surfaces and merge information are expired - expire(); - label surfi = 0; for (const sampledSurface& s : surfs) { @@ -324,7 +453,18 @@ bool Foam::sampledSurfaces::read(const dictionary& dict) { Info<< "Sampled surface:" << nl; } - Info<< " " << s.name() << " -> " << writerType << nl; + + Info<< " " << s.name() << " -> " << writers_[surfi].type(); + if (actions_[surfi] & ACTION_STORE) + { + Info<< ", store on registry (" + << IOobject::groupName(name(), s.name()) << ')'; + } + if (actions_[surfi] & ACTION_SURF_MESH) + { + Info<< ", store as surfMesh (deprecated)"; + } + Info<< nl; ++surfi; } @@ -334,24 +474,171 @@ bool Foam::sampledSurfaces::read(const dictionary& dict) if (debug && Pstream::master()) { Pout<< "sample fields:" << fieldSelection_ << nl - << "sample surfaces:" << nl << "(" << nl; + << "sample surfaces:" << nl << '(' << nl; for (const sampledSurface& s : surfaces()) { Pout<< " " << s << nl; } + Pout<< ')' << endl; + } - Pout<< ")" << endl; + // Ensure all surfaces and merge information are expired + expire(); + + return true; +} + + +bool Foam::sampledSurfaces::performAction(unsigned request) +{ + if + ( + empty() + || (request == ACTION_NONE) + || !testAny + ( + actions_, + [=] (unsigned action) { return (request & action); } + ) + ) + { + return true; } - // New geometry - changedGeom_.resize(size()); - changedGeom_ = true; + + // Finalize surfaces, update information, writer associations etc. + update(); + + bool noFaces = true; + for (const label n : nFaces_) + { + if (n) noFaces = false; + } + + if (noFaces) + { + // No surfaces with faces at all. + return true; + } + + // Determine the per-surface number of fields, including Ids etc. + // Only seems to be needed for VTK legacy + countFields(); + + + forAll(*this, surfi) + { + const sampledSurface& s = (*this)[surfi]; + + if (!nFaces_[surfi]) + { + continue; + } + + if ((request & actions_[surfi]) & ACTION_STORE) + { + storeRegistrySurface(s); + } + + if ((request & actions_[surfi]) & ACTION_SURF_MESH) + { + s.storeSurfMesh(); + } + + if ((request & actions_[surfi]) & ACTION_WRITE) + { + // Output writers + surfaceWriter& outWriter = writers_[surfi]; + + if (outWriter.needsUpdate()) + { + outWriter.setSurface(s); + } + + outWriter.open(outputPath_/s.name()); + + outWriter.beginTime(obr_.time()); + + + // Write geometry if no fields would otherwise be written + if (!outWriter.nFields() || outWriter.separateGeometry()) + { + outWriter.writeGeometry(); + continue; + } + + // Write original ids - as label or scalar field + + const word fieldName("Ids"); + if (s.hasFaceIds() && !s.interpolate()) + { + writeSurface + ( + outWriter, + Field<label>(s.originalIds()), + fieldName + ); + } + } + } + + const IOobjectList objects(obr_, obr_.time().timeName()); + + performAction<volScalarField>(objects, request); + performAction<volVectorField>(objects, request); + performAction<volSphericalTensorField>(objects, request); + performAction<volSymmTensorField>(objects, request); + performAction<volTensorField>(objects, request); + + // Only bother with surface fields if a sampler supports them + if + ( + testAny + ( + surfaces(), + [] (const sampledSurface& s) { return s.withSurfaceFields(); } + ) + ) + { + performAction<surfaceScalarField>(objects, request); + performAction<surfaceVectorField>(objects, request); + performAction<surfaceSphericalTensorField>(objects, request); + performAction<surfaceSymmTensorField>(objects, request); + performAction<surfaceTensorField>(objects, request); + } + + + // Finish this time step + forAll(writers_, surfi) + { + if ((request & actions_[surfi]) & ACTION_WRITE) + { + writers_[surfi].endTime(); + } + } + + return true; +} + + +bool Foam::sampledSurfaces::execute() +{ + if (onExecute_) + { + return performAction(ACTION_ALL & ~ACTION_WRITE); + } return true; } +bool Foam::sampledSurfaces::write() +{ + return performAction(ACTION_ALL); +} + + void Foam::sampledSurfaces::updateMesh(const mapPolyMesh& mpm) { if (&mpm.mesh() == &mesh_) @@ -383,9 +670,9 @@ void Foam::sampledSurfaces::readUpdate(const polyMesh::readUpdateState state) bool Foam::sampledSurfaces::needsUpdate() const { - forAll(*this, surfi) + for (const sampledSurface& s : surfaces()) { - if (operator[](surfi).needsUpdate()) + if (s.needsUpdate()) { return true; } @@ -397,26 +684,29 @@ bool Foam::sampledSurfaces::needsUpdate() const bool Foam::sampledSurfaces::expire() { - bool justExpired = false; + // Dimension as fraction of mesh bounding box + const scalar mergeDim = mergeTol_ * mesh_.bounds().mag(); - forAll(*this, surfi) + label nChanged = 0; + + label surfi = 0; + + for (sampledSurface& s : surfaces()) { - if (operator[](surfi).expire()) + if (s.expire()) { - justExpired = true; + ++nChanged; } - // Clear merge information - if (Pstream::parRun()) - { - mergedList_[surfi].clear(); - } - } + writers_[surfi].expire(); + writers_[surfi].mergeDim() = mergeDim; + nFaces_[surfi] = 0; - changedGeom_ = true; + ++surfi; + } - // true if any surfaces just expired - return justExpired; + // True if any surfaces just expired + return nChanged; } @@ -427,48 +717,24 @@ bool Foam::sampledSurfaces::update() return false; } - bool updated = false; + label nUpdated = 0; - // Serial: quick and easy, no merging required - if (!Pstream::parRun()) - { - forAll(*this, surfi) - { - sampledSurface& s = operator[](surfi); + label surfi = 0; - if (s.update()) - { - updated = true; - changedGeom_[surfi] = true; - } - } - - return updated; - } - - - // Dimension as fraction of mesh bounding box - const scalar mergeDim = mergeTol_*mesh_.bounds().mag(); - - if (Pstream::master() && debug) - { - Pout<< nl << "Merging all points within " - << mergeDim << " metre" << endl; - } - - forAll(*this, surfi) + for (sampledSurface& s : surfaces()) { - sampledSurface& s = operator[](surfi); - if (s.update()) { - updated = true; - changedGeom_[surfi] = true; - mergedList_[surfi].merge(s, mergeDim); + ++nUpdated; + writers_[surfi].expire(); } + + nFaces_[surfi] = returnReduce(s.faces().size(), sumOp<label>()); + + ++surfi; } - return updated; + return nUpdated; } diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H index 902b55c2c956d3e2aed8f148b223d9a8f39161de..49498f458cfad3147eac47828ea9eec255e1a917 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H @@ -53,8 +53,12 @@ Description // (only used if interpolate=true for the surfaces below) interpolationScheme cell; + // Optional: registry storage + store true + // Output surface format surfaceFormat vtk; + formatOptions { vtk @@ -76,6 +80,12 @@ Description // Optional: generate values on points instead of faces interpolate true; + + // Optional: alternative output type + surfaceFormat ensight; + + // Optional: registry storage + store true } ); } @@ -84,13 +94,24 @@ Description Entries: \table Property | Description | Required | Default - type | surfaces | yes | - surfaces | list or dictionary of sample surfaces | recommended | - fields | word/regex list of fields to sampled | yes | + type | Type-name: surfaces | yes | + surfaces | Dictionary or list of sample surfaces | expected | + fields | word/regex list of fields to sample | yes | sampleScheme | scheme to obtain face centre value | no | cell interpolationScheme | scheme to obtain node values | no | cellPoint surfaceFormat | output surface format | yes | formatOptions | dictionary of format options | no | + sampleOnExecute | Sample (store) on execution as well | no | false + store | Store surface/fields on registry | no | false + \endtable + + Additional per-surface entries: + \table + Property | Description | Required | Default + store | Store surface/fields on registry | no | + surfaceFormat | output surface format | no | + formatOptions | dictionary of format options | no | + surfMeshStore | Store surface/fields as surfMesh (transitional) | no | \endtable Note @@ -111,10 +132,8 @@ SourceFiles #include "fvMeshFunctionObject.H" #include "sampledSurface.H" #include "surfaceWriter.H" -#include "mergedSurf.H" #include "volFieldsFwd.H" #include "surfaceFieldsFwd.H" -#include "wordRes.H" #include "IOobjectList.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -122,6 +141,9 @@ SourceFiles namespace Foam { +// Forward Declarations +class polySurface; + /*---------------------------------------------------------------------------*\ Class sampledSurfaces Declaration \*---------------------------------------------------------------------------*/ @@ -133,23 +155,36 @@ class sampledSurfaces { // Static Data Members - //- Output verbosity - static bool verbose_; - //- Tolerance for merging points (fraction of mesh bounding box) static scalar mergeTol_; + //- Local control for sampling actions + enum sampleActionType : unsigned + { + ACTION_NONE = 0, + ACTION_WRITE = 0x1, + ACTION_STORE = 0x2, + ACTION_SURF_MESH = 0x4, + ACTION_ALL = 0xF + }; + // Private Data //- Load fields from files (not from objectRegistry) const bool loadFromFiles_; + //- Output verbosity + bool verbose_; + + //- Perform sample/store actions on execute as well + bool onExecute_; + //- Output path fileName outputPath_; - // Read from dictonary + // Read from dictionary //- Names of fields to sample wordRes fieldSelection_; @@ -161,19 +196,16 @@ class sampledSurfaces word sampleNodeScheme_; - // Surfaces - - //- Merged meshed surfaces (parallel only) - List<mergedSurf> mergedList_; + // Output control - //- Track which surfaces have changed - List<bool> changedGeom_; + //- Surface writers (one per surface) + PtrList<surfaceWriter> writers_; + //- Per-surface selection of store/write actions + List<unsigned> actions_; - // Calculated - - //- Surface formatter - autoPtr<surfaceWriter> formatter_; + //- Cached values of the global number of faces per-surface + labelList nFaces_; // Private Member Functions @@ -190,42 +222,82 @@ class sampledSurfaces return *this; } - //- Return number of fields - label classifyFields(); + //- A new surfaceWriter, with per-surface formatOptions + static autoPtr<surfaceWriter> newWriter + ( + word writeType, + const dictionary& formatOptions, + const dictionary& surfDict + ); - //- Write geometry only - void writeGeometry() const; - //- Write scalar field with original ids - void writeOriginalIds(); + //- Perform sampling action with store/write + bool performAction(unsigned request); + + //- Count selected/sampled fields per surface + void countFields(); //- Write sampled fieldName on surface and on outputDir path template<class Type> void writeSurface ( + surfaceWriter& writer, const Field<Type>& values, - const label surfi, - const word& fieldName, - const fileName& outputDir + const word& fieldName ); - //- Sample and write a particular volume field + //- Sample and store/write a specific volume field template<class Type> - void sampleAndWrite + void performAction ( - const GeometricField<Type, fvPatchField, volMesh>& vField + const GeometricField<Type, fvPatchField, volMesh>& fld, + unsigned request ); - //- Sample and write a particular surface field + //- Sample and store/write a specific surface field template<class Type> - void sampleAndWrite + void performAction ( - const GeometricField<Type, fvsPatchField, surfaceMesh>& sField + const GeometricField<Type, fvsPatchField, surfaceMesh>& fld, + unsigned request + ); + + //- Sample and write all applicable sampled fields + template<class GeoField> + void performAction + ( + const IOobjectList& objects, + unsigned request + ); + + + //- Get surface from registry if available. + // \return surface or nullptr + polySurface* getRegistrySurface(const sampledSurface& s) const; + + //- Put surface onto registry, when enabled. + // \return surface or nullptr it surface should not be stored + polySurface* storeRegistrySurface(const sampledSurface& s); + + //- Remove surface from registry. + // \return True if surface existed and was removed + bool removeRegistrySurface(const sampledSurface& s); + + + //- Store sampled field onto surface registry if it exists + template<class Type, class GeoMeshType> + bool storeRegistryField + ( + const sampledSurface& s, + const word& fieldName, + const dimensionSet& dims, + Field<Type>&& values ); - //- Sample and write all sampled fields - template<class Type> void sampleAndWrite(const IOobjectList& objects); + //- Test surfaces for condition + template<class Container, class Predicate> + static bool testAny(const Container& items, const Predicate& pred); //- No copy construct sampledSurfaces(const sampledSurfaces&) = delete; diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesGrouping.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesGrouping.C deleted file mode 100644 index b36710e3dccca392c7c345e4ea769a0414e45a4c..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesGrouping.C +++ /dev/null @@ -1,89 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011-2015 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "sampledSurfaces.H" -#include "IOobjectList.H" -#include "UIndirectList.H" -#include "ListOps.H" - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -Foam::label Foam::sampledSurfaces::classifyFields() -{ - label nFields = 0; - - wordList allFields; // Just needed for warnings - HashTable<wordHashSet> available; - - if (loadFromFiles_) - { - // Check files for a particular time - IOobjectList objects(obr_, obr_.time().timeName()); - - allFields = objects.names(); - available = objects.classes(fieldSelection_); - } - else - { - // Check currently available fields - allFields = obr_.names(); - available = obr_.classes(fieldSelection_); - } - - DynamicList<label> missed(fieldSelection_.size()); - - // Detect missing fields - forAll(fieldSelection_, i) - { - if (!ListOps::found(allFields, fieldSelection_[i])) - { - missed.append(i); - } - } - - if (missed.size()) - { - WarningInFunction - << nl - << "Cannot find " - << (loadFromFiles_ ? "field file" : "registered field") - << " matching " - << UIndirectList<wordRe>(fieldSelection_, missed) << endl; - } - - - // Total number selected - forAllConstIters(available, iter) - { - nFields += iter.val().size(); - } - - return nFields; -} - - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C index 150a0b6dc0bfaba0be406531bafdc60d404856b1..48ff4a204504e4fbdba120d200ca384f439fd988 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C @@ -28,110 +28,61 @@ License #include "sampledSurfaces.H" #include "volFields.H" #include "surfaceFields.H" -#include "globalIndex.H" -#include "stringListOps.H" +#include "polySurface.H" +#include "polySurfaceFields.H" +#include "polySurfacePointFields.H" +#include "surfMesh.H" +#include "surfGeoMesh.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template<class Type> void Foam::sampledSurfaces::writeSurface ( + surfaceWriter& writer, const Field<Type>& values, - const label surfi, - const word& fieldName, - const fileName& outputDir + const word& fieldName ) { - const sampledSurface& s = operator[](surfi); - - if (changedGeom_[surfi]) - { - // Trigger any changes - formatter_->updateMesh(outputDir, s.name()); - changedGeom_[surfi] = false; - } - - if (Pstream::parRun()) - { - // Gather all values into single field - Field<Type> allValues; + fileName outputName = writer.write(fieldName, values); - globalIndex::gatherOp(values, allValues); + // Case-local file name with "<case>" to make relocatable - fileName sampleFile; - if (Pstream::master()) - { - // Renumber (point data) to correspond to merged points - if (mergedList_[surfi].pointsMap().size() == allValues.size()) - { - inplaceReorder(mergedList_[surfi].pointsMap(), allValues); - allValues.resize(mergedList_[surfi].points().size()); - } - - // Write to time directory under outputPath_ - // skip surface without faces (eg, a failed cut-plane) - if (mergedList_[surfi].size()) - { - sampleFile = formatter_->write - ( - outputDir, - s.name(), - mergedList_[surfi], - fieldName, - allValues, - s.interpolate() - ); - } - } - - Pstream::scatter(sampleFile); - if (sampleFile.size()) - { - // Case-local file name with "<case>" to make relocatable - - dictionary propsDict; - propsDict.add - ( - "file", - time_.relativePath(sampleFile, true) - ); - setProperty(fieldName, propsDict); - } - } - else - { - // Write to time directory under outputPath_ - // skip surface without faces (eg, a failed cut-plane) - if (s.faces().size()) - { - fileName fName = formatter_->write - ( - outputDir, - s.name(), - s, - fieldName, - values, - s.interpolate() - ); + dictionary propsDict; + propsDict.add + ( + "file", + time_.relativePath(outputName, true) + ); + setProperty(fieldName, propsDict); +} - // Case-local file name with "<case>" to make relocatable - dictionary propsDict; - propsDict.add - ( - "file", - time_.relativePath(fName, true) - ); - setProperty(fieldName, propsDict); - } - } +template<class Type, class GeoMeshType> +bool Foam::sampledSurfaces::storeRegistryField +( + const sampledSurface& s, + const word& fieldName, + const dimensionSet& dims, + Field<Type>&& values +) +{ + return s.storeRegistryField<Type, GeoMeshType> + ( + storedObjects(), + fieldName, + dims, + std::move(values), + IOobject::groupName(name(), s.name()) + ); } template<class Type> -void Foam::sampledSurfaces::sampleAndWrite +void Foam::sampledSurfaces::performAction ( - const GeometricField<Type, fvPatchField, volMesh>& vField + const GeometricField<Type, fvPatchField, volMesh>& fld, + unsigned request ) { // The sampler for this field @@ -140,13 +91,20 @@ void Foam::sampledSurfaces::sampleAndWrite // The interpolator for this field autoPtr<interpolation<Type>> interpPtr; - const word& fieldName = vField.name(); - const fileName outputDir = outputPath_/vField.time().timeName(); + const word& fieldName = fld.name(); + + const dimensionSet& dims = fld.dimensions(); forAll(*this, surfi) { const sampledSurface& s = operator[](surfi); + // Skip surface without faces (eg, failed cut-plane) + if (!nFaces_[surfi]) + { + continue; + } + Field<Type> values; if (s.interpolate()) @@ -156,7 +114,7 @@ void Foam::sampledSurfaces::sampleAndWrite interpPtr = interpolation<Type>::New ( sampleNodeScheme_, - vField + fld ); } @@ -169,56 +127,117 @@ void Foam::sampledSurfaces::sampleAndWrite samplePtr = interpolation<Type>::New ( sampleFaceScheme_, - vField + fld ); } values = s.sample(*samplePtr); } - writeSurface<Type>(values, surfi, fieldName, outputDir); + if ((request & actions_[surfi]) & ACTION_WRITE) + { + writeSurface<Type>(writers_[surfi], values, fieldName); + } + + if ((request & actions_[surfi]) & ACTION_SURF_MESH) + { + // Face fields only! + s.storeSurfMeshField<Type, surfGeoMesh> + ( + fieldName, dims, values + ); + } + + if ((request & actions_[surfi]) & ACTION_STORE) + { + if (s.interpolate()) + { + storeRegistryField<Type, polySurfacePointGeoMesh> + ( + s, fieldName, dims, std::move(values) + ); + } + else + { + storeRegistryField<Type, polySurfaceGeoMesh> + ( + s, fieldName, dims, std::move(values) + ); + } + } } } template<class Type> -void Foam::sampledSurfaces::sampleAndWrite +void Foam::sampledSurfaces::performAction ( - const GeometricField<Type, fvsPatchField, surfaceMesh>& sField + const GeometricField<Type, fvsPatchField, surfaceMesh>& fld, + unsigned request ) { - const word& fieldName = sField.name(); - const fileName outputDir = outputPath_/sField.time().timeName(); + const word& fieldName = fld.name(); + + const dimensionSet& dims = fld.dimensions(); forAll(*this, surfi) { - const sampledSurface& s = operator[](surfi); - Field<Type> values(s.sample(sField)); - writeSurface<Type>(values, surfi, fieldName, outputDir); + const sampledSurface& s = (*this)[surfi]; + + // Skip surface without faces (eg, failed cut-plane) + if (!nFaces_[surfi]) + { + continue; + } + + Field<Type> values(s.sample(fld)); + + if ((request & actions_[surfi]) & ACTION_WRITE) + { + writeSurface<Type>(writers_[surfi], values, fieldName); + } + + if ((request & actions_[surfi]) & ACTION_SURF_MESH) + { + s.storeSurfMeshField<Type, surfGeoMesh> + ( + fieldName, dims, values + ); + } + + if ((request & actions_[surfi]) & ACTION_STORE) + { + storeRegistryField<Type, polySurfaceGeoMesh> + ( + s, fieldName, dims, std::move(values) + ); + } } } template<class GeoField> -void Foam::sampledSurfaces::sampleAndWrite(const IOobjectList& objects) +void Foam::sampledSurfaces::performAction +( + const IOobjectList& objects, + unsigned request +) { wordList fieldNames; if (loadFromFiles_) { - fieldNames = objects.sortedNames(GeoField::typeName, fieldSelection_); + fieldNames = objects.sortedNames<GeoField>(fieldSelection_); } else { fieldNames = mesh_.thisDb().sortedNames<GeoField>(fieldSelection_); - - writeOriginalIds(); } for (const word& fieldName : fieldNames) { if (verbose_) { - Info<< "sampleAndWrite: " << fieldName << endl; + Info<< "sampleWrite: " << fieldName << endl; } if (loadFromFiles_) @@ -235,17 +254,37 @@ void Foam::sampledSurfaces::sampleAndWrite(const IOobjectList& objects) mesh_ ); - sampleAndWrite(fld); + performAction(fld, request); } else { - sampleAndWrite + performAction ( - mesh_.thisDb().lookupObject<GeoField>(fieldName) + mesh_.thisDb().lookupObject<GeoField>(fieldName), + request ); } } } +template<class Container, class Predicate> +bool Foam::sampledSurfaces::testAny +( + const Container& items, + const Predicate& pred +) +{ + for (const auto& item : items) + { + if (pred(item)) + { + return true; + } + } + + return false; +} + + // ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.C b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.C deleted file mode 100644 index d1381a6e56e12f3c9132fe14d33be94c461eb14c..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.C +++ /dev/null @@ -1,116 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2015 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "boundaryDataSurfaceWriter.H" -#include "makeSurfaceWriterMethods.H" -#include "argList.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -namespace Foam -{ - makeSurfaceWriterType(boundaryDataSurfaceWriter); -} - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -// Field writing implementation -#include "boundaryDataSurfaceWriterImpl.C" - -// Field writing methods -defineSurfaceWriterWriteFields(Foam::boundaryDataSurfaceWriter); - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -Foam::fileName Foam::boundaryDataSurfaceWriter::write -( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, - const bool verbose -) const -{ - // geometry: rootdir/surfaceName/"points" - // field: rootdir/surfaceName/time/field - - const fileName baseDir(outputDir.path()/surfaceName); - const fileName timeName(outputDir.name()); - - const pointField& points = surf.points(); - - // Dummy time to use as an objectRegistry - const fileName caseDir(argList::envGlobalPath()); - - Time dummyTime - ( - caseDir.path(), // root-path, - caseDir.name(), // case-name, - "system", // - "constant", // - false // no function objects - ); - - - // Write points - if (verbose) - { - Info<< "Writing points to " << baseDir/"points" << endl; - } - - pointIOField pts - ( - IOobject - ( - baseDir/"points", - dummyTime, - IOobject::NO_READ, - IOobject::NO_WRITE, - false - ), - points - ); - - { - // Do like regIOobject::writeObject but don't do instance() adaptation - // since this would write to e.g. 0/ instead of postProcessing/ - - // Try opening an OFstream for object - mkDir(pts.path()); - OFstream os(pts.objectPath()); - - //pts.writeHeader(os); - pts.writeData(os); - //pts.writeEndDivider(os); - } - - return baseDir; -} - - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H deleted file mode 100644 index 23e9fd3153fb1f1d3f762670a1ec645f6f74fc20..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriter.H +++ /dev/null @@ -1,231 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -Class - Foam::boundaryDataSurfaceWriter - -Description - A surfaceWriter for outputting to a form useable for the - timeVaryingMapped boundary condition. This reads the data from - constant/boundaryData/\<patch\> directory - - Typical way of working: - - use a sampledSurface of type 'patch' (to sample a patch): - \verbatim - surfaces - { - type surfaces; - surfaceFormat boundaryData; - fields ( p ); - surfaces - ( - outlet - { - type patch; - patches (outlet); - interpolate false; - } - ); - } - \endverbatim - - - write using this writer. - - move postProcessing/surfaces/outlet to constant/boundaryData/outlet - in your destination case. - - use a timeVaryingMappedFixedValue condition to read and interpolate - the profile: - type timeVaryingMappedFixedValue; - setAverage false; // do not use read average - offset 0; // do not apply offset to values - - Note: - - with 'interpolate false' the data is on the face centres of the - patch. Take care that a 2D geometry will only have a single row - of face centres so might not provide a valid triangulation - (this is what timeVaryingMappedFixedValue uses to do interpolation) - (Alternatively use timeVaryingMappedFixedValue with mapMethod 'nearest') - - \heading Output file locations - - The \c rootdir normally corresponds to something like - \c postProcessing/\<name\> - - where the geometry is written as: - \verbatim - rootdir - `-- surfaceName - `-- "points" - \endverbatim - - and field data: - \verbatim - rootdir - `-- surfaceName - |-- "points" - `-- timeName - `-- field - \endverbatim - -SourceFiles - boundaryDataSurfaceWriter.C - -\*---------------------------------------------------------------------------*/ - -#ifndef boundaryDataSurfaceWriter_H -#define boundaryDataSurfaceWriter_H - -#include "surfaceWriter.H" - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -/*---------------------------------------------------------------------------*\ - Class boundaryDataSurfaceWriter Declaration -\*---------------------------------------------------------------------------*/ - -class boundaryDataSurfaceWriter -: - public surfaceWriter -{ - // Private Member Functions - - //- Templated write operation - template<class Type> - fileName writeTemplate - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<Type>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; - -public: - - //- Runtime type information - TypeName("boundaryData"); - - - // Constructors - - //- Construct null - boundaryDataSurfaceWriter() = default; - - - //- Destructor - virtual ~boundaryDataSurfaceWriter() = default; - - - // Member Functions - - //- Write single surface geometry to file. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const bool verbose = false //!< Additional verbosity - ) const; // override - - - //- Write scalarField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<scalar>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write vectorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<vector>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write sphericalTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<sphericalTensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write symmTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<symmTensor>& values,//!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write tensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<tensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriterImpl.C b/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriterImpl.C deleted file mode 100644 index d3445cab762009180c2745ed433820ba962bab3b..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/boundaryData/boundaryDataSurfaceWriterImpl.C +++ /dev/null @@ -1,132 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2015 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify i - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "OFstream.H" -#include "OSspecific.H" -#include "IOmanip.H" -#include "Time.H" -#include "pointIOField.H" -#include "primitivePatch.H" - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -template<class Type> -Foam::fileName Foam::boundaryDataSurfaceWriter::writeTemplate -( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, - const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const -{ - // geometry: rootdir/surfaceName/"points" - // field: rootdir/surfaceName/time/field - - const fileName baseDir(outputDir.path()/surfaceName); - const fileName timeName(outputDir.name()); - - const pointField& points = surf.points(); - const faceList& faces = surf.faces(); - - // Dummy time to use as an objectRegistry - const fileName caseDir(argList::envGlobalPath()); - - Time dummyTime - ( - caseDir.path(), // root-path - caseDir.name(), // case-name - "system", // - "constant", // - false // no function objects - ); - - - // Write points - - pointIOField pts - ( - IOobject - ( - baseDir/"points", - dummyTime, - IOobject::NO_READ, - IOobject::NO_WRITE, - false - ), - label(0) - ); - - if (isNodeValues) - { - if (verbose) - { - Info<< "Writing points to " << baseDir/"points" << endl; - } - pts = points; - } - else - { - if (verbose) - { - Info<< "Writing face centres to " << baseDir/"points" << endl; - } - - primitivePatch pp(SubList<face>(faces, faces.size()), points); - - pts = pp.faceCentres(); - } - - { - // Do like regIOobject::writeObject but don't do instance() adaptation - // since this would write to e.g. 0/ instead of postProcessing/ - - // Try opening an OFstream for object - mkDir(pts.path()); - OFstream os(pts.objectPath()); - - //pts.writeHeader(os); - pts.writeData(os); - //pts.writeEndDivider(os); - } - - - // Write field - { - fileName valsDir(baseDir/timeName); - mkDir(valsDir); - OFstream os(valsDir/fieldName); - os << values; - } - - return baseDir; -} - - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H deleted file mode 100644 index b26fd9a0f7b37d66823af70ef7d12b6c6a0ef170..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H +++ /dev/null @@ -1,259 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -Class - Foam::ensightSurfaceWriter - -Description - A surfaceWriter for Ensight format. - - \verbatim - formatOptions - { - ensight - { - format ascii; - collateTimes true; - } - } - \endverbatim - - Format options: - \table - Property | Description | Required | Default - format | ascii/binary | no | ascii - collateTimes | use common geometry for times | no | true - \endtable - -SourceFiles - ensightSurfaceWriter.C - -\*---------------------------------------------------------------------------*/ - -#ifndef ensightSurfaceWriter_H -#define ensightSurfaceWriter_H - -#include "surfaceWriter.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -/*---------------------------------------------------------------------------*\ - Class ensightSurfaceWriter Declaration -\*---------------------------------------------------------------------------*/ - -class ensightSurfaceWriter -: - public surfaceWriter -{ - // Private data - - //- Write option (default: IOstream::ASCII) - IOstream::streamFormat writeFormat_; - - //- Collate times (default: true) - bool collateTimes_; - - - // Private Member Functions - - //- Print time-set for ensight case file - static void printTimeset - ( - OSstream& os, - const label ts, - const scalar& timeValue - ); - - //- Print time-set for ensight case file - static void printTimeset - ( - OSstream& os, - const label ts, - const UList<scalar>& times - ); - - - //- Templated write operation - one file per timestep - template<class Type> - fileName writeCollated - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<Type>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; - - //- Templated write operation - all time steps in single file - template<class Type> - fileName writeUncollated - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<Type>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; - - //- Templated write operation - template<class Type> - fileName writeTemplate - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<Type>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; - -public: - - //- Runtime type information - TypeName("ensight"); - - - // Constructors - - //- Construct null - ensightSurfaceWriter(); - - //- Construct with some output options - ensightSurfaceWriter(const dictionary& options); - - - //- Destructor - virtual ~ensightSurfaceWriter() = default; - - - // Member Functions - - //- True if the surface format supports geometry in a separate file. - // False if geometry and field must be in a single file - virtual bool separateGeometry() const; - - //- Trigger for geometry changes. - // \note this is a stop-gap solution - virtual void updateMesh - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName //!< Name of surface - ) const; // override - - - //- Write single surface geometry to file. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const bool verbose = false //!< Additional verbosity - ) const; // override - - - //- Write scalarField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<scalar>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write vectorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<vector>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write sphericalTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<sphericalTensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write symmTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<symmTensor>& values,//!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write tensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<tensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterImpl.C b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterImpl.C deleted file mode 100644 index 57d144984519c1a25ea15b7cf97ad39055590628..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterImpl.C +++ /dev/null @@ -1,531 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011-2014 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "IOmanip.H" -#include "Fstream.H" -#include "OSspecific.H" - -#include "ensightCase.H" -#include "ensightPartFaces.H" -#include "ensightOutput.H" -#include "ensightPTraits.H" - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -template<class Type> -Foam::fileName Foam::ensightSurfaceWriter::writeUncollated -( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, - const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const -{ - const ensight::FileName surfName(surfaceName); - const ensight::VarName varName(fieldName); - - // geometry: rootdir/time/<field>/surfaceName.case - // geometry: rootdir/time/<field>/surfaceName.<index>.mesh - // field: rootdir/time/<field>/surfaceName.<index>.field - - // Variable name as sub-directory for results - // eg, something like this: - // - VAR1/SURF1.case - // - VAR1/SURF1.0000.mesh - // - VAR1/SURF1.0001.VAR1 - // - VAR1/SURF2.case - // - VAR1/SURF2.0000.mesh - // - VAR1/SURF2.0001.VAR1 - // and - // - VAR2/SURF1.case - // - VAR2/SURF1.0000.mesh - // - VAR2/SURF1.0001.VAR2 - - const fileName baseDir = outputDir/varName; - const fileName timeDir = outputDir.name(); - // Convert timeDir to a value (if possible - use 0.0 otherwise) - scalar timeValue = 0.0; - readScalar(timeDir, timeValue); - - - if (!isDir(baseDir)) - { - mkDir(baseDir); - } - - OFstream osCase(baseDir/surfName + ".case", IOstream::ASCII); - - // Format options - osCase.setf(ios_base::left); - osCase.setf(ios_base::scientific, ios_base::floatfield); - osCase.precision(5); - - ensightGeoFile osGeom - ( - baseDir, - surfName + ".00000000.mesh", - writeFormat_ - ); - ensightFile osField - ( - baseDir, - surfName + ".00000000." + varName, - writeFormat_ - ); - - if (verbose) - { - Info<< "Writing case file to " << osCase.name() << endl; - } - - osCase - << "FORMAT" << nl - << "type: ensight gold" << nl - << nl - << "GEOMETRY" << nl - << "model: 1 " << osGeom.name().name() << nl - << nl - << "VARIABLE" << nl - << ensightPTraits<Type>::typeName - << - ( - isNodeValues - ? " per node: 1 " // time-set 1 - : " per element: 1 " // time-set 1 - ) - << setw(15) << varName << ' ' - << surfName.c_str() << ".********." << varName << nl; - - osCase - << nl - << "TIME" << nl; - - printTimeset(osCase, 1, timeValue); - osCase << "# end" << nl; - - - ensightPartFaces ensPart - ( - 0, - osGeom.name().name(), - surf.points(), - surf.faces(), - true // contiguous points - ); - osGeom << ensPart; - - // Write field - osField.writeKeyword(ensightPTraits<Type>::typeName); - - if (isNodeValues) - { - ensightOutput::Serial::writePointField - ( - values, - ensPart, - osField - // false // serial - ); - } - else - { - ensightOutput::Detail::writeFaceField - ( - values, - ensPart, - osField, - false // serial - ); - } - - return osCase.name(); -} - - -template<class Type> -Foam::fileName Foam::ensightSurfaceWriter::writeCollated -( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, - const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const -{ - const ensight::FileName surfName(surfaceName); - const ensight::VarName varName(fieldName); - - // geometry: rootdir/surfaceName/surfaceName.case - // geometry: rootdir/surfaceName/surfaceName/data/<index>/geometry - // field: rootdir/surfaceName/surfaceName/data/<index>/field - - // Use surface name as sub-directory for results - // eg, something like this: - // - SURF1/SURF1.case - // - SURF1/SURF1/data/00000000/geometry - // - SURF1/SURF1/data/00000000/VAR1 - // - SURF1/SURF1/data/00000000/VAR2 - // and - // - SURF2/SURF2.case - // - SURF2/SURF2/data/00000000/geometry - // - SURF2/SURF2/data/00000000/VAR1 - // - SURF2/SURF2/data/00000000/VAR2 - - // Names "data" and "geometry" as per ensightCase: - const char* fmt = "%08d"; - const char* mask = "data/********/"; - - const fileName baseDir = outputDir.path()/surfName; - const fileName timeDir = outputDir.name(); - // Convert timeDir to a value (if possible - use 0.0 otherwise) - scalar timeValue = 0.0; - readScalar(timeDir, timeValue); - - scalar meshValue = 0; - - if (!isDir(baseDir)) - { - mkDir(baseDir); - } - - label meshIndex = 0; - label timeIndex = 0; - - fileName geometryName; - - // Do case file - { - dictionary dict; - scalarList meshes; - scalarList times; - bool stateChanged = false; - - if (isFile(baseDir/"fieldsDict")) - { - IFstream is(baseDir/"fieldsDict"); - if (is.good() && dict.read(is)) - { - dict.readIfPresent("meshes", meshes); - dict.readIfPresent("times", times); - - timeIndex = 1+findLower(times, timeValue); - - if (dict.readIfPresent("updateMesh", meshValue)) - { - meshIndex = 1+findLower(meshes, meshValue); - - dict.remove("updateMesh"); - stateChanged = true; - } - else if (meshes.size()) - { - meshIndex = meshes.size()-1; - meshValue = meshes.last(); - } - else - { - meshIndex = 0; - } - } - } - - // Update stored times list - meshes.resize(meshIndex+1, -1); - times.resize(timeIndex+1, -1); - - if (meshes[meshIndex] != meshValue) - { - stateChanged = true; - } - if (times[timeIndex] != timeValue) - { - stateChanged = true; - } - - meshes[meshIndex] = meshValue; - times[timeIndex] = timeValue; - - geometryName = - "data"/word::printf(fmt, meshIndex)/ensightCase::geometryName; - - - // Add my information to dictionary - { - dict.set("meshes", meshes); - dict.set("times", times); - if (dict.found("fields")) - { - dictionary& fieldsDict = dict.subDict("fields"); - if (!fieldsDict.found(fieldName)) - { - dictionary fieldDict; - fieldDict.set("type", ensightPTraits<Type>::typeName); - fieldDict.set("name", varName); // ensight variable name - - fieldsDict.set(fieldName, fieldDict); - - stateChanged = true; - } - } - else - { - dictionary fieldDict; - fieldDict.set("type", ensightPTraits<Type>::typeName); - fieldDict.set("name", varName); // ensight variable name - - dictionary fieldsDict; - fieldsDict.set(fieldName, fieldDict); - - dict.set("fields", fieldsDict); - - stateChanged = true; - } - } - - - if (stateChanged) - { - if (verbose) - { - Info<< "Writing state file to fieldsDict" << endl; - } - { - OFstream os(baseDir/"fieldsDict"); - os << "// Summary of Ensight fields, times" << nl << nl; - dict.write(os, false); - } - - OFstream osCase(baseDir/surfName + ".case", IOstream::ASCII); - - // Format options - osCase.setf(ios_base::left); - osCase.setf(ios_base::scientific, ios_base::floatfield); - osCase.precision(5); - - if (verbose) - { - Info<< "Writing case file to " << osCase.name() << endl; - } - - // The geometry can be any of the following: - // 0: constant/static - // 1: moving, with the same frequency as the data - // 2: moving, with different frequency as the data - - const label tsGeom = - (meshes.size() == 1 ? 0 : meshes == times ? 1 : 2); - - osCase - << "FORMAT" << nl - << "type: ensight gold" << nl - << nl - << "GEOMETRY" << nl; - - - if (tsGeom) - { - // moving - osCase - << "model: " << tsGeom << " " // time-set (1|2) - << mask << geometryName.name() << nl; - } - else - { - // steady - osCase - << "model: " - << geometryName.c_str() << nl; - } - - osCase - << nl - << "VARIABLE" << nl; - - const dictionary& fieldsDict = dict.subDict("fields"); - for (const entry& dEntry : fieldsDict) - { - const dictionary& subDict = dEntry.dict(); - - const word fieldType(subDict.get<word>("type")); - const word varName = subDict.lookupOrDefault - ( - "name", - dEntry.keyword() // fieldName as fallback - ); - - osCase - << fieldType - << - ( - isNodeValues - ? " per node: 1 " // time-set 1 - : " per element: 1 " // time-set 1 - ) - << setw(15) << varName << ' ' - << mask << varName << nl; - } - - osCase - << nl - << "TIME" << nl; - - printTimeset(osCase, 1, times); - if (tsGeom == 2) - { - printTimeset(osCase, 2, meshes); - } - - osCase << "# end" << nl; - } - } - - - // Location for data (and possibly the geometry as well) - fileName dataDir = baseDir/"data"/word::printf(fmt, timeIndex); - - // As per mkdir -p "data/00000000" - mkDir(dataDir); - - - const fileName meshFile(baseDir/geometryName); - - // Write geometry - ensightPartFaces ensPart - ( - 0, - meshFile.name(), - surf.points(), - surf.faces(), - true // contiguous points - ); - if (!exists(meshFile)) - { - if (verbose) - { - Info<< "Writing mesh file to " << meshFile.name() << endl; - } - // Use two-argument form for path-name to avoid validating the base-dir - ensightGeoFile osGeom(meshFile.path(), meshFile.name(), writeFormat_); - osGeom << ensPart; - } - - // Write field - ensightFile osField - ( - dataDir, - varName, - writeFormat_ - ); - - if (verbose) - { - Info<< "Writing field file to " << osField.name() << endl; - } - - // Write field - osField.writeKeyword(ensightPTraits<Type>::typeName); - - if (isNodeValues) - { - ensightOutput::Serial::writePointField - ( - values, - ensPart, - osField - // serial - ); - } - else - { - ensightOutput::Detail::writeFaceField - ( - values, - ensPart, - osField, - false // serial - ); - } - - // Place a timestamp in the directory for future reference - { - OFstream timeStamp(dataDir/"time"); - timeStamp - << "# timestep time" << nl - << dataDir.name() << " " << timeValue << nl; - } - - return baseDir/surfName + ".case"; -} - - -template<class Type> -Foam::fileName Foam::ensightSurfaceWriter::writeTemplate -( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, - const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const -{ - if (collateTimes_) - { - return writeCollated - ( - outputDir, - surfaceName, - surf, - fieldName, - values, - isNodeValues, - verbose - ); - } - else - { - return writeUncollated - ( - outputDir, - surfaceName, - surf, - fieldName, - values, - isNodeValues, - verbose - ); - } -} - - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/foam/foamSurfaceWriter.C b/src/sampling/sampledSurface/writers/foam/foamSurfaceWriter.C deleted file mode 100644 index 8cefc33e9be4df41964b236b7156566b8aca9cf5..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/foam/foamSurfaceWriter.C +++ /dev/null @@ -1,98 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011-2016 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "foamSurfaceWriter.H" -#include "OFstream.H" -#include "makeSurfaceWriterMethods.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -namespace Foam -{ - makeSurfaceWriterType(foamSurfaceWriter); -} - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -// Field writing implementation -#include "foamSurfaceWriterImpl.C" - -// Field writing methods -defineSurfaceWriterWriteFields(Foam::foamSurfaceWriter); - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -Foam::fileName Foam::foamSurfaceWriter::write -( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, - const bool verbose -) const -{ - // Output: - // - rootdir/time/surfaceName/{points,faces} - - fileName surfaceDir(outputDir/surfaceName); - - if (!isDir(surfaceDir)) - { - mkDir(surfaceDir); - } - - if (verbose) - { - Info<< "Writing geometry to " << surfaceDir << endl; - } - - const pointField& points = surf.points(); - const faceList& faces = surf.faces(); - - // Points - OFstream(surfaceDir/"points")() << points; - - // Faces - OFstream(surfaceDir/"faces")() << faces; - - // Face centers. Not really necessary but very handy when reusing as inputs - // for e.g. timeVaryingMapped bc. - pointField faceCentres(faces.size(), Zero); - - forAll(faces, facei) - { - faceCentres[facei] = faces[facei].centre(points); - } - - OFstream(surfaceDir/"faceCentres")() << faceCentres; - - return surfaceDir; -} - - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/foam/foamSurfaceWriter.H b/src/sampling/sampledSurface/writers/foam/foamSurfaceWriter.H deleted file mode 100644 index 04c784a8ccad7adc5cbefbb352dd4d7ef4d8955c..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/foam/foamSurfaceWriter.H +++ /dev/null @@ -1,209 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011-2016 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -Class - Foam::foamSurfaceWriter - -Description - A surfaceWriter for OpenFOAM surfaces - - \heading Output file locations - - The \c rootdir normally corresponds to something like - \c postProcessing/\<name\> - - \subheading Geometry - \verbatim - rootdir - `-- timeName - `-- surfaceName - |-- "points" - |-- "faceCentres" - `-- "faces" - \endverbatim - - \subheading Fields - \verbatim - rootdir - `-- timeName - `-- surfaceName - |-- scalarField - | |-- field - | `-- field - |-- vectorField - |-- field - `-- field - \endverbatim - -SourceFiles - foamSurfaceWriter.C - -\*---------------------------------------------------------------------------*/ - -#ifndef foamSurfaceWriter_H -#define foamSurfaceWriter_H - -#include "surfaceWriter.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -/*---------------------------------------------------------------------------*\ - Class foamSurfaceWriter Declaration -\*---------------------------------------------------------------------------*/ - -class foamSurfaceWriter -: - public surfaceWriter -{ - // Private Member Functions - - //- Templated write operation - template<class Type> - fileName writeTemplate - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<Type>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; - - -public: - - //- Runtime type information - TypeName("foam"); - - - // Constructors - - //- Construct null - foamSurfaceWriter() = default; - - - //- Destructor - virtual ~foamSurfaceWriter() = default; - - - // Member Functions - - //- True if the surface format supports geometry in a separate file. - // False if geometry and field must be in a single file - virtual bool separateGeometry() const - { - return true; - } - - //- Write single surface geometry to file. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const bool verbose = false //!< Additional verbosity - ) const; // override - - - //- Write scalarField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<scalar>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write vectorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<vector>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write sphericalTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<sphericalTensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write symmTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<symmTensor>& values,//!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write tensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<tensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/foam/foamSurfaceWriterImpl.C b/src/sampling/sampledSurface/writers/foam/foamSurfaceWriterImpl.C deleted file mode 100644 index 002c546a36f9e5c7e4eeff1b88b5ae5f30b8b604..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/foam/foamSurfaceWriterImpl.C +++ /dev/null @@ -1,77 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011-2014 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "OFstream.H" -#include "OSspecific.H" - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -template<class Type> -Foam::fileName Foam::foamSurfaceWriter::writeTemplate -( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, - const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const -{ - // Geometry should already have been written - // Values to separate directory (e.g. "scalarField/p") - - // field: rootdir/time/surfaceName/fieldType/field - - const word fieldTypeName - ( - word(pTraits<Type>::typeName) + FieldBase::typeName - ); - - const fileName base(outputDir/surfaceName); - const fileName outputFile(base / fieldTypeName / fieldName); - - if (verbose) - { - Info<< "Writing field " << fieldName << " to " << base << endl; - } - - - if (!isDir(outputFile.path())) - { - mkDir(outputFile.path()); - } - - // Write field - OFstream os(outputFile); - os << values; - - return os.name(); -} - - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C deleted file mode 100644 index 35ac3ac113787a5cd75656e9b5e8521c7b41510e..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C +++ /dev/null @@ -1,136 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011-2016 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "rawSurfaceWriter.H" -#include "OFstream.H" -#include "OSspecific.H" -#include "makeSurfaceWriterMethods.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -namespace Foam -{ - makeSurfaceWriterType(rawSurfaceWriter); - addToRunTimeSelectionTable(surfaceWriter, rawSurfaceWriter, wordDict); -} - - -// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // - -namespace Foam -{ - // Emit x,y,z - static inline void writePoint(Ostream& os, const point& p) - { - os << p.x() << ' ' << p.y() << ' ' << p.z(); - } -} // End namespace Foam - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -// Field writing implementation -#include "rawSurfaceWriterImpl.C" - -// Field writing methods -defineSurfaceWriterWriteFields(Foam::rawSurfaceWriter); - - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::rawSurfaceWriter::rawSurfaceWriter() -: - surfaceWriter(), - writeCompression_(IOstream::UNCOMPRESSED) -{} - - -Foam::rawSurfaceWriter::rawSurfaceWriter(const dictionary& options) -: - surfaceWriter(), - writeCompression_(IOstream::UNCOMPRESSED) -{ - if (options.found("compression")) - { - writeCompression_ = - IOstream::compressionEnum(options.get<word>("compression")); - } -} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -Foam::fileName Foam::rawSurfaceWriter::write -( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, - const bool verbose -) const -{ - // geometry: rootdir/time/surfaceName.raw - - const pointField& points = surf.points(); - const faceList& faces = surf.faces(); - - - if (!isDir(outputDir)) - { - mkDir(outputDir); - } - - OFstream os - ( - outputDir/surfaceName + ".raw", - IOstream::ASCII, - IOstream::currentVersion, - writeCompression_ - ); - - if (verbose) - { - Info<< "Writing geometry to " << os.name() << endl; - } - - // Header - os << "# geometry NO_DATA " << faces.size() << nl - << "# x y z" << nl; - - // Write faces centres - for (const face& f : faces) - { - writePoint(os, f.centre(points)); - os << nl; - } - - os << nl; - - return os.name(); -} - - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.H b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.H deleted file mode 100644 index 7660fa4aa1a09e503e9de4caf661cc984a7a0435..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.H +++ /dev/null @@ -1,220 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011-2016 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -Class - Foam::rawSurfaceWriter - -Description - A surfaceWriter for raw output. - - The formatOptions for raw: - \table - Property | Description | Required | Default - compression | on / off | no | off - \endtable - - For example, - \verbatim - formatOptions - { - raw - { - compression on; - } - } - \endverbatim - - \heading Output file locations - - The \c rootdir normally corresponds to something like - \c postProcessing/\<name\> - - \subheading Geometry - \verbatim - rootdir - `-- timeName - `-- surfaceName.{raw} - \endverbatim - - \subheading Fields - \verbatim - rootdir - `-- timeName - |-- <field0>_surfaceName.{raw} - `-- <field1>_surfaceName.{raw} - \endverbatim - -SourceFiles - rawSurfaceWriter.C - -\*---------------------------------------------------------------------------*/ - -#ifndef rawSurfaceWriter_H -#define rawSurfaceWriter_H - -#include "surfaceWriter.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -/*---------------------------------------------------------------------------*\ - Class rawSurfaceWriter Declaration -\*---------------------------------------------------------------------------*/ - -class rawSurfaceWriter -: - public surfaceWriter -{ - // Private data - - //- Output compression (default: uncompressed) - IOstream::compressionType writeCompression_; - - - // Private Member Functions - - //- Templated write operation - template<class Type> - fileName writeTemplate - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<Type>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; - - -public: - - //- Runtime type information - TypeName("raw"); - - - // Constructors - - //- Construct null - rawSurfaceWriter(); - - //- Construct with some output options - rawSurfaceWriter(const dictionary& options); - - - //- Destructor - virtual ~rawSurfaceWriter() = default; - - - // Member Functions - - //- Write single surface geometry to file. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const bool verbose = false //!< Additional verbosity - ) const; // override - - - //- Write scalarField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<scalar>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write vectorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<vector>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write sphericalTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<sphericalTensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write symmTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<symmTensor>& values,//!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write tensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<tensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.H b/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.H deleted file mode 100644 index 194b66afe3adfa818df02698b00e7ba00883fd42..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.H +++ /dev/null @@ -1,215 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -Class - Foam::starcdSurfaceWriter - -Description - A surfaceWriter for STARCD files. - - The geometry is written via the MeshedSurfaceProxy, the fields - are written in a trivial ASCII format with ID and VALUE as - so-called user data. These \c .usr files can be read into proSTAR - with these types of commands. For element data: - \verbatim - getuser FILENAME.usr cell scalar free - getuser FILENAME.usr cell vector free - \endverbatim - and for vertex data: - \verbatim - getuser FILENAME.usr vertex scalar free - getuser FILENAME.usr vertex vector free - \endverbatim - - \heading Output file locations - - The \c rootdir normally corresponds to something like - \c postProcessing/\<name\> - - \subheading Geometry - \verbatim - rootdir - `-- timeName - `-- surfaceName.{cel,vrt,inp} - \endverbatim - - \subheading Fields - \verbatim - rootdir - `-- timeName - |-- <field0>_surfaceName.{usr} - `-- <field1>_surfaceName.{usr} - \endverbatim - -SourceFiles - starcdSurfaceWriter.C - -\*---------------------------------------------------------------------------*/ - -#ifndef starcdSurfaceWriter_H -#define starcdSurfaceWriter_H - -#include "surfaceWriter.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -/*---------------------------------------------------------------------------*\ - Class starcdSurfaceWriter Declaration -\*---------------------------------------------------------------------------*/ - -class starcdSurfaceWriter -: - public surfaceWriter -{ - // Private Member Functions - - //- Templated write operation - template<class Type> - fileName writeTemplate - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<Type>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; - - -public: - - //- Runtime type information - TypeName("starcd"); - - - // Constructors - - //- Construct null - starcdSurfaceWriter() = default; - - - //- Destructor - virtual ~starcdSurfaceWriter() = default; - - - // Member Functions - - //- True if the surface format supports geometry in a separate file. - // False if geometry and field must be in a single file - virtual bool separateGeometry() const - { - return true; - } - - //- Write single surface geometry to file. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const bool verbose = false //!< Additional verbosity - ) const; // override - - - //- Write scalarField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<scalar>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write vectorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<vector>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write sphericalTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<sphericalTensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write symmTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<symmTensor>& values,//!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write tensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<tensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriterImpl.C b/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriterImpl.C deleted file mode 100644 index 64fb5d80927d850efb07a45fb699f20ce0bd566c..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriterImpl.C +++ /dev/null @@ -1,94 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011-2014 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "OFstream.H" -#include "OSspecific.H" - -// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // - -namespace Foam -{ - // Emit each component - template<class Type> - static inline void writeData(Ostream& os, const Type& val) - { - const direction ncmpt = pTraits<Type>::nComponents; - for (direction cmpt=0; cmpt < ncmpt; ++cmpt) - { - os << ' ' << component(val, cmpt); - } - os << nl; - } - -} // End namespace Foam - - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -template<class Type> -Foam::fileName Foam::starcdSurfaceWriter::writeTemplate -( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf&, - const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const -{ - // field: rootdir/time/<field>_surfaceName.usr - - if (!isDir(outputDir)) - { - mkDir(outputDir); - } - - OFstream os(outputDir/fieldName + '_' + surfaceName + ".usr"); - - if (verbose) - { - Info<< "Writing field " << fieldName << " to " << os.name() << endl; - } - - // 1-based ids - label elemId = 1; - - // No header, just write values - for (const Type& val : values) - { - os << elemId; - writeData(os, val); - - ++elemId; - } - - return os.name(); -} - - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/surfaceWriter.C b/src/sampling/sampledSurface/writers/surfaceWriter.C deleted file mode 100644 index c3ef1711f081c83385a37bb3dd409b3d768db4a1..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/surfaceWriter.C +++ /dev/null @@ -1,126 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011-2015 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "surfaceWriter.H" - -#include "MeshedSurfaceProxy.H" -#include "proxySurfaceWriter.H" - -#include "HashTable.H" -#include "word.H" -#include "addToRunTimeSelectionTable.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -namespace Foam -{ - defineTypeNameAndDebug(surfaceWriter, 0); - defineRunTimeSelectionTable(surfaceWriter, word); - defineRunTimeSelectionTable(surfaceWriter, wordDict); - addNamedToRunTimeSelectionTable - ( - surfaceWriter, - surfaceWriter, - word, - null - ); -} - - -// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // - -Foam::autoPtr<Foam::surfaceWriter> -Foam::surfaceWriter::New(const word& writeType) -{ - const auto cstrIter = wordConstructorTablePtr_->cfind(writeType); - - if (cstrIter.found()) - { - return autoPtr<surfaceWriter>(cstrIter()()); - } - else if (MeshedSurfaceProxy<face>::canWriteType(writeType)) - { - // Unknown, but proxy handler can manage it - return autoPtr<surfaceWriter>(new proxySurfaceWriter(writeType)); - } - - FatalErrorInFunction - << "Unknown write type \"" << writeType << "\"\n\n" - << "Valid types : " - << wordConstructorTablePtr_->sortedToc() << nl - << "Valid proxy types : " - << MeshedSurfaceProxy<face>::writeTypes() << endl - << exit(FatalError); - - return nullptr; -} - - -Foam::autoPtr<Foam::surfaceWriter> -Foam::surfaceWriter::New(const word& writeType, const dictionary& options) -{ - { - // Constructor with options (dictionary) - const auto cstrIter = wordDictConstructorTablePtr_->cfind(writeType); - - if (cstrIter.found()) - { - return autoPtr<surfaceWriter>(cstrIter()(options)); - } - } - - - // Drop through to version without options - - const auto cstrIter = wordConstructorTablePtr_->cfind(writeType); - - if (cstrIter.found()) - { - return autoPtr<surfaceWriter>(cstrIter()()); - } - else if (MeshedSurfaceProxy<face>::canWriteType(writeType)) - { - // Unknown, but proxy handler can manage it - return autoPtr<surfaceWriter> - ( - new proxySurfaceWriter(writeType, options) - ); - } - - FatalErrorInFunction - << "Unknown write type \"" << writeType << "\"\n\n" - << "Valid types : " - << wordConstructorTablePtr_->sortedToc() << nl - << "Valid proxy types : " - << MeshedSurfaceProxy<face>::writeTypes() << endl - << exit(FatalError); - - return nullptr; -} - - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/surfaceWriter.H b/src/sampling/sampledSurface/writers/surfaceWriter.H deleted file mode 100644 index 3f4b0e8cb741dc105323a7846d2d50ca054ce7a7..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/surfaceWriter.H +++ /dev/null @@ -1,230 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011-2012 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -Class - Foam::surfaceWriter - -Description - Base class for surface writers - -SourceFiles - surfaceWriter.C - -\*---------------------------------------------------------------------------*/ - -#ifndef surfaceWriter_H -#define surfaceWriter_H - -#include "typeInfo.H" -#include "autoPtr.H" -#include "fileName.H" -#include "meshedSurfRef.H" -#include "runTimeSelectionTables.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -/*---------------------------------------------------------------------------*\ - Class surfaceWriter Declaration -\*---------------------------------------------------------------------------*/ - -class surfaceWriter -{ -public: - - //- Runtime type information - TypeName("surfaceWriter"); - - // Declare run-time constructor selection table - - declareRunTimeSelectionTable - ( - autoPtr, - surfaceWriter, - word, - (), - () - ); - - declareRunTimeSelectionTable - ( - autoPtr, - surfaceWriter, - wordDict, - ( - const dictionary& options - ), - (options) - ); - - - // Selectors - - //- Return a reference to the selected surfaceWriter - static autoPtr<surfaceWriter> New(const word& writeType); - - //- Return a reference to the selected surfaceWriter - // Select with extra write option - static autoPtr<surfaceWriter> New - ( - const word& writeType, - const dictionary& writeOptions - ); - - - // Constructors - - //- Construct null - surfaceWriter() = default; - - - //- Destructor - virtual ~surfaceWriter() = default; - - - // Member Functions - - //- True if the surface format supports geometry in a separate file. - // False if geometry and field must be in a single file - virtual bool separateGeometry() const - { - return false; - } - - //- Trigger for geometry changes. - // \note this is a stop-gap solution until the writing infrastructure - // is improved. - virtual void updateMesh - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName //!< Name of surface - ) const - {} - - //- Write single surface geometry to file. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const bool verbose = false //!< Additional verbosity - ) const - { - return fileName::null; - } - - //- Write scalarField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<scalar>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const - { - return fileName::null; - } - - //- Write vectorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<vector>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const - { - return fileName::null; - } - - //- Write sphericalTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<sphericalTensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const - { - return fileName::null; - } - - //- Write symmTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<symmTensor>& values,//!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const - { - return fileName::null; - } - - //- Write tensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<tensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const - { - return fileName::null; - } -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.C b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.C deleted file mode 100644 index b81635082f21fc9dd5c976d30ce15103b98e6737..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.C +++ /dev/null @@ -1,192 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011-2016 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "vtkSurfaceWriter.H" -#include "foamVtkOutputOptions.H" -#include "OSspecific.H" -#include <fstream> -#include "makeSurfaceWriterMethods.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -namespace Foam -{ - makeSurfaceWriterType(vtkSurfaceWriter); - addToRunTimeSelectionTable(surfaceWriter, vtkSurfaceWriter, wordDict); -} - -// Field writing implementation -#include "vtkSurfaceWriterImpl.C" - -// Field writing methods -defineSurfaceWriterWriteFields(Foam::vtkSurfaceWriter); - - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -void Foam::vtkSurfaceWriter::writeGeometry -( - vtk::formatter& format, - const meshedSurf& surf, - std::string title -) -{ - const pointField& points = surf.points(); - const faceList& faces = surf.faces(); - - if (title.empty()) - { - title = "sampleSurface"; - } - - vtk::legacy::fileHeader - ( - format, - title, - vtk::fileTag::POLY_DATA - ); - - vtk::legacy::beginPoints(format.os(), points.size()); - - vtk::writeList(format, points); - format.flush(); - - // Write faces - // connectivity count without additional storage (done internally) - label nConnectivity = 0; - for (const face& f : faces) - { - nConnectivity += f.size(); - } - - vtk::legacy::beginPolys - ( - format.os(), - faces.size(), - nConnectivity - ); - - for (const face& f : faces) - { - format.write(f.size()); // The size prefix - vtk::writeList(format, f); - } - - format.flush(); -} - - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::vtkSurfaceWriter::vtkSurfaceWriter() -: - surfaceWriter(), - fmtType_(unsigned(vtk::formatType::LEGACY_ASCII)), - precision_(IOstream::defaultPrecision()) -{} - - -Foam::vtkSurfaceWriter::vtkSurfaceWriter(const dictionary& options) -: - surfaceWriter(), - fmtType_(static_cast<unsigned>(vtk::formatType::LEGACY_ASCII)), - precision_(IOstream::defaultPrecision()) -{ -#if 0 - // Future - // format: ascii | binary - // legacy true | false - - vtk::outputOptions opts(static_cast<vtk::formatType>(fmtType_)); - - const word formatName = options.lookupOrDefault<word>("format", ""); - if (formatName.size()) - { - opts.ascii - ( - IOstream::formatEnum(formatName) == IOstream::ASCII - ); - } - - if (options.lookupOrDefault("legacy", false)) - { - opts.legacy(true); - } - - // Convert back to raw data type - fmtType_ = static_cast<unsigned>(opts.fmt()); -#endif - - // The write precision for ASCII formatters - precision_ = - options.lookupOrDefaultCompat - ( - "precision", {{"writePrecision", -1806}}, - IOstream::defaultPrecision() - ); -} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -Foam::fileName Foam::vtkSurfaceWriter::write -( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, - const bool verbose -) const -{ - // geometry: rootdir/time/surfaceName.{vtk|vtp} - - fileName outputFile(outputDir/surfaceName + ".vtk"); - - if (!isDir(outputDir)) - { - mkDir(outputDir); - } - if (verbose) - { - Info<< "Writing geometry to " << outputFile << endl; - } - - // As vtk::outputOptions - vtk::outputOptions opts(static_cast<vtk::formatType>(fmtType_)); - opts.legacy(true); - opts.precision(precision_); - - std::ofstream os(outputFile); - - auto format = opts.newFormatter(os); - - writeGeometry(*format, surf, surfaceName); - - return outputFile; -} - - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.H b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.H deleted file mode 100644 index 2ced87cda1c12ec097f5e8b2fd3128d1964c2753..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.H +++ /dev/null @@ -1,251 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -Class - Foam::vtkSurfaceWriter - -Description - A surfaceWriter for VTK legacy format. - - The formatOptions for vtk: - \table - Property | Description | Required | Default - format | [FUTURE] ascii or binary format | no | ascii - legacy | [FUTURE] Legacy VTK output | no | true - precision | Write precision in ascii | no | same as IOstream - \endtable - - For example, - \verbatim - formatOptions - { - vtk - { - precision 10; - } - } - \endverbatim - - \heading Output file locations - - The \c rootdir normally corresponds to something like - \c postProcessing/\<name\> - - \subheading Geometry - \verbatim - rootdir - `-- timeName - `-- surfaceName.{vtk} - \endverbatim - - \subheading Fields - \verbatim - rootdir - `-- timeName - `-- <field>_surfaceName.{vtk} - \endverbatim - -Note - Uses ASCII-only output. - All data are written as \c double due to portability issues - (paraview on window). - -SourceFiles - vtkSurfaceWriter.C - -\*---------------------------------------------------------------------------*/ - -#ifndef vtkSurfaceWriter_H -#define vtkSurfaceWriter_H - -#include "surfaceWriter.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -namespace vtk -{ -// Forward declarations -class formatter; -} - -/*---------------------------------------------------------------------------*\ - Class vtkSurfaceWriter Declaration -\*---------------------------------------------------------------------------*/ - -class vtkSurfaceWriter -: - public surfaceWriter -{ - // Private data - - //- The VTK output format type. - // Stored as a raw value to avoid a dependency on fileFormats - unsigned fmtType_; - - //- ASCII write precision - unsigned precision_; - - - // Private Member Functions - - static void writeGeometry - ( - vtk::formatter& format, - const meshedSurf& surf, - std::string title = "" - ); - - template<class Type> - static void writeField - ( - vtk::formatter& format, - const Field<Type>& values - ); - - - //- Templated write operation - template<class Type> - fileName writeTemplate - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<Type>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; - - -public: - - //- Runtime type information - TypeName("vtk"); - - - // Constructors - - //- Construct null - vtkSurfaceWriter(); - - //- Construct with some output options - explicit vtkSurfaceWriter(const dictionary& options); - - - //- Destructor - virtual ~vtkSurfaceWriter() = default; - - - // Member Functions - - //- Write single surface geometry to file. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const bool verbose = false //!< Additional verbosity - ) const; // override - - - //- Write scalarField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<scalar>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write vectorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<vector>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write sphericalTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<sphericalTensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write symmTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<symmTensor>& values,//!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write tensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<tensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriterImpl.C b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriterImpl.C deleted file mode 100644 index 4c1fde0a542d36ffb2711a418094fb956fc05c7a..0000000000000000000000000000000000000000 --- a/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriterImpl.C +++ /dev/null @@ -1,153 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011-2014 OpenFOAM Foundation -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "foamVtkOutputOptions.H" -#include "OSspecific.H" -#include <fstream> - -// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // - -namespace Foam -{ - template<class Type> - static inline void beginFloatField - ( - vtk::formatter& format, - const word& fieldName, - const Field<Type>& values - ) - { - // Use 'double' instead of 'float' for ASCII output (issue #891) - if (format.opts().ascii()) - { - format.os() - << fieldName << ' ' - << int(pTraits<Type>::nComponents) << ' ' - << values.size() << " double" << nl; - } - else - { - format.os() - << fieldName << ' ' - << int(pTraits<Type>::nComponents) << ' ' - << values.size() << " float" << nl; - } - } -} - - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -// // Unspecialized (unknown) data type - map as zeros -// void Foam::vtkSurfaceWriter::writeZeros -// ( -// vtk::formatter& format, -// const label count -// ) -// { -// const float val(0); -// -// for (label i=0; i < count; ++i) -// { -// format.write(val); -// } -// format.flush(); -// } - - -template<class Type> -void Foam::vtkSurfaceWriter::writeField -( - vtk::formatter& format, - const Field<Type>& values -) -{ - vtk::writeList(format, values); - format.flush(); -} - - -template<class Type> -Foam::fileName Foam::vtkSurfaceWriter::writeTemplate -( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, - const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const -{ - // field: rootdir/time/<field>_surfaceName.{vtk|vtp} - - fileName outputFile(outputDir/fieldName + '_' + surfaceName + ".vtk"); - - if (!isDir(outputDir)) - { - mkDir(outputDir); - } - if (verbose) - { - Info<< "Writing field " << fieldName << " to " - << outputFile << endl; - } - - // As vtk::outputOptions - vtk::outputOptions opts(static_cast<vtk::formatType>(fmtType_)); - opts.legacy(true); - opts.precision(precision_); - - std::ofstream os(outputFile); - - auto format = opts.newFormatter(os); - - writeGeometry(*format, surf); - - if (isNodeValues) - { - format->os() - << "POINT_DATA " - << values.size() << nl - << "FIELD attributes 1" << nl; - } - else - { - format->os() - << "CELL_DATA " - << values.size() << nl - << "FIELD attributes 1" << nl; - } - - beginFloatField(*format, fieldName, values); - writeField(*format, values); - - return outputFile; -} - - -// ************************************************************************* // diff --git a/src/sampling/surfMeshSample/surfMeshSamplers/surfMeshSamplers.C b/src/sampling/surfMeshSample/surfMeshSamplers/surfMeshSamplers.C index eb8b8fde32279ea5c6449f50e7d055f2f6196bfa..a31760524a079e62e67cbac9000dbc74951e1da6 100644 --- a/src/sampling/surfMeshSample/surfMeshSamplers/surfMeshSamplers.C +++ b/src/sampling/surfMeshSample/surfMeshSamplers/surfMeshSamplers.C @@ -243,6 +243,7 @@ bool Foam::surfMeshSamplers::read(const dictionary& dict) surfaces().transfer(surfs); } + auto& surfs = surfaces(); if (surfs.size()) { @@ -252,9 +253,6 @@ bool Foam::surfMeshSamplers::read(const dictionary& dict) Info<< type() << " fields: " << flatOutput(fieldSelection_) << nl; Info<< nl; - // Ensure all surfaces and merge information are expired - expire(); - // Need to initialize corresponding surfMesh for others in the chain. // This can simply be a zero-sized placeholder, or the real surface with // faces. @@ -346,18 +344,18 @@ bool Foam::surfMeshSamplers::needsUpdate() const bool Foam::surfMeshSamplers::expire() { - bool justExpired = false; + label nChanged = 0; for (surfMeshSample& s : surfaces()) { if (s.expire()) { - justExpired = true; + ++nChanged; } } // True if any surfaces just expired - return justExpired; + return nChanged; } @@ -368,16 +366,17 @@ bool Foam::surfMeshSamplers::update() return false; } - bool updated = false; + label nUpdated = 0; + for (surfMeshSample& s : surfaces()) { if (s.update()) { - updated = true; + ++nUpdated; } } - return updated; + return nUpdated; } diff --git a/src/surfMesh/Make/files b/src/surfMesh/Make/files index c2ca286e1fe8857f95ecaf9441e3a3ca30b2c08d..4891715e49de82e90f67fa0fd546e7fd6cf10c01 100644 --- a/src/surfMesh/Make/files +++ b/src/surfMesh/Make/files @@ -57,4 +57,20 @@ triSurface/fields/triSurfaceFields.C triSurface/patches/geometricSurfacePatch.C triSurface/patches/surfacePatch.C + +writers = writers + +$(writers)/surfaceWriter.C +$(writers)/boundaryData/boundaryDataSurfaceWriter.C +$(writers)/ensight/ensightSurfaceWriter.C +$(writers)/foam/foamSurfaceWriter.C +$(writers)/nastran/nastranSurfaceWriter.C +$(writers)/null/nullSurfaceWriter.C +$(writers)/proxy/proxySurfaceWriter.C +$(writers)/raw/rawSurfaceWriter.C +$(writers)/starcd/starcdSurfaceWriter.C +$(writers)/vtk/vtkSurfaceWriter.C +/* $(writers)/x3d/x3dSurfaceWriter.C */ + + LIB = $(FOAM_LIBBIN)/libsurfMesh diff --git a/src/surfMesh/writers/boundaryData/boundaryDataSurfaceWriter.C b/src/surfMesh/writers/boundaryData/boundaryDataSurfaceWriter.C new file mode 100644 index 0000000000000000000000000000000000000000..8b3db9f2f4694159bd51ccef32c08c68631f1f4a --- /dev/null +++ b/src/surfMesh/writers/boundaryData/boundaryDataSurfaceWriter.C @@ -0,0 +1,275 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- + | Copyright (C) 2015 OpenFOAM Foundation +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "boundaryDataSurfaceWriter.H" +#include "argList.H" +#include "OFstream.H" +#include "OSspecific.H" +#include "IOmanip.H" +#include "Time.H" +#include "pointIOField.H" +#include "primitivePatch.H" +#include "surfaceWriterMethods.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace surfaceWriters +{ + defineTypeName(boundaryDataWriter); + addToRunTimeSelectionTable(surfaceWriter, boundaryDataWriter, word); +} +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surfaceWriters::boundaryDataWriter::boundaryDataWriter() +: + surfaceWriter() +{} + + +Foam::surfaceWriters::boundaryDataWriter::boundaryDataWriter +( + const dictionary& options +) +: + surfaceWriter(options) +{} + + +Foam::surfaceWriters::boundaryDataWriter::boundaryDataWriter +( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + boundaryDataWriter(options) +{ + open(surf, outputPath, parallel); +} + + +Foam::surfaceWriters::boundaryDataWriter::boundaryDataWriter +( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + boundaryDataWriter(options) +{ + open(points, faces, outputPath, parallel); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::fileName Foam::surfaceWriters::boundaryDataWriter::write() +{ + checkOpen(); + + // Geometry: rootdir/surfaceName/"points" + // Field: rootdir/surfaceName/<TIME>/field + + fileName surfaceDir = outputPath_; + + // Write points + if (verbose_) + { + Info<< "Writing points to " << surfaceDir/"points" << endl; + } + + + // Dummy time to use as an objectRegistry + const fileName caseDir(argList::envGlobalPath()); + + Time dummyTime + ( + caseDir.path(), // root-path, + caseDir.name(), // case-name, + "system", // + "constant", // + false, // no function objects + false // no libs + ); + + + const meshedSurf& surf = surface(); + + if (Pstream::master() || !parallel_) + { + if (!isDir(surfaceDir)) + { + mkDir(surfaceDir); + } + + pointIOField pts + ( + IOobject + ( + surfaceDir/"points", + dummyTime, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + surf.points() + ); + + // Do like regIOobject::writeObject but don't do instance() adaptation + // since this would write to e.g. 0/ instead of postProcessing/ + + // Try opening an OFstream for object + OFstream os(pts.objectPath()); + + //pts.writeHeader(os); + pts.writeData(os); + //pts.writeEndDivider(os); + } + + return surfaceDir; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type> +Foam::fileName Foam::surfaceWriters::boundaryDataWriter::writeTemplate +( + const word& fieldName, + const Field<Type>& localValues +) +{ + checkOpen(); + + // Geometry: rootdir/surfaceName/"points" + // Field: rootdir/surfaceName/<TIME>/field + + fileName surfaceDir = outputPath_; + + const fileName outputFile(surfaceDir/timeName()/fieldName); + + + // Dummy time to use as an objectRegistry + const fileName caseDir(argList::envGlobalPath()); + + Time dummyTime + ( + caseDir.path(), // root-path, + caseDir.name(), // case-name, + "system", // + "constant", // + false, // no function objects + false // no libs + ); + + + // Geometry merge() implicit + tmp<Field<Type>> tfield = mergeField(localValues); + + const meshedSurf& surf = surface(); + + if (Pstream::master() || !parallel_) + { + const pointField& points = surf.points(); + const faceList& faces = surf.faces(); + + if (!isDir(outputFile.path())) + { + mkDir(outputFile.path()); + } + + pointIOField pts + ( + IOobject + ( + surfaceDir/"points", + dummyTime, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ), + label(0) + ); + + if (this->isPointData()) + { + if (verbose_) + { + Info<< "Writing points to " + << surfaceDir/"points" << endl; + } + pts = points; + } + else + { + if (verbose_) + { + Info<< "Writing face centres to " + << surfaceDir/"points" << endl; + } + + primitivePatch pp(SubList<face>(faces, faces.size()), points); + + pts = pp.faceCentres(); + } + + { + // Do like regIOobject::writeObject but don't do instance() + // adaptation + // since this would write to e.g. 0/ instead of postProcessing/ + + // Try opening an OFstream for object + OFstream os(pts.objectPath()); + + //pts.writeHeader(os); + pts.writeData(os); + //pts.writeEndDivider(os); + } + + + // Write field + OFstream(outputFile)() << tfield(); + } + + return surfaceDir; +} + + +// Field writing methods +defineSurfaceWriterWriteFields(Foam::surfaceWriters::boundaryDataWriter); + + +// ************************************************************************* // diff --git a/src/surfMesh/writers/boundaryData/boundaryDataSurfaceWriter.H b/src/surfMesh/writers/boundaryData/boundaryDataSurfaceWriter.H new file mode 100644 index 0000000000000000000000000000000000000000..569c07fb5a14e9cf8cdcc3a9d9d71ec628b08763 --- /dev/null +++ b/src/surfMesh/writers/boundaryData/boundaryDataSurfaceWriter.H @@ -0,0 +1,187 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::surfaceWriters::boundaryDataWriter + +Description + A surfaceWriter for outputting to a form useable for the + timeVaryingMapped boundary condition. This reads the data from + constant/boundaryData/\<patch\> directory + + Typical way of working: + - use a sampledSurface of type 'patch' (to sample a patch): + \verbatim + surfaces + { + type surfaces; + surfaceFormat boundaryData; + fields ( p ); + surfaces + ( + outlet + { + type patch; + patches (outlet); + interpolate false; + } + ); + } + \endverbatim + + - write using this writer. + - move postProcessing/surfaces/outlet to constant/boundaryData/outlet + in your destination case. + - use a timeVaryingMappedFixedValue condition to read and interpolate + the profile: + type timeVaryingMappedFixedValue; + setAverage false; // do not use read average + offset 0; // do not apply offset to values + + Note: + - with 'interpolate false' the data is on the face centres of the + patch. Take care that a 2D geometry will only have a single row + of face centres so might not provide a valid triangulation + (this is what timeVaryingMappedFixedValue uses to do interpolation) + (Alternatively use timeVaryingMappedFixedValue with mapMethod 'nearest') + + \heading Output file locations + + The \c rootdir normally corresponds to something like + \c postProcessing/\<name\> + + where the geometry is written as: + \verbatim + rootdir + `-- surfaceName + `-- "points" + \endverbatim + + and field data: + \verbatim + rootdir + `-- surfaceName + |-- "points" + `-- timeName + `-- field + \endverbatim + +SourceFiles + boundaryDataSurfaceWriter.C + +\*---------------------------------------------------------------------------*/ + +#ifndef boundaryDataSurfaceWriter_H +#define boundaryDataSurfaceWriter_H + +#include "surfaceWriter.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace surfaceWriters +{ + +/*---------------------------------------------------------------------------*\ + Class boundaryDataWriter Declaration +\*---------------------------------------------------------------------------*/ + +class boundaryDataWriter +: + public surfaceWriter +{ + // Private Member Functions + + //- Templated write field operation + template<class Type> + fileName writeTemplate + ( + const word& fieldName, //!< Name of field + const Field<Type>& localValues //!< Local field values to write + ); + + +public: + + //- Runtime type information + TypeNameNoDebug("boundaryData"); + + + // Constructors + + //- Construct null + boundaryDataWriter(); + + //- Construct with some output options + boundaryDataWriter(const dictionary& options); + + //- Construct from components + boundaryDataWriter + ( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + //- Construct from components + boundaryDataWriter + ( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + + //- Destructor + virtual ~boundaryDataWriter() = default; + + + // Member Functions + + //- Write surface geometry to file. + virtual fileName write(); // override + + + declareSurfaceWriterWriteMethod(label); + declareSurfaceWriterWriteMethod(scalar); + declareSurfaceWriterWriteMethod(vector); + declareSurfaceWriterWriteMethod(sphericalTensor); + declareSurfaceWriterWriteMethod(symmTensor); + declareSurfaceWriterWriteMethod(tensor); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceWriters +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C b/src/surfMesh/writers/ensight/ensightSurfaceWriter.C similarity index 53% rename from src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C rename to src/surfMesh/writers/ensight/ensightSurfaceWriter.C index bcf4f00055ccd29d0db3c7c8a97ff8885e8570b5..69f2d69e8b2f80dd19549368fd0391299964c369 100644 --- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C +++ b/src/surfMesh/writers/ensight/ensightSurfaceWriter.C @@ -2,10 +2,10 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- - | Copyright (C) 2011-2013 OpenFOAM Foundation + | Copyright (C) 2011-2014 OpenFOAM Foundation ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,29 +26,32 @@ License \*---------------------------------------------------------------------------*/ #include "ensightSurfaceWriter.H" +#include "IOmanip.H" +#include "Fstream.H" +#include "OSspecific.H" +#include "ensightCase.H" #include "ensightPartFaces.H" -#include "makeSurfaceWriterMethods.H" +#include "ensightOutput.H" +#include "ensightPTraits.H" +#include "surfaceWriterMethods.H" +#include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { - makeSurfaceWriterType(ensightSurfaceWriter); - addToRunTimeSelectionTable(surfaceWriter, ensightSurfaceWriter, wordDict); +namespace surfaceWriters +{ + defineTypeName(ensightWriter); + addToRunTimeSelectionTable(surfaceWriter, ensightWriter, word); + addToRunTimeSelectionTable(surfaceWriter, ensightWriter, wordDict); +} } - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -// Field writing implementation -#include "ensightSurfaceWriterImpl.C" - -// Field writing methods -defineSurfaceWriterWriteFields(Foam::ensightSurfaceWriter); // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // -void Foam::ensightSurfaceWriter::printTimeset +void Foam::surfaceWriters::ensightWriter::printTimeset ( OSstream& os, const label ts, @@ -69,7 +72,7 @@ void Foam::ensightSurfaceWriter::printTimeset } -void Foam::ensightSurfaceWriter::printTimeset +void Foam::surfaceWriters::ensightWriter::printTimeset ( OSstream& os, const label ts, @@ -100,10 +103,9 @@ void Foam::ensightSurfaceWriter::printTimeset } - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::ensightSurfaceWriter::ensightSurfaceWriter() +Foam::surfaceWriters::ensightWriter::ensightWriter() : surfaceWriter(), writeFormat_(IOstream::ASCII), @@ -111,9 +113,12 @@ Foam::ensightSurfaceWriter::ensightSurfaceWriter() {} -Foam::ensightSurfaceWriter::ensightSurfaceWriter(const dictionary& options) +Foam::surfaceWriters::ensightWriter::ensightWriter +( + const dictionary& options +) : - surfaceWriter(), + surfaceWriter(options), writeFormat_ ( IOstreamOption::formatNames.lookupOrDefault @@ -128,6 +133,35 @@ Foam::ensightSurfaceWriter::ensightSurfaceWriter(const dictionary& options) {} +Foam::surfaceWriters::ensightWriter::ensightWriter +( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + ensightWriter(options) +{ + open(surf, outputPath, parallel); +} + + +Foam::surfaceWriters::ensightWriter::ensightWriter +( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + ensightWriter(options) +{ + open(points, faces, outputPath, parallel); +} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // Note that ensight does supports geometry in a separate file, @@ -135,114 +169,53 @@ Foam::ensightSurfaceWriter::ensightSurfaceWriter(const dictionary& options) // (when there are fields). // // Make this false to let the field writers take back control -bool Foam::ensightSurfaceWriter::separateGeometry() const +bool Foam::surfaceWriters::ensightWriter::separateGeometry() const { return false; } -void Foam::ensightSurfaceWriter::updateMesh -( - const fileName& outputDir, - const fileName& surfaceName -) const +Foam::fileName Foam::surfaceWriters::ensightWriter::write() { - if (collateTimes_ && Pstream::master()) - { - const ensight::FileName surfName(surfaceName); - - const fileName baseDir = outputDir.path()/surfName; - const fileName timeDir = outputDir.name(); - - // Convert timeDir to a value (if possible - use 0.0 otherwise) - scalar timeValue = 0.0; - readScalar(timeDir, timeValue); - - if (!isDir(baseDir)) - { - mkDir(baseDir); - } + // if (collateTimes_) + // { + // return writeCollated(); + // } + // else + // { + // return writeUncollated(); + // } + return writeUncollated(); +} - dictionary dict; - if (isFile(baseDir/"fieldsDict")) - { - IFstream is(baseDir/"fieldsDict"); - if (is.good() && dict.read(is)) - { - // ... any futher actions - } - } +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - dict.set("updateMesh", timeValue); +#include "ensightSurfaceWriterCollated.C" +#include "ensightSurfaceWriterUncollated.C" - { - OFstream os(baseDir/"fieldsDict"); - os << "// Summary of Ensight fields, times" << nl << nl; - dict.write(os, false); - } - } -} +// Field writing implementations -Foam::fileName Foam::ensightSurfaceWriter::write +template<class Type> +Foam::fileName Foam::surfaceWriters::ensightWriter::writeTemplate ( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, - const bool verbose -) const + const word& fieldName, + const Field<Type>& localValues +) { - const ensight::FileName surfName(surfaceName); - - // Uncollated - // ========== - // geometry: rootdir/time/surfaceName.case - // geometry: rootdir/time/surfaceName.00000000.mesh - - if (!isDir(outputDir)) + if (collateTimes_) { - mkDir(outputDir); + return writeCollated(fieldName, localValues); } - - OFstream osCase(outputDir/surfName + ".case"); - ensightGeoFile osGeom - ( - outputDir, - surfName + ".00000000.mesh", - writeFormat_ - ); - - if (verbose) + else { - Info<< "Writing case file to " << osCase.name() << endl; + return writeUncollated(fieldName, localValues); } - - const pointField& points = surf.points(); - const faceList& faces = surf.faces(); - - osCase - << "FORMAT" << nl - << "type: ensight gold" << nl - << nl - << "GEOMETRY" << nl - << "model: 1 " << osGeom.name().name() << nl - << nl - << "TIME" << nl; - - printTimeset(osCase, 1, 0.0); - - ensightPartFaces ensPart(0, osGeom.name().name(), points, faces, true); - osGeom << ensPart; - - return osCase.name(); +} - // Collated? - // ======== - // geometry: rootdir/surfaceName/surfaceName.case - // geometry: rootdir/surfaceName/surfaceName.mesh -} +defineSurfaceWriterWriteFields(Foam::surfaceWriters::ensightWriter); // ************************************************************************* // diff --git a/src/surfMesh/writers/ensight/ensightSurfaceWriter.H b/src/surfMesh/writers/ensight/ensightSurfaceWriter.H new file mode 100644 index 0000000000000000000000000000000000000000..39a958a20bfbba7534bef3e83364415140668c05 --- /dev/null +++ b/src/surfMesh/writers/ensight/ensightSurfaceWriter.H @@ -0,0 +1,198 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2011, 2015-2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- + | Copyright (C) 2011 OpenFOAM Foundation +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::surfaceWriters::ensightWriter + +Description + A surfaceWriter for Ensight format. + + \verbatim + formatOptions + { + ensight + { + format ascii; + collateTimes true; + } + } + \endverbatim + + Format options: + \table + Property | Description | Required | Default + format | ascii/binary | no | ascii + collateTimes | use common geometry for times | no | true + \endtable + +SourceFiles + ensightSurfaceWriter.C + +\*---------------------------------------------------------------------------*/ + +#ifndef ensightSurfaceWriter_H +#define ensightSurfaceWriter_H + +#include "surfaceWriter.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace surfaceWriters +{ + +/*---------------------------------------------------------------------------*\ + Class ensightWriter Declaration +\*---------------------------------------------------------------------------*/ + +class ensightWriter +: + public surfaceWriter +{ + // Private Data + + //- Write option (default: IOstream::ASCII) + IOstream::streamFormat writeFormat_; + + //- Collate times (default: true) + bool collateTimes_; + + + // Private Member Functions + + //- Print time-set for ensight case file + static void printTimeset + ( + OSstream& os, + const label ts, + const scalar& timeValue + ); + + //- Print time-set for ensight case file + static void printTimeset + ( + OSstream& os, + const label ts, + const UList<scalar>& times + ); + + + //- Write geometry + fileName writeCollated(); + + //- Write geometry + fileName writeUncollated(); + + //- Templated write operation - one file per timestep + template<class Type> + fileName writeCollated + ( + const word& fieldName, //!< Name of field + const Field<Type>& localValues //!< Local field values to write + ); + + //- Templated write operation - all time steps in single file + template<class Type> + fileName writeUncollated + ( + const word& fieldName, //!< Name of field + const Field<Type>& localValues //!< Local field values to write + ); + + //- Templated write operation + template<class Type> + fileName writeTemplate + ( + const word& fieldName, //!< Name of field + const Field<Type>& localValues //!< Local field values to write + ); + +public: + + //- Runtime type information + TypeNameNoDebug("ensight"); + + + // Constructors + + //- Construct null + ensightWriter(); + + //- Construct with some output options + explicit ensightWriter(const dictionary& options); + + //- Construct from components + ensightWriter + ( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + //- Construct from components + ensightWriter + ( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + + //- Destructor + virtual ~ensightWriter() = default; + + + // Member Functions + + //- True if the surface format supports geometry in a separate file. + // False if geometry and field must be in a single file + virtual bool separateGeometry() const; + + //- Write single surface geometry to file. + virtual fileName write(); // override + + declareSurfaceWriterWriteMethod(label); + declareSurfaceWriterWriteMethod(scalar); + declareSurfaceWriterWriteMethod(vector); + declareSurfaceWriterWriteMethod(sphericalTensor); + declareSurfaceWriterWriteMethod(symmTensor); + declareSurfaceWriterWriteMethod(tensor); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceWriters +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C b/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C new file mode 100644 index 0000000000000000000000000000000000000000..0b2724ae61618a5d9378c28bedb1a9a5290a5e60 --- /dev/null +++ b/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C @@ -0,0 +1,376 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- + | Copyright (C) 2011-2014 OpenFOAM Foundation +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated() +{ + // Collated? + // ======== + // Geometry: rootdir/surfaceName/surfaceName.case + // Geometry: rootdir/surfaceName/surfaceName.mesh + + return fileName(); +} + + +template<class Type> +Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated +( + const word& fieldName, + const Field<Type>& localValues +) +{ + checkOpen(); + + const ensight::FileName surfName(outputPath_.name()); + const ensight::VarName varName(fieldName); + + + // Collated + // ======== + // Geometry: rootdir/surfaceName/surfaceName.case + // Geometry: rootdir/surfaceName/data/<index>/geometry + // Field: rootdir/surfaceName/data/<index>/field + + // Use surface name as sub-directory for results. Eg, + // - SURF1/SURF1.case + // - SURF1/data/00000000/geometry + // - SURF1/data/00000000/VAR1 + // - SURF1/data/00000000/VAR2 + + // Names "data" and "geometry" as per ensightCase: + const char* fmt = "%08d"; + const char* mask = "data/********/"; + + + // Ignore the useTimeDir setting - manage ourselves + const fileName baseDir = outputPath_; + + const word timeDir = timeName(); + const scalar timeValue = currTime_.value(); + + const fileName outputFile = baseDir / surfName + ".case"; + + if (verbose_) + { + Info<< "Writing case file to " << outputFile << endl; + } + + + // Mesh changed since last output? Do before any merging. + const bool meshChanged = (!upToDate_); + + // geometry merge() implicit + tmp<Field<Type>> tfield = mergeField(localValues); + + const meshedSurf& surf = surface(); + + if (Pstream::master() || !parallel_) + { + if (!isDir(outputFile.path())) + { + mkDir(outputFile.path()); + } + + scalar meshValue = 0; + label meshIndex = 0; + label timeIndex = 0; + + fileName geometryName; + + // Do case file + { + dictionary dict; + scalarList meshes; + scalarList times; + bool stateChanged = meshChanged; + + if (isFile(baseDir/"fieldsDict")) + { + IFstream is(baseDir/"fieldsDict"); + if (is.good() && dict.read(is)) + { + dict.readIfPresent("meshes", meshes); + dict.readIfPresent("times", times); + + timeIndex = 1+findLower(times, timeValue); + + if (meshChanged) + { + meshValue = timeValue; + meshIndex = 1+findLower(meshes, meshValue); + } + else if (meshes.size()) + { + meshIndex = meshes.size()-1; + meshValue = meshes.last(); + } + else + { + meshIndex = 0; + } + } + } + + // Update stored times list + meshes.resize(meshIndex+1, -1); + times.resize(timeIndex+1, -1); + + if (meshes[meshIndex] != meshValue) + { + stateChanged = true; + } + if (times[timeIndex] != timeValue) + { + stateChanged = true; + } + + meshes[meshIndex] = meshValue; + times[timeIndex] = timeValue; + + geometryName = + "data"/word::printf(fmt, meshIndex)/ensightCase::geometryName; + + + // Add my information to dictionary + { + dict.set("meshes", meshes); + dict.set("times", times); + if (dict.found("fields")) + { + dictionary& fieldsDict = dict.subDict("fields"); + if (!fieldsDict.found(fieldName)) + { + dictionary fieldDict; + fieldDict.set("type", ensightPTraits<Type>::typeName); + fieldDict.set("name", varName); // ensight variable name + + fieldsDict.set(fieldName, fieldDict); + + stateChanged = true; + } + } + else + { + dictionary fieldDict; + fieldDict.set("type", ensightPTraits<Type>::typeName); + fieldDict.set("name", varName); // ensight variable name + + dictionary fieldsDict; + fieldsDict.set(fieldName, fieldDict); + + dict.set("fields", fieldsDict); + + stateChanged = true; + } + } + + + if (stateChanged) + { + if (verbose_) + { + Info<< "Writing state file to fieldsDict" << endl; + } + { + OFstream os(baseDir/"fieldsDict"); + os << "// Summary of Ensight fields, times" << nl << nl; + dict.write(os, false); + } + + OFstream osCase(outputFile, IOstream::ASCII); + + // Format options + osCase.setf(ios_base::left); + osCase.setf(ios_base::scientific, ios_base::floatfield); + osCase.precision(5); + + if (verbose_) + { + Info<< "Writing case file to " << osCase.name() << endl; + } + + // The geometry can be any of the following: + // 0: constant/static + // 1: moving, with the same frequency as the data + // 2: moving, with different frequency as the data + + const label tsGeom = + (meshes.size() == 1 ? 0 : meshes == times ? 1 : 2); + + osCase + << "FORMAT" << nl + << "type: ensight gold" << nl + << nl + << "GEOMETRY" << nl; + + + if (tsGeom) + { + // moving + osCase + << "model: " << tsGeom << " " // time-set (1|2) + << mask << geometryName.name() << nl; + } + else + { + // steady + osCase + << "model: " + << geometryName.c_str() << nl; + } + + osCase + << nl + << "VARIABLE" << nl; + + const dictionary& fieldsDict = dict.subDict("fields"); + for (const entry& dEntry : fieldsDict) + { + const dictionary& subDict = dEntry.dict(); + + const word fieldType(subDict.get<word>("type")); + const word varName = subDict.lookupOrDefault + ( + "name", + dEntry.keyword() // fieldName as fallback + ); + + osCase + << fieldType + << + ( + this->isPointData() + ? " per node: 1 " // time-set 1 + : " per element: 1 " // time-set 1 + ) + << setw(15) << varName << ' ' + << mask << varName << nl; + } + + osCase + << nl + << "TIME" << nl; + + printTimeset(osCase, 1, times); + if (tsGeom == 2) + { + printTimeset(osCase, 2, meshes); + } + + osCase << "# end" << nl; + } + } + + + // Location for data (and possibly the geometry as well) + fileName dataDir = baseDir/"data"/word::printf(fmt, timeIndex); + + // As per mkdir -p "data/00000000" + mkDir(dataDir); + + + const fileName meshFile(baseDir/geometryName); + + // Write geometry + ensightPartFaces ensPart + ( + 0, + meshFile.name(), + surf.points(), + surf.faces(), + true // contiguous points + ); + if (!exists(meshFile)) + { + if (verbose_) + { + Info<< "Writing mesh file to " << meshFile.name() << endl; + } + // Use two-argument form for path-name to avoid validating base-dir + ensightGeoFile osGeom + ( + meshFile.path(), + meshFile.name(), + writeFormat_ + ); + osGeom << ensPart; + } + + // Write field + ensightFile osField + ( + dataDir, + varName, + writeFormat_ + ); + + if (verbose_) + { + Info<< "Writing field file to " << osField.name() << endl; + } + + // Write field + osField.writeKeyword(ensightPTraits<Type>::typeName); + + if (this->isPointData()) + { + ensightOutput::Serial::writePointField + ( + tfield(), + ensPart, + osField + // serial + ); + } + else + { + ensightOutput::Detail::writeFaceField + ( + tfield(), + ensPart, + osField, + false // serial + ); + } + + // Place a timestamp in the directory for future reference + { + OFstream timeStamp(dataDir/"time"); + timeStamp + << "# timestep time" << nl + << dataDir.name() << " " << timeValue << nl; + } + } + + + return outputFile; +} + + +// ************************************************************************* // diff --git a/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C b/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C new file mode 100644 index 0000000000000000000000000000000000000000..c3cd3a537891b3d66d3c88d147c85b39564d274f --- /dev/null +++ b/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C @@ -0,0 +1,252 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- + | Copyright (C) 2011-2014 OpenFOAM Foundation +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated() +{ + checkOpen(); + + const ensight::FileName surfName(outputPath_.name()); + + + // Uncollated + // ========== + // Geometry: rootdir/<TIME>/surfaceName.case + // Geometry: rootdir/<TIME>/surfaceName.00000000.mesh + + fileName outputDir; + if (useTimeDir() && !timeName().empty()) + { + // Splice in time-directory + outputDir = outputPath_.path() / timeName(); + } + else + { + outputDir = outputPath_.path(); + } + + const fileName outputFile = outputDir / surfName + ".case"; + + if (verbose_) + { + Info<< "Writing case file to " << outputFile << endl; + } + + + const meshedSurf& surf = surface(); + + if (Pstream::master() || !parallel_) + { + if (!isDir(outputDir)) + { + mkDir(outputDir); + } + + OFstream osCase(outputFile); + ensightGeoFile osGeom + ( + outputDir, + surfName + ".00000000.mesh", + writeFormat_ + ); + + osCase + << "FORMAT" << nl + << "type: ensight gold" << nl + << nl + << "GEOMETRY" << nl + << "model: 1 " << osGeom.name().name() << nl + << nl + << "TIME" << nl; + + printTimeset(osCase, 1, 0.0); + + ensightPartFaces ensPart + ( + 0, + osGeom.name().name(), + surf.points(), + surf.faces(), + true // contiguous points + ); + osGeom << ensPart; + } + + return outputFile; +} + + +template<class Type> +Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated +( + const word& fieldName, + const Field<Type>& localValues +) +{ + checkOpen(); + + const ensight::FileName surfName(outputPath_.name()); + const ensight::VarName varName(fieldName); + + + // Uncollated + // ========== + // geometry: rootdir/time/<field>/surfaceName.case + // geometry: rootdir/time/<field>/surfaceName.<index>.mesh + // field: rootdir/time/<field>/surfaceName.<index>.<field> + + // Variable name as sub-directory for results. Eg, + // - VAR1/SURF1.case + // - VAR1/SURF1.00000000.mesh + // - VAR1/SURF1.00000001.VAR1 + // and + // - VAR2/SURF1.case + // - VAR2/SURF1.00000000.mesh + // - VAR2/SURF1.00000001.VAR2 + + fileName outputDir; + if (useTimeDir() && !timeName().empty()) + { + // Splice in time-directory + outputDir = outputPath_.path() / timeName(); + } + else + { + outputDir = outputPath_.path(); + } + + const fileName baseDir = outputDir / varName; + const word timeDir = timeName(); + const scalar timeValue = currTime_.value(); + + const fileName outputFile = baseDir / surfName + ".case"; + + if (verbose_) + { + Info<< "Writing case file to " << outputFile << endl; + } + + + // geometry merge() implicit + tmp<Field<Type>> tfield = mergeField(localValues); + + const meshedSurf& surf = surface(); + + if (Pstream::master() || !parallel_) + { + if (!isDir(outputFile.path())) + { + mkDir(outputFile.path()); + } + + OFstream osCase(outputFile, IOstream::ASCII); + + // Format options + osCase.setf(ios_base::left); + osCase.setf(ios_base::scientific, ios_base::floatfield); + osCase.precision(5); + + ensightGeoFile osGeom + ( + baseDir, + surfName + ".00000000.mesh", + writeFormat_ + ); + ensightFile osField + ( + baseDir, + surfName + ".00000000." + varName, + writeFormat_ + ); + + osCase + << "FORMAT" << nl + << "type: ensight gold" << nl + << nl + << "GEOMETRY" << nl + << "model: 1 " << osGeom.name().name() << nl + << nl + << "VARIABLE" << nl + << ensightPTraits<Type>::typeName + << + ( + this->isPointData() + ? " per node: 1 " // time-set 1 + : " per element: 1 " // time-set 1 + ) + << setw(15) << varName << ' ' + << surfName.c_str() << ".********." << varName << nl; + + osCase + << nl + << "TIME" << nl; + + printTimeset(osCase, 1, timeValue); + osCase << "# end" << nl; + + + ensightPartFaces ensPart + ( + 0, + osGeom.name().name(), + surf.points(), + surf.faces(), + true // contiguous points + ); + osGeom << ensPart; + + // Write field + osField.writeKeyword(ensightPTraits<Type>::typeName); + + if (this->isPointData()) + { + ensightOutput::Serial::writePointField + ( + tfield(), + ensPart, + osField + // serial + ); + } + else + { + ensightOutput::Detail::writeFaceField + ( + tfield(), + ensPart, + osField, + false // serial + ); + } + } + + return outputFile; +} + + +// ************************************************************************* // diff --git a/src/surfMesh/writers/foam/foamSurfaceWriter.C b/src/surfMesh/writers/foam/foamSurfaceWriter.C new file mode 100644 index 0000000000000000000000000000000000000000..8d72939d696ce3af7b135841cadbec07e74866ee --- /dev/null +++ b/src/surfMesh/writers/foam/foamSurfaceWriter.C @@ -0,0 +1,208 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- + | Copyright (C) 2011-2016 OpenFOAM Foundation +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "foamSurfaceWriter.H" +#include "OFstream.H" +#include "OSspecific.H" +#include "surfaceWriterMethods.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace surfaceWriters +{ + defineTypeName(foamWriter); + addToRunTimeSelectionTable(surfaceWriter, foamWriter, word); +} +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surfaceWriters::foamWriter::foamWriter() +: + surfaceWriter() +{} + + +Foam::surfaceWriters::foamWriter::foamWriter +( + const dictionary& options +) +: + surfaceWriter(options) +{} + + +Foam::surfaceWriters::foamWriter::foamWriter +( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + foamWriter(options) +{ + open(surf, outputPath, parallel); +} + + +Foam::surfaceWriters::foamWriter::foamWriter +( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + foamWriter(options) +{ + open(points, faces, outputPath, parallel); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::fileName Foam::surfaceWriters::foamWriter::write() +{ + checkOpen(); + + // Geometry: + // - rootdir/<TIME>/surfaceName/{points,faces} + + fileName surfaceDir = outputPath_; + if (useTimeDir() && !timeName().empty()) + { + // Splice in time-directory + surfaceDir = outputPath_.path() / timeName() / outputPath_.name(); + } + + if (verbose_) + { + Info<< "Writing geometry to " << surfaceDir << endl; + } + + + const meshedSurf& surf = surface(); + + if (Pstream::master() || !parallel_) + { + const pointField& points = surf.points(); + const faceList& faces = surf.faces(); + + if (!isDir(surfaceDir)) + { + mkDir(surfaceDir); + } + + // Points + OFstream(surfaceDir/"points")() << points; + + // Faces + OFstream(surfaceDir/"faces")() << faces; + + // Face centers. + // Not really necessary but very handy when reusing as inputs + // for e.g. timeVaryingMapped bc. + pointField faceCentres(faces.size(), Zero); + + forAll(faces, facei) + { + faceCentres[facei] = faces[facei].centre(points); + } + + OFstream(surfaceDir/"faceCentres")() << faceCentres; + } + + return surfaceDir; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type> +Foam::fileName Foam::surfaceWriters::foamWriter::writeTemplate +( + const word& fieldName, + const Field<Type>& localValues +) +{ + checkOpen(); + + // Geometry should already have been written + // Values to separate directory (e.g. "scalarField/p") + + // Field: rootdir/<TIME>/surfaceName/fieldType/field + //?? -> or rootdir/surfaceName/fieldType/<TIME>/field + + fileName surfaceDir = outputPath_; + if (useTimeDir() && !timeName().empty()) + { + // Splice in time-directory + surfaceDir = outputPath_.path() / timeName() / outputPath_.name(); + } + + const fileName outputFile + ( + surfaceDir + / (word(pTraits<Type>::typeName) + FieldBase::typeName) + / fieldName + ); + + if (verbose_) + { + Info<< "Writing field " << fieldName << " to " << surfaceDir << endl; + } + + + // geometry merge() implicit + tmp<Field<Type>> tfield = mergeField(localValues); + + if (Pstream::master()) + { + if (!isDir(outputFile.path())) + { + mkDir(outputFile.path()); + } + + // Write field + OFstream(outputFile)() << tfield(); + } + + return outputFile; +} + + +// Field writing methods +defineSurfaceWriterWriteFields(Foam::surfaceWriters::foamWriter); + + +// ************************************************************************* // diff --git a/src/surfMesh/writers/foam/foamSurfaceWriter.H b/src/surfMesh/writers/foam/foamSurfaceWriter.H new file mode 100644 index 0000000000000000000000000000000000000000..893f773ce558c02532062aa620fc2577d4408f47 --- /dev/null +++ b/src/surfMesh/writers/foam/foamSurfaceWriter.H @@ -0,0 +1,163 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- + | Copyright (C) 2011-2016 OpenFOAM Foundation +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::surfaceWriters::foamWriter + +Description + A surfaceWriter for OpenFOAM surfaces + + \heading Output file locations + + The \c rootdir normally corresponds to something like + \c postProcessing/\<name\> + + \subheading Geometry + \verbatim + rootdir + `-- timeName + `-- surfaceName + |-- "points" + |-- "faceCentres" + `-- "faces" + \endverbatim + + \subheading Fields + \verbatim + rootdir + `-- timeName + `-- surfaceName + |-- scalarField + | |-- field + | `-- field + |-- vectorField + |-- field + `-- field + \endverbatim + +SourceFiles + foamSurfaceWriter.C + +\*---------------------------------------------------------------------------*/ + +#ifndef foamSurfaceWriter_H +#define foamSurfaceWriter_H + +#include "surfaceWriter.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace surfaceWriters +{ + +/*---------------------------------------------------------------------------*\ + Class foamWriter Declaration +\*---------------------------------------------------------------------------*/ + +class foamWriter +: + public surfaceWriter +{ + // Private Member Functions + + //- Templated write operation + template<class Type> + fileName writeTemplate + ( + const word& fieldName, //!< Name of field + const Field<Type>& localValues //!< Local field values to write + ); + + +public: + + //- Runtime type information + TypeNameNoDebug("foam"); + + + // Constructors + + //- Construct null + foamWriter(); + + //- Construct with some output options + explicit foamWriter(const dictionary& options); + + //- Construct from components + foamWriter + ( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + //- Construct from components + foamWriter + ( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + + //- Destructor + virtual ~foamWriter() = default; + + + // Member Functions + + //- The surface format has geometry in a separate file. + virtual bool separateGeometry() const + { + return true; + } + + //- Write surface geometry to file. + virtual fileName write(); // override + + declareSurfaceWriterWriteMethod(label); + declareSurfaceWriterWriteMethod(scalar); + declareSurfaceWriterWriteMethod(vector); + declareSurfaceWriterWriteMethod(sphericalTensor); + declareSurfaceWriterWriteMethod(symmTensor); + declareSurfaceWriterWriteMethod(tensor); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceWriters +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.C b/src/surfMesh/writers/nastran/nastranSurfaceWriter.C similarity index 76% rename from src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.C rename to src/surfMesh/writers/nastran/nastranSurfaceWriter.C index bf3d23d19b5f214777470549d6e27338cf05cf7d..da98e638d4ba97223e1c1ad0b1c5331ffc6d4dc8 100644 --- a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.C +++ b/src/surfMesh/writers/nastran/nastranSurfaceWriter.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2012-2016 OpenFOAM Foundation @@ -26,17 +26,22 @@ License \*---------------------------------------------------------------------------*/ #include "nastranSurfaceWriter.H" -#include "IOmanip.H" #include "Pair.H" -#include "HashSet.H" -#include "makeSurfaceWriterMethods.H" +#include "IOmanip.H" +#include "OSspecific.H" +#include "surfaceWriterMethods.H" +#include "addToRunTimeSelectionTable.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { - makeSurfaceWriterType(nastranSurfaceWriter); - addToRunTimeSelectionTable(surfaceWriter, nastranSurfaceWriter, wordDict); +namespace surfaceWriters +{ + defineTypeName(nastranWriter); + addToRunTimeSelectionTable(surfaceWriter, nastranWriter, word); + addToRunTimeSelectionTable(surfaceWriter, nastranWriter, wordDict); +} } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -45,11 +50,12 @@ namespace Foam #include "nastranSurfaceWriterImpl.C" // Field writing methods -defineSurfaceWriterWriteFields(Foam::nastranSurfaceWriter); +defineSurfaceWriterWriteFields(Foam::surfaceWriters::nastranWriter); + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -Foam::Ostream& Foam::nastranSurfaceWriter::writeKeyword +Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeKeyword ( Ostream& os, const word& keyword @@ -59,7 +65,7 @@ Foam::Ostream& Foam::nastranSurfaceWriter::writeKeyword } -void Foam::nastranSurfaceWriter::writeCoord +void Foam::surfaceWriters::nastranWriter::writeCoord ( Ostream& os, const point& pt, @@ -117,7 +123,7 @@ void Foam::nastranSurfaceWriter::writeCoord } -void Foam::nastranSurfaceWriter::writeFace +void Foam::surfaceWriters::nastranWriter::writeFace ( Ostream& os, const word& faceType, @@ -193,7 +199,7 @@ void Foam::nastranSurfaceWriter::writeFace } -void Foam::nastranSurfaceWriter::writeGeometry +void Foam::surfaceWriters::nastranWriter::writeGeometry ( Ostream& os, const meshedSurf& surf, @@ -257,13 +263,13 @@ void Foam::nastranSurfaceWriter::writeGeometry } -Foam::Ostream& Foam::nastranSurfaceWriter::writeFooter +Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeFooter ( Ostream& os, const meshedSurf& surf ) const { - // zone id have been used for the PID. Find unique values. + // Zone id have been used for the PID. Find unique values. labelList pidsUsed = labelHashSet(surf.zoneIds()).sortedToc(); if (pidsUsed.empty()) @@ -286,7 +292,7 @@ Foam::Ostream& Foam::nastranSurfaceWriter::writeFooter } - // use single material ID + // Use single material ID const label MID = 1; @@ -307,7 +313,7 @@ Foam::Ostream& Foam::nastranSurfaceWriter::writeFooter // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::nastranSurfaceWriter::nastranSurfaceWriter() +Foam::surfaceWriters::nastranWriter::nastranWriter() : surfaceWriter(), writeFormat_(fieldFormat::SHORT), @@ -317,9 +323,12 @@ Foam::nastranSurfaceWriter::nastranSurfaceWriter() {} -Foam::nastranSurfaceWriter::nastranSurfaceWriter(const dictionary& options) +Foam::surfaceWriters::nastranWriter::nastranWriter +( + const dictionary& options +) : - surfaceWriter(), + surfaceWriter(options), writeFormat_ ( fileFormats::NASCore::fieldFormatNames.lookupOrDefault @@ -353,43 +362,82 @@ Foam::nastranSurfaceWriter::nastranSurfaceWriter(const dictionary& options) } -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -Foam::fileName Foam::nastranSurfaceWriter::write +Foam::surfaceWriters::nastranWriter::nastranWriter ( - const fileName& outputDir, - const fileName& surfaceName, const meshedSurf& surf, - const bool verbose -) const + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + nastranWriter(options) { - // geometry: rootdir/time/surfaceName.nas + open(surf, outputPath, parallel); +} + - if (!isDir(outputDir)) +Foam::surfaceWriters::nastranWriter::nastranWriter +( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + nastranWriter(options) +{ + open(points, faces, outputPath, parallel); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::fileName Foam::surfaceWriters::nastranWriter::write() +{ + checkOpen(); + + // Geometry: rootdir/<TIME>/surfaceName.nas + + fileName outputFile = outputPath_; + if (useTimeDir() && !timeName().empty()) { - mkDir(outputDir); + // Splice in time-directory + outputFile = outputPath_.path() / timeName() / outputPath_.name(); } + outputFile.ext("nas"); - OFstream os(outputDir/surfaceName + ".nas"); - fileFormats::NASCore::setPrecision(os, writeFormat_); - - if (verbose) + if (verbose_) { - Info<< "Writing nastran file to " << os.name() << endl; + Info<< "Writing nastran geometry to " << outputFile << endl; } - os << "TITLE=OpenFOAM " << surfaceName.c_str() - << " mesh" << nl - << "$" << nl - << "BEGIN BULK" << nl; - List<DynamicList<face>> decomposedFaces; - writeGeometry(os, surf, decomposedFaces); + const meshedSurf& surf = surface(); - writeFooter(os, surf) - << "ENDDATA" << nl; + if (Pstream::master() || !parallel_) + { + if (!isDir(outputFile.path())) + { + mkDir(outputFile.path()); + } + + OFstream os(outputFile); + fileFormats::NASCore::setPrecision(os, writeFormat_); + + os << "TITLE=OpenFOAM " << outputPath_.name() + << " mesh" << nl + << "$" << nl + << "BEGIN BULK" << nl; + + List<DynamicList<face>> decomposedFaces; + writeGeometry(os, surf, decomposedFaces); + + writeFooter(os, surf) + << "ENDDATA" << nl; + } - return os.name(); + return outputFile; } diff --git a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.H b/src/surfMesh/writers/nastran/nastranSurfaceWriter.H similarity index 55% rename from src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.H rename to src/surfMesh/writers/nastran/nastranSurfaceWriter.H index d8140b99e6615ad80b86c915dbf6b1d35f750b54..3993148cada03a2f84e1b1944ad99477a749da3a 100644 --- a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriter.H +++ b/src/surfMesh/writers/nastran/nastranSurfaceWriter.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2012-2016 OpenFOAM Foundation @@ -24,7 +24,7 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - Foam::nastranSurfaceWriter + Foam::surfaceWriters::nastranWriter Description A surface writer for the Nastran file format - both surface mesh and fields @@ -82,7 +82,7 @@ Description SourceFiles nastranSurfaceWriter.C - nastranSurfaceWriterTemplates.C + nastranSurfaceWriterImpl.C \*---------------------------------------------------------------------------*/ @@ -97,12 +97,14 @@ SourceFiles namespace Foam { +namespace surfaceWriters +{ /*---------------------------------------------------------------------------*\ - Class nastranSurfaceWriter Declaration + Class nastranWriter Declaration \*---------------------------------------------------------------------------*/ -class nastranSurfaceWriter +class nastranWriter : public surfaceWriter { @@ -117,7 +119,7 @@ public: private: - // Private data + // Private Data //- Field format (width and separator) fieldFormat writeFormat_; @@ -189,123 +191,68 @@ private: template<class Type> fileName writeTemplate ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry const word& fieldName, //!< Name of field - const Field<Type>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; + const Field<Type>& localValues //!< Local field values to write + ); public: //- Runtime type information - TypeName("nastran"); + TypeNameNoDebug("nastran"); // Constructors //- Construct null - nastranSurfaceWriter(); + nastranWriter(); //- Construct with some output options - nastranSurfaceWriter(const dictionary& options); + explicit nastranWriter(const dictionary& options); + + //- Construct from components + nastranWriter + ( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + //- Construct from components + nastranWriter + ( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); //- Destructor - virtual ~nastranSurfaceWriter() = default; + virtual ~nastranWriter() = default; // Member Functions - //- True if the surface format supports geometry in a separate file. - // False if geometry and field must be in a single file - virtual bool separateGeometry() const - { - return false; - } - - //- Write single surface geometry to file. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const bool verbose = false //!< Additional verbosity - ) const; // override + // Write + //- Write surface geometry to file. + virtual fileName write(); // override - //- Write scalarField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<scalar>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write vectorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<vector>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write sphericalTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<sphericalTensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write symmTensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<symmTensor>& values,//!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override - - //- Write tensorField for a single surface to file. - // One value per face or vertex. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const word& fieldName, //!< Name of field - const Field<tensor>& values, //!< Field values to write - const bool isNodeValues = false,//!< Values are per-vertex - const bool verbose = false //!< Additional verbosity - ) const; // override + declareSurfaceWriterWriteMethod(label); + declareSurfaceWriterWriteMethod(scalar); + declareSurfaceWriterWriteMethod(vector); + declareSurfaceWriterWriteMethod(sphericalTensor); + declareSurfaceWriterWriteMethod(symmTensor); + declareSurfaceWriterWriteMethod(tensor); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace surfaceWriters } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriterImpl.C b/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C similarity index 63% rename from src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriterImpl.C rename to src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C index fe0aabd52d5b886e087e71a098e6cc041a2b1301..a1809c91e6144810d9c40991fe6f0237c555eb3e 100644 --- a/src/sampling/sampledSurface/writers/nastran/nastranSurfaceWriterImpl.C +++ b/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2012-2016 OpenFOAM Foundation @@ -32,7 +32,7 @@ License // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template<class Type> -Foam::Ostream& Foam::nastranSurfaceWriter::writeValue +Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeValue ( Ostream& os, const Type& value @@ -64,7 +64,7 @@ Foam::Ostream& Foam::nastranSurfaceWriter::writeValue template<class Type> -Foam::Ostream& Foam::nastranSurfaceWriter::writeFaceValue +Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeFaceValue ( Ostream& os, const loadFormat format, @@ -144,17 +144,14 @@ Foam::Ostream& Foam::nastranSurfaceWriter::writeFaceValue template<class Type> -Foam::fileName Foam::nastranSurfaceWriter::writeTemplate +Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate ( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const + const Field<Type>& localValues +) { + checkOpen(); + if (!fieldMap_.found(fieldName)) { FatalErrorInFunction @@ -168,74 +165,97 @@ Foam::fileName Foam::nastranSurfaceWriter::writeTemplate const loadFormat& format(fieldMap_[fieldName]); - // field: rootdir/time/field/surfaceName.nas + // Field: rootdir/<TIME>/field/surfaceName.nas + fileName outputFile = outputPath_.path(); + if (useTimeDir() && !timeName().empty()) + { + // Splice in time-directory + outputFile /= timeName(); + } + outputFile /= fieldName / outputPath_.name(); + outputFile.ext("nas"); - if (!isDir(outputDir/fieldName)) + if (verbose_) { - mkDir(outputDir/fieldName); + Info<< "Writing field " << fieldName << " to " << outputFile << endl; } - // const scalar timeValue = Foam::name(this->mesh().time().timeValue()); - const scalar timeValue = 0.0; - OFstream os(outputDir/fieldName/surfaceName + ".nas"); - fileFormats::NASCore::setPrecision(os, writeFormat_); + // geometry merge() implicit + tmp<Field<Type>> tfield = mergeField(localValues); - if (verbose) + const meshedSurf& surf = surface(); + + if (Pstream::master() || !parallel_) { - Info<< "Writing nastran file to " << os.name() << endl; - } + const auto& values = tfield(); - os << "TITLE=OpenFOAM " << surfaceName.c_str() - << " " << fieldName << " data" << nl - << "$" << nl - << "TIME " << timeValue << nl - << "$" << nl - << "BEGIN BULK" << nl; + if (!isDir(outputFile.path())) + { + mkDir(outputFile.path()); + } + + const scalar timeValue = 0.0; + + OFstream os(outputFile); + fileFormats::NASCore::setPrecision(os, writeFormat_); - List<DynamicList<face>> decomposedFaces; - writeGeometry(os, surf, decomposedFaces); + if (verbose_) + { + Info<< "Writing nastran file to " << os.name() << endl; + } - os << "$" << nl - << "$ Field data" << nl - << "$" << nl; + os << "TITLE=OpenFOAM " << outputFile.name() + << " " << fieldName << " data" << nl + << "$" << nl + << "TIME " << timeValue << nl + << "$" << nl + << "BEGIN BULK" << nl; - label elemId = 0; + List<DynamicList<face>> decomposedFaces; + writeGeometry(os, surf, decomposedFaces); - if (isNodeValues) - { - for (const DynamicList<face>& dFaces : decomposedFaces) + os << "$" << nl + << "$ Field data" << nl + << "$" << nl; + + label elemId = 0; + + if (this->isPointData()) { - for (const face& f : dFaces) + for (const DynamicList<face>& dFaces : decomposedFaces) { - Type v = Zero; - - for (const label verti : f) + for (const face& f : dFaces) { - v += values[verti]; - } - v /= f.size(); + Type v = Zero; + + for (const label verti : f) + { + v += values[verti]; + } + v /= f.size(); - writeFaceValue(os, format, v, ++elemId); + writeFaceValue(os, format, v, ++elemId); + } } } - } - else - { - for (const DynamicList<face>& dFaces : decomposedFaces) + else { - forAll(dFaces, facei) + for (const DynamicList<face>& dFaces : decomposedFaces) { - writeFaceValue(os, format, values[facei], ++elemId); + forAll(dFaces, facei) + { + writeFaceValue(os, format, values[facei], ++elemId); + } } } - } - writeFooter(os, surf) - << "ENDDATA" << endl; + writeFooter(os, surf) + << "ENDDATA" << endl; + } - return os.name(); + return outputFile; } diff --git a/src/surfMesh/writers/null/nullSurfaceWriter.C b/src/surfMesh/writers/null/nullSurfaceWriter.C new file mode 100644 index 0000000000000000000000000000000000000000..b9bcbcc1c651ecec7add62d5a281f56789f82585 --- /dev/null +++ b/src/surfMesh/writers/null/nullSurfaceWriter.C @@ -0,0 +1,121 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "nullSurfaceWriter.H" +#include "surfaceWriterMethods.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace surfaceWriters +{ + defineTypeName(nullWriter); + addToRunTimeSelectionTable(surfaceWriter, nullWriter, word); + addToRunTimeSelectionTable(surfaceWriter, nullWriter, wordDict); +} +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surfaceWriters::nullWriter::nullWriter() +: + surfaceWriter() +{} + + +Foam::surfaceWriters::nullWriter::nullWriter(const dictionary& options) +: + surfaceWriter() +{} + + +Foam::surfaceWriters::nullWriter::nullWriter +( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + surfaceWriter() +{} + + +Foam::surfaceWriters::nullWriter::nullWriter +( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + surfaceWriter() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::surfaceWriters::nullWriter::needsUpdate() const +{ + return false; +} + + +bool Foam::surfaceWriters::nullWriter::enabled() const +{ + return false; +} + + +void Foam::surfaceWriters::nullWriter::setSurface +( + const meshedSurf& surf, + bool parallel +) +{} + + +void Foam::surfaceWriters::nullWriter::setSurface +( + const pointField& points, + const faceList& faces, + bool parallel +) +{} + + +void Foam::surfaceWriters::nullWriter::open(const fileName& outputPath) +{} + + +// Field writing methods +defineSurfaceWriterWriteFields(Foam::surfaceWriters::nullWriter); + + +// ************************************************************************* // diff --git a/src/surfMesh/writers/null/nullSurfaceWriter.H b/src/surfMesh/writers/null/nullSurfaceWriter.H new file mode 100644 index 0000000000000000000000000000000000000000..2174a566945a2f7500415d74107a944ffc06d935 --- /dev/null +++ b/src/surfMesh/writers/null/nullSurfaceWriter.H @@ -0,0 +1,149 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::surfaceWriters::nullWriter + +Description + Suppresses output of geometry and fields + +SourceFiles + nullSurfaceWriter.C + +\*---------------------------------------------------------------------------*/ + +#ifndef nullSurfaceWriter_H +#define nullSurfaceWriter_H + +#include "surfaceWriter.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace surfaceWriters +{ + +/*---------------------------------------------------------------------------*\ + Class nullWriter Declaration +\*---------------------------------------------------------------------------*/ + +class nullWriter +: + public surfaceWriter +{ +public: + + //- Runtime type information + TypeNameNoDebug("none"); + + + // Constructors + + //- Construct for a given extension + nullWriter(); + + //- Construct for a given extension + explicit nullWriter(const dictionary& options); + + //- Construct from components + nullWriter + ( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + //- Construct from components + nullWriter + ( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + + //- Destructor + virtual ~nullWriter() = default; + + + // Member Functions + + // Capability + + //- Never needs an update. + virtual bool needsUpdate() const; + + //- The null writer is always disabled, which lets the caller + //- skip various (possibly expensive) preparatory operations. + virtual bool enabled() const; + + + // Surface association + + //- Change association with a surface (no-op). + virtual void setSurface + ( + const meshedSurf& s, + bool parallel = Pstream::parRun() + ); // override + + //- Change association with a surface (no-op). + virtual void setSurface + ( + const pointField& points, + const faceList& faces, + bool parallel = Pstream::parRun() + ); // override + + + // Output + + //- Open for output on specified path, using existing surface (no-op) + virtual void open(const fileName& outputPath); // override + + + // Write + + declareSurfaceWriterWriteMethod(label); + declareSurfaceWriterWriteMethod(scalar); + declareSurfaceWriterWriteMethod(vector); + declareSurfaceWriterWriteMethod(sphericalTensor); + declareSurfaceWriterWriteMethod(symmTensor); + declareSurfaceWriterWriteMethod(tensor); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceWriters +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.C b/src/surfMesh/writers/proxy/proxySurfaceWriter.C similarity index 53% rename from src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.C rename to src/surfMesh/writers/proxy/proxySurfaceWriter.C index 2c83e3614c9e9e8f691ec5943314f02aa7d7b76d..1e8d20856b24dffc9ea658c5e34ef25d34b7adb6 100644 --- a/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.C +++ b/src/surfMesh/writers/proxy/proxySurfaceWriter.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011 OpenFOAM Foundation @@ -28,78 +28,129 @@ License #include "proxySurfaceWriter.H" #include "MeshedSurfaceProxy.H" #include "OSspecific.H" -#include "makeSurfaceWriterMethods.H" +#include "surfaceWriterMethods.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { - defineTypeNameAndDebug(proxySurfaceWriter, 0); +namespace surfaceWriters +{ + defineTypeName(proxyWriter); +} } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::proxySurfaceWriter::proxySurfaceWriter(const word& fileExt) +Foam::surfaceWriters::proxyWriter::proxyWriter(const word& fileExt) : surfaceWriter(), fileExtension_(fileExt) {} -Foam::proxySurfaceWriter::proxySurfaceWriter +Foam::surfaceWriters::proxyWriter::proxyWriter ( const word& fileExt, const dictionary& options ) : - surfaceWriter(), + surfaceWriter(options), fileExtension_(fileExt), options_(options) {} +Foam::surfaceWriters::proxyWriter::proxyWriter +( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + proxyWriter(outputPath.ext(), options) +{ + surfaceWriter::open(surf, outputPath, parallel); +} + + +Foam::surfaceWriters::proxyWriter::proxyWriter +( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + proxyWriter(outputPath.ext(), options) +{ + surfaceWriter::open(points, faces, outputPath, parallel); +} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -Foam::fileName Foam::proxySurfaceWriter::write +void Foam::surfaceWriters::proxyWriter::open ( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, - const bool verbose -) const + const fileName& outputPath +) +{ + fileExtension_ = outputPath.ext(); + surfaceWriter::open(outputPath); +} + + +Foam::fileName Foam::surfaceWriters::proxyWriter::write() { + checkOpen(); + // Avoid bad values if (fileExtension_.empty()) { return fileName::null; } - fileName outputFile(outputDir/surfaceName + '.' + fileExtension_); + // Geometry: rootdir/<TIME>/surfaceName.{extension} - if (!isDir(outputFile.path())) + fileName outputFile = outputPath_; + if (useTimeDir() && !timeName().empty()) { - mkDir(outputFile.path()); + // Splice in time-directory + outputFile = outputPath_.path() / timeName() / outputPath_.name(); } + outputFile.ext(fileExtension_); - if (verbose) + if (verbose_) { Info<< "Writing geometry to " << outputFile << endl; } - MeshedSurfaceProxy<face> - ( - surf.points(), - surf.faces() - ).write - ( - outputFile, - fileExtension_, - options_ - ); + const meshedSurf& surf = surface(); + + if (Pstream::master() || !parallel_) + { + if (!isDir(outputFile.path())) + { + mkDir(outputFile.path()); + } + + MeshedSurfaceProxy<face>(surf.points(), surf.faces()).write + ( + outputFile, + fileExtension_, + options_ + ); + } return outputFile; } +// Field writing methods +defineSurfaceWriterWriteFields(Foam::surfaceWriters::proxyWriter); + + // ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.H b/src/surfMesh/writers/proxy/proxySurfaceWriter.H similarity index 61% rename from src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.H rename to src/surfMesh/writers/proxy/proxySurfaceWriter.H index bd3df1ad73b8ab6eef4ea6c2f8628037a8acd40e..383d4b3fc51a77ffc7049efd6c32a58577cbd9f6 100644 --- a/src/sampling/sampledSurface/writers/proxy/proxySurfaceWriter.H +++ b/src/surfMesh/writers/proxy/proxySurfaceWriter.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011 OpenFOAM Foundation @@ -24,11 +24,11 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - Foam::proxySurfaceWriter + Foam::surfaceWriters::proxyWriter Description - A surfaceWriter that writes the geometry via the MeshedSurfaceProxy, but - which does not support any fields. + A surfaceWriter that writes the geometry via the MeshedSurfaceProxy, + but which does not support any fields. \heading Output file locations @@ -59,16 +59,18 @@ SourceFiles namespace Foam { +namespace surfaceWriters +{ /*---------------------------------------------------------------------------*\ - Class proxySurfaceWriter Declaration + Class proxyWriter Declaration \*---------------------------------------------------------------------------*/ -class proxySurfaceWriter +class proxyWriter : public surfaceWriter { - // Private data + // Private Data //- The file extension associated with the proxy word fileExtension_; @@ -80,46 +82,75 @@ class proxySurfaceWriter public: //- Runtime type information - TypeName("proxy"); + TypeNameNoDebug("proxy"); // Constructors //- Construct for a given extension - explicit proxySurfaceWriter(const word& fileExt); + explicit proxyWriter(const word& fileExt); //- Construct for a given extension, with some output options - proxySurfaceWriter(const word& fileExt, const dictionary& options); + proxyWriter(const word& fileExt, const dictionary& options); + + //- Construct from components, taking extension from outputPath + proxyWriter + ( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + //- Construct from components, taking extension from outputPath + proxyWriter + ( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); //- Destructor - virtual ~proxySurfaceWriter() = default; + virtual ~proxyWriter() = default; // Member Functions + // Capability - //- True if the surface format supports geometry in a separate file. - // False if geometry and field must be in a single file + //- A separate file is required for geometry. virtual bool separateGeometry() const { return true; } - //- Write single surface geometry to file. - virtual fileName write - ( - const fileName& outputDir, //!< output-dir - const fileName& surfaceName, //!< Name of surface - const meshedSurf& surf, //!< Surface geometry - const bool verbose = false //!< Additional verbosity - ) const; // override + // Output + + //- Open for output on specified path, using existing surface + virtual void open(const fileName& outputPath); // override + + + // Write + + //- Write surface geometry to file. + virtual fileName write(); // override + + declareSurfaceWriterWriteMethod(label); + declareSurfaceWriterWriteMethod(scalar); + declareSurfaceWriterWriteMethod(vector); + declareSurfaceWriterWriteMethod(sphericalTensor); + declareSurfaceWriterWriteMethod(symmTensor); + declareSurfaceWriterWriteMethod(tensor); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace surfaceWriters } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/surfMesh/writers/raw/rawSurfaceWriter.C b/src/surfMesh/writers/raw/rawSurfaceWriter.C new file mode 100644 index 0000000000000000000000000000000000000000..2e79256aaa6a13126e461ce76512ded754cc8369 --- /dev/null +++ b/src/surfMesh/writers/raw/rawSurfaceWriter.C @@ -0,0 +1,185 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2008-2011, 2015-2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- + | Copyright (C) 2011-2016 OpenFOAM Foundation +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "rawSurfaceWriter.H" +#include "OFstream.H" +#include "OSspecific.H" +#include "surfaceWriterMethods.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace surfaceWriters +{ + defineTypeName(rawWriter); + addToRunTimeSelectionTable(surfaceWriter, rawWriter, word); + addToRunTimeSelectionTable(surfaceWriter, rawWriter, wordDict); +} +} + + +// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // + +namespace Foam +{ + // Emit x,y,z + static inline void writePoint(Foam::Ostream& os, const Foam::point& p) + { + os << p.x() << ' ' << p.y() << ' ' << p.z(); + } + +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Field writing implementation +#include "rawSurfaceWriterImpl.C" + +// Field writing methods +defineSurfaceWriterWriteFields(Foam::surfaceWriters::rawWriter); + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surfaceWriters::rawWriter::rawWriter() +: + surfaceWriter(), + writeCompression_(IOstream::UNCOMPRESSED) +{} + + +Foam::surfaceWriters::rawWriter::rawWriter +( + const dictionary& options +) +: + surfaceWriter(options), + writeCompression_ + ( + IOstream::compressionEnum + ( + options.lookupOrDefault<word>("compression", "false") + ) + ) +{} + + +Foam::surfaceWriters::rawWriter::rawWriter +( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + rawWriter(options) +{ + open(surf, outputPath, parallel); +} + + +Foam::surfaceWriters::rawWriter::rawWriter +( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + rawWriter(options) +{ + open(points, faces, outputPath, parallel); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::fileName Foam::surfaceWriters::rawWriter::write() +{ + checkOpen(); + + // Geometry: rootdir/<TIME>/surfaceName.raw + + fileName outputFile = outputPath_; + if (useTimeDir() && !timeName().empty()) + { + // Splice in time-directory + outputFile = outputPath_.path() / timeName() / outputPath_.name(); + } + outputFile.ext("raw"); + + if (verbose_) + { + Info<< "Writing geometry to " << outputFile << endl; + } + + + const meshedSurf& surf = surface(); + + if (Pstream::master() || !parallel_) + { + const pointField& points = surf.points(); + const faceList& faces = surf.faces(); + + if (!isDir(outputFile.path())) + { + mkDir(outputFile.path()); + } + + OFstream os + ( + outputFile, + IOstream::ASCII, + IOstream::currentVersion, + writeCompression_ + ); + + // Header + { + os << "# geometry NO_DATA " << faces.size() << nl + << "# x y z" << nl; + } + + // Write faces centres + for (const face& f : faces) + { + writePoint(os, f.centre(points)); + os << nl; + } + + os << nl; + } + + return outputFile; +} + + +// ************************************************************************* // diff --git a/src/surfMesh/writers/raw/rawSurfaceWriter.H b/src/surfMesh/writers/raw/rawSurfaceWriter.H new file mode 100644 index 0000000000000000000000000000000000000000..bac91063a6660e9fc924f479392b7796485af183 --- /dev/null +++ b/src/surfMesh/writers/raw/rawSurfaceWriter.H @@ -0,0 +1,172 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2008-2011, 2015-2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- + | Copyright (C) 2011-2016 OpenFOAM Foundation +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::surfaceWriters::rawWriter + +Description + A surfaceWriter for raw output. + + The formatOptions for raw: + \table + Property | Description | Required | Default + compression | on / off | no | off + \endtable + + For example, + \verbatim + formatOptions + { + raw + { + compression on; + } + } + \endverbatim + + \heading Output file locations + + The \c rootdir normally corresponds to something like + \c postProcessing/\<name\> + + \subheading Geometry + \verbatim + rootdir + `-- timeName + `-- surfaceName.{raw} + \endverbatim + + \subheading Fields + \verbatim + rootdir + `-- timeName + |-- <field0>_surfaceName.{raw} + `-- <field1>_surfaceName.{raw} + \endverbatim + +SourceFiles + rawSurfaceWriter.C + +\*---------------------------------------------------------------------------*/ + +#ifndef rawSurfaceWriter_H +#define rawSurfaceWriter_H + +#include "surfaceWriter.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace surfaceWriters +{ + +/*---------------------------------------------------------------------------*\ + Class rawWriter Declaration +\*---------------------------------------------------------------------------*/ + +class rawWriter +: + public surfaceWriter +{ + // Private data + + //- Output compression (default: uncompressed) + IOstream::compressionType writeCompression_; + + + // Private Member Functions + + //- Templated write operation + template<class Type> + fileName writeTemplate + ( + const word& fieldName, //!< Name of field + const Field<Type>& localValues //!< Local field values to write + ); + + +public: + + //- Runtime type information + TypeNameNoDebug("raw"); + + + // Constructors + + //- Construct null + rawWriter(); + + //- Construct with some output options + explicit rawWriter(const dictionary& options); + + //- Construct from components + rawWriter + ( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + //- Construct from components + rawWriter + ( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + + //- Destructor + virtual ~rawWriter() = default; + + + // Member Functions + + //- Write surface geometry to file. + virtual fileName write(); // override + + declareSurfaceWriterWriteMethod(label); + declareSurfaceWriterWriteMethod(scalar); + declareSurfaceWriterWriteMethod(vector); + declareSurfaceWriterWriteMethod(sphericalTensor); + declareSurfaceWriterWriteMethod(symmTensor); + declareSurfaceWriterWriteMethod(tensor); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceWriters +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriterImpl.C b/src/surfMesh/writers/raw/rawSurfaceWriterImpl.C similarity index 61% rename from src/sampling/sampledSurface/writers/raw/rawSurfaceWriterImpl.C rename to src/surfMesh/writers/raw/rawSurfaceWriterImpl.C index 1735941782ac860c8a623cbc77ded16889a4fb84..662f24d7b63ee78239a24106f3449f801a85901f 100644 --- a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriterImpl.C +++ b/src/surfMesh/writers/raw/rawSurfaceWriterImpl.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2008-2011, 2015-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2014 OpenFOAM Foundation @@ -47,6 +47,13 @@ namespace Foam template<class Type> static inline void writeHeader(Ostream& os, const word& fieldName) {} + template<> + void writeHeader<label>(Ostream& os, const word& fieldName) + { + os << "# x y z" + << " " << fieldName << nl; + } + template<> void writeHeader<scalar>(Ostream& os, const word& fieldName) { @@ -101,69 +108,96 @@ namespace Foam // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template<class Type> -Foam::fileName Foam::rawSurfaceWriter::writeTemplate +Foam::fileName Foam::surfaceWriters::rawWriter::writeTemplate ( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, const word& fieldName, - const Field<Type>& values, - const bool isNodeValues, - const bool verbose -) const + const Field<Type>& localValues +) { - // field: rootdir/time/<field>_surfaceName.raw + checkOpen(); - const pointField& points = surf.points(); - const faceList& faces = surf.faces(); + // Field: rootdir/<TIME>/<field>_surfaceName.raw - if (!isDir(outputDir)) + fileName outputFile = outputPath_.path(); + if (useTimeDir() && !timeName().empty()) { - mkDir(outputDir); + // Splice in time-directory + outputFile /= timeName(); } - OFstream os(outputDir/fieldName + '_' + surfaceName + ".raw"); + // Append <field>_surfaceName.raw + outputFile /= fieldName + '_' + outputPath_.name(); + outputFile.ext("raw"); - if (verbose) + if (verbose_) { - Info<< "Writing field " << fieldName << " to " << os.name() << endl; + Info<< "Writing field " << fieldName << " to " << outputFile << endl; } - // Header - os << "# " << fieldName; - if (isNodeValues) - { - os << " POINT_DATA " << values.size() << nl; - } - else - { - os << " FACE_DATA " << values.size() << nl; - } - // Header - // # x y z field - writeHeader<Type>(os, fieldName); + // geometry merge() implicit + tmp<Field<Type>> tfield = mergeField(localValues); + + const meshedSurf& surf = surface(); - if (isNodeValues) + if (Pstream::master() || !parallel_) { - // Node values - forAll(values, elemi) + const auto& values = tfield(); + const pointField& points = surf.points(); + const faceList& faces = surf.faces(); + + if (!isDir(outputFile.path())) { - writePoint(os, points[elemi]); - writeData(os, values[elemi]); + mkDir(outputFile.path()); } - } - else - { - // Face values - forAll(values, elemi) + + OFstream os + ( + outputFile, + IOstream::ASCII, + IOstream::currentVersion, + writeCompression_ + ); + + // Header + { + os << "# " << fieldName; + if (this->isPointData()) + { + os << " POINT_DATA "; + } + else + { + os << " FACE_DATA "; + } + os << values.size() << nl; + + // # x y z field + writeHeader<Type>(os, fieldName); + } + + + if (this->isPointData()) + { + // Node values + forAll(values, elemi) + { + writePoint(os, points[elemi]); + writeData(os, values[elemi]); + } + } + else { - writePoint(os, faces[elemi].centre(points)); - writeData(os, values[elemi]); + // Face values + forAll(values, elemi) + { + writePoint(os, faces[elemi].centre(points)); + writeData(os, values[elemi]); + } } } - return os.name(); + return outputFile; } diff --git a/src/surfMesh/writers/starcd/starcdSurfaceWriter.C b/src/surfMesh/writers/starcd/starcdSurfaceWriter.C new file mode 100644 index 0000000000000000000000000000000000000000..75412a20aecb5adeb130cd85f8e0769d280c62a7 --- /dev/null +++ b/src/surfMesh/writers/starcd/starcdSurfaceWriter.C @@ -0,0 +1,217 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2008-2011, 2015-2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- + | Copyright (C) 2011 OpenFOAM Foundation +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "starcdSurfaceWriter.H" +#include "OFstream.H" +#include "OSspecific.H" +#include "MeshedSurfaceProxy.H" +#include "surfaceWriterMethods.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace surfaceWriters +{ + defineTypeName(starcdWriter); + addToRunTimeSelectionTable(surfaceWriter, starcdWriter, word); +} +} + +// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // + +namespace Foam +{ + // Emit each component + template<class Type> + static inline void writeData(Ostream& os, const Type& val) + { + const direction ncmpt = pTraits<Type>::nComponents; + for (direction cmpt=0; cmpt < ncmpt; ++cmpt) + { + os << ' ' << component(val, cmpt); + } + os << nl; + } + +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surfaceWriters::starcdWriter::starcdWriter() +: + surfaceWriter() +{} + + +Foam::surfaceWriters::starcdWriter::starcdWriter +( + const dictionary& options +) +: + surfaceWriter(options) +{} + + +Foam::surfaceWriters::starcdWriter::starcdWriter +( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + starcdWriter(options) +{ + open(surf, outputPath, parallel); +} + + +Foam::surfaceWriters::starcdWriter::starcdWriter +( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + starcdWriter(options) +{ + open(points, faces, outputPath, parallel); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::fileName Foam::surfaceWriters::starcdWriter::write() +{ + checkOpen(); + + // Geometry: rootdir/<TIME>/surfaceName.{inp,cel,vrt} + + fileName outputFile = outputPath_; + if (useTimeDir() && !timeName().empty()) + { + // Splice in time-directory + outputFile = outputPath_.path() / timeName() / outputPath_.name(); + } + outputFile.ext("inp"); + + if (verbose_) + { + Info<< "Writing geometry to " << outputFile << endl; + } + + const meshedSurf& surf = surface(); + + if (Pstream::master() || !parallel_) + { + if (!isDir(outputFile.path())) + { + mkDir(outputFile.path()); + } + + MeshedSurfaceProxy<face> + ( + surf.points(), + surf.faces() + ).write(outputFile, "inp"); + } + + return outputFile; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type> +Foam::fileName Foam::surfaceWriters::starcdWriter::writeTemplate +( + const word& fieldName, + const Field<Type>& localValues +) +{ + checkOpen(); + + // Field: rootdir/<TIME>/<field>_surfaceName.usr + + fileName outputFile = outputPath_.path(); + if (useTimeDir() && !timeName().empty()) + { + // Splice in time-directory + outputFile /= timeName(); + } + + // Append <field>_surfaceName.usr + outputFile /= fieldName + '_' + outputPath_.name(); + outputFile.ext("usr"); + + if (verbose_) + { + Info<< "Writing field " << fieldName << " to " << outputFile << endl; + } + + + // geometry merge() implicit + tmp<Field<Type>> tfield = mergeField(localValues); + + if (Pstream::master() || !parallel_) + { + const auto& values = tfield(); + + if (!isDir(outputFile.path())) + { + mkDir(outputFile.path()); + } + + OFstream os(outputFile); + + // 1-based ids + label elemId = 1; + + // No header, just write values + for (const Type& val : values) + { + os << elemId; + writeData(os, val); + + ++elemId; + } + } + + return outputFile; +} + + +// Field writing methods +defineSurfaceWriterWriteFields(Foam::surfaceWriters::starcdWriter); + + +// ************************************************************************* // diff --git a/src/surfMesh/writers/starcd/starcdSurfaceWriter.H b/src/surfMesh/writers/starcd/starcdSurfaceWriter.H new file mode 100644 index 0000000000000000000000000000000000000000..034725d1261b875d790a15b26ac14d6f5d0a3dc5 --- /dev/null +++ b/src/surfMesh/writers/starcd/starcdSurfaceWriter.H @@ -0,0 +1,170 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2008-2011, 2015-2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- + | Copyright (C) 2011 OpenFOAM Foundation +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::surfaceWriters::starcdWriter + +Description + A surfaceWriter for STARCD files. + + The geometry is written via the MeshedSurfaceProxy, the fields + are written in a trivial ASCII format with ID and VALUE as + so-called user data. These \c .usr files can be read into proSTAR + with these types of commands. For element data: + \verbatim + getuser FILENAME.usr cell scalar free + getuser FILENAME.usr cell vector free + \endverbatim + and for vertex data: + \verbatim + getuser FILENAME.usr vertex scalar free + getuser FILENAME.usr vertex vector free + \endverbatim + + \heading Output file locations + + The \c rootdir normally corresponds to something like + \c postProcessing/\<name\> + + \subheading Geometry + \verbatim + rootdir + `-- timeName + `-- surfaceName.{cel,vrt,inp} + \endverbatim + + \subheading Fields + \verbatim + rootdir + `-- timeName + |-- <field0>_surfaceName.{usr} + `-- <field1>_surfaceName.{usr} + \endverbatim + +SourceFiles + starcdSurfaceWriter.C + +\*---------------------------------------------------------------------------*/ + +#ifndef starcdSurfaceWriter_H +#define starcdSurfaceWriter_H + +#include "surfaceWriter.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace surfaceWriters +{ + +/*---------------------------------------------------------------------------*\ + Class starcdWriter Declaration +\*---------------------------------------------------------------------------*/ + +class starcdWriter +: + public surfaceWriter +{ + // Private Member Functions + + //- Templated write operation + template<class Type> + fileName writeTemplate + ( + const word& fieldName, //!< Name of field + const Field<Type>& localValues //!< Local field values to write + ); + + +public: + + //- Runtime type information + TypeNameNoDebug("starcd"); + + + // Constructors + + //- Construct null + starcdWriter(); + + //- Construct with some output options + explicit starcdWriter(const dictionary& options); + + //- Construct from components + starcdWriter + ( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + //- Construct from components + starcdWriter + ( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + + //- Destructor + virtual ~starcdWriter() = default; + + + // Member Functions + + //- True if the surface format supports geometry in a separate file. + // False if geometry and field must be in a single file + virtual bool separateGeometry() const + { + return true; + } + + //- Write single surface geometry to file. + virtual fileName write(); // override + + declareSurfaceWriterWriteMethod(label); + declareSurfaceWriterWriteMethod(scalar); + declareSurfaceWriterWriteMethod(vector); + declareSurfaceWriterWriteMethod(sphericalTensor); + declareSurfaceWriterWriteMethod(symmTensor); + declareSurfaceWriterWriteMethod(tensor); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceWriters +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/surfMesh/writers/surfaceWriter.C b/src/surfMesh/writers/surfaceWriter.C new file mode 100644 index 0000000000000000000000000000000000000000..625a82505622949497f686dedf4846f828ccf68a --- /dev/null +++ b/src/surfMesh/writers/surfaceWriter.C @@ -0,0 +1,458 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "surfaceWriter.H" +#include "proxySurfaceWriter.H" +#include "MeshedSurfaceProxy.H" + +#include "Time.H" +#include "globalIndex.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(surfaceWriter, 0); + defineRunTimeSelectionTable(surfaceWriter, word); + defineRunTimeSelectionTable(surfaceWriter, wordDict); +} + +Foam::scalar Foam::surfaceWriter::defaultMergeDim = 1e-8; + +const Foam::meshedSurf::emptySurface Foam::surfaceWriter::emptySurface_; + + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +bool Foam::surfaceWriter::supportedType(const word& writeType) +{ + return + ( + wordConstructorTablePtr_->found(writeType) + || wordDictConstructorTablePtr_->found(writeType) + || MeshedSurfaceProxy<face>::canWriteType(writeType) + ); +} + + +Foam::autoPtr<Foam::surfaceWriter> +Foam::surfaceWriter::New(const word& writeType) +{ + // Constructors without dictionary options + auto cstrIter = wordConstructorTablePtr_->cfind(writeType); + + if (!cstrIter.found()) + { + if (MeshedSurfaceProxy<face>::canWriteType(writeType)) + { + // Generally unknown, but handle via 'proxy' handler + return autoPtr<surfaceWriter> + ( + new surfaceWriters::proxyWriter(writeType) + ); + } + + FatalErrorInFunction + << "Unknown write type \"" << writeType << "\"\n\n" + << "Valid write types : " + << flatOutput(wordConstructorTablePtr_->sortedToc()) << nl + << "Valid proxy types : " + << MeshedSurfaceProxy<face>::writeTypes() << endl + << exit(FatalError); + } + + return autoPtr<surfaceWriter>(cstrIter()()); +} + + +Foam::autoPtr<Foam::surfaceWriter> +Foam::surfaceWriter::New +( + const word& writeType, + const dictionary& writeOpts +) +{ + // Constructors with dictionary options + auto cstrIter2 = wordDictConstructorTablePtr_->cfind(writeType); + + if (cstrIter2.found()) + { + return autoPtr<surfaceWriter>(cstrIter2()(writeOpts)); + } + + // Constructors without dictionary options + auto cstrIter = wordConstructorTablePtr_->cfind(writeType); + + if (!cstrIter.found()) + { + if (MeshedSurfaceProxy<face>::canWriteType(writeType)) + { + // Generally unknown, but handle via 'proxy' handler + return autoPtr<surfaceWriter> + ( + new surfaceWriters::proxyWriter(writeType, writeOpts) + ); + } + + FatalErrorInFunction + << "Unknown write type \"" << writeType << "\"\n\n" + << "Valid write types : " + << wordConstructorTablePtr_->sortedToc() << nl + << "Valid proxy types : " + << MeshedSurfaceProxy<face>::writeTypes() << endl + << exit(FatalError); + } + + return autoPtr<surfaceWriter>(cstrIter()()); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surfaceWriter::surfaceWriter() +: + surf_(std::cref<meshedSurf>(emptySurface_)), + upToDate_(false), + parallel_(true), + useTimeDir_(false), + isPointData_(false), + verbose_(false), + nFields_(0), + mergeDim_(defaultMergeDim), + merged_(), + currTime_(), + outputPath_() +{ + surfaceWriter::close(); +} + + +Foam::surfaceWriter::surfaceWriter(const dictionary& options) +: + surfaceWriter() +{ + options.readIfPresent("verbose", verbose_); +} + + +Foam::surfaceWriter::surfaceWriter +( + const meshedSurf& surf, + bool parallel, + const dictionary& options +) +: + surfaceWriter(options) +{ + setSurface(surf, parallel); +} + + +Foam::surfaceWriter::surfaceWriter +( + const pointField& points, + const faceList& faces, + bool parallel, + const dictionary& options +) +: + surfaceWriter(options) +{ + setSurface(points, faces, parallel); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::surfaceWriter::setTime(const instant& inst) +{ + currTime_ = inst; +} + + +void Foam::surfaceWriter::setTime(scalar timeValue) +{ + currTime_ = instant(timeValue); +} + + +void Foam::surfaceWriter::setTime(scalar timeValue, const word& timeName) +{ + currTime_.value() = timeValue; + currTime_.name() = timeName; +} + + +void Foam::surfaceWriter::unsetTime() +{ + currTime_.value() = 0; + currTime_.name().clear(); +} + + +void Foam::surfaceWriter::beginTime(const Time& t) +{ + setTime(t.value(), t.timeName()); +} + + +void Foam::surfaceWriter::beginTime(const instant& inst) +{ + setTime(inst); +} + + +void Foam::surfaceWriter::endTime() +{ + unsetTime(); +} + + +void Foam::surfaceWriter::open(const fileName& outputPath) +{ + outputPath_ = outputPath; +} + + +void Foam::surfaceWriter::open +( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel +) +{ + close(); + setSurface(surf, parallel); + open(outputPath); +} + + +void Foam::surfaceWriter::open +( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel +) +{ + close(); + setSurface(points, faces, parallel); + open(outputPath); +} + + +void Foam::surfaceWriter::close() +{ + outputPath_.clear(); +} + + +void Foam::surfaceWriter::clear() +{ + close(); + expire(); + surf_ = std::cref<meshedSurf>(emptySurface_); +} + + +void Foam::surfaceWriter::setSurface +( + const meshedSurf& surf, + bool parallel +) +{ + expire(); + surf_ = std::cref<meshedSurf>(surf); +} + + +void Foam::surfaceWriter::setSurface +( + const pointField& points, + const faceList& faces, + bool parallel +) +{ + expire(); + setSurface(meshedSurfRef(points, faces), parallel); +} + + +bool Foam::surfaceWriter::needsUpdate() const +{ + return !upToDate_; +} + + +bool Foam::surfaceWriter::expire() +{ + const bool changed = upToDate_; + + upToDate_ = false; + nFields_ = 0; + merged_.clear(); + + return changed; +} + + +bool Foam::surfaceWriter::hasSurface() const +{ + return (&emptySurface_ != &(surf_.get())); +} + + +bool Foam::surfaceWriter::empty() const +{ + const bool value = surf_.get().faces().empty(); + + return (parallel_ ? returnReduce(value, andOp<bool>()) : value); +} + + +Foam::label Foam::surfaceWriter::size() const +{ + const label value = surf_.get().faces().size(); + + return (parallel_ ? returnReduce(value, sumOp<label>()) : value); +} + + +bool Foam::surfaceWriter::checkOpen() const +{ + if (outputPath_.empty()) + { + FatalErrorInFunction + << type() << " : Attempted to write without a path" << nl + << exit(FatalIOError); + } + + return !outputPath_.empty(); +} + + +bool Foam::surfaceWriter::merge() const +{ + bool changed = false; + + if (parallel_ && Pstream::parRun() && !upToDate_) + { + changed = merged_.merge(surf_.get(), mergeDim_); + } + upToDate_ = true; + + return changed; +} + + +const Foam::meshedSurf& Foam::surfaceWriter::surface() const +{ + merge(); + + if (parallel_ && Pstream::parRun()) + { + return merged_; + } + + return surf_.get(); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type> +Foam::tmp<Foam::Field<Type>> Foam::surfaceWriter::mergeFieldTemplate +( + const Field<Type>& fld +) const +{ + if (parallel_ && Pstream::parRun()) + { + // Ensure geometry is also merged + merge(); + + // Gather all values + auto tfield = tmp<Field<Type>>::New(); + auto& allFld = tfield.ref(); + + globalIndex::gatherOp(fld, allFld); + + // Renumber (point data) to correspond to merged points + if (Pstream::master() && this->isPointData()) + { + inplaceReorder(merged_.pointsMap(), allFld); + allFld.resize(merged_.points().size()); + } + + return tfield; + } + + // Mark that any geometry changes have been taken care of + upToDate_ = true; + + return fld; +} + + +#define defineSurfaceWriterMergeMethod(ThisClass, Type) \ + Foam::tmp<Foam::Field<Type>> \ + ThisClass::mergeField(const Field<Type>& fld) const \ + { \ + return mergeFieldTemplate(fld); \ + } + +defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::label); +defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::scalar); +defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::vector); +defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::sphericalTensor); +defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::symmTensor); +defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::tensor) + +#undef defineSurfaceWriterMergeMethod + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +Foam::Ostream& Foam::operator<< +( + Ostream& os, + const InfoProxy<surfaceWriter>& ip +) +{ + const surfaceWriter& w = ip.t_; + + os << "surfaceWriter:" + << " upToDate: " << w.upToDate_ + << " PointData: " << w.isPointData_ + << " nFields: " << w.nFields_ + << " time: " << w.currTime_ + << " path: " << w.outputPath_ << endl; + + return os; +} + + +// ************************************************************************* // diff --git a/src/surfMesh/writers/surfaceWriter.H b/src/surfMesh/writers/surfaceWriter.H new file mode 100644 index 0000000000000000000000000000000000000000..47ff76137161da8362afb8ff1323f0a14040687c --- /dev/null +++ b/src/surfMesh/writers/surfaceWriter.H @@ -0,0 +1,491 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- + | Copyright (C) 2011-2012 OpenFOAM Foundation +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Namespace + Foam::surfaceWriters + +Description + Namespace for surface writers + +Class + Foam::surfaceWriter + +Description + Base class for surface writers. + + The surfaceWriter interface is rather large since we need a writer that + can either be initially defined without a surface association + and have that added at a later stage, or be defined with a surface + association. + + \verbatim + formatOptions + { + someFormat // Eg, ensight, vtk, etc + { + verbose true; + } + } + \endverbatim + + Format options: + \table + Property | Description | Required | Default + verbose | Additional output verbosity | no | no + \endtable + +SourceFiles + sampledWriter.C + sampledWriterI.H + sampledWriterImpl.C + +\*---------------------------------------------------------------------------*/ + +#ifndef surfaceWriter_H +#define surfaceWriter_H + +#include <functional> +#include "typeInfo.H" +#include "autoPtr.H" +#include "tmp.H" +#include "Field.H" +#include "fileName.H" +#include "instant.H" +#include "mergedSurf.H" +#include "meshedSurfRef.H" +#include "InfoProxy.H" +#include "runTimeSelectionTables.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declarations +class Time; +class surfaceWriter; + +Ostream& operator<<(Ostream& os, const InfoProxy<surfaceWriter>& ip); + + +/*---------------------------------------------------------------------------*\ + Class surfaceWriter Declaration +\*---------------------------------------------------------------------------*/ + +class surfaceWriter +{ +protected: + + // Static data members + + //- Placeholder + static const meshedSurf::emptySurface emptySurface_; + + + // Protected data + + //- Reference to the surface + std::reference_wrapper<const meshedSurf> surf_; + + //- The topology/surface is up-to-date? + mutable bool upToDate_; + + //- Writing in parallel (vai master) + bool parallel_; + + //- Writer should do something funny + bool useTimeDir_; + + //- Is point vs cell data + bool isPointData_; + + //- Additional output verbosity + bool verbose_; + + //- The number of fields + label nFields_; + + //- Dimension for merging + scalar mergeDim_; + + //- Merging information and the resulting merged surface (parallel) + mutable mergedSurf merged_; + + //- The current time value/name + instant currTime_; + + //- The full output directory and file (surface) name + fileName outputPath_; + + + // Protected Member Functions + + //- Verify that the outputPath_ has been set or FatalError + bool checkOpen() const; + + //- Merge surfaces if they are not already upToDate (parallel) + //- or simply mark the surface as being up-to-date + virtual bool merge() const; + + //- Merge surfaces (if not upToDate) and return merged or + //- the regular surface + const meshedSurf& surface() const; + + + //- Gather (merge) fields with renumbering and shrinking for point data + template<class Type> + tmp<Field<Type>> mergeFieldTemplate(const Field<Type>& fld) const; + +#undef declareSurfaceWriterMergeMethod +#define declareSurfaceWriterMergeMethod(Type) \ + tmp<Field<Type>> mergeField(const Field<Type>& fld) const; + + declareSurfaceWriterMergeMethod(label); + declareSurfaceWriterMergeMethod(scalar); + declareSurfaceWriterMergeMethod(vector); + declareSurfaceWriterMergeMethod(sphericalTensor); + declareSurfaceWriterMergeMethod(symmTensor); + declareSurfaceWriterMergeMethod(tensor); + + #undef declareSurfaceWriterMergeMethod + + //- Dummy templated write operation + template<class Type> + fileName writeTemplate + ( + const word& fieldName, //!< Name of field + const Field<Type>& localValues //!< Local field values to write + ) + { + return fileName::null; + } + + +public: + + // Public data + + //- The default merge dimension (1e-8) + static scalar defaultMergeDim; + + + //- Runtime type information + TypeName("surfaceWriter"); + + + // Declare run-time constructor selection table + declareRunTimeSelectionTable + ( + autoPtr, + surfaceWriter, + word, + (), + () + ); + + declareRunTimeSelectionTable + ( + autoPtr, + surfaceWriter, + wordDict, + ( + const dictionary& writeOpts + ), + (writeOpts) + ); + + + // Selectors + + //- True if New is likely to succeed for this writeType + static bool supportedType(const word& writeType); + + //- Return a reference to the selected surfaceWriter + static autoPtr<surfaceWriter> New(const word& writeType); + + //- Return a reference to the selected surfaceWriter + // Select with extra write option + static autoPtr<surfaceWriter> New + ( + const word& writeType, + const dictionary& writeOptions + ); + + + // Constructors + + //- Construct null + surfaceWriter(); + + //- Construct null with specified options + explicit surfaceWriter(const dictionary& options); + + //- Construct from components + explicit surfaceWriter + ( + const meshedSurf& surf, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + //- Construct from components + surfaceWriter + ( + const pointField& points, + const faceList& faces, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + + //- Destructor + virtual ~surfaceWriter() = default; + + + // Member Functions + + // Capability + + //- The writer is enabled. If the writer is not enabled, it may be + //- possible for the caller to skip various preparatory operations. + // This method is primarily useful for the null writer + virtual bool enabled() const + { + return true; + } + + //- True if the surface format requires geometry in a separate file. + virtual bool separateGeometry() const + { + return false; + } + + + // Bookkeeping + + //- Does the writer need an update (eg, lagging behind surface changes) + virtual bool needsUpdate() const; + + //- Mark that surface changed and the writer will need an update, + //- and set nFields = 0. + // May also free up unneeded data. + // Return false if it was previously already expired. + virtual bool expire(); + + //- Close any open output, remove association with a surface and + //- expire the writer. The parallel flag remains untouched. + virtual void clear(); + + + // Surface association + + //- Change association with a surface and expire the writer + virtual void setSurface + ( + const meshedSurf& surf, + bool parallel = Pstream::parRun() + ); + + //- Change association with a surface and expire the writer + virtual void setSurface + ( + const pointField& points, + const faceList& faces, + bool parallel = Pstream::parRun() + ); + + + // Queries, Access + + //- Writer is associated with a surface + bool hasSurface() const; + + //- The surface to write is empty if the global number of faces is zero + bool empty() const; + + //- The global number of faces for the associated surface + label size() const; + + //- The number of expected output fields. + // Currently only used by the legacy VTK format. + inline label nFields() const; + + //- The number of expected output fields. + // Currently only used by the legacy VTK format. + inline label& nFields(); + + //- Are the field data to be treated as point data? + inline bool isPointData() const; + + //- Set handling of field data to face/point data. + inline bool& isPointData(); + + //- Should a time directory be spliced into the output path? + inline bool useTimeDir() const; + + //- Change handling of spliced output path. + inline bool& useTimeDir(); + + //- Get output verbosity + inline bool verbose() const; + + //- Set output verbosity + inline bool& verbose(); + + //- The current value of the point merge dimension (metre) + inline scalar mergeDim() const; + + //- The current value of the point merge dimension (metre) + inline scalar& mergeDim(); + + + // Time + + //- True if there is a known time + inline bool hasTime() const; + + //- The current time value/name + inline const word& timeName() const; + + //- The current time value/name + inline scalar timeValue() const; + + + //- Set the current time + void setTime(const instant& inst); + + //- Set current time from timeValue, auto generating the name + void setTime(scalar timeValue); + + //- Set current time from timeValue and timeName + void setTime(scalar timeValue, const word& timeName); + + //- Clear the current time + void unsetTime(); + + + //- Begin a time-step + virtual void beginTime(const Time& t); + + //- Begin a time-step + virtual void beginTime(const instant& inst); + + //- End a time-step + virtual void endTime(); + + + // Output + + //- Open for output on specified path, using existing surface + virtual void open(const fileName& outputPath); + + //- Open from components + virtual void open + ( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel = Pstream::parRun() + ); + + //- Open from components + virtual void open + ( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel = Pstream::parRun() + ); + + //- Finish output, performing any necessary cleanup + virtual void close(); + + + // Write + + //- Write single surface geometry to file. + virtual fileName writeGeometry() const + { + return fileName::null; + } + + +#undef declareSurfaceWriterWriteMethod +#define declareSurfaceWriterWriteMethod(Type) \ + /**! Write field of Type (per face or vertex) */ \ + virtual fileName write \ + ( \ + const word& fieldName, /*!< Name of field */ \ + const Field<Type>& values /*!< Field values to write */ \ + ) = 0 + + declareSurfaceWriterWriteMethod(label); + declareSurfaceWriterWriteMethod(scalar); + declareSurfaceWriterWriteMethod(vector); + declareSurfaceWriterWriteMethod(sphericalTensor); + declareSurfaceWriterWriteMethod(symmTensor); + declareSurfaceWriterWriteMethod(tensor); + + +#undef declareSurfaceWriterWriteMethod +#define declareSurfaceWriterWriteMethod(Type) \ + \ + /**! Write field of Type (per face or vertex) */ \ + virtual fileName write \ + ( \ + const word& fieldName, /*!< Name of field */ \ + const Field<Type>& values /*!< Field values to write */ \ + ) // override + + + // Other IO + + //- Return info proxy. + virtual InfoProxy<surfaceWriter> info() const + { + return *this; + } + + //- Output info proxy + friend Ostream& operator<< + ( + Ostream& os, + const InfoProxy<surfaceWriter>& ip + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "surfaceWriterI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.C b/src/surfMesh/writers/surfaceWriterI.H similarity index 50% rename from src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.C rename to src/surfMesh/writers/surfaceWriterI.H index 1d7c37eab64ed5776d9ff4f41a88b194517c240d..0b62b6e04f2ac02867bb6cf95059b6deb57039cc 100644 --- a/src/sampling/sampledSurface/writers/starcd/starcdSurfaceWriter.C +++ b/src/surfMesh/writers/surfaceWriterI.H @@ -2,10 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011 OpenFOAM Foundation ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -25,56 +23,83 @@ License \*---------------------------------------------------------------------------*/ -#include "starcdSurfaceWriter.H" -#include "MeshedSurfaceProxy.H" -#include "OFstream.H" -#include "OSspecific.H" -#include "makeSurfaceWriterMethods.H" +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline Foam::label Foam::surfaceWriter::nFields() const +{ + return nFields_; +} -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // -namespace Foam +inline Foam::label& Foam::surfaceWriter::nFields() { - makeSurfaceWriterType(starcdSurfaceWriter); + return nFields_; } -// Field writing implementation -#include "starcdSurfaceWriterImpl.C" -// Field writing methods -defineSurfaceWriterWriteFields(Foam::starcdSurfaceWriter); +inline bool Foam::surfaceWriter::isPointData() const +{ + return isPointData_; +} -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +inline bool& Foam::surfaceWriter::isPointData() +{ + return isPointData_; +} + + +inline bool Foam::surfaceWriter::useTimeDir() const +{ + return useTimeDir_; +} + + +inline bool& Foam::surfaceWriter::useTimeDir() +{ + return useTimeDir_; +} + -Foam::fileName Foam::starcdSurfaceWriter::write -( - const fileName& outputDir, - const fileName& surfaceName, - const meshedSurf& surf, - const bool verbose -) const +inline bool Foam::surfaceWriter::verbose() const { - // geometry: rootdir/time/surfaceName.{raw,vrt,inp} + return verbose_; +} + + +inline bool& Foam::surfaceWriter::verbose() +{ + return verbose_; +} - fileName outputFile(outputDir/surfaceName + ".inp"); - if (verbose) - { - Info<< "Writing geometry to " << outputFile << endl; - } +inline Foam::scalar Foam::surfaceWriter::mergeDim() const +{ + return mergeDim_; +} + - if (!isDir(outputFile.path())) - { - mkDir(outputFile.path()); - } +inline Foam::scalar& Foam::surfaceWriter::mergeDim() +{ + return mergeDim_; +} - MeshedSurfaceProxy<face>(surf.points(), surf.faces()).write - ( - outputFile - ); - return outputFile; +inline bool Foam::surfaceWriter::hasTime() const +{ + return currTime_.name().size(); +} + + +inline const Foam::word& Foam::surfaceWriter::timeName() const +{ + return currTime_.name(); +} + + +inline Foam::scalar Foam::surfaceWriter::timeValue() const +{ + return currTime_.name().empty() ? 0 : currTime_.value(); } diff --git a/src/sampling/sampledSurface/writers/makeSurfaceWriterMethods.H b/src/surfMesh/writers/surfaceWriterMethods.H similarity index 54% rename from src/sampling/sampledSurface/writers/makeSurfaceWriterMethods.H rename to src/surfMesh/writers/surfaceWriterMethods.H index 5a0569b1b9b390d6e0cf28922993dccb28800185..b4672fafa86c2b11bcea52c416c6d743aba13de4 100644 --- a/src/sampling/sampledSurface/writers/makeSurfaceWriterMethods.H +++ b/src/surfMesh/writers/surfaceWriterMethods.H @@ -2,10 +2,8 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. \\/ M anipulation | -------------------------------------------------------------------------------- - | Copyright (C) 2011-2016 OpenFOAM Foundation ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,56 +22,35 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. InClass - Foam::makeSurfaceWriterMethods + Foam::surfaceWriterMethods Description - Convenience macros for instantiating writer methods for surfaceWriter - classes. + Convenience macros for instantiating surfaceWriter methods. \*---------------------------------------------------------------------------*/ -#ifndef makeSurfaceWriterMethods_H -#define makeSurfaceWriterMethods_H - -#include "surfaceWriter.H" -#include "addToRunTimeSelectionTable.H" +#ifndef surfaceWriterMethods_H +#define surfaceWriterMethods_H namespace Foam { // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -#define makeSurfaceWriterType(ThisClass) \ - defineTypeNameAndDebug(ThisClass, 0); \ - addToRunTimeSelectionTable(surfaceWriter, ThisClass, word) - - +// Instantiate templated method for standard types #define defineSurfaceWriterWriteField(ThisClass, FieldType) \ Foam::fileName ThisClass::write \ ( \ - const fileName& outputDir, \ - const fileName& surfaceName, \ - const meshedSurf& surf, \ const word& fieldName, \ - const Field<FieldType>& values, \ - const bool isNodeValues, \ - const bool verbose \ - ) const \ + const Field<FieldType>& values \ + ) \ { \ - return writeTemplate \ - ( \ - outputDir, \ - surfaceName, \ - surf, \ - fieldName, \ - values, \ - isNodeValues, \ - verbose \ - ); \ + return writeTemplate(fieldName, values); \ } #define defineSurfaceWriterWriteFields(ThisClass) \ + defineSurfaceWriterWriteField(ThisClass, label); \ defineSurfaceWriterWriteField(ThisClass, scalar); \ defineSurfaceWriterWriteField(ThisClass, vector); \ defineSurfaceWriterWriteField(ThisClass, sphericalTensor); \ diff --git a/src/surfMesh/writers/vtk/vtkSurfaceWriter.C b/src/surfMesh/writers/vtk/vtkSurfaceWriter.C new file mode 100644 index 0000000000000000000000000000000000000000..65fd1b122e5d71e037bb542f8acc42e0f4709636 --- /dev/null +++ b/src/surfMesh/writers/vtk/vtkSurfaceWriter.C @@ -0,0 +1,291 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "vtkSurfaceWriter.H" +#include "foamVtkSurfaceWriter.H" +#include "surfaceWriterMethods.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace surfaceWriters +{ + defineTypeName(vtkWriter); + addToRunTimeSelectionTable(surfaceWriter, vtkWriter, word); + addToRunTimeSelectionTable(surfaceWriter, vtkWriter, wordDict); + + // Accept vtp ending as well + addNamedToRunTimeSelectionTable + ( + surfaceWriter, + vtkWriter, + word, + vtp + ); + addNamedToRunTimeSelectionTable + ( + surfaceWriter, + vtkWriter, + wordDict, + vtp + ); +} +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surfaceWriters::vtkWriter::vtkWriter() +: + surfaceWriter(), + fmtType_(static_cast<unsigned>(vtk::formatType::INLINE_BASE64)), + precision_(IOstream::defaultPrecision()), + writer_(nullptr) +{} + + +Foam::surfaceWriters::vtkWriter::vtkWriter +( + const vtk::outputOptions& opts +) +: + surfaceWriter(), + fmtType_(static_cast<unsigned>(opts.fmt())), + precision_(opts.precision()), + writer_(nullptr) +{} + + +Foam::surfaceWriters::vtkWriter::vtkWriter +( + const dictionary& options +) +: + surfaceWriter(options), + fmtType_(static_cast<unsigned>(vtk::formatType::INLINE_BASE64)), + precision_ + ( + options.lookupOrDefaultCompat + ( + "precision", {{"writePrecision", 1806}}, + IOstream::defaultPrecision() + ) + ), + writer_(nullptr) +{ + // format: ascii | binary + // legacy: true | false + + vtk::outputOptions opts(vtk::formatType::INLINE_BASE64); + + const word formatName = options.lookupOrDefault<word>("format", ""); + if (formatName.size()) + { + opts.ascii + ( + IOstream::formatEnum(formatName) == IOstream::ASCII + ); + } + + if (options.lookupOrDefault("legacy", false)) + { + opts.legacy(true); + } + + // Convert back to raw data type + fmtType_ = static_cast<unsigned>(opts.fmt()); +} + + +Foam::surfaceWriters::vtkWriter::vtkWriter +( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + vtkWriter(options) +{ + open(surf, outputPath, parallel); +} + + +Foam::surfaceWriters::vtkWriter::vtkWriter +( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel, + const dictionary& options +) +: + vtkWriter(options) +{ + open(points, faces, outputPath, parallel); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::surfaceWriters::vtkWriter::close() +{ + writer_.clear(); + surfaceWriter::close(); +} + + +void Foam::surfaceWriters::vtkWriter::beginTime(const Time& t) +{ + writer_.clear(); + surfaceWriter::beginTime(t); +} + + +void Foam::surfaceWriters::vtkWriter::beginTime(const instant& inst) +{ + writer_.clear(); + surfaceWriter::beginTime(inst); +} + + +void Foam::surfaceWriters::vtkWriter::endTime() +{ + writer_.clear(); + surfaceWriter::endTime(); +} + + +Foam::fileName Foam::surfaceWriters::vtkWriter::write() +{ + checkOpen(); + + if (needsUpdate()) + { + writer_.clear(); + } + merge(); + + // From raw unsigned values to vtk::outputOptions + vtk::outputOptions opts(static_cast<vtk::formatType>(fmtType_), precision_); + + + // Geometry: rootdir/<TIME>/surfaceName.{vtk|vtp} + + fileName outputFile = outputPath_; + if (useTimeDir() && !timeName().empty()) + { + // Splice in time-directory + outputFile = outputPath_.path() / timeName() / outputPath_.name(); + } + outputFile.ext(vtk::surfaceWriter::ext(opts)); + + if (verbose_) + { + Info<< "Writing geometry to " << outputFile << endl; + } + + const meshedSurf& surf = surface(); + + if (writer_.empty() && (Pstream::master() || !parallel_)) + { + writer_.reset + ( + new vtk::surfaceWriter + ( + surf.points(), + surf.faces(), + opts, + outputFile, + false // serial! + ) + ); + + if (this->hasTime()) + { + // Time name in title + writer_->setTime(currTime_); + writer_->writeTimeValue(); + } + else + { + // Surface name in title + writer_->beginFile(outputPath_.nameLessExt()); + } + + writer_->writeGeometry(); + } + + return outputFile; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type> +Foam::fileName Foam::surfaceWriters::vtkWriter::writeTemplate +( + const word& fieldName, + const Field<Type>& localValues +) +{ + // Field: rootdir/<TIME>/surfaceName.{vtk|vtp} + + // Open file, writing geometry (if required) + fileName outputFile = this->write(); + + if (verbose_) + { + Info<< "Writing field " << fieldName << " to " << outputFile << endl; + } + + // geometry merge() implicit + tmp<Field<Type>> tfield = mergeField(localValues); + + if (Pstream::master() || !parallel_) + { + if (this->isPointData()) + { + writer_->beginPointData(nFields_); + } + else + { + writer_->beginCellData(nFields_); + } + + writer_->write(fieldName, tfield()); + } + + return outputFile; +} + + +// Field writing methods +defineSurfaceWriterWriteFields(Foam::surfaceWriters::vtkWriter); + + +// ************************************************************************* // diff --git a/src/surfMesh/writers/vtk/vtkSurfaceWriter.H b/src/surfMesh/writers/vtk/vtkSurfaceWriter.H new file mode 100644 index 0000000000000000000000000000000000000000..d9872b35cfbaffd1fc048063cd69f158d0f9cc3d --- /dev/null +++ b/src/surfMesh/writers/vtk/vtkSurfaceWriter.H @@ -0,0 +1,203 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2008-2011, 2015-2019 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- + | Copyright (C) 2011 OpenFOAM Foundation +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::surfaceWriters::vtkWriter + +Description + A surfaceWriter for VTK legacy (.vtk) or XML (.vtp) format. + + The formatOptions for vtk: + \table + Property | Description | Required | Default + format | ascii or binary format | no | binary + legacy | Legacy VTK output | no | false + precision | Write precision in ascii | no | same as IOstream + \endtable + + For example, + \verbatim + formatOptions + { + vtk + { + format binary; + legacy false; + precision 10; + } + } + \endverbatim + + \heading Output file locations + + The \c rootdir normally corresponds to something like + \c postProcessing/\<name\> + + \subheading Geometry and Fields + \verbatim + rootdir + `-- timeName + `-- surfaceName.{vtk,vtp} + \endverbatim + +SourceFiles + vtkSurfaceWriter.C + +\*---------------------------------------------------------------------------*/ + +#ifndef vtkSurfaceWriter_H +#define vtkSurfaceWriter_H + +#include "surfaceWriter.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +namespace vtk +{ +// Forward declarations +class outputOptions; +class surfaceWriter; +} + +namespace surfaceWriters +{ + +/*---------------------------------------------------------------------------*\ + Class vtkWriter Declaration +\*---------------------------------------------------------------------------*/ + +class vtkWriter +: + public surfaceWriter +{ + // Private Data + + //- The VTK output format type. + // Stored as a raw value to avoid a header dependency on fileFormats + unsigned fmtType_; + + //- ASCII write precision + unsigned precision_; + + //- Backend writer - master only + autoPtr<Foam::vtk::surfaceWriter> writer_; + + + // Private Member Functions + + //- Templated write field operation + template<class Type> + fileName writeTemplate + ( + const word& fieldName, //!< Name of field + const Field<Type>& localValues //!< Local field values to write + ); + + +public: + + //- Runtime type information + TypeNameNoDebug("vtk"); + + + // Constructors + + //- Construct null + vtkWriter(); + + //- Construct with some output options + explicit vtkWriter(const vtk::outputOptions& opts); + + //- Construct with some output options + explicit vtkWriter(const dictionary& options); + + //- Construct from components + // The file name is with/without an extension. + vtkWriter + ( + const meshedSurf& surf, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + //- Construct from components with specified output path. + // The file name is with/without an extension. + vtkWriter + ( + const pointField& points, + const faceList& faces, + const fileName& outputPath, + bool parallel = Pstream::parRun(), + const dictionary& options = dictionary() + ); + + + //- Destructor + virtual ~vtkWriter() = default; + + + // Member Functions + + //- Finish output, clears backend. + virtual void close(); // override + + //- Begin time step. Clears existing backend. + virtual void beginTime(const Time& t); // override + + //- Begin time step. Clears existing backend. + virtual void beginTime(const instant& inst); // override + + //- End time step. Clears existing backend. + virtual void endTime(); // override + + + // Write + + //- Write surface geometry to file. + virtual fileName write(); // override + + declareSurfaceWriterWriteMethod(label); + declareSurfaceWriterWriteMethod(scalar); + declareSurfaceWriterWriteMethod(vector); + declareSurfaceWriterWriteMethod(sphericalTensor); + declareSurfaceWriterWriteMethod(symmTensor); + declareSurfaceWriterWriteMethod(tensor); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace surfaceWriters +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* //