ENH: align foamToEnsightParts internals with foamToEnsight

- add -region option and -fields filtering
This commit is contained in:
Mark Olesen
2018-11-25 12:12:19 +01:00
parent b5432011fa
commit d8a55e46b6
15 changed files with 863 additions and 365 deletions

View File

@ -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 \<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 \<subdir\>
Define sub-directory name to use for Ensight data (default: "EnSight")
- \par -width \<n\>
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;

View File

@ -24,6 +24,7 @@ License
\*---------------------------------------------------------------------------*/
#include "readFields.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //

View File

@ -46,7 +46,7 @@ template<class Type>
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

View File

@ -47,7 +47,7 @@ template<class Type>
bool writeVolField
(
ensightCase& ensCase,
ensightMesh& ensMesh,
const ensightMesh& ensMesh,
const fvMeshSubsetProxy& proxy,
const tmp<GeometricField<Type, fvPatchField, volMesh>>& tfield,
const bool nodeValues
@ -79,7 +79,7 @@ template<class Type>
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

View File

@ -1,3 +1,4 @@
foamToEnsightParts.C
readFields.C
EXE = $(FOAM_APPBIN)/foamToEnsightParts

View File

@ -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

View File

@ -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 <http://www.gnu.org/licenses/>.
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<word>& theseCloudFields = cloudFields[cloudName];
fileNameList currentCloudDirs
(
readDir
(
runTime.timePath()/regionPrefix/cloud::prefix,
fileName::DIRECTORY
)
);
Info<< "Write " << cloudName << " (";
const bool cloudExists =
returnReduce
(
currentCloudDirs.found(cloudName),
orOp<bool>()
);
{
autoPtr<ensightFile> 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<IOField<scalar>>(false);
reduce(fieldExists, orOp<bool>());
}
bool wrote = false;
if (fieldType == scalarIOField::typeName)
{
autoPtr<ensightFile> os =
ensCase.newCloudData<scalar>(cloudName, fieldName);
wrote = ensightCloud::writeCloudField<scalar>
(
fieldObject, fieldExists, os
);
}
else if (fieldType == vectorIOField::typeName)
{
autoPtr<ensightFile> os =
ensCase.newCloudData<vector>(cloudName, fieldName);
wrote = ensightCloud::writeCloudField<vector>
(
fieldObject, fieldExists, os
);
}
if (wrote)
{
Info<< ' ' << fieldName;
if (!fieldExists)
{
Info<< "{0}"; // report empty field
}
}
}
Info<< " )" << nl;
}
}
// ************************************************************************* //

View File

@ -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 <http://www.gnu.org/licenses/>.
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;
}
// ************************************************************************* //

View File

@ -0,0 +1,94 @@
// check all time directories for the following:
// The fields for each cloud:
HashTable<HashTable<word>> 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<word>());
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;
}
// ************************************************************************* //

View File

@ -1,116 +0,0 @@
// check the final time directory for the following:
// 1. volume fields
HashTable<word> volumeFields;
// 2. the fields for each cloud:
HashTable<HashTable<word>> 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/<cloudName>
//
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<word>& 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);
}
}
// ************************************************************************* //

View File

@ -38,8 +38,15 @@ Usage
- \par -ascii
Write Ensight data in ASCII format instead of "C Binary"
- \par -name \<subdir\>
Define sub-directory name to use for Ensight data (default: "Ensight")
- \par -fields \<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 \<subdir\>
Define sub-directory name to use for Ensight data (default: "Ensight")
- \par -width \<n\>
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<wordRe>("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<ensightGeoFile> 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<ensightFile> os = ensCase.newData<scalar>
(
fieldName
);
volScalarField vf(fieldObject, mesh);
wrote = ensightSerialOutput::writeField<scalar>
(
vf, partsList, os
);
}
else if (fieldType == volVectorField::typeName)
{
autoPtr<ensightFile> os = ensCase.newData<vector>
(
fieldName
);
volVectorField vf(fieldObject, mesh);
wrote = ensightSerialOutput::writeField<vector>
(
vf, partsList, os
);
}
else if (fieldType == volSphericalTensorField::typeName)
{
autoPtr<ensightFile> os = ensCase.newData<sphericalTensor>
(
fieldName
);
volSphericalTensorField vf(fieldObject, mesh);
wrote = ensightSerialOutput::writeField<sphericalTensor>
(
vf, partsList, os
);
}
else if (fieldType == volSymmTensorField::typeName)
{
autoPtr<ensightFile> os = ensCase.newData<symmTensor>
(
fieldName
);
volSymmTensorField vf(fieldObject, mesh);
wrote = ensightSerialOutput::writeField<symmTensor>
(
vf, partsList, os
);
}
else if (fieldType == volTensorField::typeName)
{
autoPtr<ensightFile> os = ensCase.newData<tensor>
(
fieldName
);
volTensorField vf(fieldObject, mesh);
wrote = ensightSerialOutput::writeField<tensor>
(
vf, partsList, os
);
}
if (wrote)
{
Info<< " " << fieldObject.name() << flush;
}
}
Info<< " )" << endl;
// Check for clouds
forAllConstIters(cloudFields, cloudIter)
{
const word& cloudName = cloudIter.key();
const HashTable<word>& 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<scalar>(cloudName, fieldName);
wrote = ensightCloud::writeCloudField<scalar>
(
*fieldObject,
true, // field exists
os
);
}
else if (fieldType == vectorIOField::typeName)
{
auto os =
ensCase.newCloudData<vector>(cloudName, fieldName);
wrote = ensightCloud::writeCloudField<vector>
(
*fieldObject,
true, // field exists
os
);
}
else if (fieldType == tensorIOField::typeName)
{
auto os =
ensCase.newCloudData<tensor>(cloudName, fieldName);
wrote = ensightCloud::writeCloudField<tensor>
(
*fieldObject,
true, // field exists
os
);
}
if (wrote)
{
Info<< " " << fieldObject->name();
}
}
Info<< " )" << endl;
}
// Lagrangian fields
#include "convertLagrangian.H"
Info<< "Wrote in "
<< timer.cpuTimeIncrement() << " s, "

View File

@ -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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#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<volScalarField>(false, false);
if (!good)
{
break;
}
}
reduce(good, andOp<bool>());
if (good)
{
goodFields.insert(fieldName);
}
}
objectNames = goodFields.sortedToc();
return objectNames.size();
}
// ************************************************************************* //

View File

@ -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 <http://www.gnu.org/licenses/>.
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<class GeoField>
tmp<GeoField> getField(const IOobject* io, const fvMesh& mesh)
{
if (io)
{
auto tfield = tmp<GeoField>::New(*io, mesh);
return tfield;
}
return nullptr;
}
//- Get internal field and make it a zero-gradient volume field with subsetting
template<class GeoField>
tmp<GeoField>
getZeroGradField(IOobject* io, const fvMesh& mesh)
{
if (io)
{
auto tdimfield =
tmp<typename GeoField::Internal>::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
// ************************************************************************* //

View File

@ -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 <http://www.gnu.org/licenses/>.
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<class Type>
label writeDimFields
(
ensightCase& ensCase,
const ensightParts& ensParts,
const fvMesh& mesh,
const IOobjectList& objects
)
{
typedef GeometricField<Type, fvPatchField, volMesh> GeoField;
typedef typename
GeometricField
<
Type, fvPatchField, volMesh
>::Internal DimField;
label count = 0;
for (const word& fieldName : objects.sortedNames<DimField>())
{
IOobject* io = objects.findObject(fieldName);
if
(
writeVolField<Type>
(
ensCase,
ensParts,
mesh,
getZeroGradField<GeoField>(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<PrimitiveType> \
( \
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
// ************************************************************************* //

View File

@ -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 <http://www.gnu.org/licenses/>.
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<class Type>
bool writeVolField
(
ensightCase& ensCase,
const ensightParts& ensParts,
const fvMesh& mesh,
const tmp<GeometricField<Type, fvPatchField, volMesh>>& tfield
)
{
if (!tfield.valid())
{
return false;
}
const auto& field = tfield();
autoPtr<ensightFile> os = ensCase.newData<Type>(field.name());
bool wrote = ensightSerialOutput::writeField<Type>
(
field,
ensParts,
os
);
tfield.clear();
return wrote;
}
template<class Type>
label writeVolFields
(
ensightCase& ensCase,
const ensightParts& ensParts,
const fvMesh& mesh,
const IOobjectList& objects
)
{
typedef GeometricField<Type, fvPatchField, volMesh> GeoField;
label count = 0;
for (const word& fieldName : objects.sortedNames<GeoField>())
{
if
(
writeVolField<Type>
(
ensCase,
ensParts,
mesh,
getField<GeoField>(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<PrimitiveType> \
( \
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
// ************************************************************************* //