ENH: cleanup ensightParts to use updated infrastructure (issue #241).

- Use ensightCase for case writing.
  Rebase ensightPartCells/ensightPartFaces on
  ensightCells/ensightFaces routines.

- Greatly reduces code duplication potential source of errors.
This commit is contained in:
Mark Olesen
2016-10-07 11:24:47 +02:00
parent 54da8848ba
commit 3915942195
23 changed files with 1181 additions and 2049 deletions

View File

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

View File

@ -1,7 +1,7 @@
// check for "points" in all of the result directories
// - could restrict to the selected times
bool hasMovingMesh = false;
bool meshMoving = false;
if (timeDirs.size() > 1 && Pstream::master())
{
@ -13,7 +13,7 @@ if (timeDirs.size() > 1 && Pstream::master())
Info<< "Search for moving mesh ... " << flush;
forAll(timeDirs, timeI)
{
hasMovingMesh =
meshMoving =
(
isDir(baseDir/timeDirs[timeI].name()/polyMesh::meshSubDir)
&& IOobject
@ -28,13 +28,13 @@ if (timeDirs.size() > 1 && Pstream::master())
).typeHeaderOk<pointIOField>(true)
);
if (hasMovingMesh)
if (meshMoving)
{
break;
}
}
if (hasMovingMesh)
if (meshMoving)
{
Info<< "found." << nl
<< " Writing meshes for every timestep." << endl;
@ -45,4 +45,4 @@ if (timeDirs.size() > 1 && Pstream::master())
}
}
reduce(hasMovingMesh, orOp<bool>());
reduce(meshMoving, orOp<bool>());

View File

@ -1,270 +0,0 @@
// write time values to case file
scalar timeCorrection = 0;
if (timeDirs[0].value() < 0)
{
timeCorrection = - timeDirs[0].value();
Info<< "Correcting time values. Adding " << timeCorrection << endl;
}
// the case file is always ASCII
Info<< "write case: " << caseFileName.c_str() << endl;
OFstream caseFile(ensightDir/caseFileName, IOstream::ASCII);
caseFile.setf(ios_base::left);
caseFile.setf(ios_base::scientific, ios_base::floatfield);
caseFile.precision(5);
caseFile
<< "FORMAT" << nl
<< setw(16) << "type:" << "ensight gold" << nl << nl;
// time-set for geometries
// TODO: split off into separate time-set, but need to verify ensight spec
if (geometryTimesUsed.size())
{
caseFile
<< "GEOMETRY" << nl
<< setw(16) << "model: 1" << (dataMask/geometryName).c_str() << nl;
}
else
{
caseFile
<< "GEOMETRY" << nl
<< setw(16) << "model:" << geometryName << nl;
}
// add information for clouds
// multiple clouds currently require the same time index
forAllConstIter(HashTable<HashTable<word>>, cloudFields, cloudIter)
{
const word& cloudName = cloudIter.key();
caseFile
<< setw(16) << "measured: 2"
<< fileName(dataMask/cloud::prefix/cloudName/"positions").c_str()
<< nl;
}
caseFile
<< nl << "VARIABLE" << nl;
forAllConstIter(HashTable<word>, volumeFields, fieldIter)
{
const word& fieldName = fieldIter.key();
const word& fieldType = fieldIter();
string ensightType;
if (fieldType == volScalarField::typeName)
{
ensightType = ensightPTraits<scalar>::typeName;
}
else if (fieldType == volVectorField::typeName)
{
ensightType = ensightPTraits<vector>::typeName;
}
else if (fieldType == volSphericalTensorField::typeName)
{
ensightType = ensightPTraits<sphericalTensor>::typeName;
}
else if (fieldType == volSymmTensorField::typeName)
{
ensightType = ensightPTraits<symmTensor>::typeName;
}
else if (fieldType == volTensorField::typeName)
{
ensightType = ensightPTraits<tensor>::typeName;
}
else
{
continue;
}
ensightCaseEntry
(
caseFile,
ensightType,
fieldName,
dataMask
);
}
// TODO: allow similar/different time-steps for each cloud
label cloudNo = 0;
forAllConstIter(HashTable<HashTable<word>>, cloudFields, cloudIter)
{
const word& cloudName = cloudIter.key();
forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
{
const word& fieldName = fieldIter.key();
const word& fieldType = fieldIter();
string ensightType;
if (fieldType == scalarIOField::typeName)
{
ensightType = ensightPTraits<scalar>::typeName;
}
else if (fieldType == vectorIOField::typeName)
{
ensightType = ensightPTraits<vector>::typeName;
}
else if (fieldType == tensorIOField::typeName)
{
ensightType = ensightPTraits<tensor>::typeName;
}
else
{
continue;
}
ensightCaseEntry
(
caseFile,
ensightType,
fieldName,
dataMask,
cloud::prefix/cloudName,
cloudNo,
2
);
}
cloudNo++;
}
// add time values
caseFile << nl << "TIME" << nl;
// time set 1 - volume fields
if (fieldTimesUsed.size())
{
caseFile
<< "time set: " << 1 << nl
<< "number of steps: " << fieldTimesUsed.size() << nl
<< "filename numbers:" << nl;
label count = 0;
forAll(fieldTimesUsed, i)
{
caseFile
<< " " << setw(12) << fieldTimesUsed[i];
if (++count % 6 == 0)
{
caseFile << nl;
}
}
caseFile
<< nl << "time values:" << nl;
count = 0;
forAll(fieldTimesUsed, i)
{
const label index = fieldTimesUsed[i];
caseFile
<< " " << setw(12) << timeIndices[index] + timeCorrection;
if (++count % 6 == 0)
{
caseFile << nl;
}
}
caseFile << nl << nl;
}
// time set 2 - geometry
// THIS NEEDS MORE CHECKING
#if 0
if (geometryTimesUsed.size())
{
caseFile
<< "time set: " << 2 << nl
<< "number of steps: " << geometryTimesUsed.size() << nl
<< "filename numbers:" << nl;
label count = 0;
forAll(geometryTimesUsed, i)
{
caseFile
<< " " << setw(12) << geometryTimesUsed[i];
if (++count % 6 == 0)
{
caseFile << nl;
}
}
caseFile
<< nl << "time values:" << nl;
count = 0;
forAll(geometryTimesUsed, i)
{
const label index = geometryTimesUsed[i];
caseFile
<< " " << setw(12) << timeIndices[index] + timeCorrection;
if (++count % 6 == 0)
{
caseFile << nl;
}
}
caseFile << nl << nl;
}
#endif
// time set - clouds
// TODO: allow similar/different time-steps for each cloud
cloudNo = 0;
forAllConstIter(HashTable<DynamicList<label>>, cloudTimesUsed, cloudIter)
{
// const word& cloudName = cloudIter.key();
const DynamicList<label>& timesUsed = cloudIter();
if (timesUsed.size() && cloudNo == 0)
{
caseFile
<< "time set: " << 2 << nl
<< "number of steps: " << timesUsed.size() << nl
<< "filename numbers:" << nl;
label count = 0;
forAll(timesUsed, i)
{
caseFile
<< " " << setw(12) << timesUsed[i];
if (++count % 6 == 0)
{
caseFile << nl;
}
}
caseFile
<< nl << "time values:" << nl;
count = 0;
forAll(timesUsed, i)
{
const label index = timesUsed[i];
caseFile
<< " " << setw(12) << timeIndices[index] + timeCorrection;
if (++count % 6 == 0)
{
caseFile << nl;
}
}
caseFile << nl << nl;
cloudNo++;
}
}
caseFile << "# end" << nl;

View File

@ -1,245 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 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 "ensightOutputFunctions.H"
#include "ensightPTraits.H"
#include "passiveParticle.H"
#include "IOField.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "OFstream.H"
#include "IOmanip.H"
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
void Foam::ensightCaseEntry
(
OFstream& caseFile,
const string& ensightType,
const word& fieldName,
const fileName& dataMask,
const fileName& local,
const label cloudNo,
const label timeSet
)
{
const ensight::VarName varName(fieldName);
caseFile.setf(ios_base::left);
fileName dirName(dataMask);
if (local.size())
{
dirName = dirName/local;
}
if (cloudNo >= 0)
{
label ts = 1;
if (timeSet > ts)
{
ts = timeSet;
}
// prefix variables with 'c' (cloud)
caseFile
<< ensightType.c_str()
<< " per measured node: " << ts << " "
<< setw(15)
<< ("c" + Foam::name(cloudNo) + varName).c_str()
<< " "
<< (dirName/varName).c_str()
<< nl;
}
else
{
caseFile
<< ensightType.c_str()
<< " per element: "
<< setw(15) << varName
<< " "
<< (dirName/varName).c_str()
<< nl;
}
}
void Foam::ensightParticlePositions
(
const polyMesh& mesh,
const fileName& dataDir,
const fileName& subDir,
const word& cloudName,
IOstream::streamFormat format
)
{
Cloud<passiveParticle> parcels(mesh, cloudName, false);
const fileName postFileName =
subDir/cloud::prefix/cloudName/"positions";
// the ITER/lagrangian subdirectory must exist
mkDir(dataDir/postFileName.path());
ensightFile os(dataDir, postFileName, format);
// tag binary format (just like geometry files)
os.writeBinaryHeader();
os.write(postFileName); // description
os.newline();
os.write("particle coordinates");
os.newline();
os.write(parcels.size(), 8); // unusual width
os.newline();
// binary write is Ensight6 - first ids, then positions
if (format == IOstream::BINARY)
{
forAll(parcels, i)
{
os.write(i+1);
}
forAllConstIter(Cloud<passiveParticle>, parcels, elmnt)
{
const vector& p = elmnt().position();
os.write(p.x());
os.write(p.y());
os.write(p.z());
}
}
else
{
label nParcels = 0;
forAllConstIter(Cloud<passiveParticle>, parcels, elmnt)
{
const vector& p = elmnt().position();
os.write(++nParcels, 8); // unusual width
os.write(p.x());
os.write(p.y());
os.write(p.z());
os.newline();
}
}
}
template<class Type>
void Foam::ensightLagrangianField
(
const IOobject& fieldObject,
const fileName& dataDir,
const fileName& subDir,
const word& cloudName,
IOstream::streamFormat format
)
{
Info<< " " << fieldObject.name() << flush;
const fileName postFileName =
subDir/cloud::prefix/cloudName
/ensight::VarName(fieldObject.name());
// the ITER/lagrangian subdirectory was already created
// when writing positions
ensightFile os(dataDir, postFileName, format);
// description
os.write(string(postFileName + " <" + pTraits<Type>::typeName + ">"));
os.newline();
IOField<Type> field(fieldObject);
// 6 values per line
label count = 0;
forAll(field, i)
{
Type val = field[i];
if (mag(val) < 1e-90)
{
val = Zero;
}
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
label cmpt = ensightPTraits<Type>::componentOrder[d];
os.write(component(val, cmpt));
if (++count % 6 == 0)
{
os.newline();
}
}
}
// add final newline if required
if (count % 6)
{
os.newline();
}
}
template<class Type>
void Foam::ensightVolField
(
const ensightParts& partsList,
const IOobject& fieldObject,
const fvMesh& mesh,
const fileName& dataDir,
const fileName& subDir,
IOstream::streamFormat format
)
{
Info<< " " << fieldObject.name() << flush;
const fileName postFileName = subDir/ensight::VarName(fieldObject.name());
ensightFile os(dataDir, postFileName, format);
os.write(postFileName); // description
os.newline();
// ie, volField<Type>
partsList.writeField
(
os,
GeometricField<Type, fvPatchField, volMesh>
(
fieldObject,
mesh
)
);
}
// ************************************************************************* //

View File

@ -0,0 +1,95 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 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 "ensightOutputSerialCloud.H"
#include "ensightPTraits.H"
#include "passiveParticle.H"
#include "IOField.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
void Foam::ensightSerialCloud::writePositions
(
const polyMesh& mesh,
const word& cloudName,
autoPtr<ensightFile> output
)
{
label nTotParcels = 0;
autoPtr<Cloud<passiveParticle>> cloudPtr;
cloudPtr.reset(new Cloud<passiveParticle>(mesh, cloudName, false));
nTotParcels = cloudPtr().size();
Cloud<passiveParticle> parcels(mesh, cloudName, false);
if (Pstream::master())
{
ensightFile& os = output();
os.beginParticleCoordinates(nTotParcels);
// binary write is Ensight6 - first ids, then positions
if (os.format() == IOstream::BINARY)
{
// 1-index
for (label parcelId = 0; parcelId < nTotParcels; ++parcelId)
{
os.write(parcelId+1);
}
forAllConstIter(Cloud<passiveParticle>, cloudPtr(), elmnt)
{
const vector& p = elmnt().position();
os.write(p.x());
os.write(p.y());
os.write(p.z());
}
}
else
{
// ASCII id + position together
label parcelId = 0;
forAllConstIter(Cloud<passiveParticle>, cloudPtr(), elmnt)
{
const vector& p = elmnt().position();
os.write(++parcelId, 8); // unusual width
os.write(p.x());
os.write(p.y());
os.write(p.z());
os.newline();
}
}
}
}
// ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,70 +29,57 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef ensightOutputFunctions_H
#define ensightOutputFunctions_H
#ifndef ensightOutputSerialCloud_H
#define ensightOutputSerialCloud_H
#include "ensightFile.H"
#include "Cloud.H"
#include "polyMesh.H"
#include "IOobject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace ensightSerialCloud
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void ensightCaseEntry
(
OFstream& caseFile,
const string& ensightType,
const word& fieldName,
const fileName& dataMask,
const fileName& local=fileName::null,
const label cloudNo=-1,
const label timeSet=1
);
void ensightParticlePositions
//- Write cloud positions
void writePositions
(
const polyMesh& mesh,
const fileName& dataDir,
const fileName& subDir,
const word& cloudName,
IOstream::streamFormat format
autoPtr<ensightFile> output
);
//- Write lagrangian parcels
//- Write cloud field
template<class Type>
void ensightLagrangianField
bool writeCloudField
(
const IOField<Type>& field,
ensightFile& os
);
//- Write cloud field
template<class Type>
bool writeCloudField
(
const IOobject& fieldObject,
const fileName& dataDir,
const fileName& subDir,
const word& cloudName,
IOstream::streamFormat format
autoPtr<ensightFile> output
);
//- Write generalized field components
template<class Type>
void ensightVolField
(
const ensightParts& partsList,
const IOobject& fieldObject,
const fvMesh& mesh,
const fileName& dataDir,
const fileName& subDir,
IOstream::streamFormat format
);
} // namespace ensightSerialCloud
} // namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // namespace Foam
#ifdef NoRepository
#include "ensightOutputFunctions.C"
#include "ensightOutputSerialCloudTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,90 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 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 "ensightOutputSerialCloud.H"
#include "ensightSerialOutput.H"
#include "ensightPTraits.H"
#include "passiveParticle.H"
#include "IOField.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
template<class Type>
bool Foam::ensightSerialCloud::writeCloudField
(
const IOField<Type>& field,
ensightFile& os
)
{
// 6 values per line
label count = 0;
forAll(field, i)
{
Type val = field[i];
if (mag(val) < 1e-90)
{
val = Zero;
}
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
label cmpt = ensightPTraits<Type>::componentOrder[d];
os.write(component(val, cmpt));
if (++count % 6 == 0)
{
os.newline();
}
}
}
// add final newline if required
if (count % 6)
{
os.newline();
}
return true;
}
template<class Type>
bool Foam::ensightSerialCloud::writeCloudField
(
const IOobject& fieldObject,
autoPtr<ensightFile> output
)
{
IOField<Type> field(fieldObject);
return writeCloudField(field, output.rawRef());
}
// ************************************************************************* //

View File

@ -78,8 +78,14 @@ Note
#include "scalarIOField.H"
#include "tensorIOField.H"
// file-format/conversion
#include "ensightCase.H"
#include "ensightGeoFile.H"
#include "ensightParts.H"
#include "ensightOutputFunctions.H"
#include "ensightSerialOutput.H"
// local files
#include "ensightOutputSerialCloud.H"
#include "memInfo.H"
@ -146,20 +152,8 @@ int main(int argc, char *argv[])
cloudFieldTypes.insert(vectorIOField::typeName);
cloudFieldTypes.insert(tensorIOField::typeName);
const char* geometryName = "geometry";
#include "setRootCase.H"
cpuTime timer;
memInfo mem;
Info<< "Initial memory "
<< mem.update().size() << " kB" << endl;
#include "createTime.H"
// Get times list
instantList timeDirs = timeSelector::select0(runTime, args);
// Default to binary output, unless otherwise specified
const IOstream::streamFormat format =
(
@ -168,6 +162,57 @@ int main(int argc, char *argv[])
: 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.optionLookupOrDefault<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.optionLookupOrDefault<word>("name", "Ensight");
if (!ensightDir.isAbsolute())
{
ensightDir = args.rootPath()/args.globalCaseName()/ensightDir;
}
//
// Open new ensight case file, initialize header etc.
//
ensightCase ensCase
(
ensightDir,
"Ensight", // args.globalCaseName(),
caseOpts
);
//
// Miscellaneous output configuration
//
// Control for renumbering iterations
label indexingNumber = 0;
const bool optIndex = args.optionReadIfPresent("index", indexingNumber);
@ -176,93 +221,32 @@ int main(int argc, char *argv[])
// Always write the geometry, unless the -noMesh option is specified
bool optNoMesh = args.optionFound("noMesh");
// Adjust output width
if (args.optionFound("width"))
{
ensightFile::subDirWidth(args.optionRead<label>("width"));
}
// Define sub-directory name to use for Ensight data
fileName ensightDir = "Ensight";
args.optionReadIfPresent("name", ensightDir);
if (!ensightDir.isAbsolute())
{
ensightDir = args.rootPath()/args.globalCaseName()/ensightDir;
}
const fileName caseFileName = "Ensight.case";
const fileName dataDir = ensightDir/"data";
const fileName dataMask = dataDir.name()/ensightFile::mask();
// Ensight and Ensight/data directories must exist
// do not remove old data - we might wish to convert new results
// or a particular time interval
if (isDir(ensightDir))
{
Info<<"Warning: re-using existing directory" << nl
<< " " << ensightDir << endl;
}
// As per mkdir -p "Ensight/data"
mkDir(ensightDir);
mkDir(dataDir);
#include "createNamedMesh.H"
// Mesh instance (region0 gets filtered out)
fileName regionPrefix;
if (regionName != polyMesh::defaultRegion)
{
regionPrefix = regionName;
}
if (Pstream::master())
{
Info<< "Converting " << timeDirs.size() << " time steps" << endl;
}
// Construct the list of ensight parts for the entire mesh
ensightParts partsList(mesh);
// Write summary information
if (Pstream::master())
{
OFstream partsInfoFile(ensightDir/"partsInfo");
Info<< "Converting " << timeDirs.size() << " time steps" << endl;
partsInfoFile
OFstream info(ensCase.path()/"partsInfo");
info
<< "// summary of ensight parts" << nl << nl;
partsList.writeSummary(partsInfoFile);
partsList.writeSummary(info);
}
#include "checkHasMovingMesh.H"
#include "checkMeshMoving.H"
#include "findFields.H"
if (hasMovingMesh && optNoMesh)
if (meshMoving && optNoMesh)
{
Info<< "mesh is moving: ignoring '-noMesh' option" << endl;
optNoMesh = false;
}
// Map times used
Map<scalar> timeIndices;
// TODO: Track the time indices used by the geometry
DynamicList<label> geometryTimesUsed;
// Track the time indices used by the volume fields
DynamicList<label> fieldTimesUsed;
// Track the time indices used by each cloud
HashTable<DynamicList<label>> cloudTimesUsed;
// Create a new DynamicList for each cloud
forAllConstIter(HashTable<HashTable<word>>, cloudFields, cloudIter)
{
cloudTimesUsed.insert(cloudIter.key(), DynamicList<label>());
}
Info<< "Startup in "
<< timer.cpuTimeIncrement() << " s, "
<< mem.update().size() << " kB" << nl << endl;
@ -272,25 +256,10 @@ int main(int argc, char *argv[])
runTime.setTime(timeDirs[timeI], timeI);
#include "getTimeIndex.H"
// Remember the time index for the volume fields
fieldTimesUsed.append(timeIndex);
// The data/ITER subdirectory must exist
// Note that data/ITER is indeed a valid ensight::FileName
const fileName subDir = ensightFile::subDir(timeIndex);
mkDir(dataDir/subDir);
// Place a timestamp in the directory for future reference
{
OFstream timeStamp(dataDir/subDir/"time");
timeStamp
<< "# timestep time" << nl
<< subDir.c_str() << " " << runTime.timeName() << nl;
}
#include "moveMesh.H"
ensCase.setTime(timeDirs[timeI], timeIndex);
if (timeI == 0 || mesh.moving())
{
if (mesh.moving())
@ -300,19 +269,8 @@ int main(int argc, char *argv[])
if (!optNoMesh)
{
if (hasMovingMesh)
{
// Remember the time index for the geometry
geometryTimesUsed.append(timeIndex);
}
ensightGeoFile geoFile
(
(hasMovingMesh ? dataDir/subDir : ensightDir),
geometryName,
format
);
partsList.writeGeometry(geoFile);
autoPtr<ensightGeoFile> os = ensCase.newGeometry(meshMoving);
partsList.write(os.rawRef());
}
}
@ -332,68 +290,76 @@ int main(int argc, char *argv[])
IOobject::NO_WRITE
);
bool wrote = false;
if (fieldType == volScalarField::typeName)
{
ensightVolField<scalar>
autoPtr<ensightFile> os = ensCase.newData<scalar>
(
partsList,
fieldObject,
mesh,
dataDir,
subDir,
format
fieldName
);
volScalarField vf(fieldObject, mesh);
wrote = ensightSerialOutput::writeField<scalar>
(
vf, partsList, os
);
}
else if (fieldType == volVectorField::typeName)
{
ensightVolField<vector>
autoPtr<ensightFile> os = ensCase.newData<vector>
(
partsList,
fieldObject,
mesh,
dataDir,
subDir,
format
fieldName
);
volVectorField vf(fieldObject, mesh);
wrote = ensightSerialOutput::writeField<vector>
(
vf, partsList, os
);
}
else if (fieldType == volSphericalTensorField::typeName)
{
ensightVolField<sphericalTensor>
autoPtr<ensightFile> os = ensCase.newData<sphericalTensor>
(
partsList,
fieldObject,
mesh,
dataDir,
subDir,
format
fieldName
);
volSphericalTensorField vf(fieldObject, mesh);
wrote = ensightSerialOutput::writeField<sphericalTensor>
(
vf, partsList, os
);
}
else if (fieldType == volSymmTensorField::typeName)
{
ensightVolField<symmTensor>
autoPtr<ensightFile> os = ensCase.newData<symmTensor>
(
partsList,
fieldObject,
mesh,
dataDir,
subDir,
format
fieldName
);
volSymmTensorField vf(fieldObject, mesh);
wrote = ensightSerialOutput::writeField<symmTensor>
(
vf, partsList, os
);
}
else if (fieldType == volTensorField::typeName)
{
ensightVolField<tensor>
autoPtr<ensightFile> os = ensCase.newData<tensor>
(
partsList,
fieldObject,
mesh,
dataDir,
subDir,
format
fieldName
);
volTensorField vf(fieldObject, mesh);
wrote = ensightSerialOutput::writeField<tensor>
(
vf, partsList, os
);
}
if (wrote)
{
Info<< " " << fieldObject.name() << flush;
}
}
Info<< " )" << endl;
@ -422,16 +388,16 @@ int main(int argc, char *argv[])
continue;
}
Info<< "Write " << cloudName << " ( positions" << flush;
Info<< "Write " << cloudName << " (" << flush;
ensightParticlePositions
ensightSerialCloud::writePositions
(
mesh,
dataDir,
subDir,
cloudName,
format
ensCase.newCloud(cloudName)
);
Info<< " positions";
forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
{
@ -449,48 +415,39 @@ int main(int argc, char *argv[])
continue;
}
bool wrote = false;
if (fieldType == scalarIOField::typeName)
{
ensightLagrangianField<scalar>
wrote = ensightSerialCloud::writeCloudField<scalar>
(
*fieldObject,
dataDir,
subDir,
cloudName,
format
ensCase.newCloudData<scalar>(cloudName, fieldName)
);
}
else if (fieldType == vectorIOField::typeName)
{
ensightLagrangianField<vector>
wrote = ensightSerialCloud::writeCloudField<vector>
(
*fieldObject,
dataDir,
subDir,
cloudName,
format
ensCase.newCloudData<vector>(cloudName, fieldName)
);
}
else if (fieldType == tensorIOField::typeName)
{
ensightLagrangianField<tensor>
wrote = ensightSerialCloud::writeCloudField<tensor>
(
*fieldObject,
dataDir,
subDir,
cloudName,
format
ensCase.newCloudData<tensor>(cloudName, fieldName)
);
}
if (wrote)
{
Info<< " " << fieldObject->name();
}
}
Info<< " )" << endl;
// Remember the time index
cloudTimesUsed[cloudName].append(timeIndex);
}
Info<< "Wrote in "
@ -498,7 +455,7 @@ int main(int argc, char *argv[])
<< mem.update().size() << " kB" << endl;
}
#include "ensightOutputCase.H"
ensCase.write();
Info<< "\nEnd: "
<< timer.elapsedCpuTime() << " s, "

View File

@ -38,6 +38,6 @@
}
}
timeIndices.insert(timeIndex, timeDirs[timeI].value());
Info<< nl << "Time [" << timeIndex << "] = " << runTime.timeName() << nl;
// end-of-file