mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'olesenm'
This commit is contained in:
@ -1,19 +0,0 @@
|
||||
// check for lagrangian/positions information in the final directory
|
||||
|
||||
bool hasLagrangian = false;
|
||||
if (timeDirs.size() > 1)
|
||||
{
|
||||
IOobject io
|
||||
(
|
||||
"positions",
|
||||
timeDirs[timeDirs.size() - 1].name(),
|
||||
"lagrangian",
|
||||
mesh,
|
||||
IOobject::NO_READ
|
||||
);
|
||||
|
||||
if (io.headerOk())
|
||||
{
|
||||
hasLagrangian = true;
|
||||
}
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
// check that the spray variable is present for this time
|
||||
//
|
||||
bool hasSprayField = true;
|
||||
{
|
||||
IOobject ioHeader
|
||||
(
|
||||
fieldName,
|
||||
mesh.time().timeName(),
|
||||
"lagrangian",
|
||||
mesh,
|
||||
IOobject::NO_READ
|
||||
);
|
||||
|
||||
hasSprayField = ioHeader.headerOk();
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
// check that the variable is present for all times
|
||||
//
|
||||
bool hasValidField = true;
|
||||
{
|
||||
for (label i=0; i < timeDirs.size() && hasValidField; ++i)
|
||||
{
|
||||
if (fieldName.size() > 2 && fieldName(fieldName.size() - 2, 2) == "_0")
|
||||
{
|
||||
hasValidField = false;
|
||||
break;
|
||||
}
|
||||
|
||||
IOobject ioHeader
|
||||
(
|
||||
fieldName,
|
||||
timeDirs[i].name(),
|
||||
mesh,
|
||||
IOobject::NO_READ
|
||||
);
|
||||
|
||||
hasValidField = ioHeader.headerOk();
|
||||
}
|
||||
}
|
||||
@ -1,91 +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;
|
||||
}
|
||||
|
||||
caseFile.setf(ios_base::scientific, ios_base::floatfield);
|
||||
caseFile.precision(5);
|
||||
|
||||
// time set 1 - geometry and volume fields
|
||||
if (fieldFileNumbers.size())
|
||||
{
|
||||
caseFile
|
||||
<< "time set: " << 1 << nl
|
||||
<< "number of steps: " << fieldFileNumbers.size() << nl
|
||||
<< "filename numbers:" << nl;
|
||||
|
||||
label count = 0;
|
||||
forAll (fieldFileNumbers, i)
|
||||
{
|
||||
caseFile
|
||||
<< " " << setw(12) << fieldFileNumbers[i];
|
||||
|
||||
if (++count % 6 == 0)
|
||||
{
|
||||
caseFile << nl;
|
||||
}
|
||||
}
|
||||
|
||||
caseFile
|
||||
<< nl << "time values:" << nl;
|
||||
|
||||
count = 0;
|
||||
forAll (fieldFileNumbers, i)
|
||||
{
|
||||
caseFile
|
||||
<< " " << setw(12)
|
||||
<< timeIndices[fieldFileNumbers[i]] + timeCorrection;
|
||||
|
||||
if (++count % 6 == 0)
|
||||
{
|
||||
caseFile << nl;
|
||||
}
|
||||
}
|
||||
caseFile << nl << nl;
|
||||
}
|
||||
|
||||
// time set 2 - lagrangian fields
|
||||
if (hasLagrangian && sprayFileNumbers.size())
|
||||
{
|
||||
caseFile
|
||||
<< "time set: " << 2 << nl
|
||||
<< "number of steps: " << sprayFileNumbers.size() << nl
|
||||
<< "filename numbers:" << nl;
|
||||
|
||||
label count = 0;
|
||||
forAll (sprayFileNumbers, i)
|
||||
{
|
||||
caseFile
|
||||
<< " " << setw(12) << sprayFileNumbers[i];
|
||||
|
||||
if (++count % 6 == 0)
|
||||
{
|
||||
caseFile << nl;
|
||||
}
|
||||
}
|
||||
|
||||
caseFile
|
||||
<< nl << "time values:" << nl;
|
||||
|
||||
count = 0;
|
||||
forAll (sprayFileNumbers, i)
|
||||
{
|
||||
caseFile
|
||||
<< " " << setw(12)
|
||||
<< timeIndices[sprayFileNumbers[i]] + timeCorrection;
|
||||
|
||||
if (++count % 6 == 0)
|
||||
{
|
||||
caseFile << nl;
|
||||
}
|
||||
}
|
||||
caseFile << nl << nl;
|
||||
}
|
||||
|
||||
|
||||
caseFile << "# end" << nl;
|
||||
}
|
||||
@ -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/"lagrangian"/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,
|
||||
"lagrangian"/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;
|
||||
|
||||
@ -22,7 +22,6 @@ License
|
||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
$Date: 2008/04/02 11:37:10 $
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "ensightOutputFunctions.H"
|
||||
@ -41,36 +40,51 @@ namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void ensightCaseEntry
|
||||
(
|
||||
OFstream& caseFile,
|
||||
const IOobject& fieldObject,
|
||||
const string& ensightType,
|
||||
const word& fieldName,
|
||||
const fileName& dataMask,
|
||||
bool measured
|
||||
const fileName& local,
|
||||
const label cloudNo,
|
||||
const label timeSet
|
||||
)
|
||||
{
|
||||
caseFile.setf(ios_base::left);
|
||||
|
||||
if (measured)
|
||||
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
|
||||
<< pTraits<Type>::typeName
|
||||
<< " per measured node: 2 "
|
||||
<< ensightType.c_str()
|
||||
<< " per measured node: " << ts << " "
|
||||
<< setw(15)
|
||||
<< ("s" + fieldObject.name()).c_str()
|
||||
<< ("c" + Foam::name(cloudNo) + fieldName).c_str()
|
||||
<< " "
|
||||
<< (dataMask/"lagrangian"/fieldObject.name()).c_str()
|
||||
<< (dirName/fieldName).c_str()
|
||||
<< nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
caseFile
|
||||
<< pTraits<Type>::typeName
|
||||
<< " per element: "
|
||||
<< setw(15) << fieldObject.name()
|
||||
<< ensightType.c_str()
|
||||
<< " per element: "
|
||||
<< setw(15) << fieldName
|
||||
<< " "
|
||||
<< (dataMask/fieldObject.name()).c_str()
|
||||
<< (dirName/fieldName).c_str()
|
||||
<< nl;
|
||||
}
|
||||
}
|
||||
@ -81,16 +95,17 @@ void ensightParticlePositions
|
||||
const polyMesh& mesh,
|
||||
const fileName& dataDir,
|
||||
const fileName& subDir,
|
||||
const word& cloudName,
|
||||
IOstream::streamFormat format
|
||||
)
|
||||
{
|
||||
Cloud<passiveParticle> parcels(mesh);
|
||||
Cloud<passiveParticle> parcels(mesh, cloudName, false);
|
||||
|
||||
fileName lagrangianDir = subDir/"lagrangian";
|
||||
fileName postFileName = lagrangianDir/"positions";
|
||||
fileName cloudDir = subDir/"lagrangian"/cloudName;
|
||||
fileName postFileName = cloudDir/"positions";
|
||||
|
||||
// the ITER/lagrangian subdirectory must exist
|
||||
mkDir(dataDir/lagrangianDir);
|
||||
mkDir(dataDir/cloudDir);
|
||||
ensightFile os(dataDir/postFileName, format);
|
||||
|
||||
// tag binary format (just like geometry files)
|
||||
@ -139,20 +154,22 @@ void ensightParticlePositions
|
||||
|
||||
|
||||
template<class Type>
|
||||
void ensightSprayField
|
||||
void ensightLagrangianField
|
||||
(
|
||||
const IOobject& fieldObject,
|
||||
const fileName& dataDir,
|
||||
const fileName& subDir,
|
||||
const word& cloudName,
|
||||
IOstream::streamFormat format
|
||||
)
|
||||
{
|
||||
Info<< " " << fieldObject.name() << flush;
|
||||
|
||||
fileName lagrangianDir = subDir/"lagrangian";
|
||||
fileName postFileName = lagrangianDir/fieldObject.name();
|
||||
fileName cloudDir = subDir/"lagrangian"/cloudName;
|
||||
fileName postFileName = cloudDir/fieldObject.name();
|
||||
|
||||
string title = postFileName + " with " + pTraits<Type>::typeName + " values";
|
||||
string title =
|
||||
postFileName + " with " + pTraits<Type>::typeName + " values";
|
||||
|
||||
ensightFile os(dataDir/postFileName, format);
|
||||
os.write(title);
|
||||
@ -225,9 +242,9 @@ void ensightVolField
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // end namespace Foam
|
||||
} // namespace Foam
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -44,13 +44,15 @@ namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void ensightCaseEntry
|
||||
(
|
||||
OFstream& caseFile,
|
||||
const IOobject& fieldObject,
|
||||
const string& ensightType,
|
||||
const word& fieldName,
|
||||
const fileName& dataMask,
|
||||
bool measured = false
|
||||
const fileName& local=fileName::null,
|
||||
const label cloudNo=-1,
|
||||
const label timeSet=1
|
||||
);
|
||||
|
||||
|
||||
@ -59,17 +61,19 @@ void ensightParticlePositions
|
||||
const polyMesh& mesh,
|
||||
const fileName& dataDir,
|
||||
const fileName& subDir,
|
||||
const word& cloudName,
|
||||
IOstream::streamFormat format
|
||||
);
|
||||
|
||||
|
||||
//- write spray parcels
|
||||
//- write lagrangian parcels
|
||||
template<class Type>
|
||||
void ensightSprayField
|
||||
void ensightLagrangianField
|
||||
(
|
||||
const IOobject& fieldObject,
|
||||
const fileName& dataDir,
|
||||
const fileName& subDir,
|
||||
const word& cloudName,
|
||||
IOstream::streamFormat format
|
||||
);
|
||||
|
||||
@ -87,7 +91,7 @@ void ensightVolField
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // end namespace Foam
|
||||
} // namespace Foam
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "ensightOutputFunctions.C"
|
||||
|
||||
@ -0,0 +1,88 @@
|
||||
// check the final time directory for
|
||||
|
||||
// 1. volume fields
|
||||
HashTable<word> volumeFields;
|
||||
|
||||
// 2. the fields for each cloud:
|
||||
HashTable<HashTable<word> > cloudFields;
|
||||
|
||||
if (timeDirs.size() > 1)
|
||||
{
|
||||
IOobjectList objs(mesh, timeDirs[timeDirs.size()-1].name());
|
||||
|
||||
forAllConstIter(IOobjectList, objs, fieldIter)
|
||||
{
|
||||
const IOobject& obj = *fieldIter();
|
||||
|
||||
if
|
||||
(
|
||||
obj.headerClassName() == volScalarField::typeName
|
||||
|| obj.headerClassName() == volVectorField::typeName
|
||||
)
|
||||
{
|
||||
// Add field and field type
|
||||
volumeFields.insert
|
||||
(
|
||||
obj.name(),
|
||||
obj.headerClassName()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// now check for lagrangian/<cloudName>
|
||||
|
||||
fileNameList cloudDirs = readDir
|
||||
(
|
||||
runTime.path()
|
||||
/ timeDirs[timeDirs.size() - 1].name()
|
||||
/ regionPrefix
|
||||
/ "lagrangian",
|
||||
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 in the hash table
|
||||
HashTable<HashTable<word> >::iterator cloudIter =
|
||||
cloudFields.find(cloudName);
|
||||
|
||||
IOobjectList cloudObjs
|
||||
(
|
||||
mesh,
|
||||
timeDirs[timeDirs.size() - 1].name(),
|
||||
"lagrangian"/cloudName
|
||||
);
|
||||
|
||||
bool hasPositions = false;
|
||||
forAllConstIter(IOobjectList, cloudObjs, fieldIter)
|
||||
{
|
||||
const IOobject obj = *fieldIter();
|
||||
|
||||
if (obj.name() == "positions")
|
||||
{
|
||||
hasPositions = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add field and field type
|
||||
cloudIter().insert
|
||||
(
|
||||
obj.name(),
|
||||
obj.headerClassName()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// drop this cloud if it has no positions
|
||||
if (!hasPositions)
|
||||
{
|
||||
cloudFields.erase(cloudIter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,20 +71,26 @@ int main(int argc, char *argv[])
|
||||
argList::noParallel();
|
||||
argList::validOptions.insert("ascii", "");
|
||||
|
||||
const label nTypes = 2;
|
||||
const word fieldTypes[] =
|
||||
const word volFieldTypes[] =
|
||||
{
|
||||
volScalarField::typeName,
|
||||
volVectorField::typeName
|
||||
volVectorField::typeName,
|
||||
volSphericalTensorField::typeName,
|
||||
volSymmTensorField::typeName,
|
||||
volTensorField::typeName,
|
||||
word::null
|
||||
};
|
||||
|
||||
const label nSprayFieldTypes = 2;
|
||||
const word sprayFieldTypes[] =
|
||||
{
|
||||
scalarIOField::typeName,
|
||||
vectorIOField::typeName
|
||||
vectorIOField::typeName,
|
||||
tensorIOField::typeName,
|
||||
word::null
|
||||
};
|
||||
|
||||
const char* geometryName = "geometry";
|
||||
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
|
||||
@ -104,14 +110,26 @@ int main(int argc, char *argv[])
|
||||
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 (dir(ensightDir))
|
||||
{
|
||||
rmDir(ensightDir);
|
||||
Info<<"Warning: reusing existing directory" << nl
|
||||
<< " " << ensightDir << endl;
|
||||
}
|
||||
mkDir(ensightDir);
|
||||
mkDir(dataDir);
|
||||
|
||||
# include "createMesh.H"
|
||||
# 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);
|
||||
|
||||
@ -125,53 +143,24 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
# include "checkHasMovingMesh.H"
|
||||
# include "checkHasLagrangian.H"
|
||||
# include "findFields.H"
|
||||
# include "validateFields.H"
|
||||
|
||||
// only take the objects that exists at the end of the calculation
|
||||
IOobjectList objects(mesh, timeDirs[timeDirs.size()-1].name());
|
||||
IOobjectList sprayObjects(mesh, timeDirs[timeDirs.size()-1].name(), "lagrangian");
|
||||
|
||||
// write single geometry or one per time step
|
||||
fileName geometryFileName("geometry");
|
||||
if (hasMovingMesh)
|
||||
{
|
||||
geometryFileName = dataMask/geometryFileName;
|
||||
}
|
||||
|
||||
// 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
|
||||
<< "FORMAT" << nl
|
||||
<< setw(16) << "type:" << "ensight gold" << nl << nl
|
||||
<< "GEOMETRY" << nl
|
||||
<< setw(16) << "model: 1" << geometryFileName.c_str() << nl;
|
||||
|
||||
if (hasLagrangian)
|
||||
{
|
||||
caseFile
|
||||
<< setw(16) << "measured: 2"
|
||||
<< fileName(dataMask/"lagrangian"/"positions").c_str() << nl;
|
||||
}
|
||||
caseFile
|
||||
<< nl << "VARIABLE" << nl;
|
||||
|
||||
label nFieldTime = timeDirs.size();
|
||||
if (nFieldTime < 0)
|
||||
{
|
||||
nFieldTime = 0;
|
||||
}
|
||||
|
||||
List<label> fieldFileNumbers(nFieldTime);
|
||||
List<label> sprayFileNumbers(nFieldTime);
|
||||
|
||||
// map used times used
|
||||
// map times used
|
||||
Map<scalar> timeIndices;
|
||||
|
||||
nFieldTime = 0;
|
||||
label nSprayTime = 0;
|
||||
// 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)
|
||||
{
|
||||
@ -179,7 +168,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
# include "getTimeIndex.H"
|
||||
|
||||
fieldFileNumbers[nFieldTime++] = timeIndex;
|
||||
// remember the time index
|
||||
fieldTimesUsed.append(timeIndex);
|
||||
|
||||
// the data/ITER subdirectory must exist
|
||||
fileName subDir = ensightFile::subDir(timeIndex);
|
||||
@ -195,300 +185,203 @@ int main(int argc, char *argv[])
|
||||
|
||||
# include "moveMesh.H"
|
||||
|
||||
if (nFieldTime == 1 || mesh.moving())
|
||||
if (timeI == 0 || mesh.moving())
|
||||
{
|
||||
if (hasMovingMesh)
|
||||
{
|
||||
geometryFileName = dataDir/subDir/"geometry";
|
||||
}
|
||||
if (mesh.moving())
|
||||
{
|
||||
partsList.recalculate(mesh);
|
||||
}
|
||||
|
||||
ensightGeoFile geoFile(ensightDir/geometryFileName, format);
|
||||
fileName geomDir;
|
||||
if (hasMovingMesh)
|
||||
{
|
||||
geomDir = dataDir/subDir;
|
||||
}
|
||||
|
||||
ensightGeoFile geoFile(ensightDir/geomDir/geometryName, format);
|
||||
partsList.writeGeometry(geoFile);
|
||||
Info << nl;
|
||||
}
|
||||
|
||||
Info<< "write volume field: " << flush;
|
||||
Info<< "write volume field (" << flush;
|
||||
|
||||
for (label i=0; i < nTypes; i++)
|
||||
forAllConstIter(HashTable<word>, volumeFields, fieldIter)
|
||||
{
|
||||
wordList fieldNames = objects.names(fieldTypes[i]);
|
||||
const word& fieldName = fieldIter.key();
|
||||
const word& fieldType = fieldIter();
|
||||
|
||||
forAll (fieldNames, fieldI)
|
||||
IOobject fieldObject
|
||||
(
|
||||
fieldName,
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
if (fieldType == volScalarField::typeName)
|
||||
{
|
||||
word fieldName = fieldNames[fieldI];
|
||||
ensightVolField<scalar>
|
||||
(
|
||||
partsList,
|
||||
fieldObject,
|
||||
mesh,
|
||||
dataDir,
|
||||
subDir,
|
||||
format
|
||||
);
|
||||
|
||||
# include "checkHasValidField.H"
|
||||
}
|
||||
else if (fieldType == volVectorField::typeName)
|
||||
{
|
||||
ensightVolField<vector>
|
||||
(
|
||||
partsList,
|
||||
fieldObject,
|
||||
mesh,
|
||||
dataDir,
|
||||
subDir,
|
||||
format
|
||||
);
|
||||
|
||||
if (!hasValidField)
|
||||
}
|
||||
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 (!dir(runTime.timePath()/regionPrefix/"lagrangian"/cloudName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IOobjectList cloudObjs
|
||||
(
|
||||
mesh,
|
||||
runTime.timeName(),
|
||||
"lagrangian"/cloudName
|
||||
);
|
||||
|
||||
// check that the positions field is present for this time
|
||||
if (cloudObjs.lookup("positions"))
|
||||
{
|
||||
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()/"lagrangian"/cloudName/fieldName
|
||||
<< endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
IOobject fieldObject
|
||||
(
|
||||
fieldName,
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
if (fieldTypes[i] == volScalarField::typeName)
|
||||
if (fieldType == scalarIOField::typeName)
|
||||
{
|
||||
if (nFieldTime == 1)
|
||||
{
|
||||
ensightCaseEntry<scalar>
|
||||
(
|
||||
caseFile,
|
||||
fieldObject,
|
||||
dataMask
|
||||
);
|
||||
}
|
||||
|
||||
ensightVolField<scalar>
|
||||
ensightLagrangianField<scalar>
|
||||
(
|
||||
partsList,
|
||||
fieldObject,
|
||||
mesh,
|
||||
*fieldObject,
|
||||
dataDir,
|
||||
subDir,
|
||||
cloudName,
|
||||
format
|
||||
);
|
||||
|
||||
}
|
||||
else if (fieldTypes[i] == volVectorField::typeName)
|
||||
else if (fieldType == vectorIOField::typeName)
|
||||
{
|
||||
if (nFieldTime == 1)
|
||||
{
|
||||
ensightCaseEntry<vector>
|
||||
(
|
||||
caseFile,
|
||||
fieldObject,
|
||||
dataMask
|
||||
);
|
||||
}
|
||||
|
||||
ensightVolField<vector>
|
||||
ensightLagrangianField<vector>
|
||||
(
|
||||
partsList,
|
||||
fieldObject,
|
||||
mesh,
|
||||
*fieldObject,
|
||||
dataDir,
|
||||
subDir,
|
||||
cloudName,
|
||||
format
|
||||
);
|
||||
|
||||
}
|
||||
else if (fieldTypes[i] == volSphericalTensorField::typeName)
|
||||
else if (fieldType == tensorIOField::typeName)
|
||||
{
|
||||
if (nFieldTime == 1)
|
||||
{
|
||||
ensightCaseEntry<sphericalTensor>
|
||||
(
|
||||
caseFile,
|
||||
fieldObject,
|
||||
dataMask
|
||||
);
|
||||
}
|
||||
|
||||
ensightVolField<sphericalTensor>
|
||||
ensightLagrangianField<tensor>
|
||||
(
|
||||
partsList,
|
||||
fieldObject,
|
||||
mesh,
|
||||
dataDir,
|
||||
subDir,
|
||||
format
|
||||
);
|
||||
|
||||
}
|
||||
else if (fieldTypes[i] == volSymmTensorField::typeName)
|
||||
{
|
||||
if (nFieldTime == 1)
|
||||
{
|
||||
ensightCaseEntry<symmTensor>
|
||||
(
|
||||
caseFile,
|
||||
fieldObject,
|
||||
dataMask
|
||||
);
|
||||
}
|
||||
|
||||
ensightVolField<symmTensor>
|
||||
(
|
||||
partsList,
|
||||
fieldObject,
|
||||
mesh,
|
||||
dataDir,
|
||||
subDir,
|
||||
format
|
||||
);
|
||||
|
||||
}
|
||||
else if (fieldTypes[i] == volTensorField::typeName)
|
||||
{
|
||||
if (nFieldTime == 1)
|
||||
{
|
||||
ensightCaseEntry<tensor>
|
||||
(
|
||||
caseFile,
|
||||
fieldObject,
|
||||
dataMask
|
||||
);
|
||||
}
|
||||
|
||||
ensightVolField<tensor>
|
||||
(
|
||||
partsList,
|
||||
fieldObject,
|
||||
mesh,
|
||||
*fieldObject,
|
||||
dataDir,
|
||||
subDir,
|
||||
cloudName,
|
||||
format
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Info<< endl;
|
||||
|
||||
Info<< " )" << endl;
|
||||
|
||||
if (hasLagrangian)
|
||||
{
|
||||
// check that the positions field is present for this time
|
||||
{
|
||||
IOobject ioHeader
|
||||
(
|
||||
"positions",
|
||||
mesh.time().timeName(),
|
||||
"lagrangian",
|
||||
mesh,
|
||||
IOobject::NO_READ
|
||||
);
|
||||
|
||||
if (ioHeader.headerOk())
|
||||
{
|
||||
sprayFileNumbers[nSprayTime++] = timeIndex;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "write spray field: " << flush;
|
||||
|
||||
ensightParticlePositions
|
||||
(
|
||||
mesh,
|
||||
dataDir,
|
||||
subDir,
|
||||
format
|
||||
);
|
||||
|
||||
for (label i=0; i < nSprayFieldTypes; i++)
|
||||
{
|
||||
wordList fieldNames = sprayObjects.names(sprayFieldTypes[i]);
|
||||
|
||||
forAll (fieldNames, fieldI)
|
||||
{
|
||||
word fieldName = fieldNames[fieldI];
|
||||
|
||||
# include "checkHasSprayField.H"
|
||||
|
||||
if (!hasSprayField)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IOobject fieldObject
|
||||
(
|
||||
fieldName,
|
||||
mesh.time().timeName(),
|
||||
"lagrangian",
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
if (sprayFieldTypes[i] == scalarIOField::typeName)
|
||||
{
|
||||
if (nSprayTime == 1)
|
||||
{
|
||||
ensightCaseEntry<scalar>
|
||||
(
|
||||
caseFile,
|
||||
fieldObject,
|
||||
dataMask,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
ensightSprayField<scalar>
|
||||
(
|
||||
fieldObject,
|
||||
dataDir,
|
||||
subDir,
|
||||
format
|
||||
);
|
||||
|
||||
}
|
||||
else if (sprayFieldTypes[i] == vectorIOField::typeName)
|
||||
{
|
||||
if (nSprayTime == 1)
|
||||
{
|
||||
ensightCaseEntry<vector>
|
||||
(
|
||||
caseFile,
|
||||
fieldObject,
|
||||
dataMask,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
ensightSprayField<vector>
|
||||
(
|
||||
fieldObject,
|
||||
dataDir,
|
||||
subDir,
|
||||
format
|
||||
);
|
||||
|
||||
}
|
||||
else if (sprayFieldTypes[i] == tensorIOField::typeName)
|
||||
{
|
||||
if (nSprayTime == 1)
|
||||
{
|
||||
ensightCaseEntry<tensor>
|
||||
(
|
||||
caseFile,
|
||||
fieldObject,
|
||||
dataMask,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
ensightSprayField<tensor>
|
||||
(
|
||||
fieldObject,
|
||||
dataDir,
|
||||
subDir,
|
||||
format
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Info<< endl;
|
||||
// remember the time index
|
||||
cloudTimesUsed[cloudName].append(timeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
fieldFileNumbers.setSize(nFieldTime);
|
||||
sprayFileNumbers.setSize(nSprayTime);
|
||||
|
||||
// add time values
|
||||
caseFile << nl << "TIME" << nl;
|
||||
# include "ensightCaseTimes.H"
|
||||
# include "ensightOutputCase.H"
|
||||
|
||||
Info<< "\nEnd\n"<< endl;
|
||||
|
||||
|
||||
@ -0,0 +1,104 @@
|
||||
// ignore special fields or fields that we don't handle
|
||||
//
|
||||
forAllIter(HashTable<word>, volumeFields, fieldIter)
|
||||
{
|
||||
const word& fieldName = fieldIter.key();
|
||||
const word& fieldType = fieldIter();
|
||||
|
||||
if (fieldName.size() > 2 && fieldName(fieldName.size() - 2, 2) != "_0")
|
||||
{
|
||||
volumeFields.erase(fieldIter);
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove types that we don't handle:
|
||||
bool invalid = true;
|
||||
for (label typeI=0; invalid && volFieldTypes[typeI].size(); ++typeI)
|
||||
{
|
||||
if (fieldType == volFieldTypes[typeI])
|
||||
{
|
||||
invalid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (invalid)
|
||||
{
|
||||
Info<< "ignoring " << fieldType << ": " << fieldName << endl;
|
||||
volumeFields.erase(fieldIter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ignore fields that we don't handle
|
||||
//
|
||||
forAllIter(HashTable<HashTable<word> >, cloudFields, cloudIter)
|
||||
{
|
||||
const word& cloudName = cloudIter.key();
|
||||
|
||||
forAllIter(HashTable<word>, cloudIter(), fieldIter)
|
||||
{
|
||||
const word& fieldName = fieldIter.key();
|
||||
const word& fieldType = fieldIter();
|
||||
|
||||
// remove types that we don't handle:
|
||||
bool invalid = true;
|
||||
for (label typeI=0; invalid && sprayFieldTypes[typeI].size(); ++typeI)
|
||||
{
|
||||
if (fieldType == sprayFieldTypes[typeI])
|
||||
{
|
||||
invalid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (invalid)
|
||||
{
|
||||
Info<< "ignoring " << fieldType << ": " << fieldName << endl;
|
||||
cloudIter().erase(fieldIter);
|
||||
}
|
||||
}
|
||||
|
||||
if (!cloudIter().size())
|
||||
{
|
||||
Info<< "removing cloud " << cloudName<< endl;
|
||||
cloudFields.erase(cloudIter);
|
||||
}
|
||||
}
|
||||
|
||||
// DEBUGGING
|
||||
// Info<<"final fields (";
|
||||
// forAllConstIter(HashTable<word>, volumeFields, fieldIter)
|
||||
// {
|
||||
// Info<< " " << fieldIter.key();
|
||||
// }
|
||||
//
|
||||
// Info<< " )\n";
|
||||
//
|
||||
// forAllConstIter(HashTable<HashTable<word> >, cloudFields, cloudIter)
|
||||
// {
|
||||
// Info<<"final fields for lagrangian/" << cloudIter.key() << " (";
|
||||
// forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
|
||||
// {
|
||||
// Info<< " " << fieldIter.key();
|
||||
// }
|
||||
// Info<< " )\n";
|
||||
// }
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#!/bin/sh
|
||||
cd ${0%/*} || exit 1 # run from this directory
|
||||
set -x
|
||||
|
||||
rm -rf PV3FoamReader/Make
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#!/bin/sh
|
||||
cd ${0%/*} || exit 1 # run from this directory
|
||||
set -x
|
||||
|
||||
if [ -d "$ParaView_DIR" -a -r "$ParaView_DIR" ]
|
||||
|
||||
@ -27,13 +27,6 @@
|
||||
</Documentation>
|
||||
</DoubleVectorProperty>
|
||||
|
||||
<!-- Send continuous time info to the animation panel -->
|
||||
<DoubleVectorProperty
|
||||
name="TimeRange"
|
||||
information_only="1">
|
||||
<TimeRangeInformationHelper/>
|
||||
</DoubleVectorProperty>
|
||||
|
||||
<!-- Available Parts (volume, patches, lagrangian) array -->
|
||||
<StringVectorProperty
|
||||
name="PartArrayInfo"
|
||||
|
||||
@ -112,10 +112,7 @@ vtkPV3FoamReader::~vtkPV3FoamReader()
|
||||
{
|
||||
vtkDebugMacro(<<"Deconstructor");
|
||||
|
||||
if (foamData_)
|
||||
{
|
||||
delete foamData_;
|
||||
}
|
||||
delete foamData_;
|
||||
|
||||
if (FileName)
|
||||
{
|
||||
@ -186,6 +183,15 @@ int vtkPV3FoamReader::RequestInformation
|
||||
int nTimeSteps = 0;
|
||||
double* timeSteps = foamData_->findTimes(nTimeSteps);
|
||||
|
||||
if (!nTimeSteps)
|
||||
{
|
||||
vtkErrorMacro("could not find valid OpenFOAM mesh");
|
||||
|
||||
// delete foamData and flag it as fatal error
|
||||
delete foamData_;
|
||||
foamData_ = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set identical time steps for all ports
|
||||
for (int infoI = 0; infoI < nInfo; ++infoI)
|
||||
@ -249,6 +255,13 @@ int vtkPV3FoamReader::RequestData
|
||||
return 0;
|
||||
}
|
||||
|
||||
// catch previous error
|
||||
if (!foamData_)
|
||||
{
|
||||
vtkErrorMacro("Reader failed - perhaps no mesh?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nInfo = outputVector->GetNumberOfInformationObjects();
|
||||
|
||||
if (Foam::vtkPV3Foam::debug)
|
||||
@ -263,6 +276,7 @@ int vtkPV3FoamReader::RequestData
|
||||
// take port0 as the lead for other outputs
|
||||
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
||||
|
||||
|
||||
vtkMultiBlockDataSet* output = vtkMultiBlockDataSet::SafeDownCast
|
||||
(
|
||||
outInfo->Get
|
||||
|
||||
@ -103,10 +103,8 @@ int Foam::vtkPV3Foam::setTime(const double& requestedTime)
|
||||
// Get times list
|
||||
instantList Times = runTime.times();
|
||||
|
||||
int foundIndex = Time::findClosestTimeIndex(Times, requestedTime);
|
||||
int nearestIndex = foundIndex;
|
||||
|
||||
if (foundIndex < 0)
|
||||
int nearestIndex = Time::findClosestTimeIndex(Times, requestedTime);
|
||||
if (nearestIndex < 0)
|
||||
{
|
||||
nearestIndex = 0;
|
||||
}
|
||||
@ -146,7 +144,7 @@ int Foam::vtkPV3Foam::setTime(const double& requestedTime)
|
||||
<< " fieldsChanged=" << fieldsChanged_ << endl;
|
||||
}
|
||||
|
||||
return foundIndex;
|
||||
return nearestIndex;
|
||||
}
|
||||
|
||||
|
||||
@ -206,7 +204,8 @@ Foam::vtkPV3Foam::vtkPV3Foam
|
||||
reader_(reader),
|
||||
dbPtr_(NULL),
|
||||
meshPtr_(NULL),
|
||||
nMesh_(0),
|
||||
meshRegion_(polyMesh::defaultRegion),
|
||||
meshDir_(polyMesh::meshSubDir),
|
||||
timeIndex_(-1),
|
||||
meshChanged_(true),
|
||||
fieldsChanged_(true),
|
||||
@ -248,10 +247,38 @@ Foam::vtkPV3Foam::vtkPV3Foam
|
||||
setEnv("FOAM_CASE", fullCasePath, true);
|
||||
}
|
||||
|
||||
// look for 'case{region}.OpenFOAM'
|
||||
// could be stringent and insist the prefix match the directory name...
|
||||
// Note: cannot use fileName::name() due to the embedded '{}'
|
||||
string caseName(fileName(FileName).lessExt());
|
||||
string::size_type beg = caseName.find_last_of("/{");
|
||||
string::size_type end = caseName.find('}', beg);
|
||||
|
||||
if
|
||||
(
|
||||
beg != string::npos && caseName[beg] == '{'
|
||||
&& end != string::npos && end == caseName.size()-1
|
||||
)
|
||||
{
|
||||
meshRegion_ = caseName.substr(beg+1, end-beg-1);
|
||||
|
||||
// some safety
|
||||
if (!meshRegion_.size())
|
||||
{
|
||||
meshRegion_ = polyMesh::defaultRegion;
|
||||
}
|
||||
|
||||
if (meshRegion_ != polyMesh::defaultRegion)
|
||||
{
|
||||
meshDir_ = meshRegion_/polyMesh::meshSubDir;
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "fullCasePath=" << fullCasePath << nl
|
||||
<< "FOAM_CASE=" << getEnv("FOAM_CASE") << endl;
|
||||
<< "FOAM_CASE=" << getEnv("FOAM_CASE") << nl
|
||||
<< "region=" << meshRegion_ << endl;
|
||||
}
|
||||
|
||||
// Create time object
|
||||
@ -368,15 +395,20 @@ void Foam::vtkPV3Foam::updateFoamMesh()
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Creating Foam mesh" << endl;
|
||||
Info<< "Creating Foam mesh for region " << meshRegion_
|
||||
<< " at time=" << dbPtr_().timeName()
|
||||
<< endl;
|
||||
|
||||
}
|
||||
|
||||
meshPtr_ = new fvMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fvMesh::defaultRegion,
|
||||
meshRegion_,
|
||||
dbPtr_().timeName(),
|
||||
dbPtr_()
|
||||
dbPtr_(),
|
||||
IOobject::MUST_READ
|
||||
)
|
||||
);
|
||||
|
||||
@ -478,11 +510,26 @@ double* Foam::vtkPV3Foam::findTimes(int& nTimeSteps)
|
||||
Time& runTime = dbPtr_();
|
||||
instantList timeLst = runTime.times();
|
||||
|
||||
// always skip "constant" time, unless there are no other times
|
||||
nTimes = timeLst.size();
|
||||
// find the first time for which this mesh appears to exist
|
||||
label timeI = 0;
|
||||
for (; timeI < timeLst.size(); ++timeI)
|
||||
{
|
||||
const word& timeName = timeLst[timeI].name();
|
||||
|
||||
if (nTimes > 1)
|
||||
if
|
||||
(
|
||||
file(runTime.path()/timeName/meshDir_/"points")
|
||||
&& IOobject("points", timeName, meshDir_, runTime).headerOk()
|
||||
)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nTimes = timeLst.size() - timeI;
|
||||
|
||||
// always skip "constant" time if possible
|
||||
if (timeI == 0 && nTimes > 1)
|
||||
{
|
||||
timeI = 1;
|
||||
--nTimes;
|
||||
@ -699,7 +746,6 @@ void Foam::vtkPV3Foam::removePatchNames(vtkRenderer* renderer)
|
||||
|
||||
void Foam::vtkPV3Foam::PrintSelf(ostream& os, vtkIndent indent) const
|
||||
{
|
||||
os << indent << "Number of meshes: " << nMesh_ << "\n";
|
||||
os << indent << "Number of nodes: "
|
||||
<< (meshPtr_ ? meshPtr_->nPoints() : 0) << "\n";
|
||||
|
||||
@ -708,6 +754,8 @@ void Foam::vtkPV3Foam::PrintSelf(ostream& os, vtkIndent indent) const
|
||||
|
||||
os << indent << "Number of available time steps: "
|
||||
<< (dbPtr_.valid() ? dbPtr_().times().size() : 0) << endl;
|
||||
|
||||
os << indent << "mesh region: " << meshRegion_ << "\n";
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -92,11 +92,8 @@ class polyPatch;
|
||||
class faceSet;
|
||||
class pointSet;
|
||||
|
||||
template<class Type>
|
||||
class IOField;
|
||||
|
||||
template<class Type>
|
||||
class List;
|
||||
template<class Type> class IOField;
|
||||
template<class Type> class List;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class vtkPV3Foam Declaration
|
||||
@ -248,9 +245,11 @@ class vtkPV3Foam
|
||||
//- Foam mesh
|
||||
fvMesh* meshPtr_;
|
||||
|
||||
//- Number of meshes
|
||||
// TODO - for info only - only set up to process ONE mesh
|
||||
int nMesh_;
|
||||
//- The mesh region
|
||||
word meshRegion_;
|
||||
|
||||
//- The mesh directory for the region
|
||||
fileName meshDir_;
|
||||
|
||||
//- The time index
|
||||
int timeIndex_;
|
||||
@ -716,6 +715,7 @@ public:
|
||||
return timeIndex_;
|
||||
}
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
//- Debug information
|
||||
|
||||
@ -72,6 +72,8 @@ void Foam::vtkPV3Foam::convertVolFields
|
||||
vtkMultiBlockDataSet* output
|
||||
)
|
||||
{
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
wordHashSet selectedFields = getSelected
|
||||
(
|
||||
reader_->GetVolFieldSelection()
|
||||
@ -82,8 +84,8 @@ void Foam::vtkPV3Foam::convertVolFields
|
||||
return;
|
||||
}
|
||||
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
// Get objects (fields) for this time - only keep selected fields
|
||||
// the region name is already in the mesh db
|
||||
IOobjectList objects(mesh, dbPtr_().timeName());
|
||||
pruneObjectList(objects, selectedFields);
|
||||
|
||||
@ -158,6 +160,8 @@ void Foam::vtkPV3Foam::convertPointFields
|
||||
vtkMultiBlockDataSet* output
|
||||
)
|
||||
{
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
wordHashSet selectedFields = getSelected
|
||||
(
|
||||
reader_->GetPointFieldSelection()
|
||||
@ -168,8 +172,8 @@ void Foam::vtkPV3Foam::convertPointFields
|
||||
return;
|
||||
}
|
||||
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
// Get objects (fields) for this time - only keep selected fields
|
||||
// the region name is already in the mesh db
|
||||
IOobjectList objects(mesh, dbPtr_().timeName());
|
||||
pruneObjectList(objects, selectedFields);
|
||||
|
||||
@ -257,8 +261,10 @@ void Foam::vtkPV3Foam::convertLagrangianFields
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Get the Lagrangian fields for this time and this cloud
|
||||
// but only keep selected fields
|
||||
// the region name is already in the mesh db
|
||||
IOobjectList objects
|
||||
(
|
||||
mesh,
|
||||
|
||||
@ -64,7 +64,7 @@ void Foam::vtkPV3Foam::convertMeshVolume
|
||||
}
|
||||
|
||||
// Convert the internalMesh
|
||||
// TODO: multiple mesh regions
|
||||
// this looks like more than one part, but it isn't
|
||||
for (int partId = selector.start(); partId < selector.end(); ++partId)
|
||||
{
|
||||
const word partName = "internalMesh";
|
||||
@ -239,7 +239,6 @@ void Foam::vtkPV3Foam::convertMeshCellZones
|
||||
}
|
||||
|
||||
const cellZoneMesh& zMesh = mesh.cellZones();
|
||||
|
||||
for (int partId = selector.start(); partId < selector.end(); ++partId)
|
||||
{
|
||||
const word zoneName = getPartName(partId);
|
||||
@ -408,7 +407,6 @@ void Foam::vtkPV3Foam::convertMeshFaceZones
|
||||
}
|
||||
|
||||
const faceZoneMesh& zMesh = mesh.faceZones();
|
||||
|
||||
for (int partId = selector.start(); partId < selector.end(); ++partId)
|
||||
{
|
||||
const word zoneName = getPartName(partId);
|
||||
@ -515,6 +513,7 @@ void Foam::vtkPV3Foam::convertMeshPointZones
|
||||
partInfo& selector = partInfoPointZones_;
|
||||
selector.block(blockNo); // set output block
|
||||
label datasetNo = 0; // restart at dataset 0
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -522,12 +521,9 @@ void Foam::vtkPV3Foam::convertMeshPointZones
|
||||
printMemory();
|
||||
}
|
||||
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
if (selector.size())
|
||||
{
|
||||
const pointZoneMesh& zMesh = mesh.pointZones();
|
||||
|
||||
for (int partId = selector.start(); partId < selector.end(); ++partId)
|
||||
{
|
||||
word zoneName = getPartName(partId);
|
||||
|
||||
@ -36,6 +36,7 @@ Description
|
||||
#include "vtkPV3FoamPoints.H"
|
||||
|
||||
// VTK includes
|
||||
#include "vtkCellArray.h"
|
||||
#include "vtkPoints.h"
|
||||
#include "vtkPolyData.h"
|
||||
|
||||
@ -56,6 +57,8 @@ vtkPolyData* Foam::vtkPV3Foam::lagrangianVTKMesh
|
||||
printMemory();
|
||||
}
|
||||
|
||||
|
||||
// the region name is already in the mesh db
|
||||
IOobjectList sprayObjs
|
||||
(
|
||||
mesh,
|
||||
@ -75,15 +78,25 @@ vtkPolyData* Foam::vtkPV3Foam::lagrangianVTKMesh
|
||||
|
||||
vtkmesh = vtkPolyData::New();
|
||||
vtkPoints* vtkpoints = vtkPoints::New();
|
||||
vtkpoints->Allocate( parcels.size() );
|
||||
vtkCellArray* vtkcells = vtkCellArray::New();
|
||||
|
||||
vtkpoints->Allocate( parcels.size() );
|
||||
vtkcells->Allocate( parcels.size() );
|
||||
|
||||
vtkIdType particleId = 0;
|
||||
forAllConstIter(Cloud<passiveParticle>, parcels, iter)
|
||||
{
|
||||
vtkPV3FoamInsertNextPoint(vtkpoints, iter().position());
|
||||
|
||||
vtkcells->InsertNextCell(1, &particleId);
|
||||
particleId++;
|
||||
}
|
||||
|
||||
vtkmesh->SetPoints(vtkpoints);
|
||||
vtkpoints->Delete();
|
||||
|
||||
vtkmesh->SetVerts(vtkcells);
|
||||
vtkcells->Delete();
|
||||
}
|
||||
|
||||
if (debug)
|
||||
|
||||
@ -35,8 +35,8 @@ Description
|
||||
|
||||
// VTK includes
|
||||
#include "vtkCellArray.h"
|
||||
#include "vtkPoints.h"
|
||||
#include "vtkPolyData.h"
|
||||
#include "vtkUnstructuredGrid.h"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -91,11 +91,11 @@ Foam::wordList Foam::vtkPV3Foam::readZoneNames(const word& zoneType)
|
||||
zoneType,
|
||||
dbPtr_().findInstance
|
||||
(
|
||||
polyMesh::meshSubDir,
|
||||
meshDir_,
|
||||
zoneType,
|
||||
IOobject::READ_IF_PRESENT
|
||||
),
|
||||
polyMesh::meshSubDir,
|
||||
meshDir_,
|
||||
dbPtr_(),
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
@ -126,10 +126,6 @@ void Foam::vtkPV3Foam::updateInfoInternalMesh()
|
||||
|
||||
vtkDataArraySelection* partSelection = reader_->GetPartSelection();
|
||||
|
||||
// Determine number of meshes available
|
||||
HashTable<const fvMesh*> meshObjects = dbPtr_().lookupClass<const fvMesh>();
|
||||
nMesh_ = meshObjects.size();
|
||||
|
||||
// Determine mesh parts (internalMesh, patches...)
|
||||
//- Add internal mesh as first entry
|
||||
partInfoVolume_ = partSelection->GetNumberOfArrays();
|
||||
@ -155,10 +151,19 @@ void Foam::vtkPV3Foam::updateInfoLagrangian()
|
||||
<< " " << dbPtr_->timePath()/"lagrangian" << endl;
|
||||
}
|
||||
|
||||
|
||||
// use the db directly since this might be called without a mesh,
|
||||
// but the region must get added back in
|
||||
fileName lagrangianPrefix("lagrangian");
|
||||
if (meshRegion_ != polyMesh::defaultRegion)
|
||||
{
|
||||
lagrangianPrefix = meshRegion_/"lagrangian";
|
||||
}
|
||||
|
||||
// Search for list of lagrangian objects for this time
|
||||
fileNameList cloudDirs
|
||||
(
|
||||
readDir(dbPtr_->timePath()/"lagrangian", fileName::DIRECTORY)
|
||||
readDir(dbPtr_->timePath()/lagrangianPrefix, fileName::DIRECTORY)
|
||||
);
|
||||
|
||||
vtkDataArraySelection* partSelection = reader_->GetPartSelection();
|
||||
@ -221,43 +226,50 @@ void Foam::vtkPV3Foam::updateInfoPatches()
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read patches
|
||||
polyBoundaryMeshEntries patchEntries
|
||||
// mesh not loaded - read from file
|
||||
// but this could fail if we've supplied a bad region name
|
||||
IOobject ioObj
|
||||
(
|
||||
IOobject
|
||||
"boundary",
|
||||
dbPtr_().findInstance
|
||||
(
|
||||
meshDir_,
|
||||
"boundary",
|
||||
dbPtr_().findInstance(polyMesh::meshSubDir, "boundary"),
|
||||
polyMesh::meshSubDir,
|
||||
dbPtr_(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
IOobject::READ_IF_PRESENT
|
||||
),
|
||||
meshDir_,
|
||||
dbPtr_(),
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
);
|
||||
|
||||
// Add (non-zero) patches to the list of mesh parts
|
||||
forAll(patchEntries, entryI)
|
||||
// this should only ever fail if the mesh region doesn't exist
|
||||
if (ioObj.headerOk())
|
||||
{
|
||||
label nFaces
|
||||
(
|
||||
readLabel(patchEntries[entryI].dict().lookup("nFaces"))
|
||||
);
|
||||
polyBoundaryMeshEntries patchEntries(ioObj);
|
||||
|
||||
// Valid patch if nFace > 0
|
||||
if (nFaces)
|
||||
// Add (non-zero) patches to the list of mesh parts
|
||||
forAll(patchEntries, entryI)
|
||||
{
|
||||
// Add patch to GUI list
|
||||
partSelection->AddArray
|
||||
label nFaces
|
||||
(
|
||||
(patchEntries[entryI].keyword() + " - patch").c_str()
|
||||
readLabel(patchEntries[entryI].dict().lookup("nFaces"))
|
||||
);
|
||||
|
||||
++nPatches;
|
||||
// Valid patch if nFace > 0 - add patch to GUI list
|
||||
if (nFaces)
|
||||
{
|
||||
partSelection->AddArray
|
||||
(
|
||||
(patchEntries[entryI].keyword() + " - patch").c_str()
|
||||
);
|
||||
|
||||
++nPatches;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
partInfoPatches_ += nPatches;
|
||||
|
||||
if (debug)
|
||||
@ -380,8 +392,8 @@ void Foam::vtkPV3Foam::updateInfoSets()
|
||||
IOobjectList objects
|
||||
(
|
||||
dbPtr_(),
|
||||
dbPtr_().findInstance(polyMesh::meshSubDir, "faces"),
|
||||
polyMesh::meshSubDir/"sets"
|
||||
dbPtr_().findInstance(meshDir_, "faces", IOobject::READ_IF_PRESENT),
|
||||
meshDir_/"sets"
|
||||
);
|
||||
|
||||
|
||||
@ -449,11 +461,19 @@ void Foam::vtkPV3Foam::updateInfoLagrangianFields()
|
||||
|
||||
word cloudName = getPartName(partId);
|
||||
|
||||
// use the db directly since this might be called without a mesh,
|
||||
// but the region must get added back in
|
||||
fileName lagrangianPrefix("lagrangian");
|
||||
if (meshRegion_ != polyMesh::defaultRegion)
|
||||
{
|
||||
lagrangianPrefix = meshRegion_/"lagrangian";
|
||||
}
|
||||
|
||||
IOobjectList objects
|
||||
(
|
||||
dbPtr_(),
|
||||
dbPtr_().timeName(),
|
||||
"lagrangian"/cloudName
|
||||
lagrangianPrefix/cloudName
|
||||
);
|
||||
|
||||
addToSelection<IOField<label> >
|
||||
|
||||
@ -59,8 +59,16 @@ void Foam::vtkPV3Foam::updateInfoFields
|
||||
|
||||
select->RemoveAllArrays();
|
||||
|
||||
// Search for list of objects for this time
|
||||
IOobjectList objects(dbPtr_(), dbPtr_().timeName());
|
||||
// use the db directly since this might be called without a mesh,
|
||||
// but the region must get added back in
|
||||
word regionPrefix;
|
||||
if (meshRegion_ != polyMesh::defaultRegion)
|
||||
{
|
||||
regionPrefix = meshRegion_;
|
||||
}
|
||||
|
||||
// Search for list of objects for this time and mesh region
|
||||
IOobjectList objects(dbPtr_(), dbPtr_().timeName(), regionPrefix);
|
||||
|
||||
//- Add volume fields to GUI
|
||||
addToSelection<GeometricField<scalar, patchType, meshType> >
|
||||
|
||||
Reference in New Issue
Block a user