diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/files b/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/files index 87ee002e04..8716be53f4 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/files +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/Make/files @@ -1,3 +1,4 @@ +readFields.C foamToEnsight.C EXE = $(FOAM_APPBIN)/foamToEnsight diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkData.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkData.H deleted file mode 100644 index 62cb39030b..0000000000 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkData.H +++ /dev/null @@ -1,34 +0,0 @@ -// ignore special fields (_0 fields), -// ignore fields we don't handle, -// ignore fields that are not available for all time-steps - -// hash by field-name in fieldsToUse -if (!fieldsToUse.found(fieldName)) -{ - bool variableGood = false; - - forAll(timeDirs, n1) - { - variableGood = - ( - !fieldName.endsWith("_0") - && IOobject - ( - fieldName, - timeDirs[n1].name(), - mesh, - IOobject::NO_READ, - IOobject::NO_WRITE, - false // no register - ).typeHeaderOk(false, false) - ); - - if (!variableGood) - { - break; - } - } - - reduce(variableGood, andOp()); - fieldsToUse.set(fieldName, variableGood); -} diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H index 7da98b7351..4849c95128 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H @@ -8,9 +8,9 @@ if (timeDirs.size() > 1 && Pstream::master()) // See if any other "polyMesh/points" files exist too. Info<< "Search for moving mesh ... " << flush; - forAll(timeDirs, timeI) + for (const instant& inst : timeDirs) { - const word& timeName = timeDirs[timeI].name(); + const word& timeName = inst.name(); meshMoving = ( diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertLagrangian.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertLagrangian.H new file mode 100644 index 0000000000..25d4cdd90b --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertLagrangian.H @@ -0,0 +1,137 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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/foamToEnsight/convertVolumeFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertVolumeFields.H new file mode 100644 index 0000000000..b089212cb5 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/convertVolumeFields.H @@ -0,0 +1,58 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 foamToEnsight. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Cell field data output +{ + Info<< "Write volume field ("; + + writeAllVolFields + ( + ensCase, + ensMesh, + meshProxy, + objects, + nodeValues + ); + + writeAllDimFields + ( + ensCase, + ensMesh, + meshProxy, + objects, + nodeValues + ); + + Info<< " )" << nl; +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/findCloudFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/findCloudFields.H index e25b6c2443..a8a56c33a8 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/findCloudFields.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/findCloudFields.H @@ -4,29 +4,32 @@ HashTable> cloudFields; // Identify if lagrangian data exist at any time step. -if (timeDirs.size() && !noLagrangian) +if (timeDirs.size() && doLagrangian) { const fileName& baseDir = mesh.time().path(); const fileName cloudPrefix(regionPrefix/cloud::prefix); Info<< "Searching for lagrangian ... " << flush; - forAll(timeDirs, timeI) + for (const instant& inst : timeDirs) { - const word& timeName = timeDirs[timeI].name(); + 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 + fileNameList cloudDirs ( - baseDir/timeName/cloudPrefix, - fileName::DIRECTORY + readDir + ( + baseDir/timeName/cloudPrefix, + fileName::DIRECTORY + ) ); - forAll(cloudDirs, cloudI) + for (fileName& cloudDir : cloudDirs) { - const word& cloudName = cloudDirs[cloudI]; + const word cloudName(std::move(cloudDir)); IOobjectList cloudObjs ( @@ -56,10 +59,10 @@ if (timeDirs.size() && !noLagrangian) forAllConstIters(cloudObjs, fieldIter) { - const IOobject* obj = fieldIter(); + const IOobject* io = *fieldIter; // Field name/type - fieldsPerCloud.insert(obj->name(), obj->headerClassName()); + fieldsPerCloud.insert(io->name(), io->headerClassName()); } } } diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C index 5485cd1d40..f27a0081e0 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C @@ -77,50 +77,28 @@ Note #include "fvc.H" #include "volFields.H" -#include "hashedWordList.H" - #include "labelIOField.H" #include "scalarIOField.H" #include "tensorIOField.H" +#include "IOobjectList.H" // file-format/conversion #include "ensightCase.H" #include "ensightGeoFile.H" #include "ensightMesh.H" #include "ensightOutput.H" +#include "ensightOutputCloud.H" #include "fvMeshSubsetProxy.H" // local files -#include "ensightOutputCloud.H" +#include "readFields.H" +#include "writeVolFields.H" +#include "writeDimFields.H" #include "memInfo.H" using namespace Foam; - -//- Get the field and subset it -template -tmp getField(IOobject& io, const fvMeshSubsetProxy& proxy) -{ - auto tfield = tmp::New(io, proxy.baseMesh()); - return proxy.interpolate(tfield); -} - - -//- Get the field and subset it, or return nullptr -template -tmp getField(const IOobject* io, const fvMeshSubsetProxy& proxy) -{ - if (io) - { - auto tfield = tmp::New(*io, proxy.baseMesh()); - return proxy.interpolate(tfield); - } - - return nullptr; -} - - //- Get internal field and make it a zero-gradient volume field with subsetting template tmp @@ -160,9 +138,11 @@ int main(int argc, char *argv[]) ); argList::addBoolOption ( - "noPatches", + "noBoundary", "Suppress writing any patches" ); + argList::addOptionCompat("noBoundary", {"noPatches", 1806}); + argList::addOption ( "patches", @@ -200,22 +180,6 @@ int main(int argc, char *argv[]) "Width of ensight data subdir" ); - // The volume field types that we handle - const hashedWordList volFieldTypes - { - volScalarField::typeName, - volVectorField::typeName, - volSphericalTensorField::typeName, - volSymmTensorField::typeName, - volTensorField::typeName, - - volScalarField::Internal::typeName, - volVectorField::Internal::typeName, - volSphericalTensorField::Internal::typeName, - volSymmTensorField::Internal::typeName, - volTensorField::Internal::typeName - }; - #include "setRootCase.H" // Default to binary output, unless otherwise specified @@ -260,10 +224,10 @@ int main(int argc, char *argv[]) // Define sub-directory name to use for EnSight data. // The path to the ensight directory is at case level only // - For parallel cases, data only written from master - fileName ensightDir = args.lookupOrDefault("name", "EnSight"); - if (!ensightDir.isAbsolute()) + fileName outputDir = args.lookupOrDefault("name", "EnSight"); + if (!outputDir.isAbsolute()) { - ensightDir = args.globalPath()/ensightDir; + outputDir = args.globalPath()/outputDir; } @@ -272,7 +236,7 @@ int main(int argc, char *argv[]) // ensightMesh::options writeOpts(format); writeOpts.useInternalMesh(!args.found("noInternal")); - writeOpts.useBoundaryMesh(!args.found("noPatches")); + writeOpts.useBoundaryMesh(!args.found("noBoundary")); if (args.found("patches")) { @@ -286,7 +250,7 @@ int main(int argc, char *argv[]) // // output configuration (field related) // - const bool noLagrangian = args.found("noLagrangian"); + const bool doLagrangian = !args.found("noLagrangian"); wordRes fieldPatterns; args.readListIfPresent("fields", fieldPatterns); @@ -302,16 +266,8 @@ int main(int argc, char *argv[]) // Ignored (unproxied) if cellZoneName is empty fvMeshSubsetProxy meshProxy(mesh, fvMeshSubsetProxy::ZONE, cellZoneName); - // - // Open new ensight case file, initialize header etc. - // - ensightCase ensCase - ( - ensightDir, - args.globalCaseName(), - caseOpts - ); - + // New ensight case file, initialize header etc. + ensightCase ensCase(outputDir, args.globalCaseName(), caseOpts); // Construct the Ensight mesh ensightMesh ensMesh(meshProxy.mesh(), writeOpts); @@ -334,44 +290,40 @@ int main(int argc, char *argv[]) << timer.cpuTimeIncrement() << " s, " << mem.update().size() << " kB" << nl << endl; - // Get the list of supported classes/fields - HashTable usableObjects; + + // Initially all possible objects that are available at the final time + wordHashSet testedObjectNames; { - // Initially all possible objects that are available at the final time IOobjectList objects(mesh, timeDirs.last().name()); - // Categorize by classes, pre-filter on name (if requested) - usableObjects = + if (!fieldPatterns.empty()) + { + objects.filterObjects(fieldPatterns); + } + + // Remove "*_0" restart fields + objects.prune_0(); + + // Only retain volume and dimensioned fields. + objects.filterClasses ( - fieldPatterns.empty() - ? objects.classes() - : objects.classes(fieldPatterns) + [](const word& clsName){ + return + ( + fieldTypes::volume.found(clsName) + || fieldTypes::internal.found(clsName) + ); + } ); - // Limit to types that we explicitly handle - usableObjects.filterKeys(volFieldTypes); + wordList objectNames(objects.sortedNames()); - // Force each field-type into existence (simplifies code logic - // and doesn't cost much) and simultaneously remove all - // "*_0" restart fields + // Check availability for all times... + checkData(meshProxy.baseMesh(), timeDirs, objectNames); - for (const word& fieldType : volFieldTypes) - { - usableObjects - ( - fieldType - ).filterKeys - ( - [](const word& k){ return k.endsWith("_0"); }, - true // prune - ); - } + testedObjectNames = objectNames; } - // ignore special fields (_0 fields), - // ignore fields we don't handle, - // ignore fields that are not available for all time-steps - HashTable fieldsToUse; forAll(timeDirs, timeIndex) { @@ -394,357 +346,17 @@ int main(int argc, char *argv[]) ensMesh.write(os); } + // Objects at this time + IOobjectList objects(meshProxy.baseMesh(), runTime.timeName()); - // Cell field data output - // ~~~~~~~~~~~~~~~~~~~~~~ - Info<< "Write volume field ("; + // Restrict to objects that are available for all times + objects.filterObjects(testedObjectNames); - for (const word& fieldType : volFieldTypes) - { - // For convenience, just force each field-type into existence. - // This simplifies code logic and doesn't cost much at all. - wordHashSet& fieldNames = usableObjects(fieldType); + // Volume, internal, point fields + #include "convertVolumeFields.H" - forAllIters(fieldNames, fieldIter) - { - const word& fieldName = fieldIter.key(); - - #include "checkData.H" - - // Partially complete field? - if (!fieldsToUse[fieldName]) - { - fieldNames.erase(fieldIter); - continue; - } - - IOobject fieldObject - ( - fieldName, - mesh.time().timeName(), - mesh, - IOobject::MUST_READ, - IOobject::NO_WRITE - ); - - bool wrote = false; - if (fieldType == volScalarField::typeName) - { - autoPtr os = ensCase.newData - ( - fieldName - ); - - wrote = ensightOutput::writeField - ( - getField(fieldObject, meshProxy), - ensMesh, - os, - nodeValues - ); - } - else if (fieldType == volVectorField::typeName) - { - autoPtr os = ensCase.newData - ( - fieldName - ); - - wrote = ensightOutput::writeField - ( - getField(fieldObject, meshProxy), - ensMesh, - os, - nodeValues - ); - } - else if (fieldType == volSphericalTensorField::typeName) - { - autoPtr os = ensCase.newData - ( - fieldObject.name() - ); - - wrote = ensightOutput::writeField - ( - getField - ( - fieldObject, - meshProxy - ), - ensMesh, - os, - nodeValues - ); - } - else if (fieldType == volSymmTensorField::typeName) - { - autoPtr os = ensCase.newData - ( - fieldName - ); - - wrote = ensightOutput::writeField - ( - getField - ( - fieldObject, - meshProxy - ), - ensMesh, - os, - nodeValues - ); - } - else if (fieldType == volTensorField::typeName) - { - autoPtr os = ensCase.newData - ( - fieldName - ); - - wrote = ensightOutput::writeField - ( - getField(fieldObject, meshProxy), - ensMesh, - os, - nodeValues - ); - } - // DimensionedFields - else if - ( - fieldType - == volScalarField::Internal::typeName - ) - { - autoPtr os = ensCase.newData - ( - fieldName - ); - - wrote = ensightOutput::writeField - ( - getZeroGradInternalField - ( - fieldObject, - meshProxy - ), - ensMesh, - os, - nodeValues - ); - } - else if - ( - fieldType - == volVectorField::Internal::typeName - ) - { - autoPtr os = ensCase.newData - ( - fieldName - ); - - wrote = ensightOutput::writeField - ( - getZeroGradInternalField - ( - fieldObject, - meshProxy - ), - ensMesh, - os, - nodeValues - ); - } - else if - ( - fieldType - == volSphericalTensorField::Internal::typeName - ) - { - autoPtr os = ensCase.newData - ( - fieldName - ); - - wrote = ensightOutput::writeField - ( - getZeroGradInternalField - ( - fieldObject, - meshProxy - ), - ensMesh, - os, - nodeValues - ); - } - else if - ( - fieldType - == volSymmTensorField::Internal::typeName - ) - { - autoPtr os = ensCase.newData - ( - fieldName - ); - - wrote = ensightOutput::writeField - ( - getZeroGradInternalField - ( - fieldObject, - meshProxy - ), - ensMesh, - os, - nodeValues - ); - } - else if - ( - fieldType - == volTensorField::Internal::typeName - ) - { - autoPtr os = ensCase.newData - ( - fieldName - ); - - wrote = ensightOutput::writeField - ( - getZeroGradInternalField - ( - fieldObject, - meshProxy - ), - ensMesh, - os, - nodeValues - ); - } - else - { - // Do not currently handle this type - // - blacklist for the future. - fieldsToUse.set(fieldName, false); - } - - if (wrote) - { - Info<< ' ' << fieldName; - } - } - } - Info<< " )" << nl; - - - // Cloud field data output - // ~~~~~~~~~~~~~~~~~~~~~~~ - - 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; - } + // Write lagrangian data + #include "convertLagrangian.H" Info<< "Wrote in " << timer.cpuTimeIncrement() << " s, " diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.C new file mode 100644 index 0000000000..50bddbba4f --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.C @@ -0,0 +1,78 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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" + +// * * * * * * * * * * * * * * * 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/foamToEnsight/readFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.H new file mode 100644 index 0000000000..41a41eb4ad --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/readFields.H @@ -0,0 +1,94 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 "fvMeshSubsetProxy.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +//- Get the field and subset it, or return nullptr +template +tmp getField(const IOobject* io, const fvMeshSubsetProxy& proxy) +{ + if (io) + { + auto tfield = tmp::New(*io, proxy.baseMesh()); + return proxy.interpolate(tfield); + } + + return nullptr; +} + + +//- Get internal field and make it a zero-gradient volume field with subsetting +template +tmp +getZeroGradField(IOobject* io, const fvMeshSubsetProxy& proxy) +{ + if (io) + { + auto tfield = + tmp::New(*io, proxy.baseMesh()); + return proxy.interpolateInternal(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/foamToEnsight/writeDimFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeDimFields.H new file mode 100644 index 0000000000..3920e6c29c --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeDimFields.H @@ -0,0 +1,126 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 ensightMesh + +SourceFiles + writeDimFields.H + +\*---------------------------------------------------------------------------*/ + +#ifndef writeDimFields_H +#define writeDimFields_H + +#include "writeVolFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +template +label writeDimFields +( + ensightCase& ensCase, + ensightMesh& ensMesh, + const fvMeshSubsetProxy& proxy, + const IOobjectList& objects, + const bool nodeValues +) +{ + 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, + ensMesh, + proxy, + getZeroGradField(io, proxy), + nodeValues + ) + ) + { + ++count; + } + } + + return count; +} + + +label writeAllDimFields +( + ensightCase& ensCase, + ensightMesh& ensMesh, + const fvMeshSubsetProxy& proxy, + const IOobjectList& objects, + const bool nodeValues +) +{ + #undef foamToEnsight_WRITE_FIELD + #define foamToEnsight_WRITE_FIELD(PrimitiveType) \ + writeDimFields \ + ( \ + ensCase, ensMesh, \ + proxy, \ + objects, \ + nodeValues \ + ) + + 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/foamToEnsight/writeVolFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeVolFields.H new file mode 100644 index 0000000000..892b8a3cf2 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeVolFields.H @@ -0,0 +1,150 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 ensightMesh + +SourceFiles + writeVolFields.H + +\*---------------------------------------------------------------------------*/ + +#ifndef writeVolFields_H +#define writeVolFields_H + +#include "readFields.H" +#include "fvMeshSubsetProxy.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +template +bool writeVolField +( + ensightCase& ensCase, + ensightMesh& ensMesh, + const fvMeshSubsetProxy& proxy, + const tmp>& tfield, + const bool nodeValues +) +{ + if (!tfield.valid()) + { + return false; + } + + const auto& field = tfield(); + + autoPtr os = ensCase.newData(field.name()); + + bool wrote = ensightOutput::writeField + ( + field, + ensMesh, + os, + nodeValues + ); + + tfield.clear(); + return wrote; +} + + +template +label writeVolFields +( + ensightCase& ensCase, + ensightMesh& ensMesh, + const fvMeshSubsetProxy& proxy, + const IOobjectList& objects, + const bool nodeValues +) +{ + typedef GeometricField GeoField; + + label count = 0; + + for (const word& fieldName : objects.sortedNames()) + { + if + ( + writeVolField + ( + ensCase, + ensMesh, + proxy, + getField(objects.findObject(fieldName), proxy), + nodeValues + ) + ) + { + ++count; + } + } + + return count; +} + + +label writeAllVolFields +( + ensightCase& ensCase, + ensightMesh& ensMesh, + const fvMeshSubsetProxy& proxy, + const IOobjectList& objects, + const bool nodeValues +) +{ + #undef foamToEnsight_WRITE_FIELD + #define foamToEnsight_WRITE_FIELD(PrimitiveType) \ + writeVolFields \ + ( \ + ensCase, ensMesh, \ + proxy, \ + objects, \ + nodeValues \ + ) + + 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 + +// ************************************************************************* //