Merge branch 'ensight-preview' into 'develop'

Reworking of the ensight infrastructue and new ensightWrite function object



See merge request !70
This commit is contained in:
Mark Olesen
2016-11-03 08:24:52 +00:00
80 changed files with 7954 additions and 5882 deletions

View File

@ -1,5 +1,6 @@
ensightMesh.C
ensightCloud.C
ensightOutputCloud.C
meshSubsetHelper.C
foamToEnsight.C
EXE = $(FOAM_APPBIN)/foamToEnsight

View File

@ -3,14 +3,12 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/conversion/lnInclude
EXE_LIBS = \
-ldynamicMesh \
-lfileFormats \
-lsampling \
-lgenericPatchFields \
-llagrangian \
-lconversion

View File

@ -1,112 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::cellSets
Description
\*---------------------------------------------------------------------------*/
#ifndef cellSets_H
#define cellSets_H
#include "labelList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cellSets Declaration
\*---------------------------------------------------------------------------*/
class cellSets
{
public:
label nTets;
label nPyrs;
label nPrisms;
label nHexesWedges;
label nPolys;
labelList tets;
labelList pyrs;
labelList prisms;
labelList wedges;
labelList hexes;
labelList polys;
// Constructors
//- Construct given the number ov cells
cellSets(const label nCells)
:
nTets(0),
nPyrs(0),
nPrisms(0),
nHexesWedges(0),
nPolys(0),
tets(nCells),
pyrs(nCells),
prisms(nCells),
wedges(nCells),
hexes(nCells),
polys(nCells)
{}
// Member Functions
void setSize(const label nCells)
{
nTets = 0;
nPyrs = 0;
nPrisms = 0;
nHexesWedges = 0;
nPolys = 0;
tets.setSize(nCells);
pyrs.setSize(nCells);
prisms.setSize(nCells);
wedges.setSize(nCells);
hexes.setSize(nCells);
polys.setSize(nCells);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -38,8 +38,7 @@ if (timeDirs.size() > 1 && Pstream::master())
if (meshMoving)
{
Info<< "found." << nl
<< " Writing meshes for every timestep." << endl;
Info<< "found. Writing meshes for every timestep." << endl;
}
else
{

View File

@ -1,153 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 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/>.
Class
Foam::ensightAsciiStream
Description
SourceFiles
ensightAsciiStream.C
\*---------------------------------------------------------------------------*/
#ifndef ensightAsciiStream_H
#define ensightAsciiStream_H
#include "ensightStream.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightAsciiStream Declaration
\*---------------------------------------------------------------------------*/
class ensightAsciiStream
:
public ensightStream
{
// Private data
//- Output file stream
OFstream str_;
// Private Member Functions
//- Disallow default bitwise copy construct
ensightAsciiStream(const ensightAsciiStream&) = delete;
//- Disallow default bitwise assignment
void operator=(const ensightAsciiStream&) = delete;
public:
// Constructors
//- Construct from components
ensightAsciiStream(const fileName& f)
:
ensightStream(f),
str_
(
f,
IOstream::ASCII,
IOstream::currentVersion,
IOstream::UNCOMPRESSED
)
{
str_.setf(ios_base::scientific, ios_base::floatfield);
str_.precision(5);
}
//- Destructor
virtual ~ensightAsciiStream()
{}
// Member Functions
virtual bool ascii() const
{
return true;
}
virtual void write(const char* c)
{
str_ << c << nl;
}
virtual void write(const int v)
{
str_ << setw(10) << v << nl;
}
virtual void write(const scalarField& sf)
{
forAll(sf, i)
{
if (mag(sf[i]) >= scalar(floatScalarVSMALL))
{
str_ << setw(12) << sf[i] << nl;
}
else
{
str_ << setw(12) << scalar(0) << nl;
}
}
}
virtual void write(const List<int>& sf)
{
forAll(sf, i)
{
str_ << setw(10) << sf[i];
}
str_<< nl;
}
virtual void writePartHeader(const label partI)
{
str_<< "part" << nl
<< setw(10) << partI << nl;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,150 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 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/>.
Class
Foam::ensightBinaryStream
Description
SourceFiles
ensightBinaryStream.C
\*---------------------------------------------------------------------------*/
#ifndef ensightBinaryStream_H
#define ensightBinaryStream_H
#include "ensightStream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightBinaryStream Declaration
\*---------------------------------------------------------------------------*/
class ensightBinaryStream
:
public ensightStream
{
// Private data
//- Output file stream
autoPtr<std::ofstream> str_;
// Private Member Functions
//- Disallow default bitwise copy construct
ensightBinaryStream(const ensightBinaryStream&) = delete;
//- Disallow default bitwise assignment
void operator=(const ensightBinaryStream&) = delete;
public:
// Constructors
//- Construct from components
ensightBinaryStream(const fileName& f)
:
ensightStream(f),
str_
(
new std::ofstream
(
f.c_str(),
ios_base::out | ios_base::binary | ios_base::trunc
)
)
{}
//- Destructor
virtual ~ensightBinaryStream()
{}
// Member Functions
virtual void write(const char* val)
{
char buffer[80];
strncpy(buffer, val, 80);
str_().write(buffer, 80*sizeof(char));
}
virtual void write(const int val)
{
str_().write(reinterpret_cast<const char*>(&val), sizeof(int));
}
virtual void write(const scalarField& sf)
{
if (sf.size())
{
List<float> temp(sf.size());
forAll(sf, i)
{
temp[i] = float(sf[i]);
}
str_().write
(
reinterpret_cast<const char*>(temp.begin()),
sf.size()*sizeof(float)
);
}
}
virtual void write(const List<int>& sf)
{
str_().write
(
reinterpret_cast<const char*>(sf.begin()),
sf.size()*sizeof(int)
);
}
virtual void writePartHeader(const label partI)
{
write("part");
write(partI);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,33 +0,0 @@
if (Pstream::master())
{
ensightCaseFile.setf(ios_base::scientific, ios_base::floatfield);
ensightCaseFile.precision(5);
ensightCaseFile << nl << "TIME" << nl
<< "time set: " << 1 << nl
<< "number of steps: " << nTimeSteps << nl
<< "filename start number: " << 0 << nl
<< "filename increment: " << 1 << nl;
ensightCaseFile << "time values:" << nl;
label count = 0;
scalar Tcorr = 0.0;
if (timeDirs[0].value() < 0)
{
Tcorr = -timeDirs[0].value();
Info<< "Correcting time values. Adding " << Tcorr << endl;
}
forAll(timeDirs, n)
{
ensightCaseFile << setw(12) << timeDirs[n].value() + Tcorr << " ";
if (++count % 6 == 0)
{
ensightCaseFile << nl;
}
}
ensightCaseFile << nl;
}

View File

@ -1,816 +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 "ensightFile.H"
#include "ensightField.H"
#include "fvMesh.H"
#include "volFields.H"
#include "OFstream.H"
#include "IOmanip.H"
#include "volPointInterpolation.H"
#include "ensightBinaryStream.H"
#include "ensightAsciiStream.H"
#include "globalIndex.H"
#include "ensightPTraits.H"
#include "zeroGradientFvPatchField.H"
using namespace Foam;
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>>
volField
(
const fvMeshSubset& meshSubsetter,
const GeometricField<Type, fvPatchField, volMesh>& vf
)
{
if (meshSubsetter.hasSubMesh())
{
tmp<GeometricField<Type, fvPatchField, volMesh>> tfld
(
meshSubsetter.interpolate(vf)
);
tfld.ref().checkOut();
tfld.ref().rename(vf.name());
return tfld;
}
else
{
return vf;
}
}
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>>
volField
(
const fvMeshSubset& meshSubsetter,
const typename GeometricField<Type, fvPatchField, volMesh>::Internal& df
)
{
// Construct volField (with zeroGradient) from dimensioned field
IOobject io(df);
io.readOpt() = IOobject::NO_READ;
io.writeOpt() = IOobject::NO_WRITE;
io.registerObject() = false;
tmp<GeometricField<Type, fvPatchField, volMesh>> tvf
(
new GeometricField<Type, fvPatchField, volMesh>
(
io,
df.mesh(),
dimensioned<Type>("0", df.dimensions(), Zero),
zeroGradientFvPatchField<Type>::typeName
)
);
tvf.ref().primitiveFieldRef() = df;
tvf.ref().correctBoundaryConditions();
if (meshSubsetter.hasSubMesh())
{
const GeometricField<Type, fvPatchField, volMesh>& vf = tvf();
tmp<GeometricField<Type, fvPatchField, volMesh>> tfld
(
meshSubsetter.interpolate(vf)
);
tfld.ref().checkOut();
tfld.ref().rename(vf.name());
return tfld;
}
else
{
return tvf;
}
}
//template<class Container>
//void readAndConvertField
//(
// const fvMeshSubset& meshSubsetter,
// const IOobject& io,
// const fvMesh& mesh,
// const ensightMesh& eMesh,
// const fileName& dataDir,
// const label timeIndex,
// const bool nodeValues,
// Ostream& ensightCaseFile
//)
//{
// Container fld(io, mesh);
// ensightField<typename Container::value_type>
// (
// volField<typename Container::value_type>(meshSubsetter, fld),
// eMesh,
// dataDir,
// timeIndex,
// nodeValues,
// ensightCaseFile
// );
//}
template<class Type>
Field<Type> map
(
const Field<Type>& vf,
const labelList& map1,
const labelList& map2
)
{
Field<Type> mf(map1.size() + map2.size());
forAll(map1, i)
{
mf[i] = vf[map1[i]];
}
label offset = map1.size();
forAll(map2, i)
{
mf[i + offset] = vf[map2[i]];
}
return mf;
}
template<class Type>
void writeField
(
const char* key,
const Field<Type>& vf,
ensightStream& os
)
{
if (returnReduce(vf.size(), sumOp<label>()) > 0)
{
if (Pstream::master())
{
os.write(key);
for (direction i=0; i < pTraits<Type>::nComponents; ++i)
{
label cmpt = ensightPTraits<Type>::componentOrder[i];
os.write(vf.component(cmpt));
for (int slave=1; slave<Pstream::nProcs(); slave++)
{
IPstream fromSlave(Pstream::scheduled, slave);
scalarField slaveData(fromSlave);
os.write(slaveData);
}
}
}
else
{
for (direction i=0; i < pTraits<Type>::nComponents; ++i)
{
label cmpt = ensightPTraits<Type>::componentOrder[i];
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster<< vf.component(cmpt);
}
}
}
}
template<class Type>
bool writePatchField
(
const Field<Type>& pf,
const label patchi,
const label ensightPatchi,
const faceSets& boundaryFaceSet,
const ensightMesh::nFacePrimitives& nfp,
ensightStream& os
)
{
if (nfp.nTris || nfp.nQuads || nfp.nPolys)
{
if (Pstream::master())
{
os.writePartHeader(ensightPatchi);
}
writeField
(
"tria3",
Field<Type>(pf, boundaryFaceSet.tris),
os
);
writeField
(
"quad4",
Field<Type>(pf, boundaryFaceSet.quads),
os
);
writeField
(
"nsided",
Field<Type>(pf, boundaryFaceSet.polys),
os
);
return true;
}
else
{
return false;
}
}
template<class Type>
void writePatchField
(
const word& fieldName,
const Field<Type>& pf,
const word& patchName,
const ensightMesh& eMesh,
const fileName& dataDir,
const label timeIndex,
Ostream& ensightCaseFile
)
{
const List<faceSets>& boundaryFaceSets = eMesh.boundaryFaceSets();
const wordList& allPatchNames = eMesh.allPatchNames();
const HashTable<ensightMesh::nFacePrimitives>&
nPatchPrims = eMesh.nPatchPrims();
label ensightPatchi = eMesh.patchPartOffset();
label patchi = -1;
forAll(allPatchNames, i)
{
if (allPatchNames[i] == patchName)
{
patchi = i;
break;
}
ensightPatchi++;
}
ensightStream* filePtr(nullptr);
if (Pstream::master())
{
// TODO: verify that these are indeed valid ensight variable names
const word varName = patchName + '.' + fieldName;
const fileName postFileName = ensightFile::subDir(timeIndex)/varName;
// the data/ITER subdirectory must exist
mkDir(dataDir/postFileName.path());
if (timeIndex == 0)
{
const fileName dirName = dataDir.name()/ensightFile::mask();
ensightCaseFile.setf(ios_base::left);
ensightCaseFile
<< ensightPTraits<Type>::typeName << " per "
<< setw(20)
<< "element:"
<< " 1 "
<< setw(15)
<< varName.c_str() << ' '
<< (dirName/varName).c_str()
<< nl;
}
if (eMesh.format() == IOstream::BINARY)
{
filePtr = new ensightBinaryStream
(
dataDir/postFileName
);
}
else
{
filePtr = new ensightAsciiStream
(
dataDir/postFileName
);
}
filePtr->write(ensightPTraits<Type>::typeName);
}
ensightStream& os = *filePtr;
if (patchi >= 0)
{
writePatchField
(
pf,
patchi,
ensightPatchi,
boundaryFaceSets[patchi],
nPatchPrims.find(patchName)(),
os
);
}
else
{
faceSets nullFaceSets;
writePatchField
(
Field<Type>(),
-1,
ensightPatchi,
nullFaceSets,
nPatchPrims.find(patchName)(),
os
);
}
if (filePtr) // on master only
{
delete filePtr;
}
}
template<class Type>
void ensightField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightMesh& eMesh,
const fileName& dataDir,
const label timeIndex,
Ostream& ensightCaseFile
)
{
Info<< ' ' << vf.name();
const fvMesh& mesh = eMesh.mesh();
const cellSets& meshCellSets = eMesh.meshCellSets();
const List<faceSets>& boundaryFaceSets = eMesh.boundaryFaceSets();
const wordList& allPatchNames = eMesh.allPatchNames();
const wordHashSet& patchNames = eMesh.patchNames();
const HashTable<ensightMesh::nFacePrimitives>&
nPatchPrims = eMesh.nPatchPrims();
const List<faceSets>& faceZoneFaceSets = eMesh.faceZoneFaceSets();
const wordHashSet& faceZoneNames = eMesh.faceZoneNames();
const HashTable<ensightMesh::nFacePrimitives>&
nFaceZonePrims = eMesh.nFaceZonePrims();
const labelList& tets = meshCellSets.tets;
const labelList& pyrs = meshCellSets.pyrs;
const labelList& prisms = meshCellSets.prisms;
const labelList& wedges = meshCellSets.wedges;
const labelList& hexes = meshCellSets.hexes;
const labelList& polys = meshCellSets.polys;
ensightStream* filePtr(nullptr);
if (Pstream::master())
{
const ensight::VarName varName(vf.name());
const fileName postFileName = ensightFile::subDir(timeIndex)/varName;
// the data/ITER subdirectory must exist
mkDir(dataDir/postFileName.path());
if (timeIndex == 0)
{
const fileName dirName = dataDir.name()/ensightFile::mask();
ensightCaseFile.setf(ios_base::left);
ensightCaseFile
<< ensightPTraits<Type>::typeName
<< " per element: 1 "
<< setw(15)
<< varName.c_str() << ' '
<< (dirName/varName).c_str()
<< nl;
}
if (eMesh.format() == IOstream::BINARY)
{
filePtr = new ensightBinaryStream
(
dataDir/postFileName
);
}
else
{
filePtr = new ensightAsciiStream
(
dataDir/postFileName
);
}
filePtr->write(ensightPTraits<Type>::typeName);
}
ensightStream& os = *filePtr;
if (patchNames.empty())
{
eMesh.barrier();
if (Pstream::master())
{
os.writePartHeader(1);
}
writeField
(
"hexa8",
map(vf, hexes, wedges),
os
);
writeField
(
"penta6",
Field<Type>(vf, prisms),
os
);
writeField
(
"pyramid5",
Field<Type>(vf, pyrs),
os
);
writeField
(
"tetra4",
Field<Type>(vf, tets),
os
);
writeField
(
"nfaced",
Field<Type>(vf, polys),
os
);
}
label ensightPatchi = eMesh.patchPartOffset();
forAll(allPatchNames, patchi)
{
const word& patchName = allPatchNames[patchi];
eMesh.barrier();
if (patchNames.empty() || patchNames.found(patchName))
{
if
(
writePatchField
(
vf.boundaryField()[patchi],
patchi,
ensightPatchi,
boundaryFaceSets[patchi],
nPatchPrims.find(patchName)(),
os
)
)
{
ensightPatchi++;
}
}
}
// write faceZones, if requested
if (faceZoneNames.size())
{
// Interpolates cell values to faces - needed only when exporting
// faceZones...
GeometricField<Type, fvsPatchField, surfaceMesh> sf
(
linearInterpolate(vf)
);
forAllConstIter(wordHashSet, faceZoneNames, iter)
{
const word& faceZoneName = iter.key();
eMesh.barrier();
const label zoneID = mesh.faceZones().findZoneID(faceZoneName);
const faceZone& fz = mesh.faceZones()[zoneID];
// Prepare data to write
label nIncluded = 0;
forAll(fz, i)
{
if (eMesh.faceToBeIncluded(fz[i]))
{
++nIncluded;
}
}
Field<Type> values(nIncluded);
// Loop on the faceZone and store the needed field values
label j = 0;
forAll(fz, i)
{
label facei = fz[i];
if (mesh.isInternalFace(facei))
{
values[j] = sf[facei];
++j;
}
else
{
if (eMesh.faceToBeIncluded(facei))
{
label patchi = mesh.boundaryMesh().whichPatch(facei);
const polyPatch& pp = mesh.boundaryMesh()[patchi];
label patchFacei = pp.whichFace(facei);
Type value = sf.boundaryField()[patchi][patchFacei];
values[j] = value;
++j;
}
}
}
if
(
writePatchField
(
values,
zoneID,
ensightPatchi,
faceZoneFaceSets[zoneID],
nFaceZonePrims.find(faceZoneName)(),
os
)
)
{
ensightPatchi++;
}
}
}
if (filePtr) // on master only
{
delete filePtr;
}
}
template<class Type>
void ensightPointField
(
const GeometricField<Type, pointPatchField, pointMesh>& pf,
const ensightMesh& eMesh,
const fileName& dataDir,
const label timeIndex,
Ostream& ensightCaseFile
)
{
Info<< ' ' << pf.name();
const fvMesh& mesh = eMesh.mesh();
const wordList& allPatchNames = eMesh.allPatchNames();
const wordHashSet& patchNames = eMesh.patchNames();
const wordHashSet& faceZoneNames = eMesh.faceZoneNames();
ensightStream* filePtr(nullptr);
if (Pstream::master())
{
const ensight::VarName varName(pf.name());
const fileName postFileName = ensightFile::subDir(timeIndex)/varName;
// the data/ITER subdirectory must exist
mkDir(dataDir/postFileName.path());
if (timeIndex == 0)
{
const fileName dirName = dataDir.name()/ensightFile::mask();
ensightCaseFile.setf(ios_base::left);
ensightCaseFile
<< ensightPTraits<Type>::typeName
<< " per "
<< setw(20)
<< " node:"
<< " 1 "
<< setw(15)
<< varName.c_str() << ' '
<< (dirName/varName).c_str()
<< nl;
}
if (eMesh.format() == IOstream::BINARY)
{
filePtr = new ensightBinaryStream
(
dataDir/postFileName
);
}
else
{
filePtr = new ensightAsciiStream
(
dataDir/postFileName
);
}
filePtr->write(ensightPTraits<Type>::typeName);
}
ensightStream& os = *filePtr;
if (eMesh.patchNames().empty())
{
eMesh.barrier();
if (Pstream::master())
{
os.writePartHeader(1);
}
writeField
(
"coordinates",
Field<Type>(pf.primitiveField(), eMesh.uniquePointMap()),
os
);
}
label ensightPatchi = eMesh.patchPartOffset();
forAll(allPatchNames, patchi)
{
const word& patchName = allPatchNames[patchi];
eMesh.barrier();
if (patchNames.empty() || patchNames.found(patchName))
{
const fvPatch& p = mesh.boundary()[patchi];
if (returnReduce(p.size(), sumOp<label>()) > 0)
{
// Renumber the patch points/faces into unique points
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPointsPtr =
mesh.globalData().mergePoints
(
p.patch().meshPoints(),
p.patch().meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels
);
if (Pstream::master())
{
os.writePartHeader(ensightPatchi);
}
writeField
(
"coordinates",
Field<Type>(pf.primitiveField(), uniqueMeshPointLabels),
os
);
ensightPatchi++;
}
}
}
// write faceZones, if requested
if (faceZoneNames.size())
{
forAllConstIter(wordHashSet, faceZoneNames, iter)
{
const word& faceZoneName = iter.key();
eMesh.barrier();
const label zoneID = mesh.faceZones().findZoneID(faceZoneName);
const faceZone& fz = mesh.faceZones()[zoneID];
if (returnReduce(fz().nPoints(), sumOp<label>()) > 0)
{
// Renumber the faceZone points/faces into unique points
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPointsPtr =
mesh.globalData().mergePoints
(
fz().meshPoints(),
fz().meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels
);
if (Pstream::master())
{
os.writePartHeader(ensightPatchi);
}
writeField
(
"coordinates",
Field<Type>
(
pf.primitiveField(),
uniqueMeshPointLabels
),
os
);
ensightPatchi++;
}
}
}
if (filePtr) // on master only
{
delete filePtr;
}
}
template<class Type>
void ensightField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightMesh& eMesh,
const fileName& dataDir,
const label timeIndex,
const bool nodeValues,
Ostream& ensightCaseFile
)
{
if (nodeValues)
{
tmp<GeometricField<Type, pointPatchField, pointMesh>> pfld
(
volPointInterpolation::New(vf.mesh()).interpolate(vf)
);
pfld.ref().rename(vf.name());
ensightPointField<Type>
(
pfld,
eMesh,
dataDir,
timeIndex,
ensightCaseFile
);
}
else
{
ensightField<Type>
(
vf,
eMesh,
dataDir,
timeIndex,
ensightCaseFile
);
}
}
// ************************************************************************* //

View File

@ -1,102 +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/>.
InApplication
foamToEnsight
Description
SourceFiles
ensightField.C
\*---------------------------------------------------------------------------*/
#ifndef ensightField_H
#define ensightField_H
#include "ensightMesh.H"
#include "fvMeshSubset.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Wrapper to get hold of the field or the subsetted field
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
volField
(
const Foam::fvMeshSubset&,
const Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>& vf
);
//- Wrapper to convert dimensionedInternalField to volField
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
volField
(
const Foam::fvMeshSubset&,
const typename Foam::GeometricField
<
Type,
Foam::fvPatchField,
Foam::volMesh
>::Internal& df
);
template<class Type>
void ensightField
(
const Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>& vf,
const Foam::ensightMesh& eMesh,
const Foam::fileName& dataDir,
const Foam::label timeIndex,
const bool nodeValues,
Foam::Ostream& ensightCaseFile
);
template<class Type>
void writePatchField
(
const Foam::word& fieldName,
const Foam::Field<Type>& pf,
const Foam::word& patchName,
const Foam::ensightMesh& eMesh,
const Foam::fileName& dataDir,
const Foam::label timeIndex,
Foam::Ostream& ensightCaseFile
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,398 +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/>.
Class
Foam::ensightMesh
Description
SourceFiles
ensightMesh.C
\*---------------------------------------------------------------------------*/
#ifndef ensightMesh_H
#define ensightMesh_H
#include "cellSets.H"
#include "faceSets.H"
#include "HashTable.H"
#include "HashSet.H"
#include "PackedBoolList.H"
#include "wordReList.H"
#include "scalarField.H"
#include "cellShapeList.H"
#include "cellList.H"
#include <fstream>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class fvMesh;
class argList;
class globalIndex;
class ensightStream;
/*---------------------------------------------------------------------------*\
Class ensightMesh Declaration
\*---------------------------------------------------------------------------*/
class ensightMesh
{
public:
//- The name for geometry files
static const char* geometryName;
//- Helper class for managing face primitives
class nFacePrimitives
{
public:
label nTris;
label nQuads;
label nPolys;
nFacePrimitives()
:
nTris(0),
nQuads(0),
nPolys(0)
{}
};
private:
// Private data
//- Reference to the OpenFOAM mesh
const fvMesh& mesh_;
//- Suppress patches
const bool noPatches_;
//- Output selected patches only
const bool patches_;
const wordReList patchPatterns_;
//- Output selected faceZones
const bool faceZones_;
const wordReList faceZonePatterns_;
//- Ascii/Binary file output
const IOstream::streamFormat format_;
//- The ensight part id for the first patch
label patchPartOffset_;
cellSets meshCellSets_;
List<faceSets> boundaryFaceSets_;
wordList allPatchNames_;
wordHashSet patchNames_;
HashTable<nFacePrimitives> nPatchPrims_;
// faceZone - related variables
List<faceSets> faceZoneFaceSets_;
wordHashSet faceZoneNames_;
HashTable<nFacePrimitives> nFaceZonePrims_;
//- Per boundary face whether to include or not
PackedBoolList boundaryFaceToBeIncluded_;
// Parallel merged points
//- Global numbering for merged points
autoPtr<globalIndex> globalPointsPtr_;
//- From mesh point to global merged point
labelList pointToGlobal_;
//- Local points that are unique
labelList uniquePointMap_;
// Private Member Functions
//- Disallow default bitwise copy construct
ensightMesh(const ensightMesh&) = delete;
//- Disallow default bitwise assignment
void operator=(const ensightMesh&) = delete;
void writePoints
(
const scalarField& pointsComponent,
ensightStream& ensightGeometryFile
) const;
cellShapeList map
(
const cellShapeList& cellShapes,
const labelList& prims,
const labelList& pointToGlobal
) const;
cellShapeList map
(
const cellShapeList& cellShapes,
const labelList& hexes,
const labelList& wedges,
const labelList& pointToGlobal
) const;
void writePrims
(
const cellShapeList& cellShapes,
ensightStream& ensightGeometryFile
) const;
void writePolysNFaces
(
const labelList& polys,
const cellList& cellFaces,
ensightStream& ensightGeometryFile
) const;
void writePolysNPointsPerFace
(
const labelList& polys,
const cellList& cellFaces,
const faceList& faces,
ensightStream& ensightGeometryFile
) const;
void writePolysPoints
(
const labelList& polys,
const cellList& cellFaces,
const faceList& faces,
const labelList& faceOwner,
ensightStream& ensightGeometryFile
) const;
void writeAllPolys
(
const labelList& pointToGlobal,
ensightStream& ensightGeometryFile
) const;
void writeAllPrims
(
const char* key,
const label nPrims,
const cellShapeList& cellShapes,
ensightStream& ensightGeometryFile
) const;
void writeFacePrims
(
const faceList& patchFaces,
ensightStream& ensightGeometryFile
) const;
void writeAllFacePrims
(
const char* key,
const labelList& prims,
const label nPrims,
const faceList& patchFaces,
ensightStream& ensightGeometryFile
) const;
void writeNSidedNPointsPerFace
(
const faceList& patchFaces,
ensightStream& ensightGeometryFile
) const;
void writeNSidedPoints
(
const faceList& patchFaces,
ensightStream& ensightGeometryFile
) const;
void writeAllNSided
(
const labelList& prims,
const label nPrims,
const faceList& patchFaces,
ensightStream& ensightGeometryFile
) const;
void writeAllPoints
(
const label ensightPartI,
const word& ensightPartName,
const pointField& uniquePoints,
const label nPoints,
ensightStream& ensightGeometryFile
) const;
public:
// Constructors
//- Construct from fvMesh
ensightMesh
(
const fvMesh& mesh,
const bool noPatches,
const bool patches,
const wordReList& patchPatterns,
const bool faceZones,
const wordReList& faceZonePatterns,
const IOstream::streamFormat format = IOstream::BINARY
);
//- Destructor
~ensightMesh();
// Member Functions
// Access
const fvMesh& mesh() const
{
return mesh_;
}
IOstream::streamFormat format() const
{
return format_;
}
const cellSets& meshCellSets() const
{
return meshCellSets_;
}
const List<faceSets>& boundaryFaceSets() const
{
return boundaryFaceSets_;
}
const wordList& allPatchNames() const
{
return allPatchNames_;
}
const wordHashSet& patchNames() const
{
return patchNames_;
}
const HashTable<nFacePrimitives>& nPatchPrims() const
{
return nPatchPrims_;
}
const List<faceSets>& faceZoneFaceSets() const
{
return faceZoneFaceSets_;
}
const wordHashSet& faceZoneNames() const
{
return faceZoneNames_;
}
const HashTable<nFacePrimitives>& nFaceZonePrims() const
{
return nFaceZonePrims_;
}
//- The ensight part id for the first patch
label patchPartOffset() const
{
return patchPartOffset_;
}
// Parallel point merging
//- Global numbering for merged points
const globalIndex& globalPoints() const
{
return globalPointsPtr_();
}
//- From mesh point to global merged point
const labelList& pointToGlobal() const
{
return pointToGlobal_;
}
//- Local points that are unique
const labelList& uniquePointMap() const
{
return uniquePointMap_;
}
// Other
//- Update for new mesh
void correct();
//- When exporting faceZones, check if a given face has to be included
// or not (i.e. faces on processor boundaries)
bool faceToBeIncluded(const label facei) const;
//- Helper to cause barrier. Necessary on Quadrics.
static void barrier();
// I-O
void write
(
const fileName& ensightDir,
const label timeIndex,
const bool meshMoving,
Ostream& ensightCaseFile
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -23,8 +23,8 @@ License
\*---------------------------------------------------------------------------*/
#include "ensightCloud.H"
#include "ensightFile.H"
#include "ensightOutputCloud.H"
#include "fvMesh.H"
#include "passiveParticle.H"
#include "Cloud.H"
@ -32,30 +32,19 @@ License
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
void Foam::ensightParticlePositions
void Foam::ensightCloud::writePositions
(
const fvMesh& mesh,
const fileName& dataDir,
const label timeIndex,
const word& cloudName,
const bool dataExists,
IOstream::streamFormat format
const bool exists,
autoPtr<ensightFile>& output
)
{
if (dataExists)
{
Info<< " positions";
}
else
{
Info<< " positions{0}";
}
// Total number of parcels on all processes
label nTotParcels = 0;
autoPtr<Cloud<passiveParticle>> cloudPtr;
if (dataExists)
if (exists)
{
cloudPtr.reset(new Cloud<passiveParticle>(mesh, cloudName, false));
nTotParcels = cloudPtr().size();
@ -64,29 +53,15 @@ void Foam::ensightParticlePositions
if (Pstream::master())
{
const fileName postFileName =
ensightFile::subDir(timeIndex)/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(nTotParcels, 8); // unusual width
os.newline();
ensightFile& os = output();
os.beginParticleCoordinates(nTotParcels);
if (!nTotParcels)
{
return; // DONE
}
if (format == IOstream::BINARY)
if (os.format() == IOstream::BINARY)
{
// binary write is Ensight6 - first ids, then positions
@ -131,7 +106,7 @@ void Foam::ensightParticlePositions
{
const point& p = elmnt().position();
os.write(++parcelId, 8); // unusual width
os.write(++parcelId, 8); // unusual width
os.write(p.x());
os.write(p.y());
os.write(p.z());
@ -148,7 +123,7 @@ void Foam::ensightParticlePositions
{
const point& p = points[pti];
os.write(++parcelId, 8); // unusual width
os.write(++parcelId, 8); // unusual width
os.write(p.x());
os.write(p.y());
os.write(p.z());
@ -171,10 +146,11 @@ void Foam::ensightParticlePositions
{
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster<< points;
toMaster
<< points;
}
}
}
// ************************************************************************* //

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -21,78 +21,73 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Namespace
ensightOutput
Description
Miscellaneous collection of functions and template related to Ensight data
A collection of global functions for writing ensight file content.
SourceFiles
ensightOutputFunctions.C
ensightOutputCloud.C
ensightOutputCloudTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef ensightOutputFunctions_H
#define ensightOutputFunctions_H
#ifndef ensightOutputCloud_H
#define ensightOutputCloud_H
#include "ensightFile.H"
#include "Cloud.H"
#include "polyMesh.H"
#include "IOobject.H"
#include "ensightMesh.H"
#include "autoPtr.H"
#include "IOField.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace ensightCloud
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void ensightCaseEntry
//- Write cloud positions
void writePositions
(
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
const word& cloudName,
const bool exists,
autoPtr<ensightFile>& output
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Write cloud field, returning true if the field is non-empty.
template<class Type>
bool writeCloudField
(
const IOField<Type>& field,
ensightFile& os
);
//- Write cloud field from IOobject, always returning true.
template<class Type>
bool writeCloudField
(
const IOobject& fieldObject,
const bool exists,
autoPtr<ensightFile>& output
);
} // namespace ensightCloud
} // namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightOutputFunctions.C"
#include "ensightOutputCloudTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -23,24 +23,26 @@ License
\*---------------------------------------------------------------------------*/
#include "ensightCloud.H"
#include "ensightFile.H"
#include "Time.H"
#include "IOField.H"
#include "OFstream.H"
#include "IOmanip.H"
#include "ensightOutputCloud.H"
#include "ensightPTraits.H"
#include "IOField.H"
#include "Time.H"
#include "globalIndex.H"
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::writeCloudField
bool Foam::ensightCloud::writeCloudField
(
const Foam::IOField<Type>& field,
Foam::ensightFile& os
)
{
if (returnReduce(field.size(), sumOp<label>()) > 0)
const bool exists = (returnReduce(field.size(), sumOp<label>()) > 0);
if (exists)
{
if (Pstream::master())
{
@ -106,86 +108,30 @@ void Foam::writeCloudField
else
{
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster<< field;
toMaster
<< field;
}
}
return exists;
}
template<class Type>
void Foam::ensightCloudField
bool Foam::ensightCloud::writeCloudField
(
const Foam::IOobject& fieldObject,
const Foam::fileName& dataDir,
const Foam::label timeIndex,
const Foam::word& cloudName,
const Foam::label cloudNo,
Foam::Ostream& ensightCaseFile,
const bool dataExists,
Foam::IOstream::streamFormat format
const bool exists,
Foam::autoPtr<Foam::ensightFile>& output
)
{
const ensight::VarName varName(fieldObject.name());
if (dataExists)
{
Info<< ' ' << fieldObject.name();
}
else
{
Info<< ' ' << fieldObject.name() << "{0}"; // ie, empty field
}
ensightFile* filePtr(nullptr);
if (Pstream::master())
{
const fileName postFileName =
ensightFile::subDir(timeIndex)/cloud::prefix/cloudName/varName;
// the ITER/lagrangian subdirectory must exist
// the ITER/lagrangian subdirectory was already created
// when writing positions
mkDir(dataDir/postFileName.path());
if (timeIndex == 0)
{
const fileName dirName =
dataDir.name()/ensightFile::mask()/cloud::prefix/cloudName;
ensightCaseFile.setf(ios_base::left);
// prefix variables with 'c' (cloud)
ensightCaseFile
<< ensightPTraits<Type>::typeName << " per "
<< setw(20)
<< "measured node:"
<< " 1 "
<< setw(15)
<< ("c" + Foam::name(cloudNo) + varName).c_str() << ' '
<< (dirName/varName).c_str()
<< nl;
}
filePtr = new ensightFile(dataDir, postFileName, format);
// description
filePtr->write
(
string(postFileName + " <" + pTraits<Type>::typeName + ">")
);
filePtr->newline();
}
if (dataExists)
if (exists)
{
IOField<Type> field(fieldObject);
writeCloudField(field, *filePtr);
writeCloudField(field, output.rawRef());
}
if (filePtr) // on master only
{
delete filePtr;
}
return true;
}

View File

@ -1,110 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 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/>.
Class
Foam::ensightStream
Description
Abstract base class for writing Ensight data
SourceFiles
ensightStream.C
\*---------------------------------------------------------------------------*/
#ifndef ensightStream_H
#define ensightStream_H
#include "fileName.H"
#include "scalarField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightStream Declaration
\*---------------------------------------------------------------------------*/
class ensightStream
{
// Private data
const fileName name_;
// Private Member Functions
//- Disallow default bitwise copy construct
ensightStream(const ensightStream&) = delete;
//- Disallow default bitwise assignment
void operator=(const ensightStream&) = delete;
public:
// Constructors
//- Construct from components
ensightStream(const fileName& f)
:
name_(f)
{}
//- Destructor
virtual ~ensightStream()
{}
// Member Functions
const fileName& name() const
{
return name_;
}
virtual void write(const char*) = 0;
virtual void write(const int) = 0;
virtual void write(const scalarField&) = 0;
virtual void write(const List<int>&) = 0;
virtual void writePartHeader(const label) = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,78 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::faceSets
Description
\*---------------------------------------------------------------------------*/
#ifndef faceSets_H
#define faceSets_H
#include "labelList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class faceSets Declaration
\*---------------------------------------------------------------------------*/
class faceSets
{
public:
label nTris;
label nQuads;
label nPolys;
labelList tris;
labelList quads;
labelList polys;
// Constructors
//- Construct null
faceSets()
:
nTris(0),
nQuads(0),
nPolys(0)
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -50,7 +50,7 @@ if (timeDirs.size() && !noLagrangian)
forAllConstIter(IOobjectList, cloudObjs, fieldIter)
{
const IOobject obj = *fieldIter();
const IOobject& obj = *fieldIter();
// Add field and field type
cloudIter().insert

View File

@ -61,6 +61,9 @@ Usage
- \par -width \<n\>
Width of EnSight data subdir (default: 8)
- \par -deprecatedOrder
Use older ordering for volume cells (hex prism pyr tet poly)
Note
Writes to \a EnSight directory to avoid collisions with
foamToEnsightParts
@ -73,20 +76,22 @@ Note
#include "IOmanip.H"
#include "OFstream.H"
#include "fvc.H"
#include "volFields.H"
#include "labelIOField.H"
#include "scalarIOField.H"
#include "tensorIOField.H"
#include "ensightFile.H"
// file-format/conversion
#include "ensightCase.H"
#include "ensightGeoFile.H"
#include "ensightMesh.H"
#include "ensightField.H"
#include "ensightCloud.H"
#include "ensightOutput.H"
#include "fvc.H"
#include "cellSet.H"
#include "fvMeshSubset.H"
// local files
#include "meshSubsetHelper.H"
#include "ensightOutputCloud.H"
#include "memInfo.H"
@ -94,7 +99,12 @@ using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
bool inFileNameList(const fileNameList& nameList, const word& name)
// file-scope helper
static bool inFileNameList
(
const fileNameList& nameList,
const word& name
)
{
forAll(nameList, i)
{
@ -171,10 +181,16 @@ int main(int argc, char *argv[])
"n",
"width of ensight data subdir"
);
argList::addBoolOption
(
"deprecatedOrder",
"Use old ordering (hex prism pyr tet poly) "
"instead of the ascending number of points "
"(tet pyr prism hex poly)."
);
// the volume field types that we handle
const label nVolFieldTypes = 10;
const word volFieldTypes[] =
// The volume field types that we handle
const wordList volFieldTypes
{
volScalarField::typeName,
volVectorField::typeName,
@ -203,137 +219,102 @@ int main(int argc, char *argv[])
cpuTime timer;
memInfo mem;
Info<< "Initial memory "
<< mem.update().size() << " kB" << endl;
Info<< "Initial memory " << mem.update().size() << " kB" << endl;
#include "createTime.H"
instantList timeDirs = timeSelector::select0(runTime, args);
// 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);
// Path to EnSight directory at case level only
// - For parallel cases, data only written from master
if (!ensightDir.isAbsolute())
{
ensightDir = args.rootPath()/args.globalCaseName()/ensightDir;
}
const fileName dataDir = ensightDir/"data";
const fileName dataMask = dataDir.name()/ensightFile::mask();
if (Pstream::master())
{
// EnSight and EnSight/data directories must exist
// - remove old data for a clean conversion of everything
if (isDir(ensightDir))
{
rmDir(ensightDir);
}
mkDir(dataDir);
}
#include "createNamedMesh.H"
// Mesh instance (region0 gets filtered out)
fileName regionPrefix;
fileName regionPrefix; // Mesh instance (region0 gets filtered out)
if (regionName != polyMesh::defaultRegion)
{
regionPrefix = regionName;
}
// Start of case file header output
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// general (case) output options
//
ensightCase::options caseOpts(format);
OFstream *ensightCaseFilePtr(nullptr);
if (Pstream::master())
caseOpts.nodeValues(args.optionFound("nodeValues"));
caseOpts.width(args.optionLookupOrDefault<label>("width", 8));
caseOpts.overwrite(true); // remove 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())
{
fileName caseFileName = args.globalCaseName() + ".case";
Info<< "Converting " << timeDirs.size() << " time steps" << nl
<< "Ensight case: " << caseFileName.c_str() << endl;
// The case file is always ASCII
ensightCaseFilePtr = new OFstream
(
ensightDir/caseFileName,
IOstream::ASCII
);
ensightCaseFilePtr->setf(ios_base::left);
ensightCaseFilePtr->setf(ios_base::scientific, ios_base::floatfield);
ensightCaseFilePtr->precision(5);
*ensightCaseFilePtr
<< "FORMAT" << nl
<< "type: ensight gold" << nl << nl;
ensightDir = args.rootPath()/args.globalCaseName()/ensightDir;
}
OFstream& ensightCaseFile = *ensightCaseFilePtr;
// Construct the EnSight mesh
const bool selectedPatches = args.optionFound("patches");
wordReList patchPatterns;
if (selectedPatches)
//
// output configuration (geometry related)
//
ensightMesh::options writeOpts(format);
writeOpts.noPatches(args.optionFound("noPatches"));
writeOpts.deprecatedOrder(args.optionFound("deprecatedOrder"));
if (args.optionFound("patches"))
{
patchPatterns = wordReList(args.optionLookup("patches")());
writeOpts.patchSelection(args.optionReadList<wordRe>("patches"));
}
const bool selectedZones = args.optionFound("faceZones");
wordReList zonePatterns;
if (selectedZones)
if (args.optionFound("faceZones"))
{
zonePatterns = wordReList(args.optionLookup("faceZones")());
}
const bool selectedFields = args.optionFound("fields");
wordReList fieldPatterns;
if (selectedFields)
{
fieldPatterns = wordReList(args.optionLookup("fields")());
writeOpts.faceZoneSelection(args.optionReadList<wordRe>("faceZones"));
}
//
// output configuration (field related)
//
const bool noLagrangian = args.optionFound("noLagrangian");
word cellZoneName;
const bool doCellZone = args.optionReadIfPresent("cellZone", cellZoneName);
wordReList fieldPatterns;
if (args.optionFound("fields"))
{
fieldPatterns = args.optionReadList<wordRe>("fields");
}
fvMeshSubset meshSubsetter(mesh);
if (doCellZone)
word cellZoneName;
if (args.optionReadIfPresent("cellZone", cellZoneName))
{
Info<< "Converting cellZone " << cellZoneName
<< " only (puts outside faces into patch "
<< mesh.boundaryMesh()[0].name()
<< ")" << endl;
const cellZone& cz = mesh.cellZones()[cellZoneName];
cellSet c0(mesh, "c0", labelHashSet(cz));
meshSubsetter.setLargeCellSubset(c0, 0);
<< mesh.boundaryMesh()[0].name() << ")"
<< endl;
}
meshSubsetHelper myMesh(mesh, cellZoneName);
ensightMesh eMesh
//
// Open new ensight case file, initialize header etc.
//
ensightCase ensCase
(
(
meshSubsetter.hasSubMesh()
? meshSubsetter.subMesh()
: meshSubsetter.baseMesh()
),
args.optionFound("noPatches"),
selectedPatches,
patchPatterns,
selectedZones,
zonePatterns,
format
ensightDir,
args.globalCaseName(),
caseOpts
);
// Set Time to the last time before looking for the lagrangian objects
// Construct the Ensight mesh
ensightMesh ensMesh(myMesh.mesh(), writeOpts);
if (Pstream::master())
{
Info<< "Converting " << timeDirs.size() << " time steps" << nl;
ensCase.printInfo(Info) << endl;
}
// Set Time to the last time before looking for lagrangian objects
runTime.setTime(timeDirs.last(), timeDirs.size()-1);
IOobjectList objects(mesh, runTime.timeName());
@ -341,42 +322,10 @@ int main(int argc, char *argv[])
#include "checkMeshMoving.H"
#include "findCloudFields.H"
if (Pstream::master())
{
// test the pre-check variable if there is a moving mesh
// time-set for geometries
// TODO: split off into separate time-set,
// but need to verify ensight spec
if (meshMoving)
{
ensightCaseFile
<< "GEOMETRY" << nl
<< setw(16) << "model: 1"
<< (dataMask/ensightMesh::geometryName).c_str() << nl;
}
else
{
ensightCaseFile
<< "GEOMETRY" << nl
<< setw(16) << "model:"
<< ensightMesh::geometryName << nl;
}
// Add the name of the cloud(s) to the case file header
forAll(cloudNames, cloudNo)
{
const word& cloudName = cloudNames[cloudNo];
ensightCaseFile
<< setw(16) << "measured: 1"
<< fileName
(
dataMask/cloud::prefix/cloudName/"positions"
).c_str() << nl;
}
}
// test the pre-check variable if there is a moving mesh
// time-set for geometries
// TODO: split off into separate time-set,
// but need to verify ensight spec
Info<< "Startup in "
<< timer.cpuTimeIncrement() << " s, "
@ -387,63 +336,25 @@ int main(int argc, char *argv[])
// ignore fields that are not available for all time-steps
HashTable<bool> fieldsToUse;
label nTimeSteps = 0;
forAll(timeDirs, timeIndex)
{
++nTimeSteps;
runTime.setTime(timeDirs[timeIndex], timeIndex);
ensCase.nextTime(timeDirs[timeIndex]);
Info<< "Time [" << timeIndex << "] = " << runTime.timeName() << nl;
if (Pstream::master())
{
// 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;
}
polyMesh::readUpdateState meshState = mesh.readUpdate();
if (timeIndex != 0 && meshSubsetter.hasSubMesh())
{
Info<< "Converting cellZone " << cellZoneName
<< " only (puts outside faces into patch "
<< mesh.boundaryMesh()[0].name()
<< ")" << endl;
const cellZone& cz = mesh.cellZones()[cellZoneName];
cellSet c0(mesh, "c0", labelHashSet(cz));
meshSubsetter.setLargeCellSubset(c0, 0);
}
if (meshState != polyMesh::UNCHANGED)
{
eMesh.correct();
myMesh.correct();
ensMesh.expire();
ensMesh.correct();
}
if (timeIndex == 0 || meshMoving)
{
eMesh.write
(
dataDir,
timeIndex,
meshMoving,
ensightCaseFile
);
}
// Start of field data output
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
if (timeIndex == 0 && Pstream::master())
{
ensightCaseFile<< nl << "VARIABLE" << nl;
autoPtr<ensightGeoFile> os = ensCase.newGeometry(meshMoving);
ensMesh.write(os);
}
@ -451,22 +362,20 @@ int main(int argc, char *argv[])
// ~~~~~~~~~~~~~~~~~~~~~~
Info<< "Write volume field (";
for (label i=0; i<nVolFieldTypes; ++i)
forAll(volFieldTypes, typei)
{
wordList fieldNames = objects.names(volFieldTypes[i]);
const word& fieldType = volFieldTypes[typei];
wordList fieldNames = objects.names(fieldType);
forAll(fieldNames, j)
// Filter on name as required
if (!fieldPatterns.empty())
{
const word& fieldName = fieldNames[j];
inplaceSubsetStrings(fieldPatterns, fieldNames);
}
// Check if the field has to be exported
if (selectedFields)
{
if (!findStrings(fieldPatterns, fieldName))
{
continue;
}
}
forAll(fieldNames, fieldi)
{
const word& fieldName = fieldNames[fieldi];
#include "checkData.H"
@ -484,151 +393,206 @@ int main(int argc, char *argv[])
IOobject::NO_WRITE
);
if (volFieldTypes[i] == volScalarField::typeName)
bool wrote = false;
if (fieldType == volScalarField::typeName)
{
autoPtr<ensightFile> os = ensCase.newData<scalar>
(
fieldName
);
volScalarField vf(fieldObject, mesh);
ensightField<scalar>
wrote = ensightOutput::writeField<scalar>
(
volField(meshSubsetter, vf),
eMesh,
dataDir,
timeIndex,
nodeValues,
ensightCaseFile
myMesh.interpolate(vf),
ensMesh,
os,
nodeValues
);
}
else if (volFieldTypes[i] == volVectorField::typeName)
else if (fieldType == volVectorField::typeName)
{
autoPtr<ensightFile> os = ensCase.newData<vector>
(
fieldName
);
volVectorField vf(fieldObject, mesh);
ensightField<vector>
wrote = ensightOutput::writeField<vector>
(
volField(meshSubsetter, vf),
eMesh,
dataDir,
timeIndex,
nodeValues,
ensightCaseFile
myMesh.interpolate(vf),
ensMesh,
os,
nodeValues
);
}
else if (volFieldTypes[i] == volSphericalTensorField::typeName)
else if (fieldType == volSphericalTensorField::typeName)
{
autoPtr<ensightFile> os = ensCase.newData<sphericalTensor>
(
fieldObject.name()
);
volSphericalTensorField vf(fieldObject, mesh);
ensightField<sphericalTensor>
wrote = ensightOutput::writeField<sphericalTensor>
(
volField(meshSubsetter, vf),
eMesh,
dataDir,
timeIndex,
nodeValues,
ensightCaseFile
myMesh.interpolate(vf),
ensMesh,
os,
nodeValues
);
}
else if (volFieldTypes[i] == volSymmTensorField::typeName)
else if (fieldType == volSymmTensorField::typeName)
{
autoPtr<ensightFile> os = ensCase.newData<symmTensor>
(
fieldName
);
volSymmTensorField vf(fieldObject, mesh);
ensightField<symmTensor>
wrote = ensightOutput::writeField<symmTensor>
(
volField(meshSubsetter, vf),
eMesh,
dataDir,
timeIndex,
nodeValues,
ensightCaseFile
myMesh.interpolate(vf),
ensMesh,
os,
nodeValues
);
}
else if (volFieldTypes[i] == volTensorField::typeName)
else if (fieldType == volTensorField::typeName)
{
volTensorField vf(fieldObject, mesh);
ensightField<tensor>
autoPtr<ensightFile> os = ensCase.newData<tensor>
(
volField(meshSubsetter, vf),
eMesh,
dataDir,
timeIndex,
nodeValues,
ensightCaseFile
fieldName
);
volTensorField vf(fieldObject, mesh);
wrote = ensightOutput::writeField<tensor>
(
myMesh.interpolate(vf),
ensMesh,
os,
nodeValues
);
}
// DimensionedFields
else if
(
volFieldTypes[i] == volScalarField::Internal::typeName
fieldType
== volScalarField::Internal::typeName
)
{
volScalarField::Internal df(fieldObject, mesh);
ensightField<scalar>
autoPtr<ensightFile> os = ensCase.newData<scalar>
(
volField<scalar>(meshSubsetter, df),
eMesh,
dataDir,
timeIndex,
nodeValues,
ensightCaseFile
fieldName
);
volScalarField::Internal df
(
fieldObject,
mesh
);
wrote = ensightOutput::writeField<scalar>
(
myMesh.interpolate<scalar>(df),
ensMesh,
os,
nodeValues
);
}
else if
(
volFieldTypes[i] == volVectorField::Internal::typeName
fieldType
== volVectorField::Internal::typeName
)
{
volVectorField::Internal df(fieldObject, mesh);
ensightField<vector>
autoPtr<ensightFile> os = ensCase.newData<vector>
(
volField<vector>(meshSubsetter, df),
eMesh,
dataDir,
timeIndex,
nodeValues,
ensightCaseFile
fieldName
);
volVectorField::Internal df
(
fieldObject,
mesh
);
wrote = ensightOutput::writeField<vector>
(
myMesh.interpolate<vector>(df),
ensMesh,
os,
nodeValues
);
}
else if
(
volFieldTypes[i]
fieldType
== volSphericalTensorField::Internal::typeName
)
{
volSphericalTensorField::Internal df(fieldObject, mesh);
ensightField<sphericalTensor>
autoPtr<ensightFile> os = ensCase.newData<sphericalTensor>
(
volField<sphericalTensor>(meshSubsetter, df),
eMesh,
dataDir,
timeIndex,
nodeValues,
ensightCaseFile
fieldName
);
volSphericalTensorField::Internal df
(
fieldObject,
mesh
);
wrote = ensightOutput::writeField<sphericalTensor>
(
myMesh.interpolate<sphericalTensor>(df),
ensMesh,
os,
nodeValues
);
}
else if
(
volFieldTypes[i] == volSymmTensorField::Internal::typeName
fieldType
== volSymmTensorField::Internal::typeName
)
{
volSymmTensorField::Internal df(fieldObject, mesh);
ensightField<symmTensor>
autoPtr<ensightFile> os = ensCase.newData<symmTensor>
(
volField<symmTensor>(meshSubsetter, df),
eMesh,
dataDir,
timeIndex,
nodeValues,
ensightCaseFile
fieldName
);
volSymmTensorField::Internal df
(
fieldObject,
mesh
);
wrote = ensightOutput::writeField<symmTensor>
(
myMesh.interpolate<symmTensor>(df),
ensMesh,
os,
nodeValues
);
}
else if
(
volFieldTypes[i] == volTensorField::Internal::typeName
fieldType
== volTensorField::Internal::typeName
)
{
volTensorField::Internal df(fieldObject, mesh);
ensightField<tensor>
autoPtr<ensightFile> os = ensCase.newData<tensor>
(
volField<tensor>(meshSubsetter, df),
eMesh,
dataDir,
timeIndex,
nodeValues,
ensightCaseFile
fieldName
);
volTensorField::Internal df
(
fieldObject,
mesh
);
wrote = ensightOutput::writeField<tensor>
(
myMesh.interpolate<tensor>(df),
ensMesh,
os,
nodeValues
);
}
else
@ -636,6 +600,11 @@ int main(int argc, char *argv[])
// Do not currently handle this type - blacklist for the future.
fieldsToUse.set(fieldName, false);
}
if (wrote)
{
Info<< ' ' << fieldName;
}
}
}
Info<< " )" << nl;
@ -660,15 +629,23 @@ int main(int argc, char *argv[])
bool cloudExists = inFileNameList(currentCloudDirs, cloudName);
reduce(cloudExists, orOp<bool>());
ensightParticlePositions
(
mesh,
dataDir,
timeIndex,
cloudName,
cloudExists,
format
);
{
autoPtr<ensightFile> os = ensCase.newCloud(cloudName);
ensightCloud::writePositions
(
mesh,
cloudName,
cloudExists,
os
);
Info<< " positions";
if (!cloudExists)
{
Info<< "{0}"; // report empty field
}
}
forAllConstIter(HashTable<word>, theseCloudFields, fieldIter)
{
@ -684,40 +661,46 @@ int main(int argc, char *argv[])
IOobject::MUST_READ
);
bool fieldExists = fieldObject.typeHeaderOk<IOField<scalar>>
(
false
);
reduce(fieldExists, orOp<bool>());
// cannot have field without cloud positions
bool fieldExists = cloudExists;
if (cloudExists)
{
fieldExists =
fieldObject.typeHeaderOk<IOField<scalar>>(false);
reduce(fieldExists, orOp<bool>());
}
bool wrote = false;
if (fieldType == scalarIOField::typeName)
{
ensightCloudField<scalar>
autoPtr<ensightFile> os =
ensCase.newCloudData<scalar>(cloudName, fieldName);
wrote = ensightCloud::writeCloudField<scalar>
(
fieldObject,
dataDir,
timeIndex,
cloudName,
cloudNo,
ensightCaseFile,
fieldExists,
format
fieldObject, fieldExists, os
);
}
else if (fieldType == vectorIOField::typeName)
{
ensightCloudField<vector>
autoPtr<ensightFile> os =
ensCase.newCloudData<vector>(cloudName, fieldName);
wrote = ensightCloud::writeCloudField<vector>
(
fieldObject,
dataDir,
timeIndex,
cloudName,
cloudNo,
ensightCaseFile,
fieldExists,
format
fieldObject, fieldExists, os
);
}
if (wrote)
{
Info<< ' ' << fieldName;
if (!fieldExists)
{
Info<< "{0}"; // report empty field
}
}
}
Info<< " )" << nl;
}
@ -727,12 +710,7 @@ int main(int argc, char *argv[])
<< mem.update().size() << " kB" << nl << nl;
}
#include "ensightCaseTail.H"
if (ensightCaseFilePtr) // on master only
{
delete ensightCaseFilePtr;
}
ensCase.write();
Info<< "End: "
<< timer.elapsedCpuTime() << " s, "

View File

@ -0,0 +1,91 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "meshSubsetHelper.H"
#include "cellSet.H"
#include "cellZone.H"
#include "Time.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::meshSubsetHelper::meshSubsetHelper
(
fvMesh& baseMesh,
const word& name,
const bool isCellSet
)
:
baseMesh_(baseMesh),
subsetter_(baseMesh),
name_(name),
type_(name_.empty() ? 0 : isCellSet ? 1 : 2)
{
correct();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::meshSubsetHelper::correct(bool verbose)
{
if (type_ == 1)
{
if (verbose)
{
Info<< "Subsetting mesh based on cellSet " << name_ << endl;
}
cellSet subset(baseMesh_, name_);
subsetter_.setLargeCellSubset(subset);
}
else if (type_ == 2)
{
if (verbose)
{
Info<< "Subsetting mesh based on cellZone " << name_ << endl;
}
labelHashSet subset(baseMesh_.cellZones()[name_]);
subsetter_.setLargeCellSubset(subset, 0);
}
}
Foam::polyMesh::readUpdateState Foam::meshSubsetHelper::readUpdate()
{
polyMesh::readUpdateState meshState = baseMesh_.readUpdate();
if (meshState != polyMesh::UNCHANGED)
{
correct(true);
}
return meshState;
}
// ************************************************************************* //

View File

@ -0,0 +1,193 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::meshSubsetHelper
Description
Simple helper to hold a mesh or mesh-subset and provide uniform access.
SourceFiles
meshSubsetHelper.C
meshSubsetHelperTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef meshSubsetHelper_H
#define meshSubsetHelper_H
#include "fvMeshSubset.H"
#include "zeroGradientFvPatchField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class Time;
/*---------------------------------------------------------------------------*\
Class meshSubsetHelper Declaration
\*---------------------------------------------------------------------------*/
class meshSubsetHelper
{
// Private data
//- Reference to mesh
fvMesh& baseMesh_;
//- Subsetting engine + sub-fvMesh
fvMeshSubset subsetter_;
//- Name of current cellSet/cellZone (or empty)
const word name_;
//- Internal book-keeping. 0 = unused, 1 = set, 2 = zone
const int type_;
// Private Member Functions
//- Disallow default bitwise copy construct
meshSubsetHelper(const meshSubsetHelper&) = delete;
//- Disallow default bitwise assignment
void operator=(const meshSubsetHelper&) = delete;
public:
// Constructors
//- Construct from components
meshSubsetHelper
(
fvMesh& baseMesh,
const word& name = word::null,
const bool isCellSet = false
);
// Member Functions
// Access
//- The entire base mesh
inline const fvMesh& baseMesh() const
{
return baseMesh_;
}
//- The mesh subsetter
inline const fvMeshSubset& subsetter() const
{
return subsetter_;
}
//- Check if running a sub-mesh is being used
inline bool useSubMesh() const
{
return type_;
}
//- Access either mesh or submesh
inline const fvMesh& mesh() const
{
if (useSubMesh())
{
return subsetter_.subMesh();
}
else
{
return baseMesh_;
}
}
// Edit
//- Update mesh subset
void correct(bool verbose = false);
//- Read mesh
polyMesh::readUpdateState readUpdate();
//- Construct volField (with zeroGradient) from an internal field
template<class Type>
static tmp<GeometricField<Type, fvPatchField, volMesh>>
zeroGradientField
(
const typename GeometricField
<
Type,
fvPatchField,
volMesh
>::Internal& df
);
//- Wrapper for field or the subsetted field.
// Map volume field (does in fact do very little interpolation;
// just copied from fvMeshSubset)
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>>
interpolate
(
const GeometricField<Type, fvPatchField, volMesh>&
) const;
//- Convert an internal field to a volume field
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>>
interpolate
(
const typename GeometricField
<
Type,
fvPatchField,
volMesh
>::Internal&
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "meshSubsetHelperTemplates.C"
#endif
#endif
// ************************************************************************* //

View File

@ -0,0 +1,119 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "meshSubsetHelper.H"
#include "fvMesh.H"
#include "volFields.H"
#include "globalIndex.H"
#include "zeroGradientFvPatchField.H"
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
Foam::meshSubsetHelper::zeroGradientField
(
const typename GeometricField
<
Type,
fvPatchField,
volMesh
>::Internal& df
)
{
IOobject io(df);
io.readOpt() = IOobject::NO_READ;
io.writeOpt() = IOobject::NO_WRITE;
io.registerObject() = false;
tmp<GeometricField<Type, fvPatchField, volMesh>> tvf
(
new GeometricField<Type, fvPatchField, volMesh>
(
io,
df.mesh(),
dimensioned<Type>("0", df.dimensions(), Zero),
zeroGradientFvPatchField<Type>::typeName
)
);
tvf.ref().primitiveFieldRef() = df;
tvf.ref().correctBoundaryConditions();
return tvf;
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
Foam::meshSubsetHelper::interpolate
(
const GeometricField<Type, fvPatchField, volMesh>& vf
) const
{
if (subsetter_.hasSubMesh())
{
tmp<GeometricField<Type, fvPatchField, volMesh>> tfld
(
subsetter_.interpolate(vf)
);
tfld.ref().checkOut();
tfld.ref().rename(vf.name());
return tfld;
}
else
{
return vf;
}
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
Foam::meshSubsetHelper::interpolate
(
const typename GeometricField
<
Type,
fvPatchField,
volMesh
>::Internal& df
) const
{
tmp<GeometricField<Type, fvPatchField, volMesh>> tvf =
zeroGradientField<Type>(df);
if (subsetter_.hasSubMesh())
{
return interpolate<Type>(tvf());
}
else
{
return tvf;
}
}
// ************************************************************************* //

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

@ -21,68 +21,65 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
InApplication
foamToEnsight
Description
Miscellaneous collection of functions and template related to Ensight data
SourceFiles
ensightCloud.C
ensightCloudTemplates.C
ensightOutputFunctions.C
\*---------------------------------------------------------------------------*/
#ifndef ensightCloud_H
#define ensightCloud_H
#ifndef ensightOutputSerialCloud_H
#define ensightOutputSerialCloud_H
#include "ensightFile.H"
#include "fvMesh.H"
#include "Cloud.H"
#include "polyMesh.H"
#include "IOobject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace ensightSerialCloud
{
void ensightParticlePositions
//- Write cloud positions
void writePositions
(
const fvMesh& mesh,
const fileName& dataDir,
const label timeIndex,
const polyMesh& mesh,
const word& cloudName,
const bool dataExists,
const IOstream::streamFormat format
autoPtr<ensightFile> output
);
//- Write cloud field
template<class Type>
void ensightCloudField
(
const IOobject& fieldObject,
const fileName& dataDir,
const label timeIndex,
const word& cloudName,
const label cloudNo,
Ostream& ensightCaseFile,
const bool dataExists,
const IOstream::streamFormat format
);
template<class Type>
void writeCloudField
bool writeCloudField
(
const IOField<Type>& field,
ensightFile& os
);
}
//- Write cloud field
template<class Type>
bool writeCloudField
(
const IOobject& fieldObject,
autoPtr<ensightFile> output
);
} // namespace ensightSerialCloud
} // namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightCloudTemplates.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"
@ -133,33 +139,25 @@ int main(int argc, char *argv[])
);
// 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);
const wordHashSet volFieldTypes
{
volScalarField::typeName,
volVectorField::typeName,
volSphericalTensorField::typeName,
volSymmTensorField::typeName,
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";
const wordHashSet cloudFieldTypes
{
scalarIOField::typeName,
vectorIOField::typeName,
tensorIOField::typeName
};
#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 +166,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 +225,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 +260,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 +273,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 +294,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 +392,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 +419,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 +459,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