ENH: overhaul ensight handling (#1579)

- includes restructuring and simplification of low-level ensight part
  handling and refactor of backends to improve code reuse.

foamToEnsight
-------------

  * new cellZone support.
    This was previously only possible via a separate foamToEnsightParts
    utility that was not parallelized.

  * support for point fields.

  * `-nearCellValue` option (as per foamToVTK)

  * data indexing now uses values from the time index.
    This is consistent with the ensightWrite function object and
    can help with restarts.

  * existing ensight directories are removed, unless the -no-overwrite
    option is supplied

foamToEnsightParts
------------------
  * now redundant and removed.

ensightOutputSurface (new class)
--------------------------------
  * a lightweight wrapper for point/face references that is tailored
    for the ensightSurfaceWriter. It uses compact face/point information
    and is serial only, since this is the format requirements from the
    surfaceWriter class.

ensightMesh (revised class)
---------------------------
  * now only holds a polyMesh reference, which removes its dependency
    on finiteVolume and allows it to be relocated under fileFormats
    instead of conversion.

Removed classes: ensightParts, ensighPartFaces, ensightPartCells

- these were used by foamToEnsightParts, but not needed anymore.
This commit is contained in:
Mark Olesen
2020-02-10 15:21:05 +01:00
committed by Andrew Heather
parent c7e8f22baf
commit a97628121c
64 changed files with 4916 additions and 5885 deletions

View File

@ -3,13 +3,11 @@ EXE_INC = \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/conversion/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfileFormats \
-ldynamicMesh \
-lconversion \
-llagrangianIntermediate \
-lgenericPatchFields

View File

@ -1,6 +1,6 @@
// Check for "points" in any of the result directories
bool meshMoving = false;
bool hasMovingMesh = false;
if (timeDirs.size() > 1 && Pstream::master())
{
@ -12,7 +12,7 @@ if (timeDirs.size() > 1 && Pstream::master())
{
const word& timeName = inst.name();
meshMoving =
hasMovingMesh =
(
timeName != mesh.pointsInstance()
&& IOobject
@ -27,13 +27,13 @@ if (timeDirs.size() > 1 && Pstream::master())
).typeHeaderOk<pointIOField>(true, false)
);
if (meshMoving)
if (hasMovingMesh)
{
break;
}
}
if (meshMoving)
if (hasMovingMesh)
{
Info<< "found. Writing meshes for every timestep." << endl;
}
@ -43,4 +43,4 @@ if (timeDirs.size() > 1 && Pstream::master())
}
}
reduce(meshMoving, orOp<bool>());
reduce(hasMovingMesh, orOp<bool>());

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,9 +31,8 @@ Description
// Cloud field data output
if (doLagrangian)
{
forAll(cloudNames, cloudNo)
for (const word& cloudName : cloudNames)
{
const word& cloudName = cloudNames[cloudNo];
const HashTable<word>& theseCloudFields = cloudFields[cloudName];
fileNameList currentCloudDirs
@ -48,12 +47,7 @@ if (doLagrangian)
Info<< "Write " << cloudName << " (";
const bool cloudExists =
returnReduce
(
currentCloudDirs.found(cloudName),
orOp<bool>()
);
returnReduce(currentCloudDirs.found(cloudName), orOp<bool>());
{
autoPtr<ensightFile> os = ensCase.newCloud(cloudName);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -35,25 +35,19 @@ Description
{
Info<< "Write volume field (";
writeAllVolFields
(
ensCase,
ensMesh,
meshProxy,
objects,
nodeValues
);
writeAllDimFields
(
ensCase,
ensMesh,
meshProxy,
objects,
nodeValues
);
writeAllVolFields(ensCase, ensMesh, objects, nearCellValue);
writeAllDimFields(ensCase, ensMesh, objects);
Info<< " )" << nl;
// PointData
// - only construct pointMesh on request (it constructs edge addressing)
if (doPointValues)
{
Info<< "Write point field (";
writeAllPointFields(ensCase, ensMesh, objects);
Info<< " )" << nl;
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2018 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,7 +32,11 @@ Group
Description
Translate OpenFOAM data to EnSight format.
An Ensight part is created for the internalMesh and for each patch.
An Ensight part is created for cellZones (unzoned cells are "internalMesh")
and patches.
- Handles volume fields, dimensioned fields, point fields
- Handles mesh topology changes.
Usage
\b foamToEnsight [OPTION]
@ -51,36 +55,65 @@ Usage
The quoting is required to avoid shell expansions and to pass the
information as a single argument.
- \par -nearCellValue
Use zero-gradient cell values on patches
- \par -nodeValues
Force interpolation of values to nodes
- \par -no-boundary
Suppress writing any patches.
Suppress output for all boundary patches
- \par -no-internal
Suppress writing the internal mesh.
Suppress output for internal (volume) mesh
- \par -no-cellZones
Suppress cellZone handling
- \par -no-lagrangian
Suppress writing lagrangian positions and fields.
- \par -patches patch or patch list
Specify particular patches to write.
- \par -no-mesh
Suppress writing the geometry. Can be useful for converting partial
results for a static geometry.
- \par -faceZones zone or zone list
Specify faceZones to write, with wildcards
- \par -cellZone zoneName
Specify single cellZone to write (not lagrangian)
- \par -no-point-data
Suppress conversion of pointFields. No interpolated PointData.
- \par -noZero
Exclude the often incomplete initial conditions.
- \par -index \<start\>
Use consecutive indexing for \c data/######## files with the
specified start index.
Ignore the time index contained in the uniform/time file.
- \par -name \<subdir\>
Define sub-directory name to use for Ensight data (default: "EnSight")
- \par -width \<n\>
Width of Ensight data subdir (default: 8)
Note
Writes to \a EnSight directory to avoid collisions with
foamToEnsightParts
- \par -cellZones NAME | LIST
Specify single zone or multiple cell zones (name or regex) to write
- \par -faceZones NAME | LIST
Specify single zone or multiple face zones (name or regex) to write
- \par -patches NAME | LIST
Specify single patch or multiple patches (name or regex) to write
For example,
\verbatim
-patches top
-patches '( front \".*back\" )'
\endverbatim
- \par -excludePatches NAME | LIST
Specify single or multiple patches (name or regex) not to convert.
For example,
\verbatim
-excludePatches '( inlet_1 inlet_2 "proc.*" )'
\endverbatim
\*---------------------------------------------------------------------------*/
@ -93,6 +126,7 @@ Note
#include "HashOps.H"
#include "fvc.H"
#include "fvMesh.H"
#include "fieldTypes.H"
#include "volFields.H"
#include "scalarIOField.H"
@ -104,35 +138,27 @@ Note
#include "ensightMesh.H"
#include "ensightOutputCloud.H"
#include "ensightOutputVolField.H"
#include "fvMeshSubsetProxy.H"
// local files
#include "readFields.H"
#include "writeVolFields.H"
#include "writeDimFields.H"
#include "writePointFields.H"
#include "memInfo.H"
#undef foamToEnsight_useTimeIndex
using namespace Foam;
//- Get internal field and make it a zero-gradient volume field with subsetting
template<class GeoField>
tmp<GeoField>
getZeroGradInternalField(IOobject& io, const fvMeshSubsetProxy& proxy)
{
auto tfield = tmp<typename GeoField::Internal>::New(io, proxy.baseMesh());
return proxy.interpolateInternal(tfield);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"Translate OpenFOAM data to Ensight format with a part for"
" the internalMesh and for each patch."
"Translate OpenFOAM data to Ensight format with individual parts"
" for cellZones, unzoned cells and patches"
);
timeSelector::addOptions();
@ -147,10 +173,42 @@ int main(int argc, char *argv[])
"ascii",
"Write in ASCII format instead of 'C Binary'"
);
argList::addOption
(
"index",
"start",
"Starting index for consecutive number of Ensight data/ files."
" Ignore the time index contained in the uniform/time file."
, true // mark as an advanced option
);
argList::addOption
(
"name",
"subdir",
"Sub-directory name for Ensight output (default: 'EnSight')"
);
argList::addBoolOption
(
"no-overwrite",
"Suppress removal of existing EnSight output directory"
);
argList::addOption
(
"width",
"n",
"Width of Ensight data subdir"
);
argList::addBoolOption
(
"nearCellValue",
"Use zero-gradient cell values on patches"
, true // mark as an advanced option
);
argList::addBoolOption
(
"nodeValues",
"Write values at nodes"
"Force interpolation of values to nodes"
, true // mark as an advanced option
);
argList::addBoolOption
(
@ -165,12 +223,37 @@ int main(int argc, char *argv[])
"Suppress writing the internal mesh"
);
argList::addBoolOption
(
"no-cellZones",
"Suppress writing any cellZones"
);
argList::addBoolOption
(
"no-lagrangian", // noLagrangian
"Suppress writing lagrangian positions and fields"
);
argList::addOptionCompat("no-lagrangian", {"noLagrangian", 1806});
argList::addBoolOption
(
"no-point-data",
"Suppress conversion of pointFields and disables -nodeValues"
);
argList::addBoolOption
(
"no-mesh", // noMesh
"Suppress writing the geometry."
" Can be useful for converting partial results for a static geometry"
, true // mark as an advanced option
);
// Future?
// argList::addBoolOption
// (
// "one-boundary", // allPatches
// "Combine all patches into a single part"
// );
argList::addOption
(
"patches",
@ -179,6 +262,14 @@ int main(int argc, char *argv[])
"Eg, 'inlet' or '(outlet \"inlet.*\")'"
);
argList::addOption
(
"excludePatches",
"wordRes",
"Specify single patch or multiple patches to exclude from writing."
" Eg, 'outlet' or '( inlet \".*Wall\" )'"
, true // mark as an advanced option
);
argList::addOption
(
"faceZones",
"wordRes",
@ -194,22 +285,13 @@ int main(int argc, char *argv[])
);
argList::addOption
(
"cellZone",
"word",
"Specify cellZone to write"
);
argList::addOption
(
"name",
"subdir",
"Sub-directory name for Ensight output (default: 'EnSight')"
);
argList::addOption
(
"width",
"n",
"Width of Ensight data subdir"
"cellZones",
"wordRes",
"Specify single or multiple cellZones to write\n"
"Eg, 'cells' or '( slice \"mfp-.*\" )'."
);
argList::addOptionCompat("cellZone", {"cellZones", 1912});
#include "setRootCase.H"
@ -221,8 +303,6 @@ int main(int argc, char *argv[])
: IOstream::BINARY
);
const bool nodeValues = args.found("nodeValues");
cpuTime timer;
memInfo mem;
Info<< "Initial memory " << mem.update().size() << " kB" << endl;
@ -239,19 +319,50 @@ int main(int argc, char *argv[])
regionPrefix = regionName;
}
//
// Configuration
//
const bool doBoundary = !args.found("no-boundary");
const bool doInternal = !args.found("no-internal");
const bool doCellZones = !args.found("no-cellZones");
const bool doLagrangian = !args.found("no-lagrangian");
const bool doPointValues = !args.found("no-point-data");
const bool nearCellValue = args.found("nearCellValue") && doBoundary;
// Control for numbering iterations
label indexingNumber(0);
const bool doConsecutive = args.readIfPresent("index", indexingNumber);
// Write the geometry, unless otherwise specified
bool doGeometry = !args.found("no-mesh");
if (nearCellValue)
{
Info<< "Using neighbouring cell value instead of patch value"
<< nl << endl;
}
if (!doPointValues)
{
Info<< "Point fields and interpolated point data"
<< " disabled with the '-no-point-data' option"
<< nl;
}
//
// General (case) output options
//
ensightCase::options caseOpts(format);
caseOpts.nodeValues(args.found("nodeValues"));
// Forced point interpolation?
caseOpts.nodeValues(doPointValues && args.found("nodeValues"));
caseOpts.width(args.get<label>("width", 8));
caseOpts.overwrite(true); // remove existing output directory
caseOpts.overwrite(!args.found("no-overwrite")); // Remove existing?
// Can also have separate directory for lagrangian
// caseOpts.separateCloud(true);
// 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
@ -261,23 +372,32 @@ int main(int argc, char *argv[])
outputDir = args.globalPath()/outputDir;
}
//
// Output configuration (geometry related)
//
ensightMesh::options writeOpts(format);
writeOpts.useBoundaryMesh(!args.found("no-boundary"));
writeOpts.useInternalMesh(!args.found("no-internal"));
const bool doLagrangian = !args.found("no-lagrangian");
ensightMesh::options writeOpts;
writeOpts.useBoundaryMesh(doBoundary);
writeOpts.useInternalMesh(doInternal);
writeOpts.useCellZones(doCellZones);
if (args.found("patches"))
{
writeOpts.patchSelection(args.getList<wordRe>("patches"));
}
if (args.found("excludePatches"))
{
writeOpts.patchExclude(args.getList<wordRe>("excludePatches"));
}
if (args.found("faceZones"))
{
writeOpts.faceZoneSelection(args.getList<wordRe>("faceZones"));
}
if (args.found("cellZones"))
{
writeOpts.cellZoneSelection(args.getList<wordRe>("cellZones"));
}
// Report the setup
writeOpts.print(Info);
//
// Output configuration (field related)
@ -286,22 +406,11 @@ int main(int argc, char *argv[])
wordRes fieldPatterns;
args.readListIfPresent<wordRe>("fields", fieldPatterns);
word cellZoneName;
if (args.readIfPresent("cellZone", cellZoneName))
{
Info<< "Converting cellZone " << cellZoneName
<< " only, with new outside faces as \"oldInternalFaces\"."
<< nl;
}
// Ignored (unproxied) if cellZoneName is empty
fvMeshSubsetProxy meshProxy(mesh, fvMeshSubsetProxy::ZONE, cellZoneName);
// New ensight case file, initialize header etc.
ensightCase ensCase(outputDir, args.globalCaseName(), caseOpts);
// Construct the Ensight mesh
ensightMesh ensMesh(meshProxy.mesh(), writeOpts);
// Construct ensight mesh
ensightMesh ensMesh(mesh, writeOpts);
if (Pstream::master())
{
@ -335,50 +444,64 @@ int main(int argc, char *argv[])
// 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)
);
}
);
if (!doPointValues)
{
// Prune point fields if disabled
objects.filterClasses
(
[](const word& clsName)
{
return fieldTypes::point.found(clsName);
},
true // prune
);
}
wordList objectNames(objects.sortedNames());
// Check availability for all times...
checkData(meshProxy.baseMesh(), timeDirs, objectNames);
checkData(mesh, timeDirs, objectNames);
testedObjectNames = objectNames;
}
forAll(timeDirs, timeIndex)
if (hasMovingMesh && !doGeometry)
{
runTime.setTime(timeDirs[timeIndex], timeIndex);
ensCase.nextTime(timeDirs[timeIndex]);
Info<< "has moving mesh: ignoring '-no-mesh' option" << endl;
doGeometry = true;
}
forAll(timeDirs, timei)
{
runTime.setTime(timeDirs[timei], timei);
// Index for the Ensight case
#include "getTimeIndex.H"
ensCase.setTime(timeDirs[timei], timeIndex);
Info<< "Time [" << timeIndex << "] = " << runTime.timeName() << nl;
polyMesh::readUpdateState meshState = mesh.readUpdate();
if (meshState != polyMesh::UNCHANGED)
const bool moving = (meshState != polyMesh::UNCHANGED);
if (moving)
{
meshProxy.correct();
ensMesh.expire();
ensMesh.correct();
}
if (timeIndex == 0 || meshMoving)
if (timei == 0 || moving)
{
autoPtr<ensightGeoFile> os = ensCase.newGeometry(meshMoving);
ensMesh.write(os);
if (doGeometry)
{
autoPtr<ensightGeoFile> os = ensCase.newGeometry(hasMovingMesh);
ensMesh.write(os);
}
}
// Objects at this time
IOobjectList objects(meshProxy.baseMesh(), runTime.timeName());
IOobjectList objects(mesh, runTime.timeName());
// Restrict to objects that are available for all times
objects.filterObjects(testedObjectNames);
@ -386,7 +509,7 @@ int main(int argc, char *argv[])
// Volume, internal, point fields
#include "convertVolumeFields.H"
// Write lagrangian data
// Lagrangian fields
#include "convertLagrangian.H"
Info<< "Wrote in "

View File

@ -3,7 +3,7 @@
label timeIndex = 0;
{
if (optIndex)
if (doConsecutive)
{
timeIndex = indexingNumber++;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,7 +27,8 @@ InNamespace
Foam
Description
Read fields from disk for foamToEnsight
Helper routines for reading a field or fields,
for foamToEnsight
SourceFiles
readFields.C
@ -39,39 +40,114 @@ SourceFiles
#include "instantList.H"
#include "IOobjectList.H"
#include "fvMeshSubsetProxy.H"
#include "zeroGradientFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
//- Get the field and subset it, or return nullptr
//- Get the field or return nullptr
template<class GeoField>
tmp<GeoField> getField(const IOobject* io, const fvMeshSubsetProxy& proxy)
tmp<GeoField> getField
(
const IOobject* io,
const typename GeoField::Mesh& mesh
)
{
if (io)
{
auto tfield = tmp<GeoField>::New(*io, proxy.baseMesh());
return proxy.interpolate(tfield);
return tmp<GeoField>::New(*io, mesh);
}
return nullptr;
}
//- Get internal field and make it a zero-gradient volume field with subsetting
//- Get the named field from the objects, or return nullptr.
template<class GeoField>
tmp<GeoField>
getZeroGradField(const IOobject* io, const fvMeshSubsetProxy& proxy)
tmp<GeoField> getField
(
const typename GeoField::Mesh& mesh,
const IOobjectList& objects,
const word& fieldName
)
{
if (io)
// Can do something with syncPar on failure ...
return getField<GeoField>(objects.findObject(fieldName), mesh);
}
//- Convert an internal field to zero-gradient volume field
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>>
makeZeroGradientField
(
const tmp
<
typename GeometricField<Type, fvPatchField, volMesh>::Internal
>& tdf
)
{
if (tdf.valid())
{
auto tfield =
tmp<typename GeoField::Internal>::New(*io, proxy.baseMesh());
return proxy.interpolateInternal(tfield);
auto& df = tdf.ref();
auto tfield = GeometricField<Type, fvPatchField, volMesh>::New
(
df.name(),
df.mesh(),
df.dimensions(),
std::move(df.field()),
zeroGradientFvPatchScalarField::typeName
);
tfield.ref().oriented() = df.oriented();
tfield.ref().correctBoundaryConditions();
tdf.clear();
return tfield;
}
tdf.clear();
return nullptr;
}
//- Convert a volume field to zero-gradient volume field
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>>
makeZeroGradientField
(
const tmp<GeometricField<Type, fvPatchField, volMesh>>& tdf
)
{
if (tdf.valid())
{
auto& df = tdf.ref();
auto tfield = GeometricField<Type, fvPatchField, volMesh>::New
(
df.name(),
df.mesh(),
df.dimensions(),
std::move(df.primitiveFieldRef(false)), // No update accessTime
zeroGradientFvPatchScalarField::typeName
);
tfield.ref().oriented() = df.oriented();
tfield.ref().correctBoundaryConditions();
tdf.clear();
return tfield;
}
tdf.clear();
return nullptr;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,12 +30,11 @@ Description
Read dimensioned fields from disk and write with ensightMesh
SourceFiles
writeDimFields.H
\*---------------------------------------------------------------------------*/
#ifndef writeDimFields_H
#define writeDimFields_H
#ifndef ensight_writeDimFields_H
#define ensight_writeDimFields_H
#include "writeVolFields.H"
@ -44,40 +43,60 @@ SourceFiles
namespace Foam
{
template<class Type>
bool writeDimField
(
ensightCase& ensCase,
const ensightMesh& ensMesh,
const tmp<DimensionedField<Type, volMesh>>& tdf
)
{
if (!tdf.valid())
{
return false;
}
auto tfield = makeZeroGradientField<Type>(tdf);
// Now a volField with zero-gradient boundaries
return writeVolField<Type>
(
ensCase,
ensMesh,
tfield,
false // No nearCellValue, we already have zero-gradient
);
}
template<class Type>
label writeDimFields
(
ensightCase& ensCase,
const ensightMesh& ensMesh,
const fvMeshSubsetProxy& proxy,
const IOobjectList& objects,
const bool nodeValues
const IOobjectList& objects
)
{
typedef GeometricField<Type, fvPatchField, volMesh> GeoField;
typedef typename
GeometricField
<
Type, fvPatchField, volMesh
>::Internal DimField;
const fvMesh& mesh = dynamicCast<const fvMesh>(ensMesh.mesh());
label count = 0;
for (const word& fieldName : objects.sortedNames<DimField>())
{
const IOobject* io = objects.findObject(fieldName);
if
(
writeVolField<Type>
writeDimField<Type>
(
ensCase,
ensMesh,
proxy,
getZeroGradField<GeoField>(io, proxy),
nodeValues
getField<DimField>(objects.findObject(fieldName), mesh)
)
)
{
@ -94,29 +113,26 @@ label writeAllDimFields
(
ensightCase& ensCase,
const ensightMesh& ensMesh,
const fvMeshSubsetProxy& proxy,
const IOobjectList& objects,
const bool nodeValues
const IOobjectList& objects
)
{
#undef foamToEnsight_WRITE_FIELD
#define foamToEnsight_WRITE_FIELD(PrimitiveType) \
#undef ensight_WRITE_FIELD
#define ensight_WRITE_FIELD(PrimitiveType) \
writeDimFields<PrimitiveType> \
( \
ensCase, ensMesh, \
proxy, \
objects, \
nodeValues \
ensCase, \
ensMesh, \
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);
count += ensight_WRITE_FIELD(scalar);
count += ensight_WRITE_FIELD(vector);
count += ensight_WRITE_FIELD(sphericalTensor);
count += ensight_WRITE_FIELD(symmTensor);
count += ensight_WRITE_FIELD(tensor);
#undef foamToEnsight_WRITE_FIELD
#undef ensight_WRITE_FIELD
return count;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,17 +27,18 @@ InNamespace
Foam
Description
Read volume fields from disk and write with ensightParts
Read point fields from disk
and write as ensight data
SourceFiles
writeVolFields.H
\*---------------------------------------------------------------------------*/
#ifndef writeVolFields_H
#define writeVolFields_H
#ifndef ensight_writePointFields_H
#define ensight_writePointFields_H
#include "readFields.H"
#include "ensightMesh.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -46,12 +47,11 @@ namespace Foam
{
template<class Type>
bool writeVolField
bool writePointField
(
ensightCase& ensCase,
const ensightParts& ensParts,
const fvMesh& mesh,
const tmp<GeometricField<Type, fvPatchField, volMesh>>& tfield
const ensightMesh& ensMesh,
const tmp<GeometricField<Type, pointPatchField, pointMesh>>& tfield
)
{
if (!tfield.valid())
@ -61,14 +61,14 @@ bool writeVolField
const auto& field = tfield();
autoPtr<ensightFile> os = ensCase.newData<Type>(field.name());
// PointData = true
autoPtr<ensightFile> os = ensCase.newData<Type>(field.name(), true);
// Currently serial only
bool wrote = ensightOutput::Serial::writeVolField<Type>
bool wrote = ensightOutput::writePointField<Type>
(
os.ref(),
field,
ensParts,
os.ref()
ensMesh
);
tfield.clear();
@ -77,15 +77,16 @@ bool writeVolField
template<class Type>
label writeVolFields
label writePointFields
(
ensightCase& ensCase,
const ensightParts& ensParts,
const fvMesh& mesh,
const ensightMesh& ensMesh,
const IOobjectList& objects
)
{
typedef GeometricField<Type, fvPatchField, volMesh> GeoField;
typedef GeometricField<Type, pointPatchField, pointMesh> GeoField;
const pointMesh& ptMesh = pointMesh::New(ensMesh.mesh());
label count = 0;
@ -93,12 +94,11 @@ label writeVolFields
{
if
(
writeVolField<Type>
writePointField<Type>
(
ensCase,
ensParts,
mesh,
getField<GeoField>(objects.findObject(fieldName), mesh)
ensMesh,
getField<GeoField>(ptMesh, objects, fieldName)
)
)
{
@ -111,31 +111,30 @@ label writeVolFields
}
label writeAllVolFields
label writeAllPointFields
(
ensightCase& ensCase,
const ensightParts& ensParts,
const fvMesh& mesh,
const ensightMesh& ensMesh,
const IOobjectList& objects
)
{
#undef foamToEnsight_WRITE_FIELD
#define foamToEnsight_WRITE_FIELD(PrimitiveType) \
writeVolFields<PrimitiveType> \
#undef ensight_WRITE_FIELD
#define ensight_WRITE_FIELD(PrimitiveType) \
writePointFields<PrimitiveType> \
( \
ensCase, ensParts, \
mesh, \
ensCase, \
ensMesh, \
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);
count += ensight_WRITE_FIELD(scalar);
count += ensight_WRITE_FIELD(vector);
count += ensight_WRITE_FIELD(sphericalTensor);
count += ensight_WRITE_FIELD(symmTensor);
count += ensight_WRITE_FIELD(tensor);
#undef foamToEnsight_WRITE_FIELD
#undef ensight_WRITE_FIELD
return count;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,15 +30,14 @@ Description
Read volume fields from disk and write with ensightMesh
SourceFiles
writeVolFields.H
\*---------------------------------------------------------------------------*/
#ifndef writeVolFields_H
#define writeVolFields_H
#ifndef ensight_writeVolFields_H
#define ensight_writeVolFields_H
#include "readFields.H"
#include "fvMeshSubsetProxy.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -50,25 +49,41 @@ bool writeVolField
(
ensightCase& ensCase,
const ensightMesh& ensMesh,
const fvMeshSubsetProxy& proxy,
const tmp<GeometricField<Type, fvPatchField, volMesh>>& tfield,
const bool nodeValues
const bool nearCellValue = false
)
{
if (!tfield.valid())
{
return false;
}
else if (nearCellValue)
{
auto tzgrad = makeZeroGradientField<Type>(tfield);
// Recursive call
return writeVolField
(
ensCase,
ensMesh,
tzgrad,
false // No nearCellValue, we already have zero-gradient
);
}
const auto& field = tfield();
autoPtr<ensightFile> os = ensCase.newData<Type>(field.name());
// Forced use of node values?
const bool nodeValues = ensCase.nodeValues();
autoPtr<ensightFile> os =
ensCase.newData<Type>(field.name(), nodeValues);
bool wrote = ensightOutput::writeVolField<Type>
(
os.ref(),
field,
ensMesh,
os.ref(),
nodeValues
);
@ -82,13 +97,14 @@ label writeVolFields
(
ensightCase& ensCase,
const ensightMesh& ensMesh,
const fvMeshSubsetProxy& proxy,
const IOobjectList& objects,
const bool nodeValues
const bool nearCellValue = false
)
{
typedef GeometricField<Type, fvPatchField, volMesh> GeoField;
const fvMesh& mesh = dynamicCast<const fvMesh>(ensMesh.mesh());
label count = 0;
for (const word& fieldName : objects.sortedNames<GeoField>())
@ -99,9 +115,8 @@ label writeVolFields
(
ensCase,
ensMesh,
proxy,
getField<GeoField>(objects.findObject(fieldName), proxy),
nodeValues
getField<GeoField>(objects.findObject(fieldName), mesh),
nearCellValue
)
)
{
@ -118,29 +133,28 @@ label writeAllVolFields
(
ensightCase& ensCase,
const ensightMesh& ensMesh,
const fvMeshSubsetProxy& proxy,
const IOobjectList& objects,
const bool nodeValues
const bool nearCellValue = false
)
{
#undef foamToEnsight_WRITE_FIELD
#define foamToEnsight_WRITE_FIELD(PrimitiveType) \
#undef ensight_WRITE_FIELD
#define ensight_WRITE_FIELD(PrimitiveType) \
writeVolFields<PrimitiveType> \
( \
ensCase, ensMesh, \
proxy, \
ensCase, \
ensMesh, \
objects, \
nodeValues \
nearCellValue \
)
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);
count += ensight_WRITE_FIELD(scalar);
count += ensight_WRITE_FIELD(vector);
count += ensight_WRITE_FIELD(sphericalTensor);
count += ensight_WRITE_FIELD(symmTensor);
count += ensight_WRITE_FIELD(tensor);
#undef foamToEnsight_WRITE_FIELD
#undef ensight_WRITE_FIELD
return count;
}

View File

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

View File

@ -1,15 +0,0 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/conversion/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfileFormats \
-lconversion \
-ldynamicMesh \
-llagrangianIntermediate \
-lgenericPatchFields

View File

@ -1,45 +0,0 @@
// check for "points" in all of the result directories
// - could restrict to the selected times
bool meshMoving = false;
if (timeDirs.size() > 1 && Pstream::master())
{
// We already loaded a mesh (usually from constant).
// See if any other "polyMesh/points" files exist too.
Info<< "Search for moving mesh ... " << flush;
forAll(timeDirs, timeI)
{
meshMoving =
(
IOobject
(
"points",
timeDirs[timeI].name(),
polyMesh::meshSubDir,
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false // no register
).typeHeaderOk<pointIOField>(true, false)
);
if (meshMoving)
{
break;
}
}
if (meshMoving)
{
Info<< "found." << nl
<< " Writing meshes for every timestep." << endl;
}
else
{
Info<< "none detected." << endl;
}
}
reduce(meshMoving, orOp<bool>());

View File

@ -1,138 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
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);
ensightOutput::writeCloudPositions
(
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.val();
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 = ensightOutput::writeCloudField<scalar>
(
fieldObject, fieldExists, os
);
}
else if (fieldType == vectorIOField::typeName)
{
autoPtr<ensightFile> os =
ensCase.newCloudData<vector>(cloudName, fieldName);
wrote = ensightOutput::writeCloudField<vector>
(
fieldObject, fieldExists, os
);
}
if (wrote)
{
Info<< ' ' << fieldName;
if (!fieldExists)
{
Info<< "{0}"; // report empty field
}
}
}
Info<< " )" << nl;
}
}
// ************************************************************************* //

View File

@ -1,58 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
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

@ -1,94 +0,0 @@
// 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,370 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
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/>.
Application
foamToEnsightParts
Group
grpPostProcessingUtilities
Description
Translate OpenFOAM data to Ensight format with an Ensight part
for each cellZone and patch.
Usage
\b foamToEnsightParts [OPTION]
Options:
- \par -ascii
Write Ensight data in ASCII format instead of "C Binary"
- \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.
- \par -index \<start\>
Ignore the time index contained in the time file and use a
simple indexing when creating the \c Ensight/data/######## files.
- \par -no-lagrangian
Suppress writing lagrangian positions and fields.
- \par -no-mesh
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
Note
- no parallel data.
- writes to \a Ensight directory to avoid collisions with foamToEnsight.
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "timeSelector.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 "vectorIOField.H"
// file-format/conversion
#include "ensightCase.H"
#include "ensightGeoFile.H"
#include "ensightParts.H"
#include "ensightOutputCloud.H"
#include "ensightOutputVolField.H"
#include "fvMeshSubsetProxy.H"
// local files
#include "readFields.H"
#include "writeVolFields.H"
#include "writeDimFields.H"
#include "memInfo.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"Translate OpenFOAM data to Ensight format with an Ensight part"
" for each cellZone and patch."
);
// Enable -constant
// Probably don't need -withZero though, since the fields are vetted
// afterwards anyhow
timeSelector::addOptions(true, false); // constant(true), zero(false)
#include "addRegionOption.H"
argList::noParallel();
argList::addBoolOption
(
"ascii",
"Write in ASCII format instead of 'C Binary'"
);
argList::addOption
(
"index",
"start",
"Ignore the time index contained in the uniform/time file"
" and use simple indexing when creating files"
);
argList::addBoolOption
(
"no-lagrangian", // noLagrangian
"Suppress writing lagrangian positions and fields"
);
argList::addOptionCompat("no-lagrangian", {"noLagrangian", 1806});
argList::addBoolOption
(
"no-mesh", // noMesh
"Suppress writing the geometry."
" Can be useful for converting partial results for a static geometry"
);
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",
"subdir",
"Sub-directory name for Ensight output (default: 'Ensight')"
);
argList::addOption
(
"width",
"n",
"Width of Ensight data subdir"
);
#include "setRootCase.H"
// Default to binary output, unless otherwise specified
const IOstream::streamFormat format =
(
args.found("ascii")
? IOstream::ASCII
: IOstream::BINARY
);
cpuTime timer;
memInfo mem;
Info<< "Initial memory " << mem.update().size() << " kB" << endl;
#include "createTime.H"
instantList timeDirs = timeSelector::select0(runTime, args);
#include "createNamedMesh.H"
fileName regionPrefix; // Mesh instance (region0 gets filtered out)
if (regionName != polyMesh::defaultRegion)
{
regionPrefix = regionName;
}
//
// general (case) output options
//
ensightCase::options caseOpts(format);
caseOpts.width(args.get<label>("width", 8));
caseOpts.overwrite(false); // leave existing output directory
// Can also have separate directory for lagrangian
// caseOpts.separateCloud(true);
// 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.get<word>("name", "Ensight");
if (!ensightDir.isAbsolute())
{
ensightDir = args.globalPath()/ensightDir;
}
//
// Open new ensight case file, initialize header etc.
//
ensightCase ensCase
(
ensightDir,
"Ensight", // args.globalCaseName(),
caseOpts
);
//
// Output configuration
//
// Control for renumbering iterations
label indexingNumber = 0;
const bool optIndex = args.readIfPresent("index", indexingNumber);
const bool doLagrangian = !args.found("no-lagrangian");
// 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 ensParts(mesh);
// Write summary information
if (Pstream::master())
{
Info<< "Converting " << timeDirs.size() << " time steps" << endl;
OFstream info(ensCase.path()/"partsInfo");
info
<< "// summary of ensight parts" << nl << nl;
ensParts.writeSummary(info);
}
#include "checkMeshMoving.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)
{
Info<< "mesh is moving: ignoring '-no-mesh' option" << endl;
doGeometry = true;
}
forAll(timeDirs, timeI)
{
runTime.setTime(timeDirs[timeI], timeI);
#include "getTimeIndex.H"
#include "moveMesh.H"
ensCase.setTime(timeDirs[timeI], timeIndex);
Info<< "Time [" << timeIndex << "] = " << runTime.timeName() << nl;
if (timeI == 0 || mesh.moving())
{
if (mesh.moving())
{
ensParts.recalculate(mesh);
}
if (doGeometry)
{
autoPtr<ensightGeoFile> os = ensCase.newGeometry(meshMoving);
ensParts.write(os.ref());
}
}
// Objects at this time
IOobjectList objects(mesh, runTime.timeName());
// Restrict to objects that are available for all times
objects.filterObjects(testedObjectNames);
// Volume, internal fields
#include "convertVolumeFields.H"
// Lagrangian fields
#include "convertLagrangian.H"
Info<< "Wrote in "
<< timer.cpuTimeIncrement() << " s, "
<< mem.update().size() << " kB" << endl;
}
ensCase.write();
Info<< "\nEnd: "
<< timer.elapsedCpuTime() << " s, "
<< mem.update().peak() << " kB (peak)\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -1,19 +0,0 @@
{
IOobject io
(
"points",
runTime.timeName(),
polyMesh::meshSubDir,
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false // no register
);
if (io.typeHeaderOk<pointIOField>(true, false))
{
// Read new points
io.readOpt() = IOobject::MUST_READ;
mesh.movePoints(pointIOField(io));
}
}

View File

@ -1,81 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
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

@ -1,101 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
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(const 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

@ -1,125 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 ensightParts_writeDimFields_H
#define ensightParts_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>())
{
const 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
// ************************************************************************* //