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 ensightOutputCloud.C
ensightCloud.C meshSubsetHelper.C
foamToEnsight.C foamToEnsight.C
EXE = $(FOAM_APPBIN)/foamToEnsight EXE = $(FOAM_APPBIN)/foamToEnsight

View File

@ -3,14 +3,12 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \ -I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/conversion/lnInclude -I$(LIB_SRC)/conversion/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-ldynamicMesh \ -ldynamicMesh \
-lfileFormats \ -lfileFormats \
-lsampling \
-lgenericPatchFields \ -lgenericPatchFields \
-llagrangian \ -llagrangian \
-lconversion -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) if (meshMoving)
{ {
Info<< "found." << nl Info<< "found. Writing meshes for every timestep." << endl;
<< " Writing meshes for every timestep." << endl;
} }
else 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 "ensightOutputCloud.H"
#include "ensightFile.H"
#include "fvMesh.H" #include "fvMesh.H"
#include "passiveParticle.H" #include "passiveParticle.H"
#include "Cloud.H" #include "Cloud.H"
@ -32,30 +32,19 @@ License
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
void Foam::ensightParticlePositions void Foam::ensightCloud::writePositions
( (
const fvMesh& mesh, const fvMesh& mesh,
const fileName& dataDir,
const label timeIndex,
const word& cloudName, const word& cloudName,
const bool dataExists, const bool exists,
IOstream::streamFormat format autoPtr<ensightFile>& output
) )
{ {
if (dataExists)
{
Info<< " positions";
}
else
{
Info<< " positions{0}";
}
// Total number of parcels on all processes // Total number of parcels on all processes
label nTotParcels = 0; label nTotParcels = 0;
autoPtr<Cloud<passiveParticle>> cloudPtr; autoPtr<Cloud<passiveParticle>> cloudPtr;
if (dataExists) if (exists)
{ {
cloudPtr.reset(new Cloud<passiveParticle>(mesh, cloudName, false)); cloudPtr.reset(new Cloud<passiveParticle>(mesh, cloudName, false));
nTotParcels = cloudPtr().size(); nTotParcels = cloudPtr().size();
@ -64,29 +53,15 @@ void Foam::ensightParticlePositions
if (Pstream::master()) if (Pstream::master())
{ {
const fileName postFileName = ensightFile& os = output();
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();
os.beginParticleCoordinates(nTotParcels);
if (!nTotParcels) if (!nTotParcels)
{ {
return; // DONE return; // DONE
} }
if (format == IOstream::BINARY) if (os.format() == IOstream::BINARY)
{ {
// binary write is Ensight6 - first ids, then positions // binary write is Ensight6 - first ids, then positions
@ -171,10 +146,11 @@ void Foam::ensightParticlePositions
{ {
OPstream toMaster(Pstream::scheduled, Pstream::masterNo()); OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster<< points; toMaster
<< points;
}
} }
} }
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -2,8 +2,8 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -21,78 +21,73 @@ License
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Namespace
ensightOutput
Description Description
Miscellaneous collection of functions and template related to Ensight data A collection of global functions for writing ensight file content.
SourceFiles SourceFiles
ensightOutputFunctions.C ensightOutputCloud.C
ensightOutputCloudTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef ensightOutputFunctions_H #ifndef ensightOutputCloud_H
#define ensightOutputFunctions_H #define ensightOutputCloud_H
#include "ensightFile.H" #include "ensightFile.H"
#include "Cloud.H" #include "ensightMesh.H"
#include "polyMesh.H"
#include "IOobject.H" #include "autoPtr.H"
#include "IOField.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
namespace ensightCloud
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // //- Write cloud positions
void writePositions
void ensightCaseEntry
( (
OFstream& caseFile,
const string& ensightType,
const word& fieldName,
const fileName& dataMask,
const fileName& local=fileName::null,
const label cloudNo=-1,
const label timeSet=1
);
void ensightParticlePositions
(
const polyMesh& mesh,
const fileName& dataDir,
const fileName& subDir,
const word& cloudName,
IOstream::streamFormat format
);
//- Write lagrangian parcels
template<class Type>
void ensightLagrangianField
(
const IOobject& fieldObject,
const fileName& dataDir,
const fileName& subDir,
const word& cloudName,
IOstream::streamFormat format
);
//- Write generalized field components
template<class Type>
void ensightVolField
(
const ensightParts& partsList,
const IOobject& fieldObject,
const fvMesh& mesh, const fvMesh& mesh,
const fileName& dataDir, const word& cloudName,
const fileName& subDir, const bool exists,
IOstream::streamFormat format 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 } // namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "ensightOutputFunctions.C" #include "ensightOutputCloudTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -23,24 +23,26 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "ensightCloud.H" #include "ensightOutputCloud.H"
#include "ensightFile.H"
#include "Time.H"
#include "IOField.H"
#include "OFstream.H"
#include "IOmanip.H"
#include "ensightPTraits.H" #include "ensightPTraits.H"
#include "IOField.H"
#include "Time.H"
#include "globalIndex.H"
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
template<class Type> template<class Type>
void Foam::writeCloudField bool Foam::ensightCloud::writeCloudField
( (
const Foam::IOField<Type>& field, const Foam::IOField<Type>& field,
Foam::ensightFile& os Foam::ensightFile& os
) )
{ {
if (returnReduce(field.size(), sumOp<label>()) > 0) const bool exists = (returnReduce(field.size(), sumOp<label>()) > 0);
if (exists)
{ {
if (Pstream::master()) if (Pstream::master())
{ {
@ -106,86 +108,30 @@ void Foam::writeCloudField
else else
{ {
OPstream toMaster(Pstream::scheduled, Pstream::masterNo()); OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster<< field; toMaster
<< field;
} }
} }
return exists;
} }
template<class Type> template<class Type>
void Foam::ensightCloudField bool Foam::ensightCloud::writeCloudField
( (
const Foam::IOobject& fieldObject, const Foam::IOobject& fieldObject,
const Foam::fileName& dataDir, const bool exists,
const Foam::label timeIndex, Foam::autoPtr<Foam::ensightFile>& output
const Foam::word& cloudName,
const Foam::label cloudNo,
Foam::Ostream& ensightCaseFile,
const bool dataExists,
Foam::IOstream::streamFormat format
) )
{ {
const ensight::VarName varName(fieldObject.name()); if (exists)
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)
{ {
IOField<Type> field(fieldObject); IOField<Type> field(fieldObject);
writeCloudField(field, *filePtr); writeCloudField(field, output.rawRef());
} }
if (filePtr) // on master only return true;
{
delete filePtr;
}
} }

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

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

View File

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

View File

@ -1,7 +1,7 @@
// check for "points" in all of the result directories // check for "points" in all of the result directories
// - could restrict to the selected times // - could restrict to the selected times
bool hasMovingMesh = false; bool meshMoving = false;
if (timeDirs.size() > 1 && Pstream::master()) if (timeDirs.size() > 1 && Pstream::master())
{ {
@ -13,7 +13,7 @@ if (timeDirs.size() > 1 && Pstream::master())
Info<< "Search for moving mesh ... " << flush; Info<< "Search for moving mesh ... " << flush;
forAll(timeDirs, timeI) forAll(timeDirs, timeI)
{ {
hasMovingMesh = meshMoving =
( (
isDir(baseDir/timeDirs[timeI].name()/polyMesh::meshSubDir) isDir(baseDir/timeDirs[timeI].name()/polyMesh::meshSubDir)
&& IOobject && IOobject
@ -28,13 +28,13 @@ if (timeDirs.size() > 1 && Pstream::master())
).typeHeaderOk<pointIOField>(true) ).typeHeaderOk<pointIOField>(true)
); );
if (hasMovingMesh) if (meshMoving)
{ {
break; break;
} }
} }
if (hasMovingMesh) if (meshMoving)
{ {
Info<< "found." << nl Info<< "found." << nl
<< " Writing meshes for every timestep." << endl; << " 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 You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
InApplication
foamToEnsight
Description Description
Miscellaneous collection of functions and template related to Ensight data
SourceFiles SourceFiles
ensightCloud.C ensightOutputFunctions.C
ensightCloudTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef ensightCloud_H #ifndef ensightOutputSerialCloud_H
#define ensightCloud_H #define ensightOutputSerialCloud_H
#include "ensightFile.H" #include "ensightFile.H"
#include "fvMesh.H"
#include "Cloud.H" #include "Cloud.H"
#include "polyMesh.H"
#include "IOobject.H" #include "IOobject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
namespace ensightSerialCloud
{
void ensightParticlePositions //- Write cloud positions
void writePositions
( (
const fvMesh& mesh, const polyMesh& mesh,
const fileName& dataDir,
const label timeIndex,
const word& cloudName, const word& cloudName,
const bool dataExists, autoPtr<ensightFile> output
const IOstream::streamFormat format
); );
//- Write cloud field
template<class Type> template<class Type>
void ensightCloudField bool writeCloudField
(
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
( (
const IOField<Type>& field, const IOField<Type>& field,
ensightFile& os ensightFile& os
); );
}
//- Write cloud field
template<class Type>
bool writeCloudField
(
const IOobject& fieldObject,
autoPtr<ensightFile> output
);
} // namespace ensightSerialCloud
} // namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "ensightCloudTemplates.C" #include "ensightOutputSerialCloudTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -21,56 +21,69 @@ License
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
Template to write generalized field components
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "ensightPart.H" #include "ensightOutputSerialCloud.H"
#include "ensightSerialOutput.H"
#include "ensightPTraits.H" #include "ensightPTraits.H"
#include "passiveParticle.H"
#include "IOField.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
template<class Type> template<class Type>
void Foam::ensightPart::writeField bool Foam::ensightSerialCloud::writeCloudField
( (
ensightFile& os, const IOField<Type>& field,
const Field<Type>& field, ensightFile& os
const bool perNode )
) const
{ {
if (this->size() && field.size()) // 6 values per line
{ label count = 0;
writeHeader(os);
if (perNode) forAll(field, i)
{ {
os.writeKeyword("coordinates"); Type val = field[i];
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
label cmpt = ensightPTraits<Type>::componentOrder[d];
writeFieldList(os, field.component(cmpt), labelUList::null());
}
}
else
{
forAll(elementTypes(), elemI)
{
const labelUList& idList = elemLists_[elemI];
if (idList.size()) if (mag(val) < 1e-90)
{ {
os.writeKeyword(elementTypes()[elemI]); val = Zero;
}
for (direction d=0; d < pTraits<Type>::nComponents; ++d) for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{ {
label cmpt = ensightPTraits<Type>::componentOrder[d]; label cmpt = ensightPTraits<Type>::componentOrder[d];
writeFieldList(os, field.component(cmpt), idList); 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 "scalarIOField.H"
#include "tensorIOField.H" #include "tensorIOField.H"
// file-format/conversion
#include "ensightCase.H"
#include "ensightGeoFile.H"
#include "ensightParts.H" #include "ensightParts.H"
#include "ensightOutputFunctions.H" #include "ensightSerialOutput.H"
// local files
#include "ensightOutputSerialCloud.H"
#include "memInfo.H" #include "memInfo.H"
@ -133,33 +139,25 @@ int main(int argc, char *argv[])
); );
// The volume field types that we handle // The volume field types that we handle
wordHashSet volFieldTypes; const wordHashSet volFieldTypes
volFieldTypes.insert(volScalarField::typeName); {
volFieldTypes.insert(volVectorField::typeName); volScalarField::typeName,
volFieldTypes.insert(volSphericalTensorField::typeName); volVectorField::typeName,
volFieldTypes.insert(volSymmTensorField::typeName); volSphericalTensorField::typeName,
volFieldTypes.insert(volTensorField::typeName); volSymmTensorField::typeName,
volTensorField::typeName
};
// The lagrangian field types that we handle // The lagrangian field types that we handle
wordHashSet cloudFieldTypes; const wordHashSet cloudFieldTypes
cloudFieldTypes.insert(scalarIOField::typeName); {
cloudFieldTypes.insert(vectorIOField::typeName); scalarIOField::typeName,
cloudFieldTypes.insert(tensorIOField::typeName); vectorIOField::typeName,
tensorIOField::typeName
const char* geometryName = "geometry"; };
#include "setRootCase.H" #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 // Default to binary output, unless otherwise specified
const IOstream::streamFormat format = const IOstream::streamFormat format =
( (
@ -168,6 +166,57 @@ int main(int argc, char *argv[])
: IOstream::BINARY : 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 // Control for renumbering iterations
label indexingNumber = 0; label indexingNumber = 0;
const bool optIndex = args.optionReadIfPresent("index", indexingNumber); 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 // Always write the geometry, unless the -noMesh option is specified
bool optNoMesh = args.optionFound("noMesh"); 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 // Construct the list of ensight parts for the entire mesh
ensightParts partsList(mesh); ensightParts partsList(mesh);
// Write summary information // 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; << "// summary of ensight parts" << nl << nl;
partsList.writeSummary(partsInfoFile); partsList.writeSummary(info);
} }
#include "checkHasMovingMesh.H" #include "checkMeshMoving.H"
#include "findFields.H" #include "findFields.H"
if (hasMovingMesh && optNoMesh) if (meshMoving && optNoMesh)
{ {
Info<< "mesh is moving: ignoring '-noMesh' option" << endl; Info<< "mesh is moving: ignoring '-noMesh' option" << endl;
optNoMesh = false; 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 " Info<< "Startup in "
<< timer.cpuTimeIncrement() << " s, " << timer.cpuTimeIncrement() << " s, "
<< mem.update().size() << " kB" << nl << endl; << mem.update().size() << " kB" << nl << endl;
@ -272,25 +260,10 @@ int main(int argc, char *argv[])
runTime.setTime(timeDirs[timeI], timeI); runTime.setTime(timeDirs[timeI], timeI);
#include "getTimeIndex.H" #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" #include "moveMesh.H"
ensCase.setTime(timeDirs[timeI], timeIndex);
if (timeI == 0 || mesh.moving()) if (timeI == 0 || mesh.moving())
{ {
if (mesh.moving()) if (mesh.moving())
@ -300,19 +273,8 @@ int main(int argc, char *argv[])
if (!optNoMesh) if (!optNoMesh)
{ {
if (hasMovingMesh) autoPtr<ensightGeoFile> os = ensCase.newGeometry(meshMoving);
{ partsList.write(os.rawRef());
// Remember the time index for the geometry
geometryTimesUsed.append(timeIndex);
}
ensightGeoFile geoFile
(
(hasMovingMesh ? dataDir/subDir : ensightDir),
geometryName,
format
);
partsList.writeGeometry(geoFile);
} }
} }
@ -332,68 +294,76 @@ int main(int argc, char *argv[])
IOobject::NO_WRITE IOobject::NO_WRITE
); );
bool wrote = false;
if (fieldType == volScalarField::typeName) if (fieldType == volScalarField::typeName)
{ {
ensightVolField<scalar> autoPtr<ensightFile> os = ensCase.newData<scalar>
( (
partsList, fieldName
fieldObject,
mesh,
dataDir,
subDir,
format
); );
volScalarField vf(fieldObject, mesh);
wrote = ensightSerialOutput::writeField<scalar>
(
vf, partsList, os
);
} }
else if (fieldType == volVectorField::typeName) else if (fieldType == volVectorField::typeName)
{ {
ensightVolField<vector> autoPtr<ensightFile> os = ensCase.newData<vector>
( (
partsList, fieldName
fieldObject,
mesh,
dataDir,
subDir,
format
); );
volVectorField vf(fieldObject, mesh);
wrote = ensightSerialOutput::writeField<vector>
(
vf, partsList, os
);
} }
else if (fieldType == volSphericalTensorField::typeName) else if (fieldType == volSphericalTensorField::typeName)
{ {
ensightVolField<sphericalTensor> autoPtr<ensightFile> os = ensCase.newData<sphericalTensor>
( (
partsList, fieldName
fieldObject,
mesh,
dataDir,
subDir,
format
); );
volSphericalTensorField vf(fieldObject, mesh);
wrote = ensightSerialOutput::writeField<sphericalTensor>
(
vf, partsList, os
);
} }
else if (fieldType == volSymmTensorField::typeName) else if (fieldType == volSymmTensorField::typeName)
{ {
ensightVolField<symmTensor> autoPtr<ensightFile> os = ensCase.newData<symmTensor>
( (
partsList, fieldName
fieldObject, );
mesh,
dataDir, volSymmTensorField vf(fieldObject, mesh);
subDir, wrote = ensightSerialOutput::writeField<symmTensor>
format (
vf, partsList, os
); );
} }
else if (fieldType == volTensorField::typeName) else if (fieldType == volTensorField::typeName)
{ {
ensightVolField<tensor> autoPtr<ensightFile> os = ensCase.newData<tensor>
( (
partsList, fieldName
fieldObject,
mesh,
dataDir,
subDir,
format
); );
volTensorField vf(fieldObject, mesh);
wrote = ensightSerialOutput::writeField<tensor>
(
vf, partsList, os
);
}
if (wrote)
{
Info<< " " << fieldObject.name() << flush;
} }
} }
Info<< " )" << endl; Info<< " )" << endl;
@ -422,16 +392,16 @@ int main(int argc, char *argv[])
continue; continue;
} }
Info<< "Write " << cloudName << " ( positions" << flush; Info<< "Write " << cloudName << " (" << flush;
ensightParticlePositions ensightSerialCloud::writePositions
( (
mesh, mesh,
dataDir,
subDir,
cloudName, cloudName,
format ensCase.newCloud(cloudName)
); );
Info<< " positions";
forAllConstIter(HashTable<word>, cloudIter(), fieldIter) forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
{ {
@ -449,48 +419,39 @@ int main(int argc, char *argv[])
continue; continue;
} }
bool wrote = false;
if (fieldType == scalarIOField::typeName) if (fieldType == scalarIOField::typeName)
{ {
ensightLagrangianField<scalar> wrote = ensightSerialCloud::writeCloudField<scalar>
( (
*fieldObject, *fieldObject,
dataDir, ensCase.newCloudData<scalar>(cloudName, fieldName)
subDir,
cloudName,
format
); );
} }
else if (fieldType == vectorIOField::typeName) else if (fieldType == vectorIOField::typeName)
{ {
ensightLagrangianField<vector> wrote = ensightSerialCloud::writeCloudField<vector>
( (
*fieldObject, *fieldObject,
dataDir, ensCase.newCloudData<vector>(cloudName, fieldName)
subDir,
cloudName,
format
); );
} }
else if (fieldType == tensorIOField::typeName) else if (fieldType == tensorIOField::typeName)
{ {
ensightLagrangianField<tensor> wrote = ensightSerialCloud::writeCloudField<tensor>
( (
*fieldObject, *fieldObject,
dataDir, ensCase.newCloudData<tensor>(cloudName, fieldName)
subDir,
cloudName,
format
); );
}
if (wrote)
{
Info<< " " << fieldObject->name();
} }
} }
Info<< " )" << endl; Info<< " )" << endl;
// Remember the time index
cloudTimesUsed[cloudName].append(timeIndex);
} }
Info<< "Wrote in " Info<< "Wrote in "
@ -498,7 +459,7 @@ int main(int argc, char *argv[])
<< mem.update().size() << " kB" << endl; << mem.update().size() << " kB" << endl;
} }
#include "ensightOutputCase.H" ensCase.write();
Info<< "\nEnd: " Info<< "\nEnd: "
<< timer.elapsedCpuTime() << " s, " << timer.elapsedCpuTime() << " s, "

View File

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

View File

@ -7,16 +7,14 @@ common/writer/meshWriter.C
common/tables/boundaryRegion.C common/tables/boundaryRegion.C
common/tables/cellTable.C common/tables/cellTable.C
ensight/file/ensightFile.C ensight/mesh/ensightMesh.C
ensight/file/ensightGeoFile.C ensight/mesh/ensightMeshIO.C
ensight/readFile/ensightReadFile.C ensight/mesh/ensightMeshOptions.C
ensight/part/ensightPart.C ensight/part/ensightPart.C
ensight/part/ensightPartIO.C
ensight/part/ensightPartCells.C ensight/part/ensightPartCells.C
ensight/part/ensightPartFaces.C ensight/part/ensightPartFaces.C
ensight/part/ensightParts.C ensight/part/ensightParts.C
starcd/STARCDMeshReader.C starcd/STARCDMeshReader.C
starcd/STARCDMeshWriter.C starcd/STARCDMeshWriter.C

View File

@ -0,0 +1,434 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "ensightMesh.H"
#include "fvMesh.H"
#include "globalMeshData.H"
#include "PstreamCombineReduceOps.H"
#include "processorPolyPatch.H"
#include "mapDistribute.H"
#include "stringListOps.H"
#include "ensightFile.H"
#include "ensightGeoFile.H"
#include "demandDrivenData.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ensightMesh::clear()
{
meshCells_.clear();
boundaryPatchFaces_.clear();
faceZoneFaces_.clear();
patchLookup_.clear();
globalPointsPtr_.clear();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightMesh::ensightMesh
(
const fvMesh& mesh,
const ensightMesh::options& opts
)
:
options_(new options(opts)),
mesh_(mesh),
needsUpdate_(true)
{
if (!option().lazy())
{
correct();
}
}
Foam::ensightMesh::ensightMesh
(
const fvMesh& mesh,
const IOstream::streamFormat format
)
:
options_(new options(format)),
mesh_(mesh),
needsUpdate_(true)
{
if (!option().lazy())
{
correct();
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightMesh::~ensightMesh()
{
deleteDemandDrivenData(options_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::ensightMesh::needsUpdate() const
{
return needsUpdate_;
}
bool Foam::ensightMesh::expire()
{
clear();
// already marked as expired
if (needsUpdate_)
{
return false;
}
needsUpdate_ = true;
return true;
}
void Foam::ensightMesh::correct()
{
clear();
// First see if patches are allowed/disallowed
// and if only particular patches should be selected
label nParts = 1; // provisionally (for internalMesh)
if (option().usePatches())
{
// Patches are output. Check that they are synced.
mesh_.boundaryMesh().checkParallelSync(true);
wordList patchNames = mesh_.boundaryMesh().names();
if (Pstream::parRun())
{
patchNames.setSize
(
mesh_.boundary().size()
- mesh_.globalData().processorPatches().size()
);
}
labelList matched;
bool useAll = true;
const wordReList& matcher = option().patchSelection();
if (notNull(matcher))
{
nParts = 0; // no internalMesh
if (!matcher.empty())
{
useAll = false;
matched = findMatchingStrings
(
wordReListMatcher(matcher),
patchNames
);
}
}
if (useAll)
{
matched = identity(patchNames.size());
}
forAll(matched, matchi)
{
const label patchId = matched[matchi];
const word& patchName = patchNames[patchId];
// use fvPatch (not polyPatch) to automatically remove empty patches
const fvPatch& p = mesh_.boundary()[patchId];
// yes we most likely want this patch.
// - can use insert or set, since hash was cleared before
boundaryPatchFaces_.set(patchName, ensightFaces());
ensightFaces& ensFaces = boundaryPatchFaces_[patchName];
if (p.size())
{
// use local face addressing (offset = 0),
// since this is what we'll need later when writing fields
ensFaces.classify(p.patch());
}
else
{
// patch is empty (on this processor)
// or the patch is 'empty' (as fvPatch type)
ensFaces.clear();
}
// finalize
ensFaces.reduce();
if (ensFaces.total())
{
patchLookup_.set(patchId, patchName);
ensFaces.index() = nParts++;
}
else
{
boundaryPatchFaces_.erase(patchName);
}
}
// At this point,
// * patchLookup_ is a map of (patchId, name)
// * boundaryPatchFaces_ is a lookup by name for the faces elements
}
if (useInternalMesh())
{
meshCells_.index() = 0;
meshCells_.classify(mesh_);
// Determine parallel shared points
globalPointsPtr_ = mesh_.globalData().mergePoints
(
pointToGlobal_,
uniquePointMap_
);
}
meshCells_.reduce();
// faceZones
if (option().useFaceZones())
{
// Mark boundary faces to be excluded from export
PackedBoolList excludeFace(mesh_.nFaces()); // all false
forAll(mesh_.boundaryMesh(), patchi)
{
const polyPatch& pp = mesh_.boundaryMesh()[patchi];
if
(
isA<processorPolyPatch>(pp)
&& !refCast<const processorPolyPatch>(pp).owner()
)
{
label bFaceI = pp.start();
forAll(pp, i)
{
excludeFace.set(bFaceI++);
}
}
}
const wordReList& matcher = option().faceZoneSelection();
wordList selectZones = mesh_.faceZones().names();
inplaceSubsetMatchingStrings
(
wordReListMatcher(matcher),
selectZones
);
// have same order as later with sortedToc()
Foam::sort(selectZones);
// Count face types in each selected faceZone
forAll(selectZones, zoneI)
{
const word& zoneName = selectZones[zoneI];
const label zoneID = mesh_.faceZones().findZoneID(zoneName);
const faceZone& fz = mesh_.faceZones()[zoneID];
// yes we most likely want this zone
// - can use insert or set, since hash was cleared before
faceZoneFaces_.set(zoneName, ensightFaces());
ensightFaces& ensFaces = faceZoneFaces_[zoneName];
if (fz.size())
{
ensFaces.classify
(
mesh_.faces(),
fz,
fz.flipMap(),
excludeFace
);
}
// finalize
ensFaces.reduce();
if (ensFaces.total())
{
ensFaces.index() = nParts++;
}
else
{
faceZoneFaces_.erase(zoneName);
}
}
}
needsUpdate_ = false;
}
void Foam::ensightMesh::write(ensightGeoFile& os) const
{
if (useInternalMesh())
{
label nPoints = globalPoints().size();
const pointField uniquePoints(mesh_.points(), uniquePointMap_);
// writePartHeader(os, 0, "internalMesh");
// beginCoordinates(os, nPoints);
writeAllPoints
(
meshCells_.index(),
"internalMesh",
nPoints,
uniquePoints,
os
);
writeCellConnectivity(meshCells_, pointToGlobal_, os);
}
//
// write patches
// use sortedToc for extra safety
//
const labelList patchIds = patchLookup_.sortedToc();
forAll(patchIds, listi)
{
const label patchId = patchIds[listi];
const word& patchName = patchLookup_[patchId];
const ensightFaces& ensFaces = boundaryPatchFaces_[patchName];
const polyPatch& pp = mesh_.boundaryMesh()[patchId];
// Renumber the patch points/faces into unique points
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPointsPtr =
mesh_.globalData().mergePoints
(
pp.meshPoints(),
pp.meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels
);
pointField uniquePoints(mesh_.points(), uniqueMeshPointLabels);
// Renumber the patch faces
faceList patchFaces(pp.localFaces());
forAll(patchFaces, i)
{
inplaceRenumber(pointToGlobal, patchFaces[i]);
}
writeAllPoints
(
ensFaces.index(),
patchName,
globalPointsPtr().size(),
uniquePoints,
os
);
writeFaceConnectivity(ensFaces, patchFaces, os);
}
//
// write faceZones, if requested
//
const wordList zoneNames = faceZoneFaces_.sortedToc();
forAll(zoneNames, zonei)
{
const word& zoneName = zoneNames[zonei];
const ensightFaces& ensFaces = faceZoneFaces_[zoneName];
label zoneId = mesh_.faceZones().findZoneID(zoneName);
const faceZone& fz = mesh_.faceZones()[zoneId];
// Renumber the faceZone points/faces into unique points
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPointsPtr =
mesh_.globalData().mergePoints
(
fz().meshPoints(),
fz().meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels
);
pointField uniquePoints(mesh_.points(), uniqueMeshPointLabels);
primitiveFacePatch facePatch
(
faceList(mesh_.faces(), ensFaces.faceIds()),
mesh_.points()
);
const boolList& flip = ensFaces.flipMap();
forAll(facePatch[faceI], faceI)
{
if (flip[faceI])
{
facePatch[faceI].flip();
}
}
// Faces belonging to the faceZone, in local numbering
faceList localFaces(facePatch.localFaces());
// Renumber the faceZone master faces
forAll(localFaces, i)
{
inplaceRenumber(pointToGlobal, localFaces[i]);
}
writeAllPoints
(
ensFaces.index(),
zoneName,
globalPointsPtr().size(),
uniquePoints,
os
);
writeFaceConnectivity(ensFaces, localFaces, os, true);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,453 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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
Encapsulation of volume meshes for writing in ensight format.
SourceFiles
ensightMesh.C
ensightMeshIO.C
ensightMeshOptions.C
\*---------------------------------------------------------------------------*/
#ifndef ensightMesh_H
#define ensightMesh_H
#include "ensightCells.H"
#include "ensightFaces.H"
#include "ensightGeoFile.H"
#include "cellList.H"
#include "faceList.H"
#include "cellShapeList.H"
#include "HashTable.H"
#include "Map.H"
#include "scalarField.H"
#include "wordReList.H"
#include "globalIndex.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
class fvMesh;
class ensightMesh;
/*---------------------------------------------------------------------------*\
Class ensightMesh Declaration
\*---------------------------------------------------------------------------*/
class ensightMesh
{
public:
// Forward declarations
class options;
private:
// Private data
//- Writer options
const options* options_;
//- Reference to the OpenFOAM mesh
const fvMesh& mesh_;
//- The volume cells (internalMesh)
ensightCells meshCells_;
//- Face elements per patch
HashTable<ensightFaces> boundaryPatchFaces_;
//- Face elements per faceZone
HashTable<ensightFaces> faceZoneFaces_;
//- The list of patches to be output
Map<word> patchLookup_;
//- Track if it needs an update
mutable bool needsUpdate_;
// 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
//- Clear some storage
void clear();
//- Inplace renumber of cell-shapes
static cellShapeList& renumberShapes
(
cellShapeList&,
const labelUList& pointToGlobal
);
static cellShapeList map
(
const cellShapeList&,
const labelUList& prims,
const labelUList& pointToGlobal
);
//- Write list of faces
static void writeFaceList
(
const faceList&,
ensightGeoFile&
);
//- Write list of faces
static void writeFaceList
(
const UIndirectList<face>&,
ensightGeoFile&
);
//- Write sizes of faces in the list
static void writeFaceSizes
(
const faceList&,
ensightGeoFile&
);
//- Write sizes of faces in the list
static void writeFaceSizes
(
const UIndirectList<face>&,
ensightGeoFile&
);
//- Write cell connectivity via shell shapes
static void writeCellShapes
(
const cellShapeList&,
ensightGeoFile&
);
void writePolysNFaces
(
const labelList& polys,
const cellList& cellFaces,
ensightGeoFile&
) const;
void writePolysNPointsPerFace
(
const labelList& polys,
const cellList& cellFaces,
const faceList& faces,
ensightGeoFile&
) const;
void writePolysPoints
(
const labelList& polys,
const cellList& cellFaces,
const faceList& faces,
const labelList& faceOwner,
ensightGeoFile&
) const;
void writePolysConnectivity
(
const labelList& addr,
const labelList& pointToGlobal,
ensightGeoFile&
) const;
void writeCellConnectivity
(
const ensightCells&,
const labelList& pointToGlobal,
ensightGeoFile&
) const;
void writeCellConnectivity
(
ensightCells::elemType elemType,
const ensightCells&,
const labelList& pointToGlobal,
ensightGeoFile&
) const;
void writeFaceConnectivity
(
ensightFaces::elemType elemType,
const label nTotal,
const faceList& faceLst,
const labelList& addr,
ensightGeoFile&
) const;
void writeFaceConnectivity
(
ensightFaces::elemType elemType,
const label nTotal,
const faceList& faceLst,
ensightGeoFile&
) const;
void writeFaceConnectivity
(
const ensightFaces&,
const faceList& faceLst,
ensightGeoFile&,
const bool raw = false
) const;
void writeAllPoints
(
const label partId,
const word& ensightPartName,
const label nTotal,
const pointField& uniquePoints,
ensightGeoFile&
) const;
//- Disallow default bitwise copy construct
ensightMesh(const ensightMesh&) = delete;
//- Disallow default bitwise assignment
void operator=(const ensightMesh&) = delete;
public:
// Constructors
//- Construct from components
ensightMesh
(
const fvMesh& mesh,
const options& opts
);
//- Construct from fvMesh with all default options
ensightMesh
(
const fvMesh& mesh,
const IOstream::streamFormat format = IOstream::BINARY
);
//- Destructor
~ensightMesh();
// Member Functions
// Access
//- Reference to the underlying fvMesh
inline const fvMesh& mesh() const;
//- Reference to the writer/mesh options
inline const ensightMesh::options& option() const;
//- Ascii/Binary file output
inline IOstream::streamFormat format() const;
//- Using internalMesh?
inline bool useInternalMesh() const;
//- Using deprecated order? (hex prism pyr tet poly)
inline bool deprecatedOrder() const;
//- The volume cells (internalMesh)
inline const ensightCells& meshCells() const;
//- The list of patches to be output
inline const Map<word>& patches() const;
//- Face elements per selected patch
inline const HashTable<ensightFaces>& boundaryPatchFaces() const;
//- Face elements per selected faceZone.
// To be output in sorted order.
inline const HashTable<ensightFaces>& faceZoneFaces() const;
// 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
//- Does the content need an update?
bool needsUpdate() const;
//- Mark as needing an update.
// May also free up unneeded data.
// Return false if already marked as expired.
bool expire();
//- Update for new mesh
void correct();
// I-O
//- Write to file
inline void write(autoPtr<ensightGeoFile>& os) const;
//- Write to file
void write(ensightGeoFile& os) const;
};
//- Configuration options for the ensightMesh
class ensightMesh::options
{
//- Ascii/Binary file output
IOstream::streamFormat format_;
//- Create in 'expired' mode
bool lazy_;
//- Suppress patches
bool noPatches_;
//- Using deprecated order (hex prism pyr tet poly)
bool deprecatedOrder_;
//- Output selected patches only
autoPtr<wordReList> patchPatterns_;
//- Output selected faceZones
autoPtr<wordReList> faceZonePatterns_;
public:
// Constructors
//- Construct with the specified format (default is binary)
options(IOstream::streamFormat format = IOstream::BINARY);
// Member Functions
// Access
//- Ascii/Binary file output
IOstream::streamFormat format() const;
//- Lazy creation? (ie, ensightMesh starts as needsUpdate)
bool lazy() const;
//- Using internalMesh?
bool useInternalMesh() const;
//- Using deprecated order? (hex prism pyr tet poly)
bool deprecatedOrder() const;
//- Using patches?
bool usePatches() const;
//- Using faceZones?
bool useFaceZones() const;
//- Selection of patches in effect?
bool usePatchSelection() const;
//- Selection of patches - null reference if not available
const wordReList& patchSelection() const;
//- Selection of faceZones - null reference if not available
const wordReList& faceZoneSelection() const;
// Edit
//- Reset to defaults
void reset();
//- Lazy creation - ensightMesh starts as needsUpdate.
void lazy(const bool);
//- Alter deprecated order.
void deprecatedOrder(const bool);
//- Alter the patches/no-patches state
void noPatches(const bool);
//- Define patch selection matcher
void patchSelection(const wordReList&);
//- Define faceZone selection matcher
void faceZoneSelection(const wordReList&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ensightMeshI.H"
#endif
// ************************************************************************* //

View File

@ -0,0 +1,90 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
inline const Foam::fvMesh& Foam::ensightMesh::mesh() const
{
return mesh_;
}
inline const Foam::ensightMesh::options& Foam::ensightMesh::option() const
{
return *options_;
}
inline Foam::IOstream::streamFormat Foam::ensightMesh::format() const
{
return options_->format();
}
inline bool Foam::ensightMesh::useInternalMesh() const
{
return options_->useInternalMesh();
}
inline bool Foam::ensightMesh::deprecatedOrder() const
{
return options_->deprecatedOrder();
}
inline const Foam::ensightCells& Foam::ensightMesh::meshCells() const
{
return meshCells_;
}
inline const Foam::Map<Foam::word>& Foam::ensightMesh::patches() const
{
return patchLookup_;
}
inline const Foam::HashTable<Foam::ensightFaces>&
Foam::ensightMesh::boundaryPatchFaces() const
{
return boundaryPatchFaces_;
}
inline const Foam::HashTable<Foam::ensightFaces>&
Foam::ensightMesh::faceZoneFaces() const
{
return faceZoneFaces_;
}
inline void Foam::ensightMesh::write(autoPtr<ensightGeoFile>& os) const
{
write(os.rawRef());
}
// ************************************************************************* //

View File

@ -0,0 +1,698 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 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 "ensightMesh.H"
#include "fvMesh.H"
#include "globalMeshData.H"
#include "PstreamCombineReduceOps.H"
#include "processorPolyPatch.H"
#include "mapDistribute.H"
#include "stringListOps.H"
#include "ensightFile.H"
#include "ensightGeoFile.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::cellShapeList& Foam::ensightMesh::renumberShapes
(
cellShapeList& shapes,
const labelUList& pointToGlobal
)
{
forAll(shapes, i)
{
inplaceRenumber(pointToGlobal, shapes[i]);
}
return shapes;
}
Foam::cellShapeList Foam::ensightMesh::map
(
const cellShapeList& shapes,
const labelUList& addr,
const labelUList& pointToGlobal
)
{
cellShapeList lst(addr.size());
forAll(addr, i)
{
lst[i] = shapes[addr[i]];
inplaceRenumber(pointToGlobal, lst[i]);
}
return lst;
}
void Foam::ensightMesh::writeFaceList
(
const faceList& faceLst,
ensightGeoFile& os
)
{
forAll(faceLst, i)
{
const face& f = faceLst[i];
forAll(f, fp)
{
os.write(f[fp] + 1);
}
os.newline();
}
}
void Foam::ensightMesh::writeFaceList
(
const UIndirectList<face>& faceLst,
ensightGeoFile& os
)
{
forAll(faceLst, i)
{
const face& f = faceLst[i];
forAll(f, fp)
{
os.write(f[fp] + 1);
}
os.newline();
}
}
void Foam::ensightMesh::writeFaceSizes
(
const faceList& faceLst,
ensightGeoFile& os
)
{
forAll(faceLst, i)
{
const face& f = faceLst[i];
os.write(f.size());
}
}
void Foam::ensightMesh::writeFaceSizes
(
const UIndirectList<face>& faceLst,
ensightGeoFile& os
)
{
forAll(faceLst, i)
{
const face& f = faceLst[i];
os.write(f.size());
}
}
void Foam::ensightMesh::writeCellShapes
(
const cellShapeList& shapes,
ensightGeoFile& os
)
{
forAll(shapes, i)
{
const cellShape& cellPoints = shapes[i];
// convert global -> local index
// (note: Ensight indices start with 1)
// In ASCII, write one cell per line
forAll(cellPoints, pointI)
{
os.write(cellPoints[pointI] + 1);
}
os.newline();
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ensightMesh::writePolysNFaces
(
const labelList& addr,
const cellList& cellFaces,
ensightGeoFile& os
) const
{
forAll(addr, i)
{
const labelList& cf = cellFaces[addr[i]];
os.write(cf.size());
}
}
void Foam::ensightMesh::writePolysNPointsPerFace
(
const labelList& addr,
const cellList& cellFaces,
const faceList& faces,
ensightGeoFile& os
) const
{
forAll(addr, i)
{
const labelList& cf = cellFaces[addr[i]];
forAll(cf, faceI)
{
os.write(faces[cf[faceI]].size());
}
}
}
void Foam::ensightMesh::writePolysPoints
(
const labelList& addr,
const cellList& cellFaces,
const faceList& faces,
const labelList& faceOwner,
ensightGeoFile& os
) const
{
forAll(addr, i)
{
const label cellId = addr[i];
const labelList& cf = cellFaces[cellId];
forAll(cf, faceI)
{
const label faceId = cf[faceI];
const face& f = faces[faceId]; // face points (in global points)
if (faceId < faceOwner.size() && faceOwner[faceId] != cellId)
{
// internal face, neighbour
//
// as per face::reverseFace(), but without copying
os.write(f[0] + 1);
for (label ptI = f.size()-1; ptI > 0; --ptI)
{
os.write(f[ptI] + 1);
}
}
else
{
forAll(f, ptI)
{
os.write(f[ptI] + 1);
}
}
os.newline();
}
}
}
void Foam::ensightMesh::writePolysConnectivity
(
const labelList& addr,
const labelList& pointToGlobal,
ensightGeoFile& os
) const
{
const cellList& cellFaces = mesh_.cells();
const faceList& meshFaces = mesh_.faces();
const labelList& faceOwner = mesh_.faceOwner();
if (Pstream::master())
{
// Number of faces for each poly cell
// Master
writePolysNFaces(addr, cellFaces, os);
// Slaves
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::scheduled, slave);
labelList addr(fromSlave);
cellList cellFaces(fromSlave);
writePolysNFaces(addr, cellFaces, os);
}
}
else
{
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster
<< addr
<< cellFaces;
}
// Number of points for each face of the above list
if (Pstream::master())
{
// Master
writePolysNPointsPerFace
(
addr,
cellFaces,
meshFaces,
os
);
// Slaves
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::scheduled, slave);
labelList addr(fromSlave);
cellList cellFaces(fromSlave);
faceList meshFaces(fromSlave);
writePolysNPointsPerFace
(
addr,
cellFaces,
meshFaces,
os
);
}
}
else
{
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster
<< addr
<< cellFaces
<< meshFaces;
}
// Renumber faces to use global point numbers
faceList faces(mesh_.faces());
forAll(faces, i)
{
inplaceRenumber(pointToGlobal, faces[i]);
}
// List of points id for each face of the above list
if (Pstream::master())
{
// Master
writePolysPoints
(
addr,
cellFaces,
faces,
faceOwner,
os
);
// Slaves
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::scheduled, slave);
labelList addr(fromSlave);
cellList cellFaces(fromSlave);
faceList faces(fromSlave);
labelList faceOwner(fromSlave);
writePolysPoints
(
addr,
cellFaces,
faces,
faceOwner,
os
);
}
}
else
{
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster
<< addr
<< cellFaces
<< faces
<< faceOwner;
}
}
void Foam::ensightMesh::writeCellConnectivity
(
const ensightCells::elemType elemType,
const ensightCells& ensCells,
const labelList& pointToGlobal,
ensightGeoFile& os
) const
{
const label nTotal = ensCells.total(elemType);
if (nTotal)
{
const labelUList& addr = ensCells.cellIds(elemType);
if (Pstream::master())
{
os.writeKeyword(ensightCells::key(elemType));
os.write(nTotal);
os.newline();
}
if (elemType == ensightCells::NFACED)
{
writePolysConnectivity
(
addr,
pointToGlobal,
os
);
}
else
{
const cellShapeList shapes = map
(
mesh_.cellShapes(),
addr,
pointToGlobal
);
if (Pstream::master())
{
writeCellShapes(shapes, os);
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::scheduled, slave);
cellShapeList received(fromSlave);
writeCellShapes(received, os);
}
}
else
{
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster
<< shapes;
}
}
}
}
void Foam::ensightMesh::writeCellConnectivity
(
const ensightCells& ensCells,
const labelList& pointToGlobal,
ensightGeoFile& os
) const
{
if (deprecatedOrder())
{
// element ordering used in older versions
ensightCells::elemType oldOrder[5] =
{
ensightCells::HEXA8,
ensightCells::PENTA6,
ensightCells::PYRAMID5,
ensightCells::TETRA4,
ensightCells::NFACED
};
for (int i=0; i < 5; ++i)
{
const ensightCells::elemType& what = oldOrder[i];
writeCellConnectivity(what, ensCells, pointToGlobal, os);
}
}
else
{
const List<ensightCells::elemType> enums =
ensightCells::elemEnum.enums();
forAllConstIter(List<ensightCells::elemType>, enums, iter)
{
const ensightCells::elemType what = *iter;
writeCellConnectivity(what, ensCells, pointToGlobal, os);
}
}
}
void Foam::ensightMesh::writeFaceConnectivity
(
ensightFaces::elemType elemType,
const label nTotal,
const faceList& faces,
ensightGeoFile& os
) const
{
if (nTotal)
{
if (Pstream::master())
{
os.writeKeyword(ensightFaces::key(elemType));
os.write(nTotal);
os.newline();
}
if (elemType == ensightFaces::NSIDED)
{
// Number of points per face
if (Pstream::master())
{
writeFaceSizes(faces, os);
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::scheduled, slave);
faceList received(fromSlave);
writeFaceSizes(received, os);
}
}
else
{
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster
<< faces;
}
}
// List of points id for each face
if (Pstream::master())
{
writeFaceList(faces, os);
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::scheduled, slave);
faceList received(fromSlave);
writeFaceList(received, os);
}
}
else
{
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster
<< faces;
}
}
}
void Foam::ensightMesh::writeFaceConnectivity
(
ensightFaces::elemType elemType,
const label nTotal,
const faceList& faceLst,
const labelList& addr,
ensightGeoFile& os
) const
{
if (nTotal)
{
if (Pstream::master())
{
os.writeKeyword(ensightFaces::key(elemType));
os.write(nTotal);
os.newline();
}
const UIndirectList<face> faces(faceLst, addr);
if (elemType == ensightFaces::NSIDED)
{
// Number of points per face
if (Pstream::master())
{
writeFaceSizes(faces, os);
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::scheduled, slave);
faceList received(fromSlave);
writeFaceSizes(received, os);
}
}
else
{
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster
<< faces;
}
}
// List of points id per face
if (Pstream::master())
{
writeFaceList(faces, os);
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::scheduled, slave);
faceList received(fromSlave);
writeFaceList(received, os);
}
}
else
{
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster
<< faces;
}
}
}
void Foam::ensightMesh::writeFaceConnectivity
(
const ensightFaces& ensFaces,
const faceList& faceLst,
ensightGeoFile& os,
const bool raw
) const
{
const List<ensightFaces::elemType> enums = ensightFaces::elemEnum.enums();
if (raw)
{
forAllConstIter(List<ensightFaces::elemType>, enums, iter)
{
const ensightFaces::elemType what = *iter;
writeFaceConnectivity
(
what,
ensFaces.total(what),
SubList<face>
(
faceLst,
ensFaces.faceIds(what).size(),
ensFaces.offset(what)
),
os
);
}
}
else
{
forAllConstIter(List<ensightFaces::elemType>, enums, iter)
{
const ensightFaces::elemType what = *iter;
writeFaceConnectivity
(
what,
ensFaces.total(what),
faceLst,
ensFaces.faceIds(what),
os
);
}
}
}
void Foam::ensightMesh::writeAllPoints
(
const label partId,
const word& ensightPartName,
const label nPoints,
const pointField& uniquePoints,
ensightGeoFile& os
) const
{
if (Pstream::master())
{
os.beginPart(partId, ensightPartName);
// write points
os.beginCoordinates(nPoints);
for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
{
os.writeList(uniquePoints.component(cmpt));
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::scheduled, slave);
scalarField received(fromSlave);
os.writeList(received);
}
}
}
else
{
for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
{
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster
<< uniquePoints.component(cmpt);
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,174 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "ensightMesh.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightMesh::options::options(IOstream::streamFormat format)
:
format_(format),
lazy_(false),
noPatches_(false),
deprecatedOrder_(false),
patchPatterns_(),
faceZonePatterns_()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::IOstream::streamFormat Foam::ensightMesh::options::format() const
{
return format_;
}
bool Foam::ensightMesh::options::lazy() const
{
return lazy_;
}
bool Foam::ensightMesh::options::useInternalMesh() const
{
return noPatches_ ? true : !patchPatterns_.valid();
}
bool Foam::ensightMesh::options::deprecatedOrder() const
{
return deprecatedOrder_;
}
bool Foam::ensightMesh::options::usePatches() const
{
return !noPatches_;
}
bool Foam::ensightMesh::options::useFaceZones() const
{
return faceZonePatterns_.valid();
}
bool Foam::ensightMesh::options::usePatchSelection() const
{
return noPatches_ ? false : patchPatterns_.valid();
}
void Foam::ensightMesh::options::reset()
{
noPatches_ = false;
patchPatterns_.clear();
faceZonePatterns_.clear();
}
void Foam::ensightMesh::options::lazy(const bool b)
{
lazy_ = b;
}
void Foam::ensightMesh::options::deprecatedOrder(const bool b)
{
deprecatedOrder_ = b;
}
void Foam::ensightMesh::options::noPatches(const bool b)
{
noPatches_ = b;
if (noPatches_ && patchPatterns_.valid())
{
WarningInFunction
<< " existing patch selection disabled"
<< endl;
patchPatterns_.clear();
}
}
void Foam::ensightMesh::options::patchSelection
(
const wordReList& patterns
)
{
if (noPatches_)
{
WarningInFunction
<< " patch selection specified, but noPatches was already active"
<< endl;
}
else
{
patchPatterns_.reset(new wordReList(patterns));
}
}
void Foam::ensightMesh::options::faceZoneSelection
(
const wordReList& patterns
)
{
faceZonePatterns_.reset(new wordReList(patterns));
}
const Foam::wordReList& Foam::ensightMesh::options::patchSelection() const
{
if (usePatchSelection())
{
return patchPatterns_();
}
else
{
return wordReList::null();
}
}
const Foam::wordReList& Foam::ensightMesh::options::faceZoneSelection() const
{
if (faceZonePatterns_.valid())
{
return faceZonePatterns_();
}
else
{
return wordReList::null();
}
}
// ************************************************************************* //

View File

@ -0,0 +1,151 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::ensightOutput
Description
A collection of functions for writing ensight file content in parallel.
SourceFiles
ensightOutput.C
ensightOutputTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef ensightOutput_H
#define ensightOutput_H
#include "ensightFile.H"
#include "ensightMesh.H"
#include "autoPtr.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightOutput Declaration
\*---------------------------------------------------------------------------*/
class ensightOutput
{
// Private Methods
template<class Type>
static void writeField
(
const char* key,
const Field<Type>& fld,
ensightFile& os
);
template<class Type>
static bool writePatchField
(
const Field<Type>& pf,
const ensightFaces& ensFaces,
ensightFile& os
);
template<class Type>
static bool writeVolField
(
const Field<Type>& vf,
const ensightCells& ensCells,
ensightFile& os,
const bool deprecatedOrder = false
);
//- Write volume field component-wise
template<class Type>
static bool writeField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightMesh& ensMesh,
ensightFile& os
);
//- Write point field component-wise
template<class Type>
static bool ensightPointField
(
const GeometricField<Type, pointPatchField, pointMesh>& pf,
const ensightMesh& ensMesh,
ensightFile& os
);
//- Disallow null constructor
ensightOutput() = delete;
public:
// Public Methods
//- Write volume field component-wise
template<class Type>
static bool writeField
(
const GeometricField<Type, fvPatchField, volMesh>&,
const ensightMesh& ensMesh,
ensightFile& os,
const bool nodeValues
);
//- Write volume field component-wise
template<class Type>
static inline bool writeField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightMesh& ensMesh,
autoPtr<ensightFile>& output,
const bool nodeValues = false
)
{
return writeField(vf, ensMesh, output.rawRef(), nodeValues);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightOutputTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,461 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "ensightOutput.H"
#include "ensightPTraits.H"
#include "fvMesh.H"
#include "volFields.H"
#include "IOField.H"
#include "OFstream.H"
#include "IOmanip.H"
#include "Time.H"
#include "volPointInterpolation.H"
#include "globalIndex.H"
#include "uindirectPrimitivePatch.H"
#include "interpolation.H"
#include "linear.H"
// * * * * * * * * * * Static Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::ensightOutput::writeField
(
const char* key,
const Field<Type>& fld,
ensightFile& os
)
{
if (returnReduce(fld.size(), sumOp<label>()) > 0)
{
if (Pstream::master())
{
os.writeKeyword(key);
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
const label cmpt = ensightPTraits<Type>::componentOrder[d];
os.writeList(fld.component(cmpt));
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::scheduled, slave);
scalarField received(fromSlave);
os.writeList(received);
}
}
}
else
{
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
const label cmpt = ensightPTraits<Type>::componentOrder[d];
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster
<< fld.component(cmpt);
}
}
}
}
template<class Type>
bool Foam::ensightOutput::writePatchField
(
const Field<Type>& pf,
const ensightFaces& ensFaces,
Foam::ensightFile& os
)
{
if (ensFaces.total())
{
if (Pstream::master())
{
os.beginPart(ensFaces.index());
}
const List<ensightFaces::elemType> enums =
ensightFaces::elemEnum.enums();
forAllConstIter(List<ensightFaces::elemType>, enums, iter)
{
const ensightFaces::elemType& what = *iter;
writeField
(
ensightFaces::key(what),
Field<Type>(pf, ensFaces.faceIds(what)),
os
);
}
return true;
}
else
{
return false;
}
}
template<class Type>
bool Foam::ensightOutput::writeVolField
(
const Field<Type>& vf,
const ensightCells& ensCells,
ensightFile& os,
const bool deprecatedOrder
)
{
if (ensCells.total())
{
if (Pstream::master())
{
os.beginPart(ensCells.index());
}
if (deprecatedOrder)
{
// element ordering used in older versions
ensightCells::elemType oldOrder[5] =
{
ensightCells::HEXA8,
ensightCells::PENTA6,
ensightCells::PYRAMID5,
ensightCells::TETRA4,
ensightCells::NFACED
};
for (int i=0; i < 5; ++i)
{
const ensightCells::elemType& what = oldOrder[i];
writeField
(
ensightCells::key(what),
Field<Type>(vf, ensCells.cellIds(what)),
os
);
}
}
else
{
const List<ensightCells::elemType> enums =
ensightCells::elemEnum.enums();
forAllConstIter(List<ensightCells::elemType>, enums, iter)
{
const ensightCells::elemType& what = *iter;
writeField
(
ensightCells::key(what),
Field<Type>(vf, ensCells.cellIds(what)),
os
);
}
}
return true;
}
else
{
return false;
}
}
template<class Type>
bool Foam::ensightOutput::writeField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightMesh& ensMesh,
ensightFile& os
)
{
const fvMesh& mesh = ensMesh.mesh();
const ensightCells& meshCells = ensMesh.meshCells();
const Map<word>& patchLookup = ensMesh.patches();
const HashTable<ensightFaces>& patchFaces = ensMesh.boundaryPatchFaces();
const HashTable<ensightFaces>& zoneFaces = ensMesh.faceZoneFaces();
//
// write internalMesh, unless patch-selection was requested
//
if (ensMesh.useInternalMesh())
{
writeVolField(vf, meshCells, os, ensMesh.deprecatedOrder());
}
//
// write patches
// use sortedToc for extra safety
//
const labelList patchIds = patchLookup.sortedToc();
forAll(patchIds, listi)
{
const label patchId = patchIds[listi];
const word& patchName = patchLookup[listi];
const ensightFaces& ensFaces = patchFaces[patchName];
writePatchField
(
vf.boundaryField()[patchId],
ensFaces,
os
);
}
//
// write faceZones, if requested
// use sortedToc for extra safety
//
const wordList zoneNames = zoneFaces.sortedToc();
if (!zoneNames.empty())
{
// Interpolates cell values to faces - needed only when exporting
// faceZones...
GeometricField<Type, fvsPatchField, surfaceMesh> sf
(
Foam::linearInterpolate(vf)
);
// flat boundary field
// as per volPointInterpolation::flatBoundaryField()
Field<Type> flat(mesh.nFaces() - mesh.nInternalFaces());
const fvBoundaryMesh& bm = mesh.boundary();
forAll(vf.boundaryField(), patchI)
{
const polyPatch& pp = bm[patchI].patch();
const label bFaceI = pp.start() - mesh.nInternalFaces();
if
(
isA<emptyFvPatch>(bm[patchI])
|| vf.boundaryField()[patchI].coupled()
)
{
SubList<Type>
(
flat,
pp.size(),
bFaceI
) = Zero;
}
else
{
SubList<Type>
(
flat,
vf.boundaryField()[patchI].size(),
bFaceI
) = vf.boundaryField()[patchI];
}
}
forAll(zoneNames, zonei)
{
const word& zoneName = zoneNames[zonei];
const ensightFaces& ensFaces = zoneFaces[zoneName];
// field (local size)
Field<Type> values(ensFaces.size());
// Loop over face ids to store the needed field values
// - internal faces use linear interpolation
// - boundary faces use the corresponding patch value
forAll(ensFaces, i)
{
label faceId = ensFaces[i];
values[i] =
(
mesh.isInternalFace(faceId)
? sf[faceId]
: flat[faceId - mesh.nInternalFaces()]
);
}
writePatchField(values, ensFaces, os);
}
}
return true;
}
template<class Type>
bool Foam::ensightOutput::ensightPointField
(
const GeometricField<Type, pointPatchField, pointMesh>& pf,
const ensightMesh& ensMesh,
ensightFile& os
)
{
const fvMesh& mesh = ensMesh.mesh();
const Map<word>& patchLookup = ensMesh.patches();
const HashTable<ensightFaces>& patchFaces = ensMesh.boundaryPatchFaces();
const HashTable<ensightFaces>& zoneFaces = ensMesh.faceZoneFaces();
//
// write internalMesh, unless patch-selection was requested
//
if (ensMesh.useInternalMesh())
{
if (Pstream::master())
{
os.beginPart(0); // 0 = internalMesh
}
writeField
(
"coordinates",
Field<Type>(pf.internalField(), ensMesh.uniquePointMap()),
os
);
}
//
// write patches
// use sortedToc for extra safety
//
const labelList patchIds = patchLookup.sortedToc();
forAll(patchIds, listi)
{
const label patchId = patchIds[listi];
const word& patchName = patchLookup[patchId];
const ensightFaces& ensFaces = patchFaces[patchName];
const fvPatch& p = mesh.boundary()[patchId];
// 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.beginPart(ensFaces.index());
}
writeField
(
"coordinates",
Field<Type>(pf.internalField(), uniqueMeshPointLabels),
os
);
}
//
// write faceZones, if requested
//
const wordList zoneNames = zoneFaces.sortedToc();
forAll(zoneNames, zonei)
{
const word& zoneName = zoneNames[zonei];
const ensightFaces& ensFaces = zoneFaces[zoneName];
uindirectPrimitivePatch p
(
UIndirectList<face>
(
mesh.faces(),
ensFaces.faceIds()
),
mesh.points()
);
// Renumber the patch points/faces into unique points
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPointsPtr =
mesh.globalData().mergePoints
(
p.meshPoints(),
p.meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels
);
if (Pstream::master())
{
os.beginPart(ensFaces.index());
}
writeField
(
"coordinates",
Field<Type>(pf.internalField(), uniqueMeshPointLabels),
os
);
}
return true;
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class Type>
bool Foam::ensightOutput::writeField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightMesh& ensMesh,
ensightFile& os,
const bool nodeValues
)
{
if (nodeValues)
{
tmp<GeometricField<Type, pointPatchField, pointMesh>> pfld
(
volPointInterpolation::New(vf.mesh()).interpolate(vf)
);
pfld.ref().checkOut();
pfld.ref().rename(vf.name());
return ensightPointField<Type>(pfld, ensMesh, os);
}
else
{
return writeField<Type>(vf, ensMesh, os);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,146 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::ensightSerialOutput
Description
A collection of functions for writing ensight file content in serial.
Can be considered transitional and may eventually merge with ensightOutput.
SourceFiles
ensightSerialOutputTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef ensightSerialOutput_H
#define ensightSerialOutput_H
#include "ensightPart.H"
#include "ensightPartFaces.H"
#include "ensightPartCells.H"
#include "ensightParts.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightSerialOutput Declaration
\*---------------------------------------------------------------------------*/
class ensightSerialOutput
{
// Private Methods
//- Write field component-wise
template<class Type>
static void writeField
(
const word& key,
const Field<Type>& field,
ensightFile& os
);
//- Disallow null constructor
ensightSerialOutput() = delete;
public:
// Public Methods
//- Write field component-wise
template<class Type>
static bool writeField
(
const Field<Type>&,
const ensightPartFaces& part,
ensightFile& os,
const bool nodeValues
);
//- Write volume field component-wise
template<class Type>
static bool writeField
(
const GeometricField<Type, fvPatchField, volMesh>&,
const ensightPartCells& part,
ensightFile& os
);
//- Write volume field component-wise
template<class Type>
static bool writeField
(
const GeometricField<Type, fvPatchField, volMesh>&,
const ensightParts& list,
ensightFile& os
);
//- Write volume field component-wise
template<class Type>
static inline bool writeField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightPartCells& part,
autoPtr<ensightFile>& output
)
{
return writeField(vf, part, output.rawRef());
}
//- Write volume field component-wise
template<class Type>
static inline bool writeField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightParts& list,
autoPtr<ensightFile>& output
)
{
return writeField(vf, list, output.rawRef());
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightSerialOutputTemplates.C"
#endif
#endif
// ************************************************************************* //

View File

@ -0,0 +1,178 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "ensightPart.H"
#include "ensightParts.H"
#include "ensightPTraits.H"
#include "direction.H"
#include "typeInfo.H"
// * * * * * * * * * * Static Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::ensightSerialOutput::writeField
(
const word& key,
const Field<Type>& fld,
ensightFile& os
)
{
if (fld.size())
{
os.writeKeyword(key);
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
const label cmpt = ensightPTraits<Type>::componentOrder[d];
os.writeList(fld.component(cmpt));
}
}
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class Type>
bool Foam::ensightSerialOutput::writeField
(
const Field<Type>& fld,
const ensightPartFaces& part,
ensightFile& os,
const bool nodeValues
)
{
if (part.size() && fld.size())
{
if (nodeValues)
{
os.beginPart(part.index());
os.writeKeyword("coordinates");
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
const label cmpt = ensightPTraits<Type>::componentOrder[d];
os.writeList(fld.component(cmpt));
}
}
else
{
os.beginPart(part.index());
const List<ensightFaces::elemType> enums =
ensightFaces::elemEnum.enums();
forAllConstIter(List<ensightFaces::elemType>, enums, iter)
{
const ensightFaces::elemType what = *iter;
writeField
(
ensightFaces::key(what),
Field<Type>(fld, part.faceIds(what)),
os
);
}
}
}
return true;
}
template<class Type>
bool Foam::ensightSerialOutput::writeField
(
const GeometricField<Type, fvPatchField, volMesh>& fld,
const ensightPartCells& part,
ensightFile& os
)
{
if (part.size() && fld.size())
{
os.beginPart(part.index());
const List<ensightCells::elemType> enums =
ensightCells::elemEnum.enums();
forAllConstIter(List<ensightCells::elemType>, enums, iter)
{
const ensightCells::elemType what = *iter;
writeField
(
ensightCells::key(what),
Field<Type>(fld, part.cellIds(what)),
os
);
}
}
return true;
}
template<class Type>
bool Foam::ensightSerialOutput::writeField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightParts& list,
ensightFile& os
)
{
forAllConstIter(ensightParts::StorageType, list, iter)
{
if (isA<ensightPartFaces>(*iter))
{
const ensightPartFaces& part =
dynamicCast<const ensightPartFaces&>(*iter);
const label patchi = part.patchIndex();
if (patchi >= 0 && patchi < vf.boundaryField().size())
{
writeField
(
vf.boundaryField()[patchi],
part,
os,
false
);
}
}
else
{
const ensightPartCells& part =
dynamicCast<const ensightPartCells&>(*iter);
writeField(vf, part, os);
}
}
return true;
}
// ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -24,164 +24,63 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "ensightPart.H" #include "ensightPart.H"
#include "dictionary.H"
#include "ListOps.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
defineTypeNameAndDebug(ensightPart, 0); defineTypeNameAndDebug(ensightPart, 0);
defineTemplateTypeNameAndDebug(IOPtrList<ensightPart>, 0);
defineRunTimeSelectionTable(ensightPart, istream);
} }
const Foam::List<Foam::word> Foam::ensightPart::elemTypes_(0);
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
bool Foam::ensightPart::isFieldDefined(const List<scalar>& field) const // TODO - move elsewhere
#if 0
bool Foam::ensightPart::isFieldDefined
(
const List<scalar>& field
// const labelUList& addr = cellIds() or faceIds()
) const
{ {
forAll(elemLists_, elemI) forAll(addr, elemI)
{ {
const labelUList& idList = elemLists_[elemI]; const label id = addr[i];
forAll(idList, i)
{
const label id = idList[i];
if (id >= field.size() || std::isnan(field[id])) if (id >= field.size() || std::isnan(field[id]))
{ {
return false; return false;
} }
} }
}
return true; return true;
} }
#endif
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightPart::ensightPart Foam::ensightPart::ensightPart(const string& description)
()
: :
number_(0), name_(description)
name_(""),
elemLists_(0),
offset_(0),
size_(0),
isCellData_(true),
matId_(0),
points_(pointField::null())
{} {}
Foam::ensightPart::ensightPart
(
label partNumber,
const string& partDescription
)
:
number_(partNumber),
name_(partDescription),
elemLists_(0),
offset_(0),
size_(0),
isCellData_(true),
matId_(0),
points_(pointField::null())
{}
Foam::ensightPart::ensightPart
(
label partNumber,
const string& partDescription,
const pointField& points
)
:
number_(partNumber),
name_(partDescription),
elemLists_(0),
offset_(0),
size_(0),
isCellData_(true),
matId_(0),
points_(points)
{}
Foam::ensightPart::ensightPart(const ensightPart& part)
:
number_(part.number_),
name_(part.name_),
elemLists_(part.elemLists_),
offset_(part.offset_),
size_(part.size_),
isCellData_(part.isCellData_),
matId_(part.matId_),
points_(part.points_)
{}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::ensightPart> Foam::ensightPart::New(Istream& is)
{
const word partType(is);
istreamConstructorTable::iterator cstrIter =
istreamConstructorTablePtr_->find(partType);
if (cstrIter == istreamConstructorTablePtr_->end())
{
FatalIOErrorInFunction
(
is
) << "unknown ensightPart type "
<< partType << nl << nl
<< "Valid ensightPart types are :" << endl
<< istreamConstructorTablePtr_->sortedToc()
<< exit(FatalIOError);
}
return autoPtr<ensightPart>(cstrIter()(is));
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightPart::~ensightPart() Foam::ensightPart::~ensightPart()
{} {}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
void Foam::ensightPart::renumber(const labelUList& origId) Foam::ensightGeoFile& Foam::operator<<
(
ensightGeoFile& os,
const ensightPart& part
)
{ {
// transform to global values first part.write(os);
if (offset_) return os;
{
forAll(elemLists_, elemI)
{
labelList& idList = elemLists_[elemI];
forAll(idList, i)
{
idList[i] += offset_;
}
}
offset_ = 0;
}
if (origId.size())
{
forAll(elemLists_, elemI)
{
inplaceRenumber(origId, elemLists_[elemI]);
}
}
} }

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -29,21 +29,17 @@ Description
SourceFiles SourceFiles
ensightPart.C ensightPart.C
ensightPartIO.C
ensightPartTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef ensightPart_H #ifndef ensightPart_H
#define ensightPart_H #define ensightPart_H
#include "ensightFile.H"
#include "ensightGeoFile.H" #include "ensightGeoFile.H"
#include "typeInfo.H" #include "typeInfo.H"
#include "labelList.H" #include "labelList.H"
#include "polyMesh.H" #include "polyMesh.H"
#include "Field.H" #include "Field.H"
#include "IOPtrList.H"
#include "IOstream.H" #include "IOstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -54,8 +50,6 @@ namespace Foam
// Forward declaration of friend functions and operators // Forward declaration of friend functions and operators
class ensightPart; class ensightPart;
Ostream& operator<<(Ostream&, const ensightPart&);
ensightGeoFile& operator<<(ensightGeoFile&, const ensightPart&); ensightGeoFile& operator<<(ensightGeoFile&, const ensightPart&);
@ -65,40 +59,22 @@ ensightGeoFile& operator<<(ensightGeoFile&, const ensightPart&);
class ensightPart class ensightPart
{ {
// Private data // Private Data
// Static data members
static const List<word> elemTypes_;
protected:
// Protected data
//- Part number
label number_;
//- Part name (or description) //- Part name (or description)
string name_; string name_;
//- Simple labelList with a name
labelListList elemLists_;
//- Start offset for elemLists_ // Private Member Functions
label offset_;
//- Number of elements in this part //- Disallow default bitwise copy construct
label size_; ensightPart(const ensightPart&) = delete;
//- Cell or face data //- Disallow default bitwise assignment
bool isCellData_; void operator=(const ensightPart&) = delete;
//- Material id (numeric)
label matId_;
//- pointField referenced
const pointField& points_;
protected:
// Protected Classes // Protected Classes
@ -127,46 +103,6 @@ protected:
{} {}
}; };
// Protected Member Functions
//- Reconstruct part characteristics (eg, element types) from Istream
// A part reconstructed in this manner can be used when writing fields,
// but cannot be used to write a new geometry
void reconstruct(Istream&);
//- Check for fully defined fields
bool isFieldDefined(const List<scalar>&) const;
//- Write the part header
void writeHeader(ensightFile&, bool withDescription=false) const;
//- Write a scalar field for idList
// A null reference for idList writes the perNode values
void writeFieldList
(
ensightFile& os,
const List<scalar>& field,
const labelUList& idList
) const;
//- Track points used
virtual localPoints calcLocalPoints() const
{
return localPoints();
}
//- Write connectivities
virtual void writeConnectivity
(
ensightGeoFile&,
const word& key,
const labelUList& idList,
const labelUList& pointMap
) const
{}
public: public:
//- Runtime type information //- Runtime type information
@ -175,85 +111,23 @@ public:
// Constructors // Constructors
//- Construct null //- Construct with description
ensightPart(); ensightPart(const string& description);
//- Construct empty part with number and description
ensightPart(label partNumber, const string& partDescription);
//- Construct part with number, description and points reference
ensightPart
(
label partNumber,
const string& partDescription,
const pointField& points
);
//- Construct as copy
ensightPart(const ensightPart&);
// Selectors
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
ensightPart,
istream,
(
Istream& is
),
(is)
);
//- Construct and return clone
autoPtr<ensightPart> clone() const
{
return autoPtr<ensightPart>(new ensightPart(*this));
};
//- Reconstruct part characteristics on freestore from Istream
// \sa reconstruct
static autoPtr<ensightPart> New(Istream&);
//- Destructor //- Destructor
virtual ~ensightPart(); virtual ~ensightPart();
// Static members
virtual const List<word>& elementTypes() const
{
return elemTypes_;
}
// Access // Access
//- Part index (0-based)
virtual label index() const = 0;
//- Number of elements in this part //- Number of elements in this part
label size() const virtual label size() const
{ {
return size_; return 0;
}
//- Represents cell data
bool isCellData() const
{
return isCellData_;
}
//- Represents face data
bool isFaceData() const
{
return !isCellData_;
}
//- Part number
label number() const
{
return number_;
} }
//- Part name or description //- Part name or description
@ -262,80 +136,35 @@ public:
return name_; return name_;
} }
//- Material id
label materialId() const
{
return matId_;
}
//- non-const access to part name or description //- non-const access to part name or description
void name(const string& value) void name(const string& value)
{ {
name_ = value; name_ = value;
} }
//- non-const access to material id
void materialId(const label value)
{
matId_ = value;
}
//- Simple labelList with a name // Output
const labelListList& elemLists() const
{
return elemLists_;
}
//- Offset for element ids
label offset() const
{
return offset_;
}
// Edit
//- Renumber elements
void renumber(const labelUList&);
//- Write summary information about the object
bool writeSummary(Ostream&) const;
//- Write reconstruction information for the object
bool writeData(Ostream&) const;
//- Write geometry //- Write geometry
virtual void writeGeometry(ensightGeoFile&) const virtual void write(ensightGeoFile&) const = 0;
{}
//- Helper: write geometry given the pointField //- Helper: write geometry with given pointField
void writeGeometry(ensightGeoFile&, const pointField&) const; virtual void write
//- Write generalized field components
// optionally write data per node
template<class Type>
void writeField
( (
ensightFile&, ensightGeoFile&,
const Field<Type>&, const pointField&
const bool perNode = false ) const = 0;
) const;
// Member Operators //- Write summary information about the object
virtual void writeSummary(Ostream&) const = 0;
//- Disallow default bitwise assignment //- Print various types of debugging information
void operator=(const ensightPart&) virtual void dumpInfo(Ostream&) const = 0;
{
NotImplemented;
}
// IOstream Operators // IOstream Operators
//- Write data (reconstruction information)
friend Ostream& operator<<(Ostream&, const ensightPart&);
//- Write geometry //- Write geometry
friend ensightGeoFile& operator<<(ensightGeoFile&, const ensightPart&); friend ensightGeoFile& operator<<(ensightGeoFile&, const ensightPart&);
@ -348,12 +177,6 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightPartTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -24,247 +24,29 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "ensightPartCells.H" #include "ensightPartCells.H"
#include "IOstream.H"
#include "IStringStream.H"
#include "dictionary.H"
#include "cellModeller.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
defineTypeNameAndDebug(ensightPartCells, 0); defineTypeNameAndDebug(ensightPartCells, 0);
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream);
} }
const Foam::List<Foam::word> Foam::ensightPartCells::elemTypes_
(
IStringStream
(
"(tetra4 pyramid5 penta6 hexa8 nfaced)"
)()
);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ensightPartCells::classify
(
const polyMesh& mesh,
const labelUList& idList
)
{
// References to cell shape models
const cellModel& tet = *(cellModeller::lookup("tet"));
const cellModel& pyr = *(cellModeller::lookup("pyr"));
const cellModel& prism = *(cellModeller::lookup("prism"));
const cellModel& hex = *(cellModeller::lookup("hex"));
const cellShapeList& cellShapes = mesh.cellShapes();
offset_ = 0;
size_ = mesh.nCells();
bool limited = false;
if (notNull(idList))
{
limited = true;
size_ = idList.size();
}
// count the shapes
label nTet = 0;
label nPyr = 0;
label nPrism = 0;
label nHex = 0;
label nPoly = 0;
for (label listI = 0; listI < size_; ++listI)
{
label cellId = listI;
if (limited)
{
cellId = idList[listI];
}
const cellShape& cellShape = cellShapes[cellId];
const cellModel& cellModel = cellShape.model();
if (cellModel == tet)
{
nTet++;
}
else if (cellModel == pyr)
{
nPyr++;
}
else if (cellModel == prism)
{
nPrism++;
}
else if (cellModel == hex)
{
nHex++;
}
else
{
nPoly++;
}
}
// we can avoid double looping, but at the cost of allocation
labelList tetCells(nTet);
labelList pyramidCells(nPyr);
labelList prismCells(nPrism);
labelList hexCells(nHex);
labelList polyCells(nPoly);
nTet = 0,
nPyr = 0;
nPrism = 0;
nHex = 0;
nPoly = 0;
// classify the shapes
for (label listI = 0; listI < size_; ++listI)
{
label cellId = listI;
if (limited)
{
cellId = idList[listI];
}
const cellShape& cellShape = cellShapes[cellId];
const cellModel& cellModel = cellShape.model();
if (cellModel == tet)
{
tetCells[nTet++] = cellId;
}
else if (cellModel == pyr)
{
pyramidCells[nPyr++] = cellId;
}
else if (cellModel == prism)
{
prismCells[nPrism++] = cellId;
}
else if (cellModel == hex)
{
hexCells[nHex++] = cellId;
}
else
{
polyCells[nPoly++] = cellId;
}
}
// MUST match with elementTypes
elemLists_.setSize(elementTypes().size());
elemLists_[tetra4Elements].transfer(tetCells);
elemLists_[pyramid5Elements].transfer(pyramidCells);
elemLists_[penta6Elements].transfer(prismCells);
elemLists_[hexa8Elements].transfer(hexCells);
elemLists_[nfacedElements].transfer(polyCells);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightPartCells::ensightPartCells
(
label partNumber,
const string& partDescription
)
:
ensightPart(partNumber, partDescription),
mesh_(*reinterpret_cast<polyMesh*>(0))
{}
Foam::ensightPartCells::ensightPartCells
(
label partNumber,
const polyMesh& mesh
)
:
ensightPart(partNumber, "cells", mesh.points()),
mesh_(mesh)
{
classify(mesh);
}
Foam::ensightPartCells::ensightPartCells
(
label partNumber,
const polyMesh& mesh,
const labelUList& idList
)
:
ensightPart(partNumber, "cells", mesh.points()),
mesh_(mesh)
{
classify(mesh, idList);
}
Foam::ensightPartCells::ensightPartCells
(
label partNumber,
const polyMesh& mesh,
const cellZone& cZone
)
:
ensightPart(partNumber, cZone.name(), mesh.points()),
mesh_(mesh)
{
classify(mesh, cZone);
}
Foam::ensightPartCells::ensightPartCells(const ensightPartCells& part)
:
ensightPart(part),
mesh_(part.mesh_)
{}
Foam::ensightPartCells::ensightPartCells(Istream& is)
:
ensightPart(),
mesh_(*reinterpret_cast<polyMesh*>(0))
{
reconstruct(is);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightPartCells::~ensightPartCells()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::ensightPart::localPoints Foam::ensightPartCells::calcLocalPoints() const Foam::ensightPart::localPoints Foam::ensightPartCells::calcLocalPoints() const
{ {
localPoints ptList(points_); localPoints ptList(mesh_.points());
labelList& usedPoints = ptList.list; labelList& usedPoints = ptList.list;
label nPoints = 0; label nPoints = 0;
forAll(elemLists_, typeI)
{
const labelUList& idList = elemLists_[typeI];
// add all points from cells // add all points from cells
const labelUList& idList = this->cellIds();
forAll(idList, i) forAll(idList, i)
{ {
const label id = idList[i] + offset_; const label id = idList[i];
const labelUList& cFaces = mesh_.cells()[id]; const labelUList& cFaces = mesh_.cells()[id];
forAll(cFaces, cFacei) forAll(cFaces, cFacei)
@ -280,7 +62,6 @@ Foam::ensightPart::localPoints Foam::ensightPartCells::calcLocalPoints() const
} }
} }
} }
}
// this is not absolutely necessary, but renumber anyhow // this is not absolutely necessary, but renumber anyhow
nPoints = 0; nPoints = 0;
@ -297,6 +78,60 @@ Foam::ensightPart::localPoints Foam::ensightPartCells::calcLocalPoints() const
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightPartCells::ensightPartCells
(
label partIndex,
const polyMesh& mesh
)
:
ensightCells(partIndex),
ensightPart("cells"),
mesh_(mesh)
{
classify(mesh);
}
Foam::ensightPartCells::ensightPartCells
(
label partIndex,
const polyMesh& mesh,
const labelUList& idList
)
:
ensightCells(partIndex),
ensightPart("cells"),
mesh_(mesh)
{
classify(mesh, idList);
}
Foam::ensightPartCells::ensightPartCells
(
label partIndex,
const polyMesh& mesh,
const cellZone& cZone
)
:
ensightCells(partIndex),
ensightPart(cZone.name()),
mesh_(mesh)
{
classify(mesh, cZone);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightPartCells::~ensightPartCells()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ensightPartCells::writeConnectivity void Foam::ensightPartCells::writeConnectivity
( (
ensightGeoFile& os, ensightGeoFile& os,
@ -305,6 +140,8 @@ void Foam::ensightPartCells::writeConnectivity
const labelUList& pointMap const labelUList& pointMap
) const ) const
{ {
if (idList.empty()) return;
os.writeKeyword(key); os.writeKeyword(key);
os.write(idList.size()); os.write(idList.size());
os.newline(); os.newline();
@ -318,7 +155,7 @@ void Foam::ensightPartCells::writeConnectivity
// write the number of faces per element // write the number of faces per element
forAll(idList, i) forAll(idList, i)
{ {
const label id = idList[i] + offset_; const label id = idList[i];
const labelUList& cFace = mesh_.cells()[id]; const labelUList& cFace = mesh_.cells()[id];
os.write(cFace.size()); os.write(cFace.size());
@ -328,7 +165,7 @@ void Foam::ensightPartCells::writeConnectivity
// write the number of points per element face // write the number of points per element face
forAll(idList, i) forAll(idList, i)
{ {
const label id = idList[i] + offset_; const label id = idList[i];
const labelUList& cFace = mesh_.cells()[id]; const labelUList& cFace = mesh_.cells()[id];
forAll(cFace, facei) forAll(cFace, facei)
@ -343,7 +180,7 @@ void Foam::ensightPartCells::writeConnectivity
// write the points describing each element face // write the points describing each element face
forAll(idList, i) forAll(idList, i)
{ {
const label id = idList[i] + offset_; const label id = idList[i];
const labelUList& cFace = mesh_.cells()[id]; const labelUList& cFace = mesh_.cells()[id];
forAll(cFace, cFacei) forAll(cFace, cFacei)
@ -380,12 +217,12 @@ void Foam::ensightPartCells::writeConnectivity
else else
{ {
// write primitive // write primitive
const cellShapeList& cellShapes = mesh_.cellShapes(); const cellShapeList& shapes = mesh_.cellShapes();
forAll(idList, i) forAll(idList, i)
{ {
const label id = idList[i] + offset_; const label id = idList[i];
const cellShape& cellPoints = cellShapes[id]; const cellShape& cellPoints = shapes[id];
// convert global -> local index // convert global -> local index
// (note: Ensight indices start with 1) // (note: Ensight indices start with 1)
@ -399,9 +236,97 @@ void Foam::ensightPartCells::writeConnectivity
} }
void Foam::ensightPartCells::writeGeometry(ensightGeoFile& os) const void Foam::ensightPartCells::write
(
ensightGeoFile& os,
const pointField& points
) const
{ {
ensightPart::writeGeometry(os, points_); if (size())
{
const localPoints ptList = calcLocalPoints();
const labelUList& pointMap = ptList.list;
os.beginPart(index(), name());
os.beginCoordinates(ptList.nPoints);
for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
{
forAll(pointMap, ptI)
{
if (pointMap[ptI] > -1)
{
os.write(points[ptI].component(cmpt));
os.newline();
}
}
}
// write each element type
const List<ensightCells::elemType> enums =
ensightCells::elemEnum.enums();
forAllConstIter(List<ensightCells::elemType>, enums, iter)
{
const ensightCells::elemType what = *iter;
writeConnectivity
(
os,
ensightCells::key(what),
cellIds(what),
pointMap
);
}
}
}
void Foam::ensightPartCells::write(ensightGeoFile& os) const
{
this->write(os, mesh_.points());
}
void Foam::ensightPartCells::writeSummary(Ostream& os) const
{
os.beginBlock(type());
os.writeEntry("id", index()+1); // Ensight starts with 1
os.writeEntry("name", name());
os.writeEntry("size", size());
os.endBlock() << flush;
}
void Foam::ensightPartCells::dumpInfo(Ostream& os) const
{
os.beginBlock(type());
os.writeEntry("id", index()+1); // Ensight starts with 1
os.writeEntry("name", name());
os.writeEntry("size", size());
const List<ensightCells::elemType> enums = ensightCells::elemEnum.enums();
forAllConstIter(List<ensightCells::elemType>, enums, iter)
{
const ensightCells::elemType what = *iter;
const labelUList& addr = this->cellIds(what);
os.writeKeyword(ensightCells::key(what));
// DIY flat output
os << addr.size() << '(';
forAll(addr, i)
{
if (i) os << ' ';
os << addr[i];
}
os << ')' << endEntry;
}
os.endBlock() << flush;
} }

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -36,6 +36,7 @@ SourceFiles
#define ensightPartCells_H #define ensightPartCells_H
#include "ensightPart.H" #include "ensightPart.H"
#include "ensightCells.H"
#include "typeInfo.H" #include "typeInfo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -49,28 +50,22 @@ namespace Foam
class ensightPartCells class ensightPartCells
: :
public ensightCells,
public ensightPart public ensightPart
{ {
// Private data
//- Mesh referenced
const polyMesh& mesh_;
// Private Member Functions // Private Member Functions
//- Disallow default bitwise assignment
void operator=(const ensightPartCells&);
//- Classify the cell types, set elemLists.
void classify
(
const polyMesh&,
const labelUList& idLabels = labelUList::null()
);
//- Track points used //- Track points used
virtual localPoints calcLocalPoints() const; localPoints calcLocalPoints() const;
//- Track the points used
// virtual void makeLocalPointMap();
//- Element connectivity //- Element connectivity
virtual void writeConnectivity void writeConnectivity
( (
ensightGeoFile&, ensightGeoFile&,
const word& key, const word& key,
@ -79,28 +74,11 @@ class ensightPartCells
) const; ) const;
protected: //- Disallow default bitwise copy construct
ensightPartCells(const ensightPartCells&) = delete;
//- Addressable ensight element types //- Disallow default bitwise assignment
enum elemType void operator=(const ensightPartCells&) = delete;
{
tetra4Elements,
pyramid5Elements,
penta6Elements,
hexa8Elements,
nfacedElements
};
// Static data members
static const List<word> elemTypes_;
// Protected data
//- Mesh referenced
const polyMesh& mesh_;
public: public:
@ -110,16 +88,17 @@ public:
// Constructors // Constructors
//- Construct empty part with number and description
ensightPartCells(label partNumber, const string& partDescription);
//- Construct from polyMesh without zones //- Construct from polyMesh without zones
ensightPartCells(label partNumber, const polyMesh&); ensightPartCells
(
label partIndex,
const polyMesh&
);
//- Construct from polyMesh and list of (non-zoned) cells //- Construct from polyMesh and list of (non-zoned) cells
ensightPartCells ensightPartCells
( (
label partNumber, label partIndex,
const polyMesh&, const polyMesh&,
const labelUList& const labelUList&
); );
@ -127,26 +106,11 @@ public:
//- Construct from polyMesh and cellZone //- Construct from polyMesh and cellZone
ensightPartCells ensightPartCells
( (
label partNumber, label partIndex,
const polyMesh&, const polyMesh&,
const cellZone& const cellZone&
); );
//- Construct as copy
ensightPartCells(const ensightPartCells&);
//- Reconstruct part characteristics (eg, element types) from Istream
// A part reconstructed in this manner can be used when writing fields,
// but cannot be used to write a new geometry
// \sa Foam::ensightPart::reconstruct
ensightPartCells(Istream&);
//- Reconstruct part characteristics on freestore from Istream
static autoPtr<ensightPartCells> New(Istream& is)
{
return autoPtr<ensightPartCells>(new ensightPartCells(is));
}
//- Destructor //- Destructor
virtual ~ensightPartCells(); virtual ~ensightPartCells();
@ -154,14 +118,36 @@ public:
// Member Functions // Member Functions
//- Write geometry // Access
virtual void writeGeometry(ensightGeoFile&) const;
//- Static listing of the element types //- Part index (0-based)
virtual const List<word>& elementTypes() const virtual label index() const
{ {
return elemTypes_; return ensightCells::index();
} }
//- Number of elements in this part
virtual label size() const
{
return ensightCells::size();
}
// Output
//- Write geometry
virtual void write(ensightGeoFile&) const;
//- Helper: write geometry given the pointField
virtual void write(ensightGeoFile&, const pointField&) const;
//- Write summary information about the object
virtual void writeSummary(Ostream&) const;
//- Print various types of debugging information
virtual void dumpInfo(Ostream&) const;
}; };

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -24,182 +24,15 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "ensightPartFaces.H" #include "ensightPartFaces.H"
#include "IOstreams.H"
#include "IStringStream.H"
#include "dictionary.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
defineTypeNameAndDebug(ensightPartFaces, 0); defineTypeNameAndDebug(ensightPartFaces, 0);
addToRunTimeSelectionTable(ensightPart, ensightPartFaces, istream);
} }
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
const Foam::List<Foam::word> Foam::ensightPartFaces::elemTypes_
(
IStringStream
(
"(tria3 quad4 nsided)"
)()
);
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::ensightPartFaces::classify(const faceList& faces)
{
// count the shapes
label nTri = 0;
label nQuad = 0;
label nPoly = 0;
forAll(faces, facei)
{
const face& f = faces[facei];
if (f.size() == 3)
{
nTri++;
}
else if (f.size() == 4)
{
nQuad++;
}
else
{
nPoly++;
}
}
// we can avoid double looping, but at the cost of allocation
labelList triCells(nTri);
labelList quadCells(nQuad);
labelList polygonCells(nPoly);
nTri = 0;
nQuad = 0;
nPoly = 0;
// classify the shapes
forAll(faces, facei)
{
const face& f = faces[facei];
if (f.size() == 3)
{
triCells[nTri++] = facei;
}
else if (f.size() == 4)
{
quadCells[nQuad++] = facei;
}
else
{
polygonCells[nPoly++] = facei;
}
}
// MUST match with elementTypes
elemLists_.setSize(elementTypes().size());
elemLists_[tria3Elements].transfer(triCells);
elemLists_[quad4Elements].transfer(quadCells);
elemLists_[nsidedElements].transfer(polygonCells);
size_ = faces.size();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightPartFaces::ensightPartFaces
(
label partNumber,
const string& partDescription
)
:
ensightPart(partNumber, partDescription),
faces_(faceList::null()),
contiguousPoints_(false)
{
isCellData_ = false;
offset_ = 0;
size_ = 0;
}
Foam::ensightPartFaces::ensightPartFaces
(
label partNumber,
const string& partDescription,
const pointField& points,
const faceList& faces,
const bool contiguousPoints
)
:
ensightPart(partNumber, partDescription, points),
faces_(faces),
contiguousPoints_(contiguousPoints)
{
isCellData_ = false;
offset_ = 0;
size_ = 0;
// classify the face shapes
classify(faces);
}
Foam::ensightPartFaces::ensightPartFaces
(
label partNumber,
const polyMesh& mesh,
const polyPatch& patch
)
:
ensightPart(partNumber, patch.name(), mesh.points()),
faces_(mesh.faces()),
contiguousPoints_(false)
{
isCellData_ = false;
offset_ = patch.start();
// classify the face shapes
classify(patch);
}
Foam::ensightPartFaces::ensightPartFaces(const ensightPartFaces& part)
:
ensightPart(part),
faces_(part.faces_),
contiguousPoints_(part.contiguousPoints_)
{}
Foam::ensightPartFaces::ensightPartFaces(Istream& is)
:
ensightPart(),
faces_(faceList::null()),
contiguousPoints_(false)
{
isCellData_ = false;
reconstruct(is);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightPartFaces::~ensightPartFaces()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::ensightPart::localPoints Foam::ensightPartFaces::calcLocalPoints() const Foam::ensightPart::localPoints Foam::ensightPartFaces::calcLocalPoints() const
{ {
@ -215,14 +48,13 @@ Foam::ensightPart::localPoints Foam::ensightPartFaces::calcLocalPoints() const
labelList& usedPoints = ptList.list; labelList& usedPoints = ptList.list;
label nPoints = 0; label nPoints = 0;
forAll(elemLists_, typeI) // add all points from faces
{ const labelUList& idList = this->faceIds();
const labelUList& idList = elemLists_[typeI];
// add all points from faces // add all points from faces
forAll(idList, i) forAll(idList, i)
{ {
const label id = idList[i] + offset_; const label id = idList[i] + start_;
const face& f = faces_[id]; const face& f = faces_[id];
forAll(f, fp) forAll(f, fp)
@ -233,7 +65,7 @@ Foam::ensightPart::localPoints Foam::ensightPartFaces::calcLocalPoints() const
} }
} }
} }
}
// this is not absolutely necessary, but renumber anyhow // this is not absolutely necessary, but renumber anyhow
nPoints = 0; nPoints = 0;
@ -250,6 +82,58 @@ Foam::ensightPart::localPoints Foam::ensightPartFaces::calcLocalPoints() const
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightPartFaces::ensightPartFaces
(
label partIndex,
const string& description,
const pointField& points,
const faceList& faces,
const bool contiguousPoints
)
:
ensightFaces(partIndex),
ensightPart(description),
start_(0),
patchIndex_(-1),
faces_(faces),
points_(points),
contiguousPoints_(contiguousPoints)
{
// classify the face shapes
classify(faces);
}
Foam::ensightPartFaces::ensightPartFaces
(
label partIndex,
const polyMesh& mesh,
const polyPatch& patch
)
:
ensightFaces(partIndex),
ensightPart(patch.name()),
start_(patch.start()),
patchIndex_(patch.index()),
faces_(mesh.faces()),
points_(mesh.points()),
contiguousPoints_(false)
{
// classify the face shapes
classify(patch);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightPartFaces::~ensightPartFaces()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ensightPartFaces::writeConnectivity void Foam::ensightPartFaces::writeConnectivity
( (
ensightGeoFile& os, ensightGeoFile& os,
@ -259,6 +143,8 @@ void Foam::ensightPartFaces::writeConnectivity
const labelUList& pointMap const labelUList& pointMap
) const ) const
{ {
if (idList.empty()) return;
os.writeKeyword(key); os.writeKeyword(key);
os.write(idList.size()); os.write(idList.size());
os.newline(); os.newline();
@ -269,7 +155,7 @@ void Foam::ensightPartFaces::writeConnectivity
// write the number of points per face // write the number of points per face
forAll(idList, i) forAll(idList, i)
{ {
const label id = idList[i] + offset_; const label id = idList[i] + start_;
const face& f = faces[id]; const face& f = faces[id];
os.write(f.size()); os.write(f.size());
@ -280,7 +166,7 @@ void Foam::ensightPartFaces::writeConnectivity
// write the points describing the face // write the points describing the face
forAll(idList, i) forAll(idList, i)
{ {
const label id = idList[i] + offset_; const label id = idList[i] + start_;
const face& f = faces[id]; const face& f = faces[id];
// convert global -> local index // convert global -> local index
@ -313,9 +199,99 @@ void Foam::ensightPartFaces::writeConnectivity
} }
void Foam::ensightPartFaces::writeGeometry(ensightGeoFile& os) const void Foam::ensightPartFaces::write
(
ensightGeoFile& os,
const pointField& points
) const
{ {
ensightPart::writeGeometry(os, points_); if (ensightPart::size())
{
const localPoints ptList = calcLocalPoints();
const labelUList& pointMap = ptList.list;
os.beginPart(index(), name());
os.beginCoordinates(ptList.nPoints);
for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
{
forAll(pointMap, ptI)
{
if (pointMap[ptI] > -1)
{
os.write(points[ptI].component(cmpt));
os.newline();
}
}
}
// write part
const List<ensightFaces::elemType> enums =
ensightFaces::elemEnum.enums();
forAllConstIter(List<ensightFaces::elemType>, enums, iter)
{
const ensightFaces::elemType what = *iter;
writeConnectivity
(
os,
ensightFaces::key(what),
faceIds(what),
pointMap
);
}
}
}
void Foam::ensightPartFaces::write(ensightGeoFile& os) const
{
this->write(os, points_);
}
void Foam::ensightPartFaces::writeSummary(Ostream& os) const
{
os.beginBlock(type());
os.writeEntry("id", index()+1); // Ensight starts with 1
os.writeEntry("name", name());
os.writeEntry("start", start_);
os.writeEntry("size", size());
os.endBlock() << flush;
}
void Foam::ensightPartFaces::dumpInfo(Ostream& os) const
{
os.beginBlock(type());
os.writeEntry("id", index()+1); // Ensight starts with 1
os.writeEntry("name", name());
os.writeEntry("start", start_);
os.writeEntry("size", size());
const List<ensightFaces::elemType> enums = ensightFaces::elemEnum.enums();
forAllConstIter(List<ensightFaces::elemType>, enums, iter)
{
const ensightFaces::elemType what = *iter;
const labelUList& addr = this->faceIds(what);
os.writeKeyword(ensightFaces::key(what));
// DIY flat output
os << addr.size() << '(';
forAll(addr, i)
{
if (i) os << ' ';
os << addr[i];
}
os << ')' << endEntry;
}
os.endBlock() << flush;
} }

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -25,7 +25,7 @@ Class
Foam::ensightPartFaces Foam::ensightPartFaces
Description Description
An implementation of ensightPart to hold volume mesh faces. An implementation of ensightPart to hold mesh faces.
SourceFiles SourceFiles
ensightPartFaces.C ensightPartFaces.C
@ -36,6 +36,8 @@ SourceFiles
#define ensightPartFaces_H #define ensightPartFaces_H
#include "ensightPart.H" #include "ensightPart.H"
#include "ensightFaces.H"
#include "typeInfo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -48,18 +50,34 @@ namespace Foam
class ensightPartFaces class ensightPartFaces
: :
public ensightFaces,
public ensightPart public ensightPart
{ {
// Private data
//- Start offset for patch
const label start_;
//- Patch index
const label patchIndex_;
//- Faces referenced
const faceList& faces_;
//- pointField referenced
const pointField& points_;
//- Can skip local point renumbering when points are contiguous
const bool contiguousPoints_;
// Private Member Functions // Private Member Functions
//- Disallow default bitwise assignment
void operator=(const ensightPartFaces&);
//- Track points used //- Track points used
virtual localPoints calcLocalPoints() const; localPoints calcLocalPoints() const;
//- Element connectivity //- Element connectivity
virtual void writeConnectivity void writeConnectivity
( (
ensightGeoFile&, ensightGeoFile&,
const word& key, const word& key,
@ -68,36 +86,6 @@ class ensightPartFaces
) const; ) const;
protected:
//- Addressable ensight element types
enum elemType
{
tria3Elements,
quad4Elements,
nsidedElements
};
// Static data members
static const List<word> elemTypes_;
// Protected data
//- Faces referenced
const faceList& faces_;
//- Can skip local point renumbering when points are contiguous
const bool contiguousPoints_;
// Protected Member Functions
//- Classify the face shapes, set elemLists.
void classify(const faceList&);
//- Helper: write connectivity //- Helper: write connectivity
void writeConnectivity void writeConnectivity
( (
@ -109,22 +97,27 @@ protected:
) const; ) const;
//- Disallow default bitwise copy construct
ensightPartFaces(const ensightPartFaces&) = delete;
//- Disallow default bitwise assignment
void operator=(const ensightPartFaces&) = delete;
public: public:
//- Runtime type information //- Runtime type information
TypeName("ensightFaces"); TypeName("ensightFaces");
// Constructors // Constructors
//- Construct empty part with number and description //- Construct part with 0-based index, description, points and faces
ensightPartFaces(label partNumber, const string& partDescription);
//- Construct part with number, description, points and faces
// Can skip local point renumbering when points are contiguous // Can skip local point renumbering when points are contiguous
ensightPartFaces ensightPartFaces
( (
label partNumber, label partIndex,
const string& partDescription, const string& description,
const pointField&, const pointField&,
const faceList&, const faceList&,
const bool contiguousPoints = false const bool contiguousPoints = false
@ -133,26 +126,11 @@ public:
//- Construct from polyMesh and polyPatch //- Construct from polyMesh and polyPatch
ensightPartFaces ensightPartFaces
( (
label partNumber, label partIndex,
const polyMesh&, const polyMesh&,
const polyPatch& const polyPatch&
); );
//- Construct as copy
ensightPartFaces(const ensightPartFaces&);
//- Reconstruct part characteristics (eg, element types) from Istream
// A part reconstructed in this manner can be used when writing fields,
// but cannot be used to write a new geometry
// \sa Foam::ensightPart::reconstruct
ensightPartFaces(Istream&);
//- Reconstruct part characteristics on freestore from Istream
static autoPtr<ensightPartFaces> New(Istream& is)
{
return autoPtr<ensightPartFaces>(new ensightPartFaces(is));
}
//- Destructor //- Destructor
virtual ~ensightPartFaces(); virtual ~ensightPartFaces();
@ -160,14 +138,44 @@ public:
// Member Functions // Member Functions
//- Write geometry // Access
virtual void writeGeometry(ensightGeoFile&) const;
//- Static listing of the element types //- Part index (0-based)
virtual const List<word>& elementTypes() const virtual label index() const
{ {
return elemTypes_; return ensightFaces::index();
} }
//- Number of elements in this part
virtual label size() const
{
return ensightFaces::size();
}
//- Return the patch index, -1 when not in use.
inline label patchIndex() const
{
return patchIndex_;
}
// Output
//- Write summary information about the object
virtual void writeSummary(Ostream&) const;
//- Write geometry
virtual void write(ensightGeoFile&) const;
//- Helper: write geometry given the pointField
virtual void write(ensightGeoFile&, const pointField&) const;
//- Print various types of debugging information
virtual void dumpInfo(Ostream&) const;
}; };

View File

@ -1,240 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
Output for ensightPart
\*---------------------------------------------------------------------------*/
#include "ensightPart.H"
#include "dictionary.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ensightPart::writeHeader
(
ensightFile& os,
bool withDescription
) const
{
os.write("part");
os.newline();
os.write(number() + 1); // Ensight starts with 1
os.newline();
if (withDescription)
{
os.write(name());
os.newline();
}
}
void Foam::ensightPart::writeFieldList
(
ensightFile& os,
const List<scalar>& field,
const labelUList& idList
) const
{
if (notNull(idList))
{
forAll(idList, i)
{
if (idList[i] >= field.size() || std::isnan(field[idList[i]]))
{
os.writeUndef();
}
else
{
os.write(field[idList[i]]);
}
os.newline();
}
}
else
{
// no idList => perNode
forAll(field, i)
{
if (std::isnan(field[i]))
{
os.writeUndef();
}
else
{
os.write(field[i]);
}
os.newline();
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ensightPart::reconstruct(Istream& is)
{
dictionary dict(is);
dict.lookup("id") >> number_;
dict.lookup("name") >> name_;
offset_ = 0;
dict.readIfPresent("offset", offset_);
// populate elemLists_
elemLists_.setSize(elementTypes().size());
forAll(elementTypes(), elemI)
{
word key(elementTypes()[elemI]);
elemLists_[elemI].clear();
dict.readIfPresent(key, elemLists_[elemI]);
size_ += elemLists_[elemI].size();
}
is.check("ensightPart::reconstruct(Istream&)");
}
bool Foam::ensightPart::writeSummary(Ostream& os) const
{
os << indent << type() << nl
<< indent << token::BEGIN_BLOCK << incrIndent << nl;
// Ensight starts with 1
os.writeKeyword("id") << (number() + 1) << token::END_STATEMENT << nl;
os.writeKeyword("name") << name() << token::END_STATEMENT << nl;
os.writeKeyword("offset") << offset() << token::END_STATEMENT << nl;
os.writeKeyword("size") << size() << token::END_STATEMENT << nl;
os << decrIndent << indent << token::END_BLOCK << nl << endl;
return true;
}
bool Foam::ensightPart::writeData(Ostream& os) const
{
os << indent << type() << nl
<< indent << token::BEGIN_BLOCK << incrIndent << nl;
os.writeKeyword("id") << number() << token::END_STATEMENT << nl;
os.writeKeyword("name") << name() << token::END_STATEMENT << nl;
os.writeKeyword("offset") << offset() << token::END_STATEMENT << nl;
forAll(elementTypes(), typeI)
{
word key(elementTypes()[typeI]);
if (elemLists_[typeI].size())
{
elemLists_[typeI].writeEntry(key, os);
}
}
os << decrIndent << indent << token::END_BLOCK << nl << endl;
return true;
}
void Foam::ensightPart::writeGeometry
(
ensightGeoFile& os,
const pointField& points
) const
{
if (size())
{
const localPoints ptList = calcLocalPoints();
const labelUList& pointMap = ptList.list;
writeHeader(os, true);
// write points
os.writeKeyword("coordinates");
os.write(ptList.nPoints);
os.newline();
for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
{
forAll(pointMap, ptI)
{
if (pointMap[ptI] > -1)
{
os.write(points[ptI].component(cmpt));
os.newline();
}
}
}
// write parts
forAll(elementTypes(), elemI)
{
if (elemLists_[elemI].size())
{
writeConnectivity
(
os,
elementTypes()[elemI],
elemLists_[elemI],
pointMap
);
}
}
}
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const ensightPart& part
)
{
part.writeData(os);
return os;
}
Foam::ensightGeoFile& Foam::operator<<
(
ensightGeoFile& os,
const ensightPart& part
)
{
part.writeGeometry(os);
return os;
}
// ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -29,21 +29,12 @@ License
Foam::ensightParts::ensightParts(const polyMesh& mesh) Foam::ensightParts::ensightParts(const polyMesh& mesh)
: :
partsList_() StorageType()
{ {
recalculate(mesh); recalculate(mesh);
} }
Foam::ensightParts::ensightParts(const IOobject& ioObj)
:
partsList_()
{
IOPtrList<ensightPart> ioList(ioObj);
partsList_.transfer(ioList);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightParts::~ensightParts() Foam::ensightParts::~ensightParts()
@ -54,19 +45,9 @@ Foam::ensightParts::~ensightParts()
void Foam::ensightParts::recalculate(const polyMesh& mesh) void Foam::ensightParts::recalculate(const polyMesh& mesh)
{ {
partsList_.clear(); StorageType::clear();
// extra space for unzoned cells
label nPart =
(
mesh.cellZones().size()
+ mesh.boundaryMesh().size()
+ 1
);
partsList_.setSize(nPart);
nPart = 0;
label nPart = 0;
label nZoneCells = 0; label nZoneCells = 0;
// do cell zones // do cell zones
@ -77,13 +58,7 @@ void Foam::ensightParts::recalculate(const polyMesh& mesh)
if (cZone.size()) if (cZone.size())
{ {
partsList_.set this->append(new ensightPartCells(nPart++, mesh, cZone));
(
nPart,
new ensightPartCells(nPart, mesh, cZone)
);
nPart++;
} }
} }
@ -92,13 +67,7 @@ void Foam::ensightParts::recalculate(const polyMesh& mesh)
// special case: no zones at all - do entire mesh // special case: no zones at all - do entire mesh
if (nZoneCells == 0) if (nZoneCells == 0)
{ {
partsList_.set this->append(new ensightPartCells(nPart++, mesh));
(
nPart,
new ensightPartCells(nPart, mesh)
);
nPart++;
} }
else if (mesh.nCells() > nZoneCells) else if (mesh.nCells() > nZoneCells)
{ {
@ -128,13 +97,7 @@ void Foam::ensightParts::recalculate(const polyMesh& mesh)
if (unzoned.size()) if (unzoned.size())
{ {
partsList_.set this->append(new ensightPartCells(nPart++, mesh, unzoned));
(
nPart,
new ensightPartCells(nPart, mesh, unzoned)
);
nPart++;
} }
} }
@ -145,96 +108,41 @@ void Foam::ensightParts::recalculate(const polyMesh& mesh)
const polyPatch& patch = mesh.boundaryMesh()[patchi]; const polyPatch& patch = mesh.boundaryMesh()[patchi];
if (patch.size() && !isA<processorPolyPatch>(patch)) if (patch.size() && !isA<processorPolyPatch>(patch))
{ {
partsList_.set this->append(new ensightPartFaces(nPart++, mesh, patch));
( }
nPart,
new ensightPartFaces(nPart, mesh, patch)
);
nPart++;
} }
} }
// truncate to correct size
partsList_.setSize(nPart);
}
void Foam::ensightParts::write(ensightGeoFile& os) const
void Foam::ensightParts::renumber
(
const labelUList& origCellId,
const labelUList& origFaceId
)
{ {
forAll(partsList_, partI) // Some feedback
{ Info<< "Write geometry part (" << flush;
if (partsList_[partI].isCellData())
{
partsList_[partI].renumber(origCellId);
}
else
{
partsList_[partI].renumber(origFaceId);
}
}
}
forAllConstIter(StorageType, *this, iter)
void Foam::ensightParts::writeGeometry(ensightGeoFile& os) const
{ {
// with some feedback Info<< ' ' << (*iter).index() << flush;
Info<< "write geometry part (" << flush; (*iter).write(os);
forAll(partsList_, partI)
{
Info<< " " << partI << flush;
partsList_[partI].writeGeometry(os);
} }
Info<< " )" << endl; Info<< " )" << endl;
} }
bool Foam::ensightParts::writeSummary(Ostream& os) const void Foam::ensightParts::writeSummary(Ostream& os) const
{ {
forAll(partsList_, partI) forAllConstIter(StorageType, *this, iter)
{ {
partsList_[partI].writeSummary(os); (*iter).writeSummary(os);
} }
return true;
} }
void Foam::ensightParts::writeData(Ostream& os) const void Foam::ensightParts::dumpInfo(Ostream& os) const
{ {
// Begin write list forAllConstIter(StorageType, *this, iter)
os << nl << partsList_.size()
<< nl << token::BEGIN_LIST;
// Write list contents
forAll(partsList_, i)
{ {
os << nl << partsList_[i]; (*iter).dumpInfo(os);
} }
// End write list
os << nl << token::END_LIST << nl;
// Check state of IOstream
os.check("ensightParts::writeData(Ostream&)");
}
// * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
Foam::ensightGeoFile& Foam::operator<<
(
ensightGeoFile& os,
const ensightParts& parts
)
{
parts.writeGeometry(os);
return os;
} }

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -29,13 +29,13 @@ Description
SourceFiles SourceFiles
ensightParts.C ensightParts.C
ensightPartsTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef ensightParts_H #ifndef ensightParts_H
#define ensightParts_H #define ensightParts_H
#include "SLPtrList.H"
#include "ensightPart.H" #include "ensightPart.H"
#include "ensightPartFaces.H" #include "ensightPartFaces.H"
#include "ensightPartCells.H" #include "ensightPartCells.H"
@ -46,43 +46,34 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declaration of friend functions and operators
class ensightParts;
ensightGeoFile& operator<<(ensightGeoFile&, const ensightParts&);
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class ensightParts Declaration Class ensightParts Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class ensightParts class ensightParts
:
public SLPtrList<ensightPart>
{ {
// Private Data
//- List of parts
PtrList<ensightPart> partsList_;
// Private Member Functions // Private Member Functions
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
ensightParts(const ensightParts&); ensightParts(const ensightParts&) = delete;
//- Disallow default bitwise assignment //- Disallow default bitwise assignment
void operator=(const ensightParts&); void operator=(const ensightParts&) = delete;
public: public:
//- Storage type used
typedef SLPtrList<ensightPart> StorageType;
// Constructors // Constructors
//- Construct from polyMesh //- Construct from polyMesh
ensightParts(const polyMesh&); ensightParts(const polyMesh&);
//- Construct from IOobject
ensightParts(const IOobject&);
//- Destructor //- Destructor
~ensightParts(); ~ensightParts();
@ -93,41 +84,19 @@ public:
//- Clear old information and construct anew from polyMesh //- Clear old information and construct anew from polyMesh
void recalculate(const polyMesh&); void recalculate(const polyMesh&);
//- Renumber elements
void renumber
(
const labelUList& origCellId,
const labelUList& origFaceId
);
//- Number of parts //- Number of parts
label size() const using StorageType::size;
{
return partsList_.size();
}
//- Write the geometry //- Write the geometry
void writeGeometry(ensightGeoFile&) const; void write(ensightGeoFile&) const;
//- Write summary information about the objects //- Write summary information about the objects
bool writeSummary(Ostream&) const; void writeSummary(Ostream&) const;
//- Write the lists //- Print various types of debugging information
void writeData(Ostream&) const; void dumpInfo(Ostream&) const;
//- Write generalized volume field components
template<class Type>
void writeField
(
ensightFile&,
const GeometricField<Type, fvPatchField, volMesh>&
) const;
// Friend Operators
//- Write geometry
friend ensightGeoFile& operator<<(ensightGeoFile&, const ensightParts&);
}; };
@ -137,10 +106,6 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightPartsTemplates.C"
#endif
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -1,3 +1,12 @@
ensight/file/ensightCase.C
ensight/file/ensightCaseOptions.C
ensight/file/ensightFile.C
ensight/file/ensightGeoFile.C
ensight/part/ensightCells.C
ensight/part/ensightFaces.C
ensight/read/ensightReadFile.C
ensight/type/ensightPTraits.C
vtk/vtkUnstructuredReader.C vtk/vtkUnstructuredReader.C
nas/NASCore.C nas/NASCore.C
starcd/STARCDCore.C starcd/STARCDCore.C
@ -8,7 +17,6 @@ setWriters = sampledSetWriters
$(setWriters)/writers.C $(setWriters)/writers.C
$(setWriters)/ensight/ensightSetWriterRunTime.C $(setWriters)/ensight/ensightSetWriterRunTime.C
$(setWriters)/ensight/ensightPTraits.C
$(setWriters)/gnuplot/gnuplotSetWriterRunTime.C $(setWriters)/gnuplot/gnuplotSetWriterRunTime.C
$(setWriters)/jplot/jplotSetWriterRunTime.C $(setWriters)/jplot/jplotSetWriterRunTime.C
$(setWriters)/raw/rawSetWriterRunTime.C $(setWriters)/raw/rawSetWriterRunTime.C

View File

@ -0,0 +1,742 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "ensightCase.H"
#include "stringListOps.H"
#include "Time.H"
#include "cloud.H"
#include "IOmanip.H"
#include "globalIndex.H"
#include "ensightFile.H"
#include "ensightGeoFile.H"
#include "demandDrivenData.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const char* Foam::ensightCase::dataDirName = "data";
const char* Foam::ensightCase::geometryName = "geometry";
// * * * * * * * * * * * * * Private Functions * * * * * * * * * * * * * * //
Foam::fileName Foam::ensightCase::dataDir() const
{
return ensightDir_/dataDirName;
}
void Foam::ensightCase::initialize()
{
if (Pstream::master())
{
// EnSight and EnSight/data directories must exist
// We may wish to retain old data
// eg, convert new results or a particular time interva
// OR remove everything
if (isDir(ensightDir_))
{
if (options_->overwrite())
{
Foam::rmDir(ensightDir_);
}
else
{
Info<<"Warning: re-using existing directory" << nl
<< " " << ensightDir_ << endl;
}
}
// Create ensight and data directories
mkDir(dataDir());
// The case file is always ASCII
os_ = new OFstream(ensightDir_/caseName_, IOstream::ASCII);
// Format options
os_->setf(ios_base::left);
os_->setf(ios_base::scientific, ios_base::floatfield);
os_->precision(5);
writeHeader();
}
}
Foam::label Foam::ensightCase::checkTimeset(const labelHashSet& lookup) const
{
// assume the worst
label ts = -1;
// work on a copy
labelHashSet tsTimes(lookup);
tsTimes.erase(-1);
if (tsTimes.empty())
{
// no times needed
ts = 0;
}
else if (tsTimes.size() == timesUsed_.size())
{
forAllConstIter(Map<scalar>, timesUsed_, iter)
{
tsTimes.erase(iter.key());
}
// OR
// tsTimes -= timesUsed_.toc();
// tsTimes -= timesUsed_;
if (tsTimes.empty())
{
ts = 1; // can use timeset 1
}
}
return ts;
}
void Foam::ensightCase::writeHeader() const
{
if (os_) // master only
{
this->rewind();
*os_
<< "FORMAT" << nl
<< "type: ensight gold" << nl;
}
}
Foam::scalar Foam::ensightCase::writeTimeset() const
{
const label ts = 1;
const labelList indices = timesUsed_.sortedToc();
label count = indices.size();
// correct for negative starting values
scalar timeCorrection = timesUsed_[indices[0]];
if (timeCorrection < 0)
{
timeCorrection = -timeCorrection;
Info<< "Correcting time values. Adding " << timeCorrection << endl;
}
else
{
timeCorrection = 0;
}
*os_
<< "time set: " << ts << nl
<< "number of steps: " << count << nl;
if (indices[0] == 0 && indices[count-1] == count-1)
{
// looks to be contiguous numbering
*os_
<< "filename start number: " << 0 << nl
<< "filename increment: " << 1 << nl;
}
else
{
*os_
<< "filename numbers:" << nl;
count = 0;
forAll(indices, idx)
{
*os_ << " " << setw(12) << indices[idx];
if (++count % 6 == 0)
{
*os_ << nl;
}
}
if (count)
{
*os_ << nl;
}
}
*os_ << "time values:" << nl;
count = 0;
forAll(indices, idx)
{
*os_ << " " << setw(12) << timesUsed_[indices[idx]] + timeCorrection;
if (++count % 6 == 0)
{
*os_ << nl;
}
}
if (count)
{
*os_ << nl;
}
return timeCorrection;
}
void Foam::ensightCase::writeTimeset
(
const label ts,
const labelHashSet& lookup,
const scalar timeCorrection
) const
{
// make a copy
labelHashSet hashed(lookup);
hashed.erase(-1);
const labelList indices = hashed.sortedToc();
label count = indices.size();
*os_
<< "time set: " << ts << nl
<< "number of steps: " << count << nl
<< "filename numbers:" << nl;
count = 0;
forAll(indices, idx)
{
*os_ << " " << setw(12) << indices[idx];
if (++count % 6 == 0)
{
*os_ << nl;
}
}
if (count)
{
*os_ << nl;
}
*os_ << "time values:" << nl;
count = 0;
forAll(indices, idx)
{
*os_ << " " << setw(12) << timesUsed_[indices[idx]] + timeCorrection;
if (++count % 6 == 0)
{
*os_ << nl;
}
}
if (count)
{
*os_ << nl;
}
}
void Foam::ensightCase::noteGeometry(const bool moving) const
{
if (moving)
{
geomTimes_.insert(timeIndex_);
}
else
{
geomTimes_.insert(-1);
}
changed_ = true;
}
void Foam::ensightCase::noteCloud(const word& cloudName) const
{
if (!cloudVars_.found(cloudName))
{
cloudVars_.insert(cloudName, HashTable<string>());
}
cloudTimes_.insert(timeIndex_);
changed_ = true;
}
void Foam::ensightCase::noteCloud
(
const word& cloudName,
const word& varName,
const char* ensightType
) const
{
if (cloudVars_.found(cloudName))
{
if (cloudVars_[cloudName].insert(varName, ensightType))
{
changed_ = true;
}
}
else
{
FatalErrorInFunction
<< "Tried to add a cloud variable for writing without having added a cloud"
<< abort(FatalError);
}
}
void Foam::ensightCase::noteVariable
(
const word& varName,
const char* ensightType
) const
{
if (variables_.insert(varName, ensightType))
{
changed_ = true;
}
}
Foam::autoPtr<Foam::ensightFile>
Foam::ensightCase::createDataFile
(
const word& name
) const
{
autoPtr<ensightFile> output;
if (Pstream::master())
{
// the data/ITER subdirectory must exist
// Note that data/ITER is indeed a valid ensight::FileName
const fileName outdir = dataDir()/padded(timeIndex_);
mkDir(outdir);
output.reset(new ensightFile(outdir, name, format()));
}
return output;
}
Foam::autoPtr<Foam::ensightFile>
Foam::ensightCase::createCloudFile
(
const word& cloudName,
const word& name
) const
{
autoPtr<Foam::ensightFile> output;
if (Pstream::master())
{
// Write
// eg -> "data/********/lagrangian/<cloudName>/positions"
// or -> "lagrangian/<cloudName>/********/positions"
// TODO? check that cloudName is a valid ensight filename
const fileName outdir =
(
separateCloud()
? (ensightDir_ / cloud::prefix / cloudName / padded(timeIndex_))
: (dataDir() / padded(timeIndex_) / cloud::prefix / cloudName)
);
mkDir(outdir); // should be unnecessary after newCloud()
output.reset(new ensightFile(outdir, name, format()));
}
return output;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightCase::ensightCase
(
const fileName& ensightDir,
const word& caseName,
const ensightCase::options& opts
)
:
options_(new options(opts)),
ensightDir_(ensightDir),
caseName_(caseName + ".case"),
os_(nullptr),
changed_(false),
timeIndex_(0),
timeValue_(0),
timesUsed_(),
geomTimes_(),
cloudTimes_(),
variables_(),
cloudVars_()
{
initialize();
}
Foam::ensightCase::ensightCase
(
const fileName& ensightDir,
const word& caseName,
const IOstream::streamFormat format
)
:
options_(new options(format)),
ensightDir_(ensightDir),
caseName_(caseName + ".case"),
os_(nullptr),
changed_(false),
timeIndex_(0),
timeValue_(0),
timesUsed_(),
geomTimes_(),
cloudTimes_(),
variables_(),
cloudVars_()
{
initialize();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightCase::~ensightCase()
{
deleteDemandDrivenData(options_);
deleteDemandDrivenData(os_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ensightCase::nextTime(const scalar value)
{
// use next available index
setTime(value, timesUsed_.size());
}
void Foam::ensightCase::nextTime(const instant& t)
{
nextTime(t.value());
}
void Foam::ensightCase::setTime(const scalar value, const label index)
{
timeIndex_ = index;
timeValue_ = value;
if (Pstream::master())
{
// The data/ITER subdirectory must exist
// Note that data/ITER is indeed a valid ensight::FileName
const fileName outdir = dataDir()/padded(timeIndex_);
mkDir(outdir);
// place a timestamp in the directory for future reference
OFstream timeStamp(outdir/"time");
timeStamp
<< "# index time" << nl
<< outdir.name() << ' ' << timeValue_ << nl;
}
// Record of time index/value used
timesUsed_.set(index, value);
}
void Foam::ensightCase::setTime(const instant& t, const label index)
{
setTime(t.value(), index);
}
void Foam::ensightCase::write() const
{
if (!os_) return; // master only
// geometry timeset
bool staticGeom = (geomTimes_.size() == 1 && geomTimes_.found(-1));
label tsGeom = staticGeom ? 0 : checkTimeset(geomTimes_);
// cloud timeset
label tsCloud = checkTimeset(cloudTimes_);
// increment time-sets to the correct indices
if (tsGeom < 0)
{
tsGeom = 2; // next available timeset
}
if (tsCloud < 0)
{
tsCloud = tsGeom + 1; // next available timeset
}
writeHeader();
// data mask: eg "data/******"
const fileName dataMask = (dataDirName/mask());
//
// GEOMETRY
//
if (!geomTimes_.empty() || !cloudTimes_.empty())
{
// start of variables
*os_
<< nl
<< "GEOMETRY" << nl;
}
if (staticGeom)
{
// steady
*os_
<< setw(16) << "model:"
<< geometryName
<< nl;
}
else if (!geomTimes_.empty())
{
// moving
*os_
<< Foam::name("model: %-9d", tsGeom) // width 16
<< (dataMask/geometryName).c_str()
<< nl;
}
// clouds and cloud variables
const wordList cloudNames = cloudVars_.sortedToc();
forAll(cloudNames, cloudNo)
{
const word& cloudName = cloudNames[cloudNo];
const fileName masked =
(
separateCloud()
? (cloud::prefix / cloudName / mask())
: (dataMask / cloud::prefix / cloudName)
);
*os_
<< Foam::name("measured: %-6d", tsCloud) // width 16
<< (masked/"positions").c_str()
<< nl;
}
//
// VARIABLE
//
if (variables_.size() || cloudVars_.size())
{
// start of variables
*os_
<< nl
<< "VARIABLE" << nl;
}
// field variables (always use timeset 1)
const wordList varNames = variables_.sortedToc();
forAll(varNames, vari)
{
const word& varName = varNames[vari];
const string& ensType = variables_[varName];
*os_
<< ensType.c_str()
<<
(
nodeValues()
? " per node: 1 " // time-set 1
: " per element: 1 " // time-set 1
)
<< setw(15) << varName << ' '
<< (dataMask/varName).c_str() << nl;
}
// clouds and cloud variables (using cloud timeset)
// Write
// as -> "data/********/lagrangian/<cloudName>/positions"
// or -> "lagrangian/<cloudName>/********/positions"
forAll(cloudNames, cloudNo)
{
const word& cloudName = cloudNames[cloudNo];
const fileName masked =
(
separateCloud()
? (cloud::prefix / cloudName / mask())
: (dataMask / cloud::prefix / cloudName)
);
const HashTable<string>& vars = cloudVars_[cloudName];
const wordList tocVars = vars.sortedToc();
forAll(tocVars, vari)
{
const word& varName = tocVars[vari];
const string& ensType = vars[varName];
// prefix variables with 'c' (cloud) and cloud index
*os_
<< ensType.c_str() << " per "
<< Foam::name("measured node: %-5d", tsCloud) // width 20
<< setw(15)
<< ("c" + Foam::name(cloudNo) + varName).c_str() << ' '
<< (masked/varName).c_str()
<< nl;
}
}
//
// TIME
//
if (!timesUsed_.empty())
{
*os_
<< nl << "TIME" << nl;
// timeset 1
const scalar timeCorrection = writeTimeset();
// timeset geometry
if (tsGeom > 1)
{
writeTimeset(tsGeom, geomTimes_, timeCorrection);
}
// timeset cloud
if (tsCloud > 1)
{
writeTimeset(tsCloud, cloudTimes_, timeCorrection);
}
*os_
<< "# end" << nl;
}
*os_ << flush;
changed_ = false;
}
Foam::autoPtr<Foam::ensightGeoFile>
Foam::ensightCase::newGeometry
(
const bool moving
) const
{
autoPtr<Foam::ensightGeoFile> output;
if (Pstream::master())
{
// set the path of the ensight file
fileName path;
if (moving)
{
// Moving mesh: write as "data/********/geometry"
path = dataDir()/padded(timeIndex_);
mkDir(path);
}
else
{
// Static mesh: write as "geometry"
path = ensightDir_;
}
output.reset(new ensightGeoFile(path, geometryName, format()));
noteGeometry(moving); // note for later use
}
return output;
}
Foam::autoPtr<Foam::ensightFile>
Foam::ensightCase::newCloud
(
const word& cloudName
) const
{
autoPtr<Foam::ensightFile> output;
if (Pstream::master())
{
output = createCloudFile(cloudName, "positions");
// tag binary format (just like geometry files)
output().writeBinaryHeader();
// description
output().write(cloud::prefix/cloudName);
output().newline();
noteCloud(cloudName); // note for later use
}
return output;
}
void Foam::ensightCase::rewind() const
{
if (os_) // master only
{
os_->stdStream().seekp(0, std::ios_base::beg);
}
}
Foam::Ostream& Foam::ensightCase::printInfo(Ostream& os) const
{
os << "Ensight case:" << nl
<< " path: " << ensightDir_ << nl
<< " name: " << caseName_ << nl
<< " format: " << format() << nl
<< " values per " << (nodeValues() ? "node" : "element") << nl;
return os;
}
// ************************************************************************* //

View File

@ -0,0 +1,405 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::ensightCase
Description
Supports writing of ensight cases as well as providing common factory
methods to open new files.
SourceFiles
ensightCase.C
\*---------------------------------------------------------------------------*/
#ifndef ensightCase_H
#define ensightCase_H
#include "autoPtr.H"
#include "HashSet.H"
#include "InfoProxy.H"
#include "Map.H"
#include "OSspecific.H"
#include "Pstream.H"
#include "ensightGeoFile.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
class ensightCase;
class instant;
class Time;
/*---------------------------------------------------------------------------*\
Class ensightCase Declaration
\*---------------------------------------------------------------------------*/
class ensightCase
{
public:
// Forward declarations
class options;
// Public Data
//- The name for "data" subdirectory
static const char* dataDirName;
//- The name for geometry files
static const char* geometryName;
private:
// Private data
//- Case writing options
const options* options_;
//- Output path (absolute)
fileName ensightDir_;
//- Case name (with ".case" ending)
word caseName_;
//- Output stream
mutable OFstream* os_;
//- Track state changes since last write
mutable bool changed_;
//- Time index (timeset 1)
label timeIndex_;
//- Time value (timeset 1)
scalar timeValue_;
//- Record of time index/value used (eg, field values).
// These values will be used for timeset 1.
Map<scalar> timesUsed_;
//- Record time indices when geometry is written.
// These values will be used to decide if timeset 1
// or a separate timeset are used.
// The special index '-1' is used static geometry.
mutable labelHashSet geomTimes_;
//- Record time indices when clouds are written.
// These values will be used to decide if timeset 1
// or a separate timeset are used.
mutable labelHashSet cloudTimes_;
//- Fields/Variables with the ensight type
mutable HashTable<string> variables_;
//- Cloud names and variables
mutable HashTable<HashTable<string>> cloudVars_;
// Private Member Functions
//- The data directory
fileName dataDir() const;
//- Initial file management (master only)
void initialize();
//- Check if timeset uses different times than from time-set 1
label checkTimeset(const labelHashSet& lookup) const;
//- Write the header into the case file.
void writeHeader() const;
//- Write the timeset 1 into the case file.
// Return the time correction in effect
scalar writeTimeset() const;
//- Write the timeset into the case file.
void writeTimeset
(
const label ts,
const labelHashSet& lookup,
const scalar timeCorrection = 0
) const;
//- Note geometry being used
void noteGeometry(const bool moving) const;
//- Note cloud being used
void noteCloud(const word& cloudName) const;
//- Note cloud/variable being used
void noteCloud
(
const word& cloudName,
const word& varName,
const char* ensightType
) const;
//- Note field variable being used
void noteVariable
(
const word& varName,
const char* ensightType
) const;
//- Open stream for new data file (on master), using the current index.
// File is without initial description lines.
autoPtr<ensightFile> createDataFile(const word&) const;
//- Open stream for new cloud file (on master).
// File is without initial description lines.
autoPtr<ensightFile> createCloudFile
(
const word& cloudName,
const word& name
) const;
//- Disallow default bitwise copy construct
ensightCase(const ensightCase&) = delete;
//- Disallow default bitwise assignment
void operator=(const ensightCase&) = delete;
public:
// Constructors
//- Construct from components
ensightCase
(
const fileName& ensightDir,
const word& caseName,
const options& opts
);
//- Construct from components with all default options
ensightCase
(
const fileName& ensightDir,
const word& caseName,
const IOstream::streamFormat format = IOstream::BINARY
);
//- Destructor
~ensightCase();
// Member Functions
// Access
//- Reference to the case options
inline const ensightCase::options& option() const;
//- Ascii/Binary file output
inline IOstream::streamFormat format() const;
//- The nominal path to the case file
inline const fileName& path() const;
//- The output '*' mask
inline const word& mask() const;
//- Consistent zero-padded integer value
inline word padded(const label i) const;
//- Use values per nodes instead of per element
inline bool nodeValues() const;
//- Write clouds into their own directory instead in "data" directory
inline bool separateCloud() const;
// Edit
//- Set time for time-set 1, using next available index.
// Create corresponding sub-directory.
// Do not mix between nextTime and setTime in an application.
void nextTime(const scalar t);
//- Set time for time-set 1, using next available index.
// Create corresponding sub-directory.
// Do not mix between nextTime and setTime in an application.
void nextTime(const instant& t);
//- Set current index and time for time-set 1.
// Create corresponding sub-directory
// Do not mix between nextTime and setTime in an application.
void setTime(const scalar t, const label index);
//- Set current index and time for time-set 1.
// Create corresponding sub-directory
// Do not mix between nextTime and setTime in an application.
void setTime(const instant& t, const label index);
// Addition of entries to case file
//- Open stream for new geometry file (on master).
autoPtr<ensightGeoFile> newGeometry(const bool moving = false) const;
//- Open stream for new cloud positions (on master).
// Note the use of ensightFile, not ensightGeoFile.
autoPtr<ensightFile> newCloud
(
const word& cloudName
) const;
//- Open stream for new data file (on master), using the current index.
template<class Type>
autoPtr<ensightFile> newData(const word& varName) const;
//- Open stream for new cloud data file (on master), using the current index.
template<class Type>
autoPtr<ensightFile> newCloudData
(
const word& cloudName,
const word& varName
) const;
// Output
//- Rewind the output stream (master only).
void rewind() const;
//- Write the case file
void write() const;
//- Output stream (master only).
inline Ostream& operator()() const;
//- Print some general information.
Ostream& printInfo(Ostream&) const;
};
//- Configuration options for the ensightCase
class ensightCase::options
{
private:
//- Ascii/Binary file output
IOstream::streamFormat format_;
//- Width of mask for subdirectories
label width_;
//- The '*' mask appropriate for subdirectories
word mask_;
//- The printf format for zero-padded subdirectory numbers
string printf_;
//- Remove existing directory and sub-directories on creation
bool overwrite_;
//- Write values at nodes
bool nodeValues_;
//- Write clouds into their own directory
bool separateCloud_;
public:
// Constructors
//- Construct with the specified format (default is binary)
options(IOstream::streamFormat format = IOstream::BINARY);
// Member Functions
// Access
//- Ascii/Binary file output
IOstream::streamFormat format() const;
//- The '*' mask appropriate for sub-directories
const word& mask() const;
//- Consistent zero-padded integer value
word padded(const label i) const;
//- Return current width of mask and padded.
label width() const;
//- Remove existing directory and sub-directories on creation
bool overwrite() const;
//- Use values per nodes instead of per element
bool nodeValues() const;
//- Write clouds into their own directory instead in "data" directory
bool separateCloud() const;
// Edit
//- Set width of mask and padded.
// Default width is 8 digits, max width is 31 digits.
void width(const label i);
//- Remove existing directory and sub-directories on creation
void overwrite(bool);
//- Use values per nodes instead of per element
void nodeValues(bool);
//- Write clouds into their own directory instead in "data" directory
void separateCloud(bool);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ensightCaseI.H"
#ifdef NoRepository
#include "ensightCaseTemplates.C"
#endif
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -21,58 +21,58 @@ License
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. 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 inline const Foam::ensightCase::options& Foam::ensightCase::option() const
{ {
return *options_;
}
/*---------------------------------------------------------------------------*\
Class faceSets Declaration
\*---------------------------------------------------------------------------*/
class faceSets inline Foam::IOstream::streamFormat Foam::ensightCase::format() const
{ {
public: return options_->format();
}
label nTris;
label nQuads;
label nPolys;
labelList tris;
labelList quads;
labelList polys;
// Constructors inline const Foam::fileName& Foam::ensightCase::path() const
{
//- Construct null return ensightDir_;
faceSets() }
:
nTris(0),
nQuads(0),
nPolys(0)
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // inline const Foam::word& Foam::ensightCase::mask() const
{
return options_->mask();
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // inline Foam::word Foam::ensightCase::padded(const label i) const
{
return options_->padded(i);
}
inline bool Foam::ensightCase::nodeValues() const
{
return options_->nodeValues();
}
inline bool Foam::ensightCase::separateCloud() const
{
return options_->separateCloud();
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline Foam::Ostream& Foam::ensightCase::operator()() const
{
return *os_;
}
#endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "ensightCase.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightCase::options::options(IOstream::streamFormat format)
:
format_(format),
width_(0),
mask_(),
printf_(),
overwrite_(false),
nodeValues_(false),
separateCloud_(false)
{
width(8); // ensures that the mask and printf-format are also resized
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::IOstream::streamFormat Foam::ensightCase::options::format() const
{
return format_;
}
const Foam::word& Foam::ensightCase::options::mask() const
{
return mask_;
}
Foam::word Foam::ensightCase::options::padded(const label i) const
{
// As per Foam::name, but with fixed length
char buf[32];
::snprintf(buf, 32, printf_.c_str(), i);
buf[31] = 0;
// no stripping required
return word(buf, false);
}
Foam::label Foam::ensightCase::options::width() const
{
return width_;
}
void Foam::ensightCase::options::width(const label n)
{
// enforce min/max sanity limits
if (n < 1 || n > 31)
{
return;
}
// set mask accordingly
mask_.resize(n, '*');
// appropriate printf format
printf_ = "%0" + Foam::name(n) + "d";
}
bool Foam::ensightCase::options::overwrite() const
{
return overwrite_;
}
void Foam::ensightCase::options::overwrite(bool b)
{
overwrite_ = b;
}
bool Foam::ensightCase::options::nodeValues() const
{
return nodeValues_;
}
void Foam::ensightCase::options::nodeValues(bool b)
{
nodeValues_ = b;
}
bool Foam::ensightCase::options::separateCloud() const
{
return separateCloud_;
}
void Foam::ensightCase::options::separateCloud(bool b)
{
separateCloud_ = b;
}
// ************************************************************************* //

View File

@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "cloud.H"
#include "ensightPTraits.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::autoPtr<Foam::ensightFile>
Foam::ensightCase::newData
(
const word& name
) const
{
autoPtr<ensightFile> output;
if (Pstream::master())
{
const ensight::VarName varName(name);
output = createDataFile(varName);
// description
output().write
(
string
(
padded(timeIndex_) / varName
+ " <" + pTraits<Type>::typeName + ">"
)
);
output().newline();
// note variable for later use
noteVariable(varName, ensightPTraits<Type>::typeName);
}
return output;
}
template<class Type>
Foam::autoPtr<Foam::ensightFile>
Foam::ensightCase::newCloudData
(
const word& cloudName,
const word& name
) const
{
autoPtr<Foam::ensightFile> output;
if (Pstream::master())
{
const ensight::VarName varName(name);
output = createCloudFile(cloudName, varName);
// description
output().write
(
string
(
padded(timeIndex_) / cloudName / varName
+ " <" + pTraits<Type>::typeName + ">"
)
);
output().newline();
// note cloud variable for later use
noteCloud(cloudName, varName, ensightPTraits<Type>::typeName);
}
return output;
}
// ************************************************************************* //

View File

@ -25,6 +25,7 @@ License
#include "ensightFile.H" #include "ensightFile.H"
#include "error.H" #include "error.H"
#include "UList.H"
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
@ -307,4 +308,76 @@ Foam::Ostream& Foam::ensightFile::writeBinaryHeader()
} }
//
// Convenience Output Methods
//
void Foam::ensightFile::beginPart(const label index)
{
write("part");
newline();
write(index+1); // Ensight starts with 1
newline();
}
void Foam::ensightFile::beginParticleCoordinates(const label nparticles)
{
write("particle coordinates");
newline();
write(nparticles, 8); // unusual width
newline();
}
void Foam::ensightFile::writeList
(
const UList<scalar>& field
)
{
forAll(field, i)
{
if (std::isnan(field[i]))
{
writeUndef();
}
else
{
write(field[i]);
}
newline();
}
}
void Foam::ensightFile::writeList
(
const UList<scalar>& field,
const labelUList& idList
)
{
if (notNull(idList))
{
forAll(idList, i)
{
if (idList[i] >= field.size() || std::isnan(field[idList[i]]))
{
writeUndef();
}
else
{
write(field[idList[i]]);
}
newline();
}
}
else
{
// no idList => perNode
writeList(field);
}
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -38,6 +38,7 @@ Description
#include "ensightFileName.H" #include "ensightFileName.H"
#include "ensightVarName.H" #include "ensightVarName.H"
#include "UList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -80,9 +81,13 @@ class ensightFile
public: public:
// Forward declarations // Static Member Functions
class FileName;
class VarName; //- Return a null ensightFile
inline static const ensightFile& null()
{
return NullObjectRef<ensightFile>();
}
// Constructors // Constructors
@ -172,6 +177,28 @@ public:
//- Add carriage return to ascii stream //- Add carriage return to ascii stream
void newline(); void newline();
// Convenience Output Methods
//- Begin a part (0-based index).
void beginPart(const label index);
//- Begin a "particle coordinates" block (measured data)
void beginParticleCoordinates(const label nparticles);
//- Write a list of floats as "%12.5e" or as binary
// With carriage return after each value (ascii stream)
void writeList(const UList<scalar>& field);
//- Write an indirect list of scalars as "%12.5e" or as binary
// With carriage return after each value (ascii stream)
void writeList
(
const UList<scalar>& field,
const labelUList& idList
);
}; };

View File

@ -35,17 +35,25 @@ License
void Foam::ensightGeoFile::initialize() void Foam::ensightGeoFile::initialize()
{ {
writeBinaryHeader();
// Description line 1
write("Ensight Geometry File");
newline();
// Description line 2
#ifdef OPENFOAM_PLUS #ifdef OPENFOAM_PLUS
string desc2("Written by OpenFOAM+ " STRING_QUOTE(OPENFOAM_PLUS)); write(string("Written by OpenFOAM+ " STRING_QUOTE(OPENFOAM_PLUS)));
#else #else
string desc2("Written by OpenFOAM-" + string(Foam::FOAMversion)); write(string("Written by OpenFOAM-" + string(Foam::FOAMversion)));
#endif #endif
writeBinaryHeader(); newline();
write("Ensight Geometry File"); newline(); // description line 1 write("node id assign");
write(desc2); newline(); // description line 2 newline();
write("node id assign"); newline();
write("element id assign"); newline(); write("element id assign");
newline();
} }
@ -87,10 +95,36 @@ Foam::ensightGeoFile::~ensightGeoFile()
Foam::Ostream& Foam::ensightGeoFile::writeKeyword(const keyType& key) Foam::Ostream& Foam::ensightGeoFile::writeKeyword(const keyType& key)
{ {
// ensure we get ensightFile::write(const string&) // ensure we get ensightFile::write(const string&)
write(static_cast<const string&>(key)); newline(); write(static_cast<const string&>(key));
newline();
return *this; return *this;
} }
//
// Convenience Output Methods
//
void Foam::ensightGeoFile::beginPart
(
const label index,
const string& description
)
{
beginPart(index);
write(description);
newline();
}
void Foam::ensightGeoFile::beginCoordinates(const label npoints)
{
write("coordinates");
newline();
write(npoints);
newline();
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -61,6 +61,15 @@ class ensightGeoFile
public: public:
// Static Member Functions
//- Return a null ensightGeoFile
inline static const ensightGeoFile& null()
{
return NullObjectRef<ensightGeoFile>();
}
// Constructors // Constructors
//- Construct from pathname. //- Construct from pathname.
@ -89,6 +98,18 @@ public:
//- Write keyword with trailing newline //- Write keyword with trailing newline
virtual Ostream& writeKeyword(const keyType& key); virtual Ostream& writeKeyword(const keyType& key);
// Convenience Output Methods
using ensightFile::beginPart;
//- Begin a "part" (0-based index), with a description.
void beginPart(const label index, const string& description);
//- Begin a "coordinates" block
void beginCoordinates(const label npoints);
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -28,7 +28,7 @@ Description
Specification of a valid Ensight file-name. Specification of a valid Ensight file-name.
Spaces must be quoted, Spaces must be quoted,
no '*' wildcards, not '%' (structured block continuation). no '*' wildcards, no '%' (structured block continuation).
Overall line length within case file is limited to 1024, but this is not Overall line length within case file is limited to 1024, but this is not
yet addresssed. yet addresssed.
@ -80,9 +80,10 @@ public:
//- Is this character valid for an ensight file-name //- Is this character valid for an ensight file-name
inline static bool valid(char); inline static bool valid(char);
// Member operators // Member operators
// Assignment // Assignment (disabled)
void operator=(const fileName&) = delete; void operator=(const fileName&) = delete;
void operator=(const word&) = delete; void operator=(const word&) = delete;

View File

@ -63,10 +63,8 @@ class VarName
//- Strip invalid characters //- Strip invalid characters
inline void stripInvalid(); inline void stripInvalid();
public: public:
// Constructors // Constructors
//- Construct as copy //- Construct as copy
@ -87,8 +85,7 @@ public:
// Member operators // Member operators
// Assignment // Assignment (disabled)
void operator=(const word&) = delete; void operator=(const word&) = delete;
void operator=(const string&) = delete; void operator=(const string&) = delete;
void operator=(const std::string&) = delete; void operator=(const std::string&) = delete;

View File

@ -0,0 +1,288 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "ensightCells.H"
#include "error.H"
#include "polyMesh.H"
#include "cellModeller.H"
#include "demandDrivenData.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::label Foam::ensightCells::nTypes = 5;
namespace Foam
{
template<>
const char* Foam::NamedEnum
<
Foam::ensightCells::elemType,
5
>::names[] = { "tetra4", "pyramid5", "penta6", "hexa8", "nfaced" };
}
const Foam::NamedEnum<Foam::ensightCells::elemType, 5>
Foam::ensightCells::elemEnum;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
inline Foam::label Foam::ensightCells::offset
(
const enum elemType what,
const label i
) const
{
label n = i;
for (label typeI = 0; typeI < label(what); ++typeI)
{
n += sizes_[typeI];
}
return n;
}
void Foam::ensightCells::resize()
{
// overall required size
label n = 0;
forAll(sizes_, typeI)
{
n += sizes_[typeI];
}
address_.setSize(n, Zero);
// assign corresponding sub-lists
n = 0;
forAll(sizes_, typeI)
{
deleteDemandDrivenData(lists_[typeI]);
lists_[typeI] = new SubList<label>(address_, sizes_[typeI], n);
n += sizes_[typeI];
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightCells::ensightCells(const label partIndex)
:
index_(partIndex),
address_(),
sizes_(Zero),
lists_()
{
// Ensure sub-lists are properly initialized to nullptr
forAll(lists_, typeI)
{
lists_[typeI] = nullptr;
}
resize(); // adjust allocation
}
Foam::ensightCells::ensightCells(const ensightCells& obj)
:
index_(obj.index_),
address_(obj.address_),
sizes_(),
lists_()
{
// Ensure sub-lists are properly initialized to nullptr
forAll(lists_, typeI)
{
lists_[typeI] = nullptr;
}
// Total (reduced) sizes
FixedList<label, 5> totSizes = obj.sizes_;
// Local sizes
this->sizes_ = obj.sizes();
resize(); // adjust allocation
// Restore total (reduced) sizes
this->sizes_ = totSizes;
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightCells::~ensightCells()
{
forAll(lists_, typeI)
{
deleteDemandDrivenData(lists_[typeI]);
}
address_.clear();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::FixedList<Foam::label, 5> Foam::ensightCells::sizes() const
{
FixedList<label, 5> count;
forAll(lists_, typeI)
{
count[typeI] = lists_[typeI]->size();
}
return count;
}
Foam::label Foam::ensightCells::total() const
{
label n = 0;
forAll(sizes_, typeI)
{
n += sizes_[typeI];
}
return n;
}
void Foam::ensightCells::clear()
{
sizes_ = Zero; // reset sizes
resize();
}
void Foam::ensightCells::reduce()
{
forAll(sizes_, typeI)
{
sizes_[typeI] = lists_[typeI]->size();
Foam::reduce(sizes_[typeI], sumOp<label>());
}
}
void Foam::ensightCells::sort()
{
forAll(lists_, typeI)
{
if (lists_[typeI])
{
Foam::sort(*(lists_[typeI]));
}
}
}
void Foam::ensightCells::classify
(
const polyMesh& mesh,
const labelUList& addressing
)
{
// References to cell shape models
const cellModel& tet = *(cellModeller::lookup("tet"));
const cellModel& pyr = *(cellModeller::lookup("pyr"));
const cellModel& prism = *(cellModeller::lookup("prism"));
const cellModel& hex = *(cellModeller::lookup("hex"));
const cellShapeList& shapes = mesh.cellShapes();
const bool indirect = notNull(addressing);
const label sz = indirect ? addressing.size() : mesh.nCells();
// Count the shapes
// Can avoid double looping, but only at the expense of allocation
sizes_ = Zero; // reset sizes
for (label listI = 0; listI < sz; ++listI)
{
const label id = indirect ? addressing[listI] : listI;
const cellModel& model = shapes[id].model();
enum elemType what = NFACED;
if (model == tet)
{
what = TETRA4;
}
else if (model == pyr)
{
what = PYRAMID5;
}
else if (model == prism)
{
what = PENTA6;
}
else if (model == hex)
{
what = HEXA8;
}
sizes_[what]++;
}
resize(); // adjust allocation
sizes_ = Zero; // reset sizes
// Assign cell-id per shape type
for (label listI = 0; listI < sz; ++listI)
{
const label id = indirect ? addressing[listI] : listI;
const cellModel& model = shapes[id].model();
enum elemType what = NFACED;
if (model == tet)
{
what = TETRA4;
}
else if (model == pyr)
{
what = PYRAMID5;
}
else if (model == prism)
{
what = PENTA6;
}
else if (model == hex)
{
what = HEXA8;
}
// eg, the processor local cellId
lists_[what]->operator[](sizes_[what]++) = id;
}
}
Foam::label Foam::ensightCells::offset(const enum elemType what) const
{
return offset(what, 0);
}
// ************************************************************************* //

View File

@ -0,0 +1,206 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::ensightCells
Description
Sorting/classification of cells (3D) into corresponding ensight element
types.
\*---------------------------------------------------------------------------*/
#ifndef ensightCells_H
#define ensightCells_H
#include "labelList.H"
#include "FixedList.H"
#include "SubList.H"
#include "NamedEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class polyMesh;
/*---------------------------------------------------------------------------*\
Class ensightCells Declaration
\*---------------------------------------------------------------------------*/
class ensightCells
{
public:
// Public data
//- Addressable ensight element types
enum elemType
{
TETRA4,
PYRAMID5,
PENTA6,
HEXA8,
NFACED
};
//- Number of element types (5)
static const label nTypes;
//- The Ensight names for each element type
static const NamedEnum<elemType, 5> elemEnum;
// Static Member Functions
//- Return the ensight element name for the specified type
inline static const char* key(const enum elemType);
private:
// Private data
//- Location within a list.
// The ensight part number is typically this value +1.
label index_;
//- Linear list of ids, sub-sectioned per element type via SubLists
labelList address_;
//- List of sizes for each element type
FixedList<label, 5> sizes_;
//- List of ids for each element type
// Managed via pointers, since a SubList cannot be relocated/resized.
FixedList<SubList<label>*, 5> lists_;
// Private Member Functions
//- Low-level offset routine
inline label offset(const enum elemType what, const label i) const;
//- Use current sizes to redimension the element lists
void resize();
//- Disallow default bitwise assignment
void operator=(const ensightCells&) = delete;
public:
// Constructors
//- Construct null, optionally with index
ensightCells(label partIndex = 0);
//- Copy constructor. Needed for lists etc.
ensightCells(const ensightCells&);
//- Destructor
~ensightCells();
// Member Functions
// Access
//- The index in a list.
inline label index() const;
//- The index in a list, non-const access.
inline label& index();
//- The processor local size of all elements.
inline label size() const;
//- The global number of the specified element type.
// This value is only meaningful after a reduce operation.
inline label total(const enum elemType) const;
//- The global number of all element types.
// This value is only meaningful after a reduce operation.
label total() const;
//- The processor local sizes per element type.
FixedList<label, 5> sizes() const;
//- The global numbers per element type.
// This value is only meaningful after a reduce operation.
inline const FixedList<label, 5>& totals() const;
//- Return the (local) cell ids of the specified element type
inline const labelUList& cellIds(const enum elemType) const;
//- Return the cell ids of all elements
inline const labelUList& cellIds() const;
//- Starting offset of element type.
label offset(const enum elemType what) const;
// Edit
//- Classify cell types and set the element lists.
// The optional indirect addressing can be used when classifying
// groups of cells (eg, from a cellZone etc).
void classify
(
const polyMesh&,
const labelUList& addressing = labelUList::null()
);
//- Set addressable sizes to zero, free up addressing memory.
void clear();
//- Sum element counts across all processes.
void reduce();
//- Sort element lists numerically.
void sort();
// Member operators
//- Return id from linear list of addressing.
inline label operator[](const label i) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ensightCellsI.H"
#endif
// ************************************************************************* //

View File

@ -0,0 +1,95 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "error.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
inline const char* Foam::ensightCells::key(const enum elemType what)
{
return elemEnum[what];
}
inline Foam::label Foam::ensightCells::index() const
{
return index_;
}
inline Foam::label& Foam::ensightCells::index()
{
return index_;
}
inline Foam::label Foam::ensightCells::size() const
{
return address_.size();
}
inline const Foam::FixedList<Foam::label,5>& Foam::ensightCells::totals() const
{
return sizes_;
}
inline Foam::label Foam::ensightCells::total(const enum elemType what) const
{
return sizes_[what];
}
inline const Foam::labelUList& Foam::ensightCells::cellIds
(
const enum elemType what
) const
{
if (!lists_[what])
{
FatalErrorInFunction
<< "Accessing unallocated sublist for elem-type: "
<< elemEnum[what]
<< exit(FatalError);
}
return *(lists_[what]);
}
inline const Foam::labelUList& Foam::ensightCells::cellIds() const
{
return address_;
}
inline Foam::label Foam::ensightCells::operator[](const label i) const
{
return address_[i];
}
// ************************************************************************* //

View File

@ -0,0 +1,363 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "ensightFaces.H"
#include "error.H"
#include "polyMesh.H"
#include "ListOps.H"
#include "demandDrivenData.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::label Foam::ensightFaces::nTypes = 3;
namespace Foam
{
template<>
const char* Foam::NamedEnum
<
Foam::ensightFaces::elemType,
3
>::names[] = { "tria3", "quad4", "nsided" };
}
const Foam::NamedEnum<Foam::ensightFaces::elemType, 3>
Foam::ensightFaces::elemEnum;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// only used in this file-scope
inline Foam::ensightFaces::elemType
Foam::ensightFaces::whatType(const face& f)
{
return
(
f.size() == 3
? Foam::ensightFaces::elemType::TRIA3
: f.size() == 4
? Foam::ensightFaces::elemType::QUAD4
: Foam::ensightFaces::elemType::NSIDED
);
}
// only used in this file-scope
inline void Foam::ensightFaces::add
(
const face& f,
const label id,
const bool flip
)
{
const enum elemType what = whatType(f);
label n = sizes_[what]++;
lists_[what]->operator[](n) = id;
if (flipMap_.size())
{
flipMap_[offset(what, n)] = flip;
}
}
// only used in this file-scope
inline Foam::label Foam::ensightFaces::offset
(
const enum elemType what,
const label i
) const
{
label n = i;
for (label typeI = 0; typeI < label(what); ++typeI)
{
n += sizes_[typeI];
}
return n;
}
void Foam::ensightFaces::resize()
{
// overall required size
label n = 0;
forAll(sizes_, typeI)
{
n += sizes_[typeI];
}
address_.setSize(n, Zero);
// assign corresponding sub-lists
n = 0;
forAll(sizes_, typeI)
{
deleteDemandDrivenData(lists_[typeI]);
lists_[typeI] = new SubList<label>(address_, sizes_[typeI], n);
n += sizes_[typeI];
}
// normally assume no flipMap
flipMap_.clear();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightFaces::ensightFaces(label partIndex)
:
index_(partIndex),
address_(),
flipMap_(),
sizes_(Zero),
lists_()
{
// Ensure sub-lists are properly initialized to nullptr
forAll(lists_, typeI)
{
lists_[typeI] = nullptr;
}
resize(); // adjust allocation
}
Foam::ensightFaces::ensightFaces(const ensightFaces& obj)
:
index_(obj.index_),
address_(obj.address_),
flipMap_(obj.flipMap_),
sizes_(),
lists_()
{
// Ensure sub-lists are properly initialized to nullptr
forAll(lists_, typeI)
{
lists_[typeI] = nullptr;
}
// Total (reduced) sizes
FixedList<label, 3> totSizes = obj.sizes_;
// Local sizes
this->sizes_ = obj.sizes();
resize(); // adjust allocation
// Restore total (reduced) sizes
this->sizes_ = totSizes;
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightFaces::~ensightFaces()
{
forAll(lists_, typeI)
{
deleteDemandDrivenData(lists_[typeI]);
}
address_.clear();
flipMap_.clear();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::FixedList<Foam::label, 3> Foam::ensightFaces::sizes() const
{
FixedList<label, 3> count;
forAll(lists_, typeI)
{
count[typeI] = lists_[typeI]->size();
}
return count;
}
Foam::label Foam::ensightFaces::total() const
{
label n = 0;
forAll(sizes_, typeI)
{
n += sizes_[typeI];
}
return n;
}
void Foam::ensightFaces::clear()
{
sizes_ = Zero; // reset sizes
resize();
}
void Foam::ensightFaces::reduce()
{
forAll(sizes_, typeI)
{
sizes_[typeI] = lists_[typeI]->size();
Foam::reduce(sizes_[typeI], sumOp<label>());
}
}
void Foam::ensightFaces::sort()
{
if (flipMap_.size() == address_.size())
{
// sort flip too
labelList order;
label start = 0;
forAll(lists_, typeI)
{
if (lists_[typeI])
{
SubList<label>& idLst = *(lists_[typeI]);
const label sz = idLst.size();
if (sz)
{
SubList<bool> flip(flipMap_, sz, start);
start += sz; // for next sub-list
sortedOrder(idLst, order);
idLst = reorder<labelList>(order, idLst);
flip = reorder<boolList>(order, flip);
}
}
}
}
else
{
// no flip-maps, simpler to sort
forAll(lists_, typeI)
{
if (lists_[typeI])
{
SubList<label>& idLst = *(lists_[typeI]);
const label sz = idLst.size();
if (sz)
{
Foam::sort(idLst);
}
}
}
}
}
void Foam::ensightFaces::classify(const faceList& faces)
{
const label sz = faces.size();
// Count the shapes
// Can avoid double looping, but only at the expense of allocation
sizes_ = Zero; // reset sizes
for (label listI = 0; listI < sz; ++listI)
{
const enum elemType what = whatType(faces[listI]);
sizes_[what]++;
}
resize(); // adjust allocation
sizes_ = Zero; // reset sizes
// Assign face-id per shape type
for (label listI = 0; listI < sz; ++listI)
{
add(faces[listI], listI);
}
}
void Foam::ensightFaces::classify
(
const faceList& faces,
const labelUList& addressing,
const boolList& flipMap,
const PackedBoolList& exclude
)
{
// Note: Since PackedList::operator[] returns zero (false) for out-of-range
// indices, can skip our own bounds checking here.
const label sz = addressing.size();
const bool useFlip = (addressing.size() == flipMap.size());
// Count the shapes
// Can avoid double looping, but only at the expense of allocation
sizes_ = Zero; // reset sizes
for (label listI = 0; listI < sz; ++listI)
{
const label faceId = addressing[listI];
if (!exclude[faceId])
{
const enum elemType what = whatType(faces[faceId]);
sizes_[what]++;
}
}
resize(); // adjust allocation
sizes_ = Zero; // reset sizes
if (useFlip)
{
flipMap_.setSize(address_.size(), false);
flipMap_ = false;
}
// Assign face-id per shape type
for (label listI = 0; listI < sz; ++listI)
{
const label faceId = addressing[listI];
const bool flip = useFlip && flipMap[listI];
if (!exclude[faceId])
{
add(faces[faceId], faceId, flip);
}
}
}
Foam::label Foam::ensightFaces::offset(const enum elemType what) const
{
return offset(what, 0);
}
// ************************************************************************* //

View File

@ -0,0 +1,225 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::ensightFaces
Description
Sorting/classification of faces (2D) into corresponding ensight types
\*---------------------------------------------------------------------------*/
#ifndef ensightFaces_H
#define ensightFaces_H
#include "boolList.H"
#include "labelList.H"
#include "faceList.H"
#include "FixedList.H"
#include "PackedBoolList.H"
#include "NamedEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightFaces Declaration
\*---------------------------------------------------------------------------*/
class ensightFaces
{
public:
// Public data
//- Addressable ensight element types
enum elemType
{
TRIA3,
QUAD4,
NSIDED
};
//- Number of element types (3)
static const label nTypes;
//- The Ensight names for each element type
static const NamedEnum<elemType, 3> elemEnum;
// Static Member Functions
//- Return the ensight element name for the specified type
static inline const char* key(const enum elemType);
private:
// Private data
//- Location within a list.
// The ensight part number is typically this value +1.
label index_;
//- Linear list of ids, sub-sectioned per element type via SubLists
labelList address_;
//- Linear list of face-flips
boolList flipMap_;
//- List of global sizes for each element type
FixedList<label, 3> sizes_;
//- SubLists of ids for each element type.
// Managed via pointers, since a SubList cannot be relocated/resized.
FixedList<SubList<label>*, 3> lists_;
// Private Member Functions
//- Simple classifier
inline static elemType whatType(const face&);
//- Low-level addition routine
inline void add(const face&, const label id, const bool flip = false);
//- Low-level offset routine
inline label offset(const enum elemType what, const label i) const;
//- Use current sizes to redimension the element lists
void resize();
//- Disallow default bitwise assignment
void operator=(const ensightFaces&) = delete;
public:
// Constructors
//- Construct null, optionally with index
ensightFaces(label partIndex = 0);
//- Copy constructor. Needed for lists etc.
ensightFaces(const ensightFaces&);
//- Destructor
~ensightFaces();
// Member Functions
// Access
//- The index in a list.
inline label index() const;
//- The index in a list, non-const access.
inline label& index();
//- The processor local size of all elements.
inline label size() const;
//- The global number of the specified element type.
// This value is only meaningful after a reduce operation.
inline label total(const enum elemType) const;
//- The global number of all element types.
// This value is only meaningful after a reduce operation.
label total() const;
//- The processor local sizes per element type.
FixedList<label, 3> sizes() const;
//- The global numbers per element type.
// This value is only meaningful after a reduce operation.
const FixedList<label, 3>& totals() const;
//- Return the (local) face ids of the specified element type
inline const labelUList& faceIds(const enum elemType) const;
//- Return the face ids of all elements
inline const labelUList& faceIds() const;
//- Return the flip-map of all elements
inline const boolList& flipMap() const;
//- Starting offset of element type.
label offset(const enum elemType what) const;
// Edit
//- Classify the face types, set element list.
void classify(const faceList& faces);
//- Classify the face types, set element list.
// The indirect addressing can be used when classifying groups of
// face (eg, from a faceZone etc) with an optional flipMap.
// The optional exclude marker can be used to skip faces on particular
// boundary types or regions.
void classify
(
const faceList& faces,
const labelUList& addressing,
const boolList& flipMap = boolList(),
const PackedBoolList& exclude = PackedBoolList()
);
//- Set addressable sizes to zero, free up addressing memory.
void clear();
//- Sum element counts across all processes.
void reduce();
//- Sort element lists numerically.
void sort();
// Member operators
//- Return element from linear-list.
inline label operator[](const label i) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ensightFacesI.H"
#endif
// ************************************************************************* //

View File

@ -0,0 +1,101 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "error.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
inline const char* Foam::ensightFaces::key(const enum elemType what)
{
return elemEnum[what];
}
inline Foam::label Foam::ensightFaces::index() const
{
return index_;
}
inline Foam::label& Foam::ensightFaces::index()
{
return index_;
}
inline Foam::label Foam::ensightFaces::size() const
{
return address_.size();
}
inline const Foam::FixedList<Foam::label,3>& Foam::ensightFaces::totals() const
{
return sizes_;
}
inline Foam::label Foam::ensightFaces::total(const enum elemType what) const
{
return sizes_[what];
}
inline const Foam::labelUList& Foam::ensightFaces::faceIds
(
const enum elemType what
) const
{
if (!lists_[what])
{
FatalErrorInFunction
<< "Accessing unallocated sublist for elem-type: "
<< elemEnum[what]
<< exit(FatalError);
}
return *(lists_[what]);
}
inline const Foam::labelUList& Foam::ensightFaces::faceIds() const
{
return address_;
}
inline const Foam::boolList& Foam::ensightFaces::flipMap() const
{
return flipMap_;
}
inline Foam::label Foam::ensightFaces::operator[](const label i) const
{
return address_[i];
}
// ************************************************************************* //

View File

@ -28,56 +28,51 @@ License
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template<> template<>
const char* const Foam::ensightPTraits<Foam::scalar>::typeName = const char* const
Foam::pTraits<Foam::scalar>::typeName; Foam::ensightPTraits<Foam::scalar>::typeName = "scalar";
template<> template<>
const Foam::direction const Foam::direction
Foam::ensightPTraits<Foam::scalar>::componentOrder[] = {0}; Foam::ensightPTraits<Foam::scalar>::componentOrder[] = {0};
template<> template<>
const char* const Foam::ensightPTraits<Foam::vector>::typeName = const char* const
Foam::pTraits<Foam::vector>::typeName; Foam::ensightPTraits<Foam::vector>::typeName = "vector";
template<> template<>
const Foam::direction const Foam::direction
Foam::ensightPTraits<Foam::vector>::componentOrder[] = {0, 1, 2}; Foam::ensightPTraits<Foam::vector>::componentOrder[] = {0, 1, 2};
// use mag(sphericalTensor) instead
template<> template<>
const char* const Foam::ensightPTraits<Foam::sphericalTensor>::typeName = const char* const
Foam::pTraits<Foam::scalar>::typeName; Foam::ensightPTraits<Foam::sphericalTensor>::typeName = "scalar";
template<> template<>
const Foam::direction const Foam::direction
Foam::ensightPTraits<Foam::sphericalTensor>::componentOrder[] = {0}; Foam::ensightPTraits<Foam::sphericalTensor>::componentOrder[] = {0};
template<> template<>
const char* const Foam::ensightPTraits<Foam::symmTensor>::typeName = const char* const
"tensor symm"; Foam::ensightPTraits<Foam::symmTensor>::typeName = "tensor symm";
template<> template<>
const Foam::direction const Foam::direction
Foam::ensightPTraits<Foam::symmTensor>::componentOrder[] = {0, 3, 5, 1, 2, 4}; Foam::ensightPTraits<Foam::symmTensor>::componentOrder[] = {0, 3, 5, 1, 2, 4};
template<> template<>
const char* const Foam::ensightPTraits<Foam::tensor>::typeName = const char* const
"tensor asym"; Foam::ensightPTraits<Foam::tensor>::typeName = "tensor asym";
template<> template<>
const Foam::direction const Foam::direction
Foam::ensightPTraits<Foam::tensor>::componentOrder[] = Foam::ensightPTraits<Foam::tensor>::componentOrder[] =
{ { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
0,
1,
2,
3,
4,
5,
6,
7,
8
};
// ************************************************************************* // // ************************************************************************* //

View File

@ -1,6 +1,7 @@
abort/abort.C abort/abort.C
codedFunctionObject/codedFunctionObject.C codedFunctionObject/codedFunctionObject.C
ensightWrite/ensightWrite.C
removeRegisteredObject/removeRegisteredObject.C removeRegisteredObject/removeRegisteredObject.C

View File

@ -1,5 +1,7 @@
EXE_INC = \ EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/conversion/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \ -I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/ODE/lnInclude \ -I$(LIB_SRC)/ODE/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
@ -7,6 +9,8 @@ EXE_INC = \
LIB_LIBS = \ LIB_LIBS = \
-lfiniteVolume \ -lfiniteVolume \
-lconversion \
-lsampling \
-lfluidThermophysicalModels \ -lfluidThermophysicalModels \
-lcompressibleTransportModels \ -lcompressibleTransportModels \
-lODE -lODE

View File

@ -0,0 +1,329 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "ensightWrite.H"
#include "Time.H"
#include "polyMesh.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
defineTypeNameAndDebug(ensightWrite, 0);
addToRunTimeSelectionTable
(
functionObject,
ensightWrite,
dictionary
);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::functionObjects::ensightWrite::uniqWords(wordReList& lst)
{
boolList retain(lst.size());
wordHashSet uniq;
forAll(lst, i)
{
const wordRe& select = lst[i];
retain[i] =
(
select.isPattern()
|| uniq.insert(static_cast<const word&>(select))
);
}
inplaceSubset(retain, lst);
}
int Foam::functionObjects::ensightWrite::process(const word& fieldName)
{
int state = 0;
writeVolField<scalar>(fieldName, state);
writeVolField<vector>(fieldName, state);
writeVolField<sphericalTensor>(fieldName, state);
writeVolField<symmTensor>(fieldName, state);
writeVolField<tensor>(fieldName, state);
return state;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::ensightWrite::ensightWrite
(
const word& name,
const Time& runTime,
const dictionary& dict
)
:
fvMeshFunctionObject(name, runTime, dict),
writeOpts_
(
dict.found("format")
? IOstream::formatEnum(dict.lookup("format"))
: runTime.writeFormat()
),
caseOpts_(writeOpts_.format()),
selectFields_(),
dirName_("ensightWrite"),
consecutive_(false)
{
read(dict);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::functionObjects::ensightWrite::~ensightWrite()
{
if (ensCase_.valid())
{
// finalize case
ensCase().write();
ensCase_.clear();
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::ensightWrite::read(const dictionary& dict)
{
fvMeshFunctionObject::read(dict);
//
// writer options
//
writeOpts_.noPatches
(
dict.lookupOrDefault<Switch>("noPatches", false)
);
writeOpts_.deprecatedOrder
(
dict.lookupOrDefault<Switch>("deprecatedOrder", false)
);
if (dict.found("patches"))
{
wordReList lst(dict.lookup("patches"));
uniqWords(lst);
writeOpts_.patchSelection(lst);
}
if (dict.found("faceZones"))
{
wordReList lst(dict.lookup("faceZones"));
uniqWords(lst);
writeOpts_.faceZoneSelection(lst);
}
//
// case options
//
caseOpts_.width(dict.lookupOrDefault<label>("width", 8));
// remove existing output directory
caseOpts_.overwrite(dict.lookupOrDefault<Switch>("overwrite", false));
//
// other options
//
dict.readIfPresent("directory", dirName_);
consecutive_ = dict.lookupOrDefault<Switch>("consecutive", false);
//
// output fields
//
dict.lookup("fields") >> selectFields_;
uniqWords(selectFields_);
return true;
}
bool Foam::functionObjects::ensightWrite::execute()
{
return true;
}
bool Foam::functionObjects::ensightWrite::write()
{
const Time& t = obr_.time();
if (!ensCase_.valid())
{
// 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 = dirName_;
if (!ensightDir.isAbsolute())
{
ensightDir = t.rootPath()/t.globalCaseName()/ensightDir;
}
ensCase_.reset
(
new ensightCase
(
ensightDir,
t.globalCaseName(),
caseOpts_
)
);
}
if (!ensMesh_.valid())
{
ensMesh_.reset(new ensightMesh(mesh_, writeOpts_));
if (ensMesh_().needsUpdate())
{
ensMesh_().correct();
}
// assume static geometry - need to fix later
autoPtr<ensightGeoFile> os = ensCase_().newGeometry(false);
ensMesh_().write(os);
}
else if (ensMesh_().needsUpdate())
{
// appears to have moved
ensMesh_().correct();
autoPtr<ensightGeoFile> os = ensCase_().newGeometry(true);
ensMesh_().write(os);
}
Log << type() << " " << name() << " write: (";
if (consecutive_)
{
ensCase().nextTime(t.value());
}
else
{
ensCase().setTime(t.value(), t.timeIndex());
}
wordHashSet candidates = subsetStrings(selectFields_, mesh_.names());
DynamicList<word> missing(selectFields_.size());
DynamicList<word> ignored(selectFields_.size());
// check exact matches first
forAll(selectFields_, i)
{
const wordRe& select = selectFields_[i];
if (!select.isPattern())
{
const word& fieldName = static_cast<const word&>(select);
if (!candidates.erase(fieldName))
{
missing.append(fieldName);
}
else if (process(fieldName) < 1)
{
ignored.append(fieldName);
}
}
}
forAllConstIter(wordHashSet, candidates, iter)
{
process(iter.key());
}
Log << " )" << endl;
if (missing.size())
{
WarningInFunction
<< "Missing field " << missing << endl;
}
if (ignored.size())
{
WarningInFunction
<< "Unprocessed field " << ignored << endl;
}
return true;
}
bool Foam::functionObjects::ensightWrite::end()
{
if (ensCase_.valid())
{
// finalize case
ensCase().write();
ensCase_.clear();
}
return true;
}
void Foam::functionObjects::ensightWrite::updateMesh(const mapPolyMesh& mpm)
{
// fvMeshFunctionObject::updateMesh(mpm);
if (ensMesh_.valid())
{
ensMesh_().expire();
}
}
void Foam::functionObjects::ensightWrite::movePoints(const polyMesh& mpm)
{
// fvMeshFunctionObject::updateMesh(mpm);
if (ensMesh_.valid())
{
ensMesh_().expire();
}
}
// ************************************************************************* //

View File

@ -0,0 +1,227 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::functionObjects::ensightWrite
Group
grpUtilitiesFunctionObjects
Description
Writes fields in ensight format.
Example of function object specification:
\verbatim
ensight
{
type ensightWrite;
libs ("libutilityFunctionObjects.so");
writeControl writeTime;
writeInterval 1;
format binary;
overwrite true;
width 12;
directory "EnSight";
fields
(
U
p
);
}
\endverbatim
\heading Function object usage
\table
Property | Description | Required | Default value
type | Type name: ensightWrite | yes |
fields | Fields to output | yes |
writeControl | Output control | recommended | timeStep
directory | The output directory name | no | "ensightWrite"
overwrite | Remove existing directory | no | false
format | ASCII or binary format | no | same as simulation
width | Mask width for \c data/XXXX | no | 8
noPatches | Suppress writing patches | no | false
patches | Select patches to write | no |
faceZones | Select faceZones to write | no |
deprecatedOrder | Old ordering of volume cells | no | false
consecutive | Consecutive output numbering | no | false
\endtable
Note that if the \c patches entry is an empty list, this will select all
patches and suppress writing the internalMesh.
Consecutive output numbering can be used in conjunction with \c overwrite.
SourceFiles
ensightWrite.C
ensightWriteTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef functionObjects_ensightWrite_H
#define functionObjects_ensightWrite_H
#include "fvMeshFunctionObject.H"
#include "ensightCase.H"
#include "ensightMesh.H"
#include "wordReList.H"
#include "interpolation.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class dictionary;
namespace functionObjects
{
/*---------------------------------------------------------------------------*\
Class ensightWrite Declaration
\*---------------------------------------------------------------------------*/
class ensightWrite
:
public fvMeshFunctionObject
{
// Private data
//- Writer options
ensightMesh::options writeOpts_;
ensightCase::options caseOpts_;
//- Name of fields to process
wordReList selectFields_;
//- Output directory name
fileName dirName_;
//- Consecutive output numbering
bool consecutive_;
//- Ensight case handler
autoPtr<ensightCase> ensCase_;
//- Ensight mesh handler
autoPtr<ensightMesh> ensMesh_;
// Private Member Functions
//- Eliminate duplicate 'word' entries
static void uniqWords(wordReList&);
//- Ensight case handler
ensightCase& ensCase()
{
return ensCase_();
}
//- Ensight mesh handler
ensightMesh& ensMesh()
{
return ensMesh_();
}
//- Apply for the volume field type
template<class Type>
int writeVolField(const word& inputName, int& state);
//- Process by trying to apply for various volume field types.
int process(const word& inputName);
//- Disallow default bitwise copy construct
ensightWrite(const ensightWrite&) = delete;
//- Disallow default bitwise assignment
void operator=(const ensightWrite&) = delete;
public:
//- Runtime type information
TypeName("ensightWrite");
// Constructors
//- Construct from runTime and dictionary.
ensightWrite
(
const word& name,
const Time& runTime,
const dictionary& dict
);
//- Destructor
virtual ~ensightWrite();
// Member Functions
//- Read the ensightWrite specification
virtual bool read(const dictionary&);
//- Do nothing
virtual bool execute();
//- Write fields
virtual bool write();
//- Execute at the final time-loop, flush case file
virtual bool end();
//- Update for changes of mesh
virtual void updateMesh(const mapPolyMesh&);
//- Update for mesh point-motion
virtual void movePoints(const polyMesh&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace functionObjects
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightWriteTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -21,54 +21,41 @@ License
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
Template to write generalized field components
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "ensightParts.H" #include "Time.H"
#include "ensightOutput.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type> template<class Type>
void Foam::ensightParts::writeField int Foam::functionObjects::ensightWrite::writeVolField
( (
ensightFile& os, const word& inputName,
const GeometricField<Type, fvPatchField, volMesh>& field int& state
) const )
{ {
// find offset to patch parts (ie, the first face data) // State: return 0 (not-processed), -1 (skip), +1 ok
label patchOffset = 0; typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
forAll(partsList_, partI)
// Already done, or not available
if (state || !foundObject<VolFieldType>(inputName))
{ {
if (partsList_[partI].isFaceData()) return state;
{
patchOffset = partI;
break;
}
} }
forAll(partsList_, partI) autoPtr<ensightFile> os = ensCase().newData<Type>(inputName);
{ ensightOutput::writeField<Type>
label patchi = partI - patchOffset; (
lookupObject<VolFieldType>(inputName),
ensMesh(),
os
);
if (partsList_[partI].isCellData()) Log << " " << inputName;
{
partsList_[partI].writeField state = +1;
( return state;
os,
field
);
}
else if (patchi < field.boundaryField().size())
{
partsList_[partI].writeField
(
os,
field.boundaryField()[patchi]
);
}
}
} }

View File

@ -28,6 +28,7 @@ License
#include "OFstream.H" #include "OFstream.H"
#include "OSspecific.H" #include "OSspecific.H"
#include "ensightPartFaces.H" #include "ensightPartFaces.H"
#include "ensightSerialOutput.H"
#include "ensightPTraits.H" #include "ensightPTraits.H"
#include "OStringStream.H" #include "OStringStream.H"
#include "regExp.H" #include "regExp.H"
@ -121,7 +122,13 @@ Foam::fileName Foam::ensightSurfaceWriter::writeUncollated
// Write field // Write field
osField.writeKeyword(ensightPTraits<Type>::typeName); osField.writeKeyword(ensightPTraits<Type>::typeName);
ensPart.writeField(osField, values, isNodeValues); ensightSerialOutput::writeField
(
values,
ensPart,
osField,
isNodeValues
);
return osCase.name(); return osCase.name();
} }
@ -337,12 +344,21 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
varName, varName,
writeFormat_ writeFormat_
); );
if (verbose) if (verbose)
{ {
Info<< "Writing field file to " << osField.name() << endl; Info<< "Writing field file to " << osField.name() << endl;
} }
// Write field
osField.writeKeyword(ensightPTraits<Type>::typeName); osField.writeKeyword(ensightPTraits<Type>::typeName);
ensPart.writeField(osField, values, isNodeValues); ensightSerialOutput::writeField
(
values,
ensPart,
osField,
isNodeValues
);
// place a timestamp in the directory for future reference // place a timestamp in the directory for future reference
{ {

View File

@ -50,6 +50,7 @@ functions
#include "wallBoundedStreamLines" #include "wallBoundedStreamLines"
#include "cuttingPlane" #include "cuttingPlane"
#include "forceCoeffs" #include "forceCoeffs"
#include "ensightWrite"
} }

View File

@ -0,0 +1,17 @@
// -*- C++ -*-
// Minimal example of using the ensight write function object.
// Many more options possible
ensightWrite
{
type ensightWrite;
libs ("libutilityFunctionObjects.so");
log true;
// Fields to output (words or regex)
fields (U p "(k|epsilon|omega)");
writeControl writeTime;
writeIterval 1;
}
// ************************************************************************* //