From d8a55e46b6b3635ce46321614f6d5fd618fa8145 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Sun, 25 Nov 2018 12:12:19 +0100 Subject: [PATCH] ENH: align foamToEnsightParts internals with foamToEnsight - add -region option and -fields filtering --- .../foamToEnsight/foamToEnsight.C | 24 +- .../dataConversion/foamToEnsight/readFields.C | 1 + .../foamToEnsight/writeDimFields.H | 5 +- .../foamToEnsight/writeVolFields.H | 7 +- .../foamToEnsightParts/Make/files | 1 + .../foamToEnsightParts/Make/options | 8 +- .../foamToEnsightParts/convertLagrangian.H | 136 +++++++ .../foamToEnsightParts/convertVolumeFields.H | 56 +++ .../foamToEnsightParts/findCloudFields.H | 94 +++++ .../foamToEnsightParts/findFields.H | 116 ------ .../foamToEnsightParts/foamToEnsightParts.C | 334 ++++++------------ .../foamToEnsightParts/readFields.C | 79 +++++ .../foamToEnsightParts/readFields.H | 99 ++++++ .../foamToEnsightParts/writeDimFields.H | 123 +++++++ .../foamToEnsightParts/writeVolFields.H | 145 ++++++++ 15 files changed, 863 insertions(+), 365 deletions(-) create mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/convertLagrangian.H create mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/convertVolumeFields.H create mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/findCloudFields.H delete mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/findFields.H create mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/readFields.C create mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/readFields.H create mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/writeDimFields.H create mode 100644 applications/utilities/postProcessing/dataConversion/foamToEnsightParts/writeVolFields.H diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C index cb05347ac2..652a9c21ed 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C @@ -39,8 +39,15 @@ Usage - \par -ascii Write Ensight data in ASCII format instead of "C Binary" - - \par -noZero - Exclude the often incomplete initial conditions. + - \par -fields \ + Specify single or multiple fields to write (all by default) + For example, + \verbatim + -fields T + -fields '(p T U \"alpha.*\")' + \endverbatim + The quoting is required to avoid shell expansions and to pass the + information as a single argument. - \par -no-boundary Suppress writing any patches. @@ -60,6 +67,12 @@ Usage - \par -cellZone zoneName Specify single cellZone to write (not lagrangian) + - \par -noZero + Exclude the often incomplete initial conditions. + + - \par -name \ + Define sub-directory name to use for Ensight data (default: "EnSight") + - \par -width \ Width of Ensight data subdir (default: 8) @@ -78,11 +91,10 @@ Note #include "HashOps.H" #include "fvc.H" +#include "fieldTypes.H" #include "volFields.H" -#include "labelIOField.H" #include "scalarIOField.H" -#include "tensorIOField.H" -#include "IOobjectList.H" +#include "vectorIOField.H" // file-format/conversion #include "ensightCase.H" @@ -372,7 +384,7 @@ int main(int argc, char *argv[]) ensCase.write(); - Info<< "End: " + Info<< "\nEnd: " << timer.elapsedCpuTime() << " s, " << mem.update().peak() << " kB (peak)" << nl << endl; diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.C index 50bddbba4f..a731bde5bb 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.C @@ -24,6 +24,7 @@ License \*---------------------------------------------------------------------------*/ #include "readFields.H" +#include "volFields.H" // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeDimFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeDimFields.H index 3920e6c29c..b96682d7d0 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeDimFields.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeDimFields.H @@ -46,7 +46,7 @@ template label writeDimFields ( ensightCase& ensCase, - ensightMesh& ensMesh, + const ensightMesh& ensMesh, const fvMeshSubsetProxy& proxy, const IOobjectList& objects, const bool nodeValues @@ -79,6 +79,7 @@ label writeDimFields ) ) { + Info<< ' ' << fieldName; ++count; } } @@ -90,7 +91,7 @@ label writeDimFields label writeAllDimFields ( ensightCase& ensCase, - ensightMesh& ensMesh, + const ensightMesh& ensMesh, const fvMeshSubsetProxy& proxy, const IOobjectList& objects, const bool nodeValues diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeVolFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeVolFields.H index 892b8a3cf2..98f388d9ec 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeVolFields.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeVolFields.H @@ -47,7 +47,7 @@ template bool writeVolField ( ensightCase& ensCase, - ensightMesh& ensMesh, + const ensightMesh& ensMesh, const fvMeshSubsetProxy& proxy, const tmp>& tfield, const bool nodeValues @@ -79,7 +79,7 @@ template label writeVolFields ( ensightCase& ensCase, - ensightMesh& ensMesh, + const ensightMesh& ensMesh, const fvMeshSubsetProxy& proxy, const IOobjectList& objects, const bool nodeValues @@ -103,6 +103,7 @@ label writeVolFields ) ) { + Info<< ' ' << fieldName; ++count; } } @@ -114,7 +115,7 @@ label writeVolFields label writeAllVolFields ( ensightCase& ensCase, - ensightMesh& ensMesh, + const ensightMesh& ensMesh, const fvMeshSubsetProxy& proxy, const IOobjectList& objects, const bool nodeValues diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/files b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/files index 739c971551..2dcb81ea73 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/files +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/files @@ -1,3 +1,4 @@ foamToEnsightParts.C +readFields.C EXE = $(FOAM_APPBIN)/foamToEnsightParts diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/options b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/options index 481d843cac..2ca27b9fbc 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/options +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/Make/options @@ -3,11 +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 \ + -ldynamicMesh \ + -lgenericPatchFields \ -llagrangianIntermediate \ - -lmeshTools \ - -lconversion \ - -lgenericPatchFields + -lconversion diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/convertLagrangian.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/convertLagrangian.H new file mode 100644 index 0000000000..83daf3544e --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/convertLagrangian.H @@ -0,0 +1,136 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 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 . + +Description + Code chunk for post-processing conversion of cloud(s) to Ensight + +\*---------------------------------------------------------------------------*/ + +// Cloud field data output +if (doLagrangian) +{ + forAll(cloudNames, cloudNo) + { + const word& cloudName = cloudNames[cloudNo]; + const HashTable& theseCloudFields = cloudFields[cloudName]; + + fileNameList currentCloudDirs + ( + readDir + ( + runTime.timePath()/regionPrefix/cloud::prefix, + fileName::DIRECTORY + ) + ); + + Info<< "Write " << cloudName << " ("; + + const bool cloudExists = + returnReduce + ( + currentCloudDirs.found(cloudName), + orOp() + ); + + { + autoPtr os = ensCase.newCloud(cloudName); + + ensightCloud::writePositions + ( + mesh, + cloudName, + cloudExists, + os + ); + + Info<< " positions"; + if (!cloudExists) + { + Info<< "{0}"; // report empty field + } + } + + forAllConstIters(theseCloudFields, fieldIter) + { + const word& fieldName = fieldIter.key(); + const word& fieldType = fieldIter.object(); + + IOobject fieldObject + ( + fieldName, + mesh.time().timeName(), + cloud::prefix/cloudName, + mesh, + IOobject::MUST_READ + ); + + bool fieldExists = cloudExists; // No field without positions + if (cloudExists) + { + // Want MUST_READ (globally) and valid=false (locally), + // but that combination does not work. + // So check the header and sync globally + + fieldExists = + fieldObject.typeHeaderOk>(false); + + reduce(fieldExists, orOp()); + } + + bool wrote = false; + if (fieldType == scalarIOField::typeName) + { + autoPtr os = + ensCase.newCloudData(cloudName, fieldName); + + wrote = ensightCloud::writeCloudField + ( + fieldObject, fieldExists, os + ); + } + else if (fieldType == vectorIOField::typeName) + { + autoPtr os = + ensCase.newCloudData(cloudName, fieldName); + + wrote = ensightCloud::writeCloudField + ( + fieldObject, fieldExists, os + ); + } + + if (wrote) + { + Info<< ' ' << fieldName; + if (!fieldExists) + { + Info<< "{0}"; // report empty field + } + } + } + Info<< " )" << nl; + } +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/convertVolumeFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/convertVolumeFields.H new file mode 100644 index 0000000000..37364c6e71 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/convertVolumeFields.H @@ -0,0 +1,56 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 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 . + +Description + Code chunk for converting volume and dimensioned fields + included by foamToEnsightParts. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Cell field data output +{ + Info<< "Write volume field ("; + + writeAllVolFields + ( + ensCase, + ensParts, + mesh, + objects + ); + + writeAllDimFields + ( + ensCase, + ensParts, + mesh, + objects + ); + + Info<< " )" << nl; +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/findCloudFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/findCloudFields.H new file mode 100644 index 0000000000..a8a56c33a8 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/findCloudFields.H @@ -0,0 +1,94 @@ +// check all time directories for the following: + +// The fields for each cloud: +HashTable> cloudFields; + +// Identify if lagrangian data exist at any time step. +if (timeDirs.size() && doLagrangian) +{ + const fileName& baseDir = mesh.time().path(); + const fileName cloudPrefix(regionPrefix/cloud::prefix); + + Info<< "Searching for lagrangian ... " << flush; + + for (const instant& inst : timeDirs) + { + const word& timeName = inst.name(); + + // DO NOT USE -->> runTime.setTime(timeDirs[timeI], timeI); <<-- + // It incurs a large overhead when done so frequently. + + fileNameList cloudDirs + ( + readDir + ( + baseDir/timeName/cloudPrefix, + fileName::DIRECTORY + ) + ); + + for (fileName& cloudDir : cloudDirs) + { + const word cloudName(std::move(cloudDir)); + + IOobjectList cloudObjs + ( + mesh, + timeName, + cloudPrefix/cloudName + ); + + // Clouds require "coordinates". + // The "positions" are for v1706 and lower. + // - detect and remove since these are treated specially + + bool isCloud = false; + if (cloudObjs.erase("coordinates")) + { + isCloud = true; + } + if (cloudObjs.erase("positions")) + { + isCloud = true; + } + + if (isCloud) + { + // Save the cloud fields on a per cloud basis + auto& fieldsPerCloud = cloudFields(cloudName); + + forAllConstIters(cloudObjs, fieldIter) + { + const IOobject* io = *fieldIter; + + // Field name/type + fieldsPerCloud.insert(io->name(), io->headerClassName()); + } + } + } + } + + if (Pstream::parRun()) + { + Pstream::mapCombineGather(cloudFields, HashTableOps::plusEqOp()); + Pstream::mapCombineScatter(cloudFields); + } + + if (cloudFields.empty()) + { + Info<< "none detected." << endl; + } +} + + +// Sorted list of cloud names +const wordList cloudNames(cloudFields.sortedToc()); + +if (cloudNames.size()) +{ + // Complete the echo information - as flatOutput + cloudNames.writeList(Info) << endl; +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/findFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/findFields.H deleted file mode 100644 index f43584b4f6..0000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/findFields.H +++ /dev/null @@ -1,116 +0,0 @@ -// check the final time directory for the following: - -// 1. volume fields -HashTable volumeFields; - -// 2. the fields for each cloud: -HashTable> cloudFields; - -if (timeDirs.size()) -{ - const word& lastTimeName = timeDirs.last().name(); - const fileName cloudPrefix(regionPrefix/cloud::prefix); - - IOobjectList objs(mesh, lastTimeName); - - forAllConstIters(objs, fieldIter) - { - const IOobject& obj = *fieldIter(); - const word& fieldName = obj.name(); - const word& fieldType = obj.headerClassName(); - - if (volFieldTypes.found(fieldType) && !fieldName.endsWith("_0")) - { - // ignore types that we don't handle, and ignore _0 fields - volumeFields.insert(fieldName, fieldType); - } - } - - - // - // Now check for lagrangian/ - // - fileNameList cloudDirs; - if (doLagrangian) - { - cloudDirs = readDir - ( - runTime.path() - / lastTimeName - / cloudPrefix, - fileName::DIRECTORY - ); - } - - forAll(cloudDirs, cloudI) - { - const word& cloudName = cloudDirs[cloudI]; - - IOobjectList cloudObjs - ( - mesh, - lastTimeName, - cloudPrefix/cloudName - ); - - // Clouds require "coordinates". - // The "positions" are for v1706 and lower. - if (cloudObjs.found("coordinates") || cloudObjs.found("positions")) - { - // Save the cloud fields on a per cloud basis - auto& fieldsPerCloud = cloudFields(cloudName); - - forAllConstIters(cloudObjs, fieldIter) - { - const IOobject* obj = fieldIter(); - - const word& fieldName = obj->name(); - const word& fieldType = obj->headerClassName(); - - if (cloudFieldTypes.found(fieldType)) - { - // Field name/type - ignore types that we don't handle - fieldsPerCloud.insert(fieldName, fieldType); - } - } - } - } - - // Only retain a cloud that actually has fields - cloudFields.filterValues - ( - [](const HashTable& v){ return v.size(); } - ); - - - // - // Verify that the variable is present for all times - // - for (label i=0; volumeFields.size() && i < timeDirs.size(); ++i) - { - const word& timeName = timeDirs[i].name(); - - // Everything is potentially missing, unless we discover otherwise - wordHashSet missing(volumeFields); - - // Avoid -->> IOobjectList objs(mesh, timeName); <<-- - // Too much overhead when done so frequently. - - fileNameList contents = readDir - ( - runTime.path() - / timeName, - fileName::FILE - ); - - for (const fileName& file : contents) - { - missing.erase(file.name()); - } - - volumeFields.erase(missing); - } -} - - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C index a294e3c708..6112c199a6 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C @@ -38,8 +38,15 @@ Usage - \par -ascii Write Ensight data in ASCII format instead of "C Binary" - - \par -name \ - Define sub-directory name to use for Ensight data (default: "Ensight") + - \par -fields \ + Specify single or multiple fields to write (all by default) + For example, + \verbatim + -fields T + -fields '(p T U \"alpha.*\")' + \endverbatim + The quoting is required to avoid shell expansions and to pass the + information as a single argument. - \par -noZero Exclude the often incomplete initial conditions. @@ -55,6 +62,12 @@ Usage Suppress writing the geometry. Can be useful for converting partial results for a static geometry. + - \par -noZero + Exclude the often incomplete initial conditions. + + - \par -name \ + Define sub-directory name to use for Ensight data (default: "Ensight") + - \par -width \ Width of Ensight data subdir @@ -66,13 +79,16 @@ Note #include "argList.H" #include "timeSelector.H" - -#include "volFields.H" -#include "OFstream.H" -#include "IOmanip.H" #include "IOobjectList.H" +#include "IOmanip.H" +#include "OFstream.H" +#include "PstreamCombineReduceOps.H" +#include "HashOps.H" + +#include "fieldTypes.H" +#include "volFields.H" #include "scalarIOField.H" -#include "tensorIOField.H" +#include "vectorIOField.H" // file-format/conversion #include "ensightCase.H" @@ -80,6 +96,12 @@ Note #include "ensightParts.H" #include "ensightSerialOutput.H" #include "ensightOutputCloud.H" +#include "fvMeshSubsetProxy.H" + +// local files +#include "readFields.H" +#include "writeVolFields.H" +#include "writeDimFields.H" #include "memInfo.H" @@ -87,13 +109,14 @@ using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - int main(int argc, char *argv[]) { // Enable -constant // Probably don't need -withZero though, since the fields are vetted // afterwards anyhow timeSelector::addOptions(true, false); + #include "addRegionOption.H" + argList::noParallel(); argList::addBoolOption ( @@ -122,6 +145,14 @@ int main(int argc, char *argv[]) ); argList::addOptionCompat("no-mesh", {"noMesh", 1806}); + argList::addOption + ( + "fields", + "wordRes", + "Specify single or multiple fields to write (all by default)\n" + "Eg, 'T' or '( \"U.*\" )'" + ); + argList::addOption ( "name", @@ -135,24 +166,6 @@ int main(int argc, char *argv[]) "Width of Ensight data subdir" ); - // The volume field types that we handle - const wordHashSet volFieldTypes - { - volScalarField::typeName, - volVectorField::typeName, - volSphericalTensorField::typeName, - volSymmTensorField::typeName, - volTensorField::typeName - }; - - // The lagrangian field types that we handle - const wordHashSet cloudFieldTypes - { - scalarIOField::typeName, - vectorIOField::typeName, - tensorIOField::typeName - }; - #include "setRootCase.H" // Default to binary output, unless otherwise specified @@ -211,7 +224,7 @@ int main(int argc, char *argv[]) // - // Miscellaneous output configuration + // Output configuration // // Control for renumbering iterations @@ -222,9 +235,16 @@ int main(int argc, char *argv[]) // Write the geometry, unless otherwise specified bool doGeometry = !args.found("no-mesh"); + // + // Output configuration (field related) + // + + wordRes fieldPatterns; + args.readListIfPresent("fields", fieldPatterns); + // Construct the list of ensight parts for the entire mesh - ensightParts partsList(mesh); + ensightParts ensParts(mesh); // Write summary information if (Pstream::master()) @@ -235,11 +255,49 @@ int main(int argc, char *argv[]) info << "// summary of ensight parts" << nl << nl; - partsList.writeSummary(info); + ensParts.writeSummary(info); } #include "checkMeshMoving.H" - #include "findFields.H" + #include "findCloudFields.H" + + Info<< "Startup in " + << timer.cpuTimeIncrement() << " s, " + << mem.update().size() << " kB" << nl << endl; + + + // Initially all possible objects that are available at the final time + wordHashSet testedObjectNames; + { + IOobjectList objects(mesh, timeDirs.last().name()); + + if (!fieldPatterns.empty()) + { + objects.filterObjects(fieldPatterns); + } + + // Remove "*_0" restart fields + objects.prune_0(); + + // Only retain volume and dimensioned fields. + objects.filterClasses + ( + [](const word& clsName){ + return + ( + fieldTypes::volume.found(clsName) + || fieldTypes::internal.found(clsName) + ); + } + ); + + wordList objectNames(objects.sortedNames()); + + // Check availability for all times... + checkData(mesh, timeDirs, objectNames); + + testedObjectNames = objectNames; + } if (meshMoving && !doGeometry) { @@ -248,10 +306,6 @@ int main(int argc, char *argv[]) } - Info<< "Startup in " - << timer.cpuTimeIncrement() << " s, " - << mem.update().size() << " kB" << nl << endl; - forAll(timeDirs, timeI) { runTime.setTime(timeDirs[timeI], timeI); @@ -261,221 +315,33 @@ int main(int argc, char *argv[]) ensCase.setTime(timeDirs[timeI], timeIndex); + Info<< "Time [" << timeIndex << "] = " << runTime.timeName() << nl; + if (timeI == 0 || mesh.moving()) { if (mesh.moving()) { - partsList.recalculate(mesh); + ensParts.recalculate(mesh); } if (doGeometry) { autoPtr os = ensCase.newGeometry(meshMoving); - partsList.write(os.ref()); + ensParts.write(os.ref()); } } - Info<< "Write volume field (" << flush; + // Objects at this time + IOobjectList objects(mesh, runTime.timeName()); - forAllConstIters(volumeFields, fieldIter) - { - const word& fieldName = fieldIter.key(); - const word& fieldType = fieldIter.object(); + // Restrict to objects that are available for all times + objects.filterObjects(testedObjectNames); - IOobject fieldObject - ( - fieldName, - mesh.time().timeName(), - mesh, - IOobject::MUST_READ, - IOobject::NO_WRITE - ); + // Volume, internal fields + #include "convertVolumeFields.H" - bool wrote = false; - if (fieldType == volScalarField::typeName) - { - autoPtr os = ensCase.newData - ( - fieldName - ); - - volScalarField vf(fieldObject, mesh); - wrote = ensightSerialOutput::writeField - ( - vf, partsList, os - ); - } - else if (fieldType == volVectorField::typeName) - { - autoPtr os = ensCase.newData - ( - fieldName - ); - - volVectorField vf(fieldObject, mesh); - wrote = ensightSerialOutput::writeField - ( - vf, partsList, os - ); - } - else if (fieldType == volSphericalTensorField::typeName) - { - autoPtr os = ensCase.newData - ( - fieldName - ); - - volSphericalTensorField vf(fieldObject, mesh); - wrote = ensightSerialOutput::writeField - ( - vf, partsList, os - ); - } - else if (fieldType == volSymmTensorField::typeName) - { - autoPtr os = ensCase.newData - ( - fieldName - ); - - volSymmTensorField vf(fieldObject, mesh); - wrote = ensightSerialOutput::writeField - ( - vf, partsList, os - ); - } - else if (fieldType == volTensorField::typeName) - { - autoPtr os = ensCase.newData - ( - fieldName - ); - - volTensorField vf(fieldObject, mesh); - wrote = ensightSerialOutput::writeField - ( - vf, partsList, os - ); - } - - if (wrote) - { - Info<< " " << fieldObject.name() << flush; - } - } - Info<< " )" << endl; - - // Check for clouds - forAllConstIters(cloudFields, cloudIter) - { - const word& cloudName = cloudIter.key(); - const HashTable& theseCloudFields = cloudIter.object(); - - const fileName cloudPrefix(regionPrefix/cloud::prefix); - - if (!isDir(runTime.timePath()/cloudPrefix/cloudName)) - { - continue; - } - - IOobjectList cloudObjs - ( - mesh, - runTime.timeName(), - cloudPrefix/cloudName - ); - - // Clouds require "coordinates". - // The "positions" are for v1706 and lower. - const bool cloudExists = - ( - cloudObjs.found("coordinates") - || cloudObjs.found("positions") - ); - - if (!cloudExists) - { - continue; - } - - Info<< "Write " << cloudName << " (" << flush; - - { - auto os = ensCase.newCloud(cloudName); - - ensightCloud::writePositions - ( - mesh, - cloudName, - cloudExists, - os - ); - - Info<< " positions"; - } - - - forAllConstIters(theseCloudFields, fieldIter) - { - const word& fieldName = fieldIter.key(); - const word& fieldType = fieldIter.object(); - - IOobject *fieldObject = cloudObjs.findObject(fieldName); - - if (!fieldObject) - { - Info<< "missing " - << runTime.timeName()/cloudPrefix/cloudName/fieldName - << endl; - continue; - } - - bool wrote = false; - if (fieldType == scalarIOField::typeName) - { - auto os = - ensCase.newCloudData(cloudName, fieldName); - - wrote = ensightCloud::writeCloudField - ( - *fieldObject, - true, // field exists - os - ); - } - else if (fieldType == vectorIOField::typeName) - { - auto os = - ensCase.newCloudData(cloudName, fieldName); - - wrote = ensightCloud::writeCloudField - ( - *fieldObject, - true, // field exists - os - ); - } - else if (fieldType == tensorIOField::typeName) - { - auto os = - ensCase.newCloudData(cloudName, fieldName); - - wrote = ensightCloud::writeCloudField - ( - *fieldObject, - true, // field exists - os - ); - } - - if (wrote) - { - Info<< " " << fieldObject->name(); - } - } - - Info<< " )" << endl; - } + // Lagrangian fields + #include "convertLagrangian.H" Info<< "Wrote in " << timer.cpuTimeIncrement() << " s, " diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/readFields.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/readFields.C new file mode 100644 index 0000000000..a731bde5bb --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/readFields.C @@ -0,0 +1,79 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 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 . + +\*---------------------------------------------------------------------------*/ + +#include "readFields.H" +#include "volFields.H" + +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +Foam::label Foam::checkData +( + const fvMesh& mesh, + const instantList& timeDirs, + wordList& objectNames +) +{ + // Assume prune_0() was used prior to calling this + + wordHashSet goodFields; + + for (const word& fieldName : objectNames) + { + bool good = false; + + for (const instant& inst : timeDirs) + { + good = + IOobject + ( + fieldName, + inst.name(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE, + false // no register + ).typeHeaderOk(false, false); + + if (!good) + { + break; + } + } + + reduce(good, andOp()); + + if (good) + { + goodFields.insert(fieldName); + } + } + + objectNames = goodFields.sortedToc(); + + return objectNames.size(); +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/readFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/readFields.H new file mode 100644 index 0000000000..f11e318b69 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/readFields.H @@ -0,0 +1,99 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 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 . + +InNamespace + Foam + +Description + Read fields from disk for foamToEnsight + +SourceFiles + readFields.C + +\*---------------------------------------------------------------------------*/ + +#ifndef readFields_H +#define readFields_H + +#include "instantList.H" +#include "IOobjectList.H" +#include "fvMesh.H" +#include "fvMeshSubsetProxy.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +//- Get the field and subset it, or return nullptr +template +tmp getField(const IOobject* io, const fvMesh& mesh) +{ + if (io) + { + auto tfield = tmp::New(*io, mesh); + return tfield; + } + + return nullptr; +} + + +//- Get internal field and make it a zero-gradient volume field with subsetting +template +tmp +getZeroGradField(IOobject* io, const fvMesh& mesh) +{ + if (io) + { + auto tdimfield = + tmp::New(*io, mesh); + + auto tfield = fvMeshSubsetProxy::zeroGradientField(tdimfield()); + tdimfield.clear(); + + return tfield; + } + + return nullptr; +} + + +//- Check if fields are good to use (available at all times) +// ignore special fields (_0 fields), +// ignore fields that are not available for all time-steps +label checkData +( + const fvMesh& mesh, + const instantList& timeDirs, + wordList& objectNames +); + + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/writeDimFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/writeDimFields.H new file mode 100644 index 0000000000..338e213edc --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/writeDimFields.H @@ -0,0 +1,123 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 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 . + +InNamespace + Foam + +Description + Read dimensioned fields from disk and write with ensightParts + +SourceFiles + writeDimFields.H + +\*---------------------------------------------------------------------------*/ + +#ifndef writeDimFields_H +#define writeDimFields_H + +#include "writeVolFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +template +label writeDimFields +( + ensightCase& ensCase, + const ensightParts& ensParts, + const fvMesh& mesh, + const IOobjectList& objects +) +{ + typedef GeometricField GeoField; + + typedef typename + GeometricField + < + Type, fvPatchField, volMesh + >::Internal DimField; + + + label count = 0; + + for (const word& fieldName : objects.sortedNames()) + { + IOobject* io = objects.findObject(fieldName); + + if + ( + writeVolField + ( + ensCase, + ensParts, + mesh, + getZeroGradField(io, mesh) + ) + ) + { + Info<< ' ' << fieldName; + ++count; + } + } + + return count; +} + + +label writeAllDimFields +( + ensightCase& ensCase, + const ensightParts& ensParts, + const fvMesh& mesh, + const IOobjectList& objects +) +{ + #undef foamToEnsight_WRITE_FIELD + #define foamToEnsight_WRITE_FIELD(PrimitiveType) \ + writeDimFields \ + ( \ + ensCase, ensParts, \ + mesh, \ + objects \ + ) + + label count = 0; + count += foamToEnsight_WRITE_FIELD(scalar); + count += foamToEnsight_WRITE_FIELD(vector); + count += foamToEnsight_WRITE_FIELD(sphericalTensor); + count += foamToEnsight_WRITE_FIELD(symmTensor); + count += foamToEnsight_WRITE_FIELD(tensor); + + #undef foamToEnsight_WRITE_FIELD + return count; +} + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/writeVolFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/writeVolFields.H new file mode 100644 index 0000000000..303f97ad53 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/writeVolFields.H @@ -0,0 +1,145 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 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 . + +InNamespace + Foam + +Description + Read volume fields from disk and write with ensightParts + +SourceFiles + writeVolFields.H + +\*---------------------------------------------------------------------------*/ + +#ifndef writeVolFields_H +#define writeVolFields_H + +#include "readFields.H" +#include "fvMesh.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +template +bool writeVolField +( + ensightCase& ensCase, + const ensightParts& ensParts, + const fvMesh& mesh, + const tmp>& tfield +) +{ + if (!tfield.valid()) + { + return false; + } + + const auto& field = tfield(); + + autoPtr os = ensCase.newData(field.name()); + + bool wrote = ensightSerialOutput::writeField + ( + field, + ensParts, + os + ); + + tfield.clear(); + return wrote; +} + + +template +label writeVolFields +( + ensightCase& ensCase, + const ensightParts& ensParts, + const fvMesh& mesh, + const IOobjectList& objects +) +{ + typedef GeometricField GeoField; + + label count = 0; + + for (const word& fieldName : objects.sortedNames()) + { + if + ( + writeVolField + ( + ensCase, + ensParts, + mesh, + getField(objects.findObject(fieldName), mesh) + ) + ) + { + Info<< ' ' << fieldName; + ++count; + } + } + + return count; +} + + +label writeAllVolFields +( + ensightCase& ensCase, + const ensightParts& ensParts, + const fvMesh& mesh, + const IOobjectList& objects +) +{ + #undef foamToEnsight_WRITE_FIELD + #define foamToEnsight_WRITE_FIELD(PrimitiveType) \ + writeVolFields \ + ( \ + ensCase, ensParts, \ + mesh, \ + objects \ + ) + + label count = 0; + count += foamToEnsight_WRITE_FIELD(scalar); + count += foamToEnsight_WRITE_FIELD(vector); + count += foamToEnsight_WRITE_FIELD(sphericalTensor); + count += foamToEnsight_WRITE_FIELD(symmTensor); + count += foamToEnsight_WRITE_FIELD(tensor); + + #undef foamToEnsight_WRITE_FIELD + return count; +} + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* //