From a97628121ce307662600b5671ba93e0eeda10b50 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 10 Feb 2020 15:21:05 +0100 Subject: [PATCH] ENH: overhaul ensight handling (#1579) - includes restructuring and simplification of low-level ensight part handling and refactor of backends to improve code reuse. foamToEnsight ------------- * new cellZone support. This was previously only possible via a separate foamToEnsightParts utility that was not parallelized. * support for point fields. * `-nearCellValue` option (as per foamToVTK) * data indexing now uses values from the time index. This is consistent with the ensightWrite function object and can help with restarts. * existing ensight directories are removed, unless the -no-overwrite option is supplied foamToEnsightParts ------------------ * now redundant and removed. ensightOutputSurface (new class) -------------------------------- * a lightweight wrapper for point/face references that is tailored for the ensightSurfaceWriter. It uses compact face/point information and is serial only, since this is the format requirements from the surfaceWriter class. ensightMesh (revised class) --------------------------- * now only holds a polyMesh reference, which removes its dependency on finiteVolume and allows it to be relocated under fileFormats instead of conversion. Removed classes: ensightParts, ensighPartFaces, ensightPartCells - these were used by foamToEnsightParts, but not needed anymore. --- .../dataConversion/foamToEnsight/Make/options | 2 - .../foamToEnsight/checkMeshMoving.H | 10 +- .../foamToEnsight/convertLagrangian.H | 12 +- .../foamToEnsight/convertVolumeFields.H | 30 +- .../foamToEnsight/foamToEnsight.C | 307 +++++-- .../getTimeIndex.H | 2 +- .../dataConversion/foamToEnsight/readFields.H | 104 ++- .../foamToEnsight/writeDimFields.H | 76 +- .../writePointFields.H} | 71 +- .../foamToEnsight/writeVolFields.H | 68 +- .../foamToEnsightParts/Make/files | 4 - .../foamToEnsightParts/Make/options | 15 - .../foamToEnsightParts/checkMeshMoving.H | 45 - .../foamToEnsightParts/convertLagrangian.H | 138 --- .../foamToEnsightParts/findCloudFields.H | 94 --- .../foamToEnsightParts/foamToEnsightParts.C | 370 -------- .../foamToEnsightParts/moveMesh.H | 19 - .../foamToEnsightParts/readFields.H | 101 --- .../foamToEnsightParts/writeDimFields.H | 125 --- src/conversion/Make/files | 4 - src/conversion/ensight/mesh/ensightMesh.C | 404 --------- src/conversion/ensight/mesh/ensightMesh.H | 503 ----------- src/conversion/ensight/mesh/ensightMeshIO.C | 794 ------------------ .../ensight/mesh/ensightMeshOptions.C | 183 ---- .../ensight/output/ensightOutputVolField.H | 80 +- .../output/ensightOutputVolFieldTemplates.C | 434 ++++------ src/fileFormats/Make/files | 20 +- src/fileFormats/ensight/mesh/ensightMesh.C | 479 +++++++++++ src/fileFormats/ensight/mesh/ensightMesh.H | 342 ++++++++ .../ensight/mesh/ensightMeshI.H | 66 +- .../ensight/mesh/ensightMeshOptions.C | 340 ++++++++ .../ensight/output/ensightOutput.C | 490 +++++++++++ .../ensight/output/ensightOutput.H | 280 ++++-- .../ensight/output/ensightOutputTemplates.C | 356 ++++---- .../ensight/part/{ => cells}/ensightCells.C | 156 ++-- .../ensight/part/cells/ensightCells.H | 279 ++++++ .../ensight/part/cells/ensightCellsAddr.C | 238 ++++++ .../ensight/part/{ => cells}/ensightCellsI.H | 65 +- .../ensight/part/cells/ensightCellsIO.C | 322 +++++++ src/fileFormats/ensight/part/ensightCells.H | 215 ----- src/fileFormats/ensight/part/ensightFaces.H | 222 ----- src/fileFormats/ensight/part/ensightPart.H | 183 ---- .../ensight/part/ensightPartCells.C | 344 -------- .../ensight/part/ensightPartCells.H | 180 ---- .../ensight/part/ensightPartFaces.C | 302 ------- .../ensight/part/ensightPartFaces.H | 202 ----- src/fileFormats/ensight/part/ensightParts.C | 134 --- src/fileFormats/ensight/part/ensightParts.H | 120 --- .../ensight/part/{ => faces}/ensightFaces.C | 247 +++--- .../ensight/part/faces/ensightFaces.H | 264 ++++++ .../ensight/part/faces/ensightFacesAddr.C | 96 +++ .../ensight/part/{ => faces}/ensightFacesI.H | 76 +- .../ensight/part/faces/ensightFacesIO.C | 138 +++ .../ensight/part/{ => part}/ensightPart.C | 47 +- .../ensight/part/part/ensightPart.H | 214 +++++ .../part/surface/ensightOutputSurface.C | 62 +- .../part/surface/ensightOutputSurface.H | 137 +++ .../surface/ensightOutputSurfaceTemplates.C | 94 ++- .../utilities/ensightWrite/ensightWrite.C | 4 +- .../ensightWrite/ensightWriteTemplates.C | 4 +- .../writers/ensight/ensightSurfaceWriter.C | 2 +- .../ensight/ensightSurfaceWriterCollated.C | 41 +- .../ensight/ensightSurfaceWriterUncollated.C | 44 +- tutorials/basic/laplacianFoam/flange/Allrun | 1 - 64 files changed, 4916 insertions(+), 5885 deletions(-) rename applications/utilities/postProcessing/dataConversion/{foamToEnsightParts => foamToEnsight}/getTimeIndex.H (97%) rename applications/utilities/postProcessing/dataConversion/{foamToEnsightParts/writeVolFields.H => foamToEnsight/writePointFields.H} (64%) delete mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/files delete mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/options delete mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkMeshMoving.H delete mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/convertLagrangian.H delete mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/findCloudFields.H delete mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C delete mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/moveMesh.H delete mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/readFields.H delete mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/writeDimFields.H delete mode 100644 src/conversion/ensight/mesh/ensightMesh.C delete mode 100644 src/conversion/ensight/mesh/ensightMesh.H delete mode 100644 src/conversion/ensight/mesh/ensightMeshIO.C delete mode 100644 src/conversion/ensight/mesh/ensightMeshOptions.C create mode 100644 src/fileFormats/ensight/mesh/ensightMesh.C create mode 100644 src/fileFormats/ensight/mesh/ensightMesh.H rename src/{conversion => fileFormats}/ensight/mesh/ensightMeshI.H (55%) create mode 100644 src/fileFormats/ensight/mesh/ensightMeshOptions.C create mode 100644 src/fileFormats/ensight/output/ensightOutput.C rename src/fileFormats/ensight/part/{ => cells}/ensightCells.C (68%) create mode 100644 src/fileFormats/ensight/part/cells/ensightCells.H create mode 100644 src/fileFormats/ensight/part/cells/ensightCellsAddr.C rename src/fileFormats/ensight/part/{ => cells}/ensightCellsI.H (54%) create mode 100644 src/fileFormats/ensight/part/cells/ensightCellsIO.C delete mode 100644 src/fileFormats/ensight/part/ensightCells.H delete mode 100644 src/fileFormats/ensight/part/ensightFaces.H delete mode 100644 src/fileFormats/ensight/part/ensightPart.H delete mode 100644 src/fileFormats/ensight/part/ensightPartCells.C delete mode 100644 src/fileFormats/ensight/part/ensightPartCells.H delete mode 100644 src/fileFormats/ensight/part/ensightPartFaces.C delete mode 100644 src/fileFormats/ensight/part/ensightPartFaces.H delete mode 100644 src/fileFormats/ensight/part/ensightParts.C delete mode 100644 src/fileFormats/ensight/part/ensightParts.H rename src/fileFormats/ensight/part/{ => faces}/ensightFaces.C (52%) create mode 100644 src/fileFormats/ensight/part/faces/ensightFaces.H create mode 100644 src/fileFormats/ensight/part/faces/ensightFacesAddr.C rename src/fileFormats/ensight/part/{ => faces}/ensightFacesI.H (52%) create mode 100644 src/fileFormats/ensight/part/faces/ensightFacesIO.C rename src/fileFormats/ensight/part/{ => part}/ensightPart.C (73%) create mode 100644 src/fileFormats/ensight/part/part/ensightPart.H rename applications/utilities/postProcessing/dataConversion/foamToEnsightParts/convertVolumeFields.H => src/fileFormats/ensight/part/surface/ensightOutputSurface.C (59%) create mode 100644 src/fileFormats/ensight/part/surface/ensightOutputSurface.H rename applications/utilities/postProcessing/dataConversion/foamToEnsightParts/readFields.C => src/fileFormats/ensight/part/surface/ensightOutputSurfaceTemplates.C (54%) diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/options b/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/options index 49c30cf775..2c48a25324 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/options +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/options @@ -3,13 +3,11 @@ EXE_INC = \ -I$(LIB_SRC)/fileFormats/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/conversion/lnInclude \ - -I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/lagrangian/intermediate/lnInclude EXE_LIBS = \ -lfiniteVolume \ -lfileFormats \ - -ldynamicMesh \ -lconversion \ -llagrangianIntermediate \ -lgenericPatchFields diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H index 4849c95128..bb1b2dd446 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H @@ -1,6 +1,6 @@ // Check for "points" in any of the result directories -bool meshMoving = false; +bool hasMovingMesh = false; if (timeDirs.size() > 1 && Pstream::master()) { @@ -12,7 +12,7 @@ if (timeDirs.size() > 1 && Pstream::master()) { const word& timeName = inst.name(); - meshMoving = + hasMovingMesh = ( timeName != mesh.pointsInstance() && IOobject @@ -27,13 +27,13 @@ if (timeDirs.size() > 1 && Pstream::master()) ).typeHeaderOk(true, false) ); - if (meshMoving) + if (hasMovingMesh) { break; } } - if (meshMoving) + if (hasMovingMesh) { Info<< "found. Writing meshes for every timestep." << endl; } @@ -43,4 +43,4 @@ if (timeDirs.size() > 1 && Pstream::master()) } } -reduce(meshMoving, orOp()); +reduce(hasMovingMesh, orOp()); diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertLagrangian.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertLagrangian.H index b0478d844c..143f9f226f 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertLagrangian.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertLagrangian.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018 OpenCFD Ltd. + Copyright (C) 2018-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -31,9 +31,8 @@ Description // Cloud field data output if (doLagrangian) { - forAll(cloudNames, cloudNo) + for (const word& cloudName : cloudNames) { - const word& cloudName = cloudNames[cloudNo]; const HashTable& theseCloudFields = cloudFields[cloudName]; fileNameList currentCloudDirs @@ -48,12 +47,7 @@ if (doLagrangian) Info<< "Write " << cloudName << " ("; const bool cloudExists = - returnReduce - ( - currentCloudDirs.found(cloudName), - orOp() - ); - + returnReduce(currentCloudDirs.found(cloudName), orOp()); { autoPtr os = ensCase.newCloud(cloudName); diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertVolumeFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertVolumeFields.H index 5490eec6d7..042fe86426 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertVolumeFields.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertVolumeFields.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018 OpenCFD Ltd. + Copyright (C) 2018-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -35,25 +35,19 @@ Description { Info<< "Write volume field ("; - writeAllVolFields - ( - ensCase, - ensMesh, - meshProxy, - objects, - nodeValues - ); - - writeAllDimFields - ( - ensCase, - ensMesh, - meshProxy, - objects, - nodeValues - ); + writeAllVolFields(ensCase, ensMesh, objects, nearCellValue); + writeAllDimFields(ensCase, ensMesh, objects); Info<< " )" << nl; + + // PointData + // - only construct pointMesh on request (it constructs edge addressing) + if (doPointValues) + { + Info<< "Write point field ("; + writeAllPointFields(ensCase, ensMesh, objects); + Info<< " )" << nl; + } } diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C index c440c35825..dd5d4dbf8f 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2016-2018 OpenCFD Ltd. + Copyright (C) 2016-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -32,7 +32,11 @@ Group Description Translate OpenFOAM data to EnSight format. - An Ensight part is created for the internalMesh and for each patch. + An Ensight part is created for cellZones (unzoned cells are "internalMesh") + and patches. + + - Handles volume fields, dimensioned fields, point fields + - Handles mesh topology changes. Usage \b foamToEnsight [OPTION] @@ -51,36 +55,65 @@ Usage The quoting is required to avoid shell expansions and to pass the information as a single argument. + - \par -nearCellValue + Use zero-gradient cell values on patches + + - \par -nodeValues + Force interpolation of values to nodes + - \par -no-boundary - Suppress writing any patches. + Suppress output for all boundary patches - \par -no-internal - Suppress writing the internal mesh. + Suppress output for internal (volume) mesh + + - \par -no-cellZones + Suppress cellZone handling - \par -no-lagrangian Suppress writing lagrangian positions and fields. - - \par -patches patch or patch list - Specify particular patches to write. + - \par -no-mesh + Suppress writing the geometry. Can be useful for converting partial + results for a static geometry. - - \par -faceZones zone or zone list - Specify faceZones to write, with wildcards - - - \par -cellZone zoneName - Specify single cellZone to write (not lagrangian) + - \par -no-point-data + Suppress conversion of pointFields. No interpolated PointData. - \par -noZero Exclude the often incomplete initial conditions. + - \par -index \ + Use consecutive indexing for \c data/######## files with the + specified start index. + Ignore the time index contained in the uniform/time file. + - \par -name \ Define sub-directory name to use for Ensight data (default: "EnSight") - \par -width \ Width of Ensight data subdir (default: 8) -Note - Writes to \a EnSight directory to avoid collisions with - foamToEnsightParts + - \par -cellZones NAME | LIST + Specify single zone or multiple cell zones (name or regex) to write + + - \par -faceZones NAME | LIST + Specify single zone or multiple face zones (name or regex) to write + + - \par -patches NAME | LIST + Specify single patch or multiple patches (name or regex) to write + For example, + \verbatim + -patches top + -patches '( front \".*back\" )' + \endverbatim + + - \par -excludePatches NAME | LIST + Specify single or multiple patches (name or regex) not to convert. + For example, + \verbatim + -excludePatches '( inlet_1 inlet_2 "proc.*" )' + \endverbatim \*---------------------------------------------------------------------------*/ @@ -93,6 +126,7 @@ Note #include "HashOps.H" #include "fvc.H" +#include "fvMesh.H" #include "fieldTypes.H" #include "volFields.H" #include "scalarIOField.H" @@ -104,35 +138,27 @@ Note #include "ensightMesh.H" #include "ensightOutputCloud.H" #include "ensightOutputVolField.H" -#include "fvMeshSubsetProxy.H" // local files #include "readFields.H" #include "writeVolFields.H" #include "writeDimFields.H" +#include "writePointFields.H" #include "memInfo.H" +#undef foamToEnsight_useTimeIndex + using namespace Foam; -//- Get internal field and make it a zero-gradient volume field with subsetting -template -tmp -getZeroGradInternalField(IOobject& io, const fvMeshSubsetProxy& proxy) -{ - auto tfield = tmp::New(io, proxy.baseMesh()); - return proxy.interpolateInternal(tfield); -} - - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { argList::addNote ( - "Translate OpenFOAM data to Ensight format with a part for" - " the internalMesh and for each patch." + "Translate OpenFOAM data to Ensight format with individual parts" + " for cellZones, unzoned cells and patches" ); timeSelector::addOptions(); @@ -147,10 +173,42 @@ int main(int argc, char *argv[]) "ascii", "Write in ASCII format instead of 'C Binary'" ); + argList::addOption + ( + "index", + "start", + "Starting index for consecutive number of Ensight data/ files." + " Ignore the time index contained in the uniform/time file." + , true // mark as an advanced option + ); + argList::addOption + ( + "name", + "subdir", + "Sub-directory name for Ensight output (default: 'EnSight')" + ); + argList::addBoolOption + ( + "no-overwrite", + "Suppress removal of existing EnSight output directory" + ); + argList::addOption + ( + "width", + "n", + "Width of Ensight data subdir" + ); + argList::addBoolOption + ( + "nearCellValue", + "Use zero-gradient cell values on patches" + , true // mark as an advanced option + ); argList::addBoolOption ( "nodeValues", - "Write values at nodes" + "Force interpolation of values to nodes" + , true // mark as an advanced option ); argList::addBoolOption ( @@ -165,12 +223,37 @@ int main(int argc, char *argv[]) "Suppress writing the internal mesh" ); argList::addBoolOption + ( + "no-cellZones", + "Suppress writing any cellZones" + ); + argList::addBoolOption ( "no-lagrangian", // noLagrangian "Suppress writing lagrangian positions and fields" ); argList::addOptionCompat("no-lagrangian", {"noLagrangian", 1806}); + argList::addBoolOption + ( + "no-point-data", + "Suppress conversion of pointFields and disables -nodeValues" + ); + argList::addBoolOption + ( + "no-mesh", // noMesh + "Suppress writing the geometry." + " Can be useful for converting partial results for a static geometry" + , true // mark as an advanced option + ); + + // Future? + // argList::addBoolOption + // ( + // "one-boundary", // allPatches + // "Combine all patches into a single part" + // ); + argList::addOption ( "patches", @@ -179,6 +262,14 @@ int main(int argc, char *argv[]) "Eg, 'inlet' or '(outlet \"inlet.*\")'" ); argList::addOption + ( + "excludePatches", + "wordRes", + "Specify single patch or multiple patches to exclude from writing." + " Eg, 'outlet' or '( inlet \".*Wall\" )'" + , true // mark as an advanced option + ); + argList::addOption ( "faceZones", "wordRes", @@ -194,22 +285,13 @@ int main(int argc, char *argv[]) ); argList::addOption ( - "cellZone", - "word", - "Specify cellZone to write" - ); - argList::addOption - ( - "name", - "subdir", - "Sub-directory name for Ensight output (default: 'EnSight')" - ); - argList::addOption - ( - "width", - "n", - "Width of Ensight data subdir" + "cellZones", + "wordRes", + "Specify single or multiple cellZones to write\n" + "Eg, 'cells' or '( slice \"mfp-.*\" )'." ); + argList::addOptionCompat("cellZone", {"cellZones", 1912}); + #include "setRootCase.H" @@ -221,8 +303,6 @@ int main(int argc, char *argv[]) : IOstream::BINARY ); - const bool nodeValues = args.found("nodeValues"); - cpuTime timer; memInfo mem; Info<< "Initial memory " << mem.update().size() << " kB" << endl; @@ -239,19 +319,50 @@ int main(int argc, char *argv[]) regionPrefix = regionName; } + + // + // Configuration + // + const bool doBoundary = !args.found("no-boundary"); + const bool doInternal = !args.found("no-internal"); + const bool doCellZones = !args.found("no-cellZones"); + const bool doLagrangian = !args.found("no-lagrangian"); + const bool doPointValues = !args.found("no-point-data"); + const bool nearCellValue = args.found("nearCellValue") && doBoundary; + + // Control for numbering iterations + label indexingNumber(0); + const bool doConsecutive = args.readIfPresent("index", indexingNumber); + + + // Write the geometry, unless otherwise specified + bool doGeometry = !args.found("no-mesh"); + + if (nearCellValue) + { + Info<< "Using neighbouring cell value instead of patch value" + << nl << endl; + } + if (!doPointValues) + { + Info<< "Point fields and interpolated point data" + << " disabled with the '-no-point-data' option" + << nl; + } + // // General (case) output options // ensightCase::options caseOpts(format); - caseOpts.nodeValues(args.found("nodeValues")); + // Forced point interpolation? + caseOpts.nodeValues(doPointValues && args.found("nodeValues")); caseOpts.width(args.get