mirror of
https://github.com/OpenFOAM/OpenFOAM-6.git
synced 2025-12-08 06:57:46 +00:00
Add the OpenFOAM source tree
This commit is contained in:
@ -0,0 +1,3 @@
|
||||
foamToEnsightParts.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/foamToEnsightParts
|
||||
@ -0,0 +1,12 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||
-I$(LIB_SRC)/conversion/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-llagrangian \
|
||||
-lmeshTools \
|
||||
-lgenericPatchFields \
|
||||
-lconversion
|
||||
@ -0,0 +1,18 @@
|
||||
// check for "points" in all of the result directories
|
||||
|
||||
bool hasMovingMesh = false;
|
||||
if (timeDirs.size() > 1)
|
||||
{
|
||||
hasMovingMesh = true;
|
||||
for (label i=0; i < timeDirs.size() && hasMovingMesh; ++i)
|
||||
{
|
||||
hasMovingMesh = IOobject
|
||||
(
|
||||
"points",
|
||||
timeDirs[i].name(),
|
||||
polyMesh::meshSubDir,
|
||||
mesh,
|
||||
IOobject::NO_READ
|
||||
).headerOk();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,224 @@
|
||||
// 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;
|
||||
|
||||
if (hasMovingMesh)
|
||||
{
|
||||
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 = "scalar";
|
||||
}
|
||||
else if (fieldType == volVectorField::typeName)
|
||||
{
|
||||
ensightType = "vector";
|
||||
}
|
||||
else if (fieldType == volSphericalTensorField::typeName)
|
||||
{
|
||||
ensightType = "tensor symm";
|
||||
}
|
||||
else if (fieldType == volSymmTensorField::typeName)
|
||||
{
|
||||
ensightType = "tensor symm";
|
||||
}
|
||||
else if (fieldType == volTensorField::typeName)
|
||||
{
|
||||
ensightType = "tensor asym";
|
||||
}
|
||||
|
||||
if (ensightType.size())
|
||||
{
|
||||
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 = "scalar";
|
||||
}
|
||||
else if (fieldType == vectorIOField::typeName)
|
||||
{
|
||||
ensightType = "vector";
|
||||
}
|
||||
else if (fieldType == tensorIOField::typeName)
|
||||
{
|
||||
ensightType = "tensor";
|
||||
}
|
||||
|
||||
if (ensightType.size())
|
||||
{
|
||||
ensightCaseEntry
|
||||
(
|
||||
caseFile,
|
||||
ensightType,
|
||||
fieldName,
|
||||
dataMask,
|
||||
cloud::prefix/cloudName,
|
||||
cloudNo,
|
||||
2
|
||||
);
|
||||
}
|
||||
}
|
||||
cloudNo++;
|
||||
}
|
||||
|
||||
|
||||
// add time values
|
||||
caseFile << nl << "TIME" << nl;
|
||||
|
||||
// time set 1 - geometry and 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)
|
||||
{
|
||||
caseFile
|
||||
<< " " << setw(12)
|
||||
<< timeIndices[fieldTimesUsed[i]] + timeCorrection;
|
||||
|
||||
if (++count % 6 == 0)
|
||||
{
|
||||
caseFile << nl;
|
||||
}
|
||||
}
|
||||
caseFile << nl << nl;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
caseFile
|
||||
<< " " << setw(12)
|
||||
<< timeIndices[timesUsed[i]] + timeCorrection;
|
||||
|
||||
if (++count % 6 == 0)
|
||||
{
|
||||
caseFile << nl;
|
||||
}
|
||||
}
|
||||
caseFile << nl << nl;
|
||||
|
||||
cloudNo++;
|
||||
}
|
||||
}
|
||||
|
||||
caseFile << "# end" << nl;
|
||||
|
||||
@ -0,0 +1,242 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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 "ensightOutputFunctions.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
|
||||
)
|
||||
{
|
||||
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) + fieldName).c_str()
|
||||
<< " "
|
||||
<< (dirName/fieldName).c_str()
|
||||
<< nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
caseFile
|
||||
<< ensightType.c_str()
|
||||
<< " per element: "
|
||||
<< setw(15) << fieldName
|
||||
<< " "
|
||||
<< (dirName/fieldName).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);
|
||||
|
||||
fileName cloudDir = subDir/cloud::prefix/cloudName;
|
||||
fileName postFileName = cloudDir/"positions";
|
||||
|
||||
// the ITER/lagrangian subdirectory must exist
|
||||
mkDir(dataDir/cloudDir);
|
||||
ensightFile os(dataDir/postFileName, format);
|
||||
|
||||
// tag binary format (just like geometry files)
|
||||
os.writeBinaryHeader();
|
||||
os.write(postFileName);
|
||||
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;
|
||||
|
||||
fileName cloudDir = subDir/cloud::prefix/cloudName;
|
||||
fileName postFileName = cloudDir/fieldObject.name();
|
||||
|
||||
string title =
|
||||
postFileName + " with " + pTraits<Type>::typeName + " values";
|
||||
|
||||
ensightFile os(dataDir/postFileName, format);
|
||||
os.write(title);
|
||||
os.newline();
|
||||
|
||||
IOField<Type> field(fieldObject);
|
||||
|
||||
// 6 values per line
|
||||
label count = 0;
|
||||
|
||||
forAll(field, i)
|
||||
{
|
||||
Type val = field[i];
|
||||
|
||||
if (mag(val) < 1.0e-90)
|
||||
{
|
||||
val = pTraits<Type>::zero;
|
||||
}
|
||||
|
||||
for (direction cmpt=0; cmpt < pTraits<Type>::nComponents; cmpt++)
|
||||
{
|
||||
os.write( component(val, cmpt) );
|
||||
}
|
||||
|
||||
count += pTraits<Type>::nComponents;
|
||||
|
||||
if (count % 6 == 0)
|
||||
{
|
||||
os.newline();
|
||||
}
|
||||
}
|
||||
|
||||
// add final newline if required
|
||||
if (count % 6)
|
||||
{
|
||||
os.newline();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//- write generalized field components
|
||||
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;
|
||||
|
||||
fileName postFileName = subDir/fieldObject.name();
|
||||
|
||||
ensightFile os(dataDir/postFileName, format);
|
||||
os.write(postFileName);
|
||||
os.newline();
|
||||
|
||||
// ie, volField<Type>
|
||||
partsList.writeField
|
||||
(
|
||||
os,
|
||||
GeometricField<Type, fvPatchField, volMesh>
|
||||
(
|
||||
fieldObject,
|
||||
mesh
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,102 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||
\\/ 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
|
||||
Miscellaneous collection of functions and template related to Ensight data
|
||||
|
||||
SourceFiles
|
||||
ensightOutputFunctions.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef ensightOutputFunctions_H
|
||||
#define ensightOutputFunctions_H
|
||||
|
||||
#include "ensightFile.H"
|
||||
#include "Cloud.H"
|
||||
#include "polyMesh.H"
|
||||
#include "IOobject.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
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
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const fileName& dataDir,
|
||||
const fileName& subDir,
|
||||
const word& cloudName,
|
||||
IOstream::streamFormat format
|
||||
);
|
||||
|
||||
|
||||
//- write lagrangian parcels
|
||||
template<class Type>
|
||||
void ensightLagrangianField
|
||||
(
|
||||
const IOobject& fieldObject,
|
||||
const fileName& dataDir,
|
||||
const fileName& subDir,
|
||||
const word& cloudName,
|
||||
IOstream::streamFormat format
|
||||
);
|
||||
|
||||
//- 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 Foam
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "ensightOutputFunctions.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,105 @@
|
||||
// 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())
|
||||
{
|
||||
IOobjectList objs(mesh, timeDirs.last().name());
|
||||
|
||||
forAllConstIter(IOobjectList, objs, fieldIter)
|
||||
{
|
||||
const IOobject& obj = *fieldIter();
|
||||
const word& fieldName = obj.name();
|
||||
const word& fieldType = obj.headerClassName();
|
||||
|
||||
if (fieldName.size() > 2 && fieldName(fieldName.size()-2, 2) == "_0")
|
||||
{
|
||||
// ignore _0 fields
|
||||
}
|
||||
else if (volFieldTypes.found(fieldType))
|
||||
{
|
||||
// simply ignore types that we don't handle
|
||||
volumeFields.insert(fieldName, fieldType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// now check for lagrangian/<cloudName>
|
||||
//
|
||||
fileNameList cloudDirs = readDir
|
||||
(
|
||||
runTime.path()
|
||||
/ timeDirs.last().name()
|
||||
/ regionPrefix
|
||||
/ cloud::prefix,
|
||||
fileName::DIRECTORY
|
||||
);
|
||||
|
||||
forAll(cloudDirs, cloudI)
|
||||
{
|
||||
const word& cloudName = cloudDirs[cloudI];
|
||||
|
||||
// Create a new hash table for each cloud
|
||||
cloudFields.insert(cloudName, HashTable<word>());
|
||||
|
||||
// Identify the new cloud within the hash table
|
||||
HashTable<HashTable<word> >::iterator cloudIter =
|
||||
cloudFields.find(cloudName);
|
||||
|
||||
IOobjectList objs
|
||||
(
|
||||
mesh,
|
||||
timeDirs.last().name(),
|
||||
cloud::prefix/cloudName
|
||||
);
|
||||
|
||||
bool hasPositions = false;
|
||||
forAllConstIter(IOobjectList, objs, fieldIter)
|
||||
{
|
||||
const IOobject obj = *fieldIter();
|
||||
const word& fieldName = obj.name();
|
||||
const word& fieldType = obj.headerClassName();
|
||||
|
||||
if (fieldName == "positions")
|
||||
{
|
||||
hasPositions = true;
|
||||
}
|
||||
else if (cloudFieldTypes.found(fieldType))
|
||||
{
|
||||
// simply ignore types that we don't handle
|
||||
cloudIter().insert(fieldName, fieldType);
|
||||
}
|
||||
}
|
||||
|
||||
// drop this cloud if it has no positions or is otherwise empty
|
||||
if (!hasPositions || cloudIter().empty())
|
||||
{
|
||||
Info<< "removing cloud " << cloudName << endl;
|
||||
cloudFields.erase(cloudIter);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// verify that the variable is present for all times
|
||||
//
|
||||
for (label i=0; volumeFields.size() && i < timeDirs.size(); ++i)
|
||||
{
|
||||
IOobjectList objs(mesh, timeDirs[i].name());
|
||||
|
||||
forAllIter(HashTable<word>, volumeFields, fieldIter)
|
||||
{
|
||||
const word& fieldName = fieldIter.key();
|
||||
|
||||
if (!objs.found(fieldName))
|
||||
{
|
||||
volumeFields.erase(fieldIter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,471 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ 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/>.
|
||||
|
||||
Application
|
||||
foamToEnsightParts
|
||||
|
||||
Description
|
||||
Translates OpenFOAM data to Ensight format.
|
||||
An Ensight part is created for each cellZone and patch.
|
||||
|
||||
Usage
|
||||
- foamToEnsightParts [OPTION] \n
|
||||
Translates OpenFOAM data to Ensight format
|
||||
|
||||
\param -ascii \n
|
||||
Write Ensight data in ASCII format instead of "C Binary"
|
||||
|
||||
\parm -name \<subdir\>\n
|
||||
define sub-directory name to use for Ensight data (default: "Ensight")
|
||||
|
||||
\param -noZero \n
|
||||
Exclude the often incomplete initial conditions.
|
||||
|
||||
\param -index \<start\>\n
|
||||
Ignore the time index contained in the time file and use a
|
||||
simple indexing when creating the \c Ensight/data/######## files.
|
||||
|
||||
\param -noMesh \n
|
||||
Suppress writing the geometry. Can be useful for converting partial
|
||||
results for a static geometry.
|
||||
|
||||
\param -width \<n\>\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 "volFields.H"
|
||||
#include "OFstream.H"
|
||||
#include "IOmanip.H"
|
||||
#include "IOobjectList.H"
|
||||
#include "scalarIOField.H"
|
||||
#include "tensorIOField.H"
|
||||
|
||||
#include "ensightParts.H"
|
||||
#include "ensightOutputFunctions.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// enable -constant
|
||||
// probably don't need -zeroTime though, since the fields are vetted
|
||||
// afterwards anyhow
|
||||
timeSelector::addOptions(true, false);
|
||||
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 the files"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"noMesh",
|
||||
"suppress writing the geometry. "
|
||||
"Can be useful for converting partial results for a static geometry"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"name",
|
||||
"subdir",
|
||||
"define sub-directory name to use for Ensight data "
|
||||
"(default: \"Ensight\")"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"width",
|
||||
"n",
|
||||
"width of Ensight data subdir"
|
||||
);
|
||||
|
||||
// the volume field types that we handle
|
||||
wordHashSet volFieldTypes;
|
||||
volFieldTypes.insert(volScalarField::typeName);
|
||||
volFieldTypes.insert(volVectorField::typeName);
|
||||
volFieldTypes.insert(volSphericalTensorField::typeName);
|
||||
volFieldTypes.insert(volSymmTensorField::typeName);
|
||||
volFieldTypes.insert(volTensorField::typeName);
|
||||
|
||||
// the lagrangian field types that we handle
|
||||
wordHashSet cloudFieldTypes;
|
||||
cloudFieldTypes.insert(scalarIOField::typeName);
|
||||
cloudFieldTypes.insert(vectorIOField::typeName);
|
||||
cloudFieldTypes.insert(tensorIOField::typeName);
|
||||
|
||||
const char* geometryName = "geometry";
|
||||
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
|
||||
// get times list
|
||||
instantList timeDirs = timeSelector::select0(runTime, args);
|
||||
|
||||
// default to binary output, unless otherwise specified
|
||||
IOstream::streamFormat format = IOstream::BINARY;
|
||||
if (args.optionFound("ascii"))
|
||||
{
|
||||
format = IOstream::ASCII;
|
||||
}
|
||||
|
||||
// control for renumbering iterations
|
||||
label indexingNumber = 0;
|
||||
bool optIndex = args.optionReadIfPresent("index", indexingNumber);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
fileName dataDir = ensightDir/"data";
|
||||
fileName caseFileName = "Ensight.case";
|
||||
fileName dataMask = fileName("data")/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;
|
||||
}
|
||||
mkDir(ensightDir);
|
||||
mkDir(dataDir);
|
||||
|
||||
#include "createNamedMesh.H"
|
||||
|
||||
// Mesh instance (region0 gets filtered out)
|
||||
fileName regionPrefix;
|
||||
|
||||
if (regionName != polyMesh::defaultRegion)
|
||||
{
|
||||
regionPrefix = regionName;
|
||||
}
|
||||
|
||||
// Construct the list of ensight parts for the entire mesh
|
||||
ensightParts partsList(mesh);
|
||||
|
||||
// write summary information
|
||||
{
|
||||
OFstream partsInfoFile(ensightDir/"partsInfo");
|
||||
|
||||
partsInfoFile
|
||||
<< "// summary of ensight parts" << nl << nl;
|
||||
partsList.writeSummary(partsInfoFile);
|
||||
}
|
||||
|
||||
#include "checkHasMovingMesh.H"
|
||||
#include "findFields.H"
|
||||
|
||||
if (hasMovingMesh && optNoMesh)
|
||||
{
|
||||
Info<< "mesh is moving: ignoring '-noMesh' option" << endl;
|
||||
optNoMesh = false;
|
||||
}
|
||||
|
||||
|
||||
// map times used
|
||||
Map<scalar> timeIndices;
|
||||
|
||||
// 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>());
|
||||
}
|
||||
|
||||
|
||||
forAll(timeDirs, timeI)
|
||||
{
|
||||
runTime.setTime(timeDirs[timeI], timeI);
|
||||
|
||||
#include "getTimeIndex.H"
|
||||
|
||||
// remember the time index
|
||||
fieldTimesUsed.append(timeIndex);
|
||||
|
||||
// the data/ITER subdirectory must exist
|
||||
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"
|
||||
|
||||
if (timeI == 0 || mesh.moving())
|
||||
{
|
||||
if (mesh.moving())
|
||||
{
|
||||
partsList.recalculate(mesh);
|
||||
}
|
||||
|
||||
if (!optNoMesh)
|
||||
{
|
||||
fileName geomDir;
|
||||
if (hasMovingMesh)
|
||||
{
|
||||
geomDir = dataDir/subDir;
|
||||
}
|
||||
|
||||
ensightGeoFile geoFile(ensightDir/geomDir/geometryName, format);
|
||||
partsList.writeGeometry(geoFile);
|
||||
Info<< nl;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "write volume field (" << flush;
|
||||
|
||||
forAllConstIter(HashTable<word>, volumeFields, fieldIter)
|
||||
{
|
||||
const word& fieldName = fieldIter.key();
|
||||
const word& fieldType = fieldIter();
|
||||
|
||||
IOobject fieldObject
|
||||
(
|
||||
fieldName,
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
if (fieldType == volScalarField::typeName)
|
||||
{
|
||||
ensightVolField<scalar>
|
||||
(
|
||||
partsList,
|
||||
fieldObject,
|
||||
mesh,
|
||||
dataDir,
|
||||
subDir,
|
||||
format
|
||||
);
|
||||
|
||||
}
|
||||
else if (fieldType == volVectorField::typeName)
|
||||
{
|
||||
ensightVolField<vector>
|
||||
(
|
||||
partsList,
|
||||
fieldObject,
|
||||
mesh,
|
||||
dataDir,
|
||||
subDir,
|
||||
format
|
||||
);
|
||||
|
||||
}
|
||||
else if (fieldType == volSphericalTensorField::typeName)
|
||||
{
|
||||
ensightVolField<sphericalTensor>
|
||||
(
|
||||
partsList,
|
||||
fieldObject,
|
||||
mesh,
|
||||
dataDir,
|
||||
subDir,
|
||||
format
|
||||
);
|
||||
|
||||
}
|
||||
else if (fieldType == volSymmTensorField::typeName)
|
||||
{
|
||||
ensightVolField<symmTensor>
|
||||
(
|
||||
partsList,
|
||||
fieldObject,
|
||||
mesh,
|
||||
dataDir,
|
||||
subDir,
|
||||
format
|
||||
);
|
||||
}
|
||||
else if (fieldType == volTensorField::typeName)
|
||||
{
|
||||
ensightVolField<tensor>
|
||||
(
|
||||
partsList,
|
||||
fieldObject,
|
||||
mesh,
|
||||
dataDir,
|
||||
subDir,
|
||||
format
|
||||
);
|
||||
}
|
||||
}
|
||||
Info<< " )" << endl;
|
||||
|
||||
// check for clouds
|
||||
forAllConstIter(HashTable<HashTable<word> >, cloudFields, cloudIter)
|
||||
{
|
||||
const word& cloudName = cloudIter.key();
|
||||
|
||||
if
|
||||
(
|
||||
!isDir
|
||||
(
|
||||
runTime.timePath()/regionPrefix/
|
||||
cloud::prefix/cloudName
|
||||
)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IOobjectList cloudObjs
|
||||
(
|
||||
mesh,
|
||||
runTime.timeName(),
|
||||
cloud::prefix/cloudName
|
||||
);
|
||||
|
||||
// check that the positions field is present for this time
|
||||
IOobject* positionPtr = cloudObjs.lookup(word("positions"));
|
||||
if (positionPtr != NULL)
|
||||
{
|
||||
ensightParticlePositions
|
||||
(
|
||||
mesh,
|
||||
dataDir,
|
||||
subDir,
|
||||
cloudName,
|
||||
format
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Info<< "write " << cloudName << " (" << flush;
|
||||
|
||||
forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
|
||||
{
|
||||
const word& fieldName = fieldIter.key();
|
||||
const word& fieldType = fieldIter();
|
||||
|
||||
IOobject *fieldObject = cloudObjs.lookup(fieldName);
|
||||
|
||||
if (!fieldObject)
|
||||
{
|
||||
Info<< "missing "
|
||||
<< runTime.timeName()/cloud::prefix/cloudName
|
||||
/ fieldName
|
||||
<< endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fieldType == scalarIOField::typeName)
|
||||
{
|
||||
ensightLagrangianField<scalar>
|
||||
(
|
||||
*fieldObject,
|
||||
dataDir,
|
||||
subDir,
|
||||
cloudName,
|
||||
format
|
||||
);
|
||||
|
||||
}
|
||||
else if (fieldType == vectorIOField::typeName)
|
||||
{
|
||||
ensightLagrangianField<vector>
|
||||
(
|
||||
*fieldObject,
|
||||
dataDir,
|
||||
subDir,
|
||||
cloudName,
|
||||
format
|
||||
);
|
||||
|
||||
}
|
||||
else if (fieldType == tensorIOField::typeName)
|
||||
{
|
||||
ensightLagrangianField<tensor>
|
||||
(
|
||||
*fieldObject,
|
||||
dataDir,
|
||||
subDir,
|
||||
cloudName,
|
||||
format
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Info<< " )" << endl;
|
||||
|
||||
// remember the time index
|
||||
cloudTimesUsed[cloudName].append(timeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
#include "ensightOutputCase.H"
|
||||
|
||||
Info<< "\nEnd\n"<< endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,43 @@
|
||||
// Read time index from */uniform/time, but treat 0 and constant specially
|
||||
// or simply increment from the '-index' option if it was supplied
|
||||
|
||||
label timeIndex = 0;
|
||||
|
||||
if (optIndex)
|
||||
{
|
||||
timeIndex = indexingNumber++;
|
||||
}
|
||||
else if
|
||||
(
|
||||
runTime.timeName() != runTime.constant()
|
||||
&& runTime.timeName() != "0"
|
||||
)
|
||||
{
|
||||
IOobject io
|
||||
(
|
||||
"time",
|
||||
runTime.timeName(),
|
||||
"uniform",
|
||||
runTime,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
);
|
||||
|
||||
if (io.headerOk())
|
||||
{
|
||||
io.readOpt() = IOobject::MUST_READ_IF_MODIFIED;
|
||||
IOdictionary timeObject(io);
|
||||
|
||||
timeObject.lookup("index") >> timeIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "skip ... missing entry " << io.objectPath() << endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
timeIndices.insert(timeIndex, timeDirs[timeI].value());
|
||||
Info<< "\nTime [" << timeIndex << "] = " << runTime.timeName() << nl;
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
IOobject io
|
||||
(
|
||||
"points",
|
||||
runTime.timeName(),
|
||||
polyMesh::meshSubDir,
|
||||
mesh
|
||||
);
|
||||
|
||||
if (io.headerOk())
|
||||
{
|
||||
// Read new points
|
||||
io.readOpt() = IOobject::MUST_READ;
|
||||
mesh.movePoints(pointIOField(io));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user