ENH: complete reworking of foamToEnsight to make into a library (issue #241)

- eliminate ensightAsciiStream, ensightBinaryStream, ensightStream in
  favour of using ensightFile and ensightGeoFile classes throughout.

- encapsulate mesh-parts sorting with the ensightCells, ensightFaces
  class.

- handle of patches/faceZones entirely within ensightMesh for a lighter
  interaction with field output. Both faceZones and point fields need
  more testing to see if they behave properly for all cases.

- move some output functionality into its own namespace
  'ensightOutput', move into a library.

- use the ensightCase class to open new ensight output streams
  in the proper sub-directory locations.
This commit is contained in:
Mark Olesen
2016-10-06 10:43:22 +02:00
parent e1240ece7b
commit e57ca15bda
24 changed files with 2771 additions and 3368 deletions

View File

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

View File

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

View File

@ -1,112 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::cellSets
Description
\*---------------------------------------------------------------------------*/
#ifndef cellSets_H
#define cellSets_H
#include "labelList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cellSets Declaration
\*---------------------------------------------------------------------------*/
class cellSets
{
public:
label nTets;
label nPyrs;
label nPrisms;
label nHexesWedges;
label nPolys;
labelList tets;
labelList pyrs;
labelList prisms;
labelList wedges;
labelList hexes;
labelList polys;
// Constructors
//- Construct given the number ov cells
cellSets(const label nCells)
:
nTets(0),
nPyrs(0),
nPrisms(0),
nHexesWedges(0),
nPolys(0),
tets(nCells),
pyrs(nCells),
prisms(nCells),
wedges(nCells),
hexes(nCells),
polys(nCells)
{}
// Member Functions
void setSize(const label nCells)
{
nTets = 0;
nPyrs = 0;
nPrisms = 0;
nHexesWedges = 0;
nPolys = 0;
tets.setSize(nCells);
pyrs.setSize(nCells);
prisms.setSize(nCells);
wedges.setSize(nCells);
hexes.setSize(nCells);
polys.setSize(nCells);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

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

View File

@ -1,153 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::ensightAsciiStream
Description
SourceFiles
ensightAsciiStream.C
\*---------------------------------------------------------------------------*/
#ifndef ensightAsciiStream_H
#define ensightAsciiStream_H
#include "ensightStream.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightAsciiStream Declaration
\*---------------------------------------------------------------------------*/
class ensightAsciiStream
:
public ensightStream
{
// Private data
//- Output file stream
OFstream str_;
// Private Member Functions
//- Disallow default bitwise copy construct
ensightAsciiStream(const ensightAsciiStream&) = delete;
//- Disallow default bitwise assignment
void operator=(const ensightAsciiStream&) = delete;
public:
// Constructors
//- Construct from components
ensightAsciiStream(const fileName& f)
:
ensightStream(f),
str_
(
f,
IOstream::ASCII,
IOstream::currentVersion,
IOstream::UNCOMPRESSED
)
{
str_.setf(ios_base::scientific, ios_base::floatfield);
str_.precision(5);
}
//- Destructor
virtual ~ensightAsciiStream()
{}
// Member Functions
virtual bool ascii() const
{
return true;
}
virtual void write(const char* c)
{
str_ << c << nl;
}
virtual void write(const int v)
{
str_ << setw(10) << v << nl;
}
virtual void write(const scalarField& sf)
{
forAll(sf, i)
{
if (mag(sf[i]) >= scalar(floatScalarVSMALL))
{
str_ << setw(12) << sf[i] << nl;
}
else
{
str_ << setw(12) << scalar(0) << nl;
}
}
}
virtual void write(const List<int>& sf)
{
forAll(sf, i)
{
str_ << setw(10) << sf[i];
}
str_<< nl;
}
virtual void writePartHeader(const label partI)
{
str_<< "part" << nl
<< setw(10) << partI << nl;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,150 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::ensightBinaryStream
Description
SourceFiles
ensightBinaryStream.C
\*---------------------------------------------------------------------------*/
#ifndef ensightBinaryStream_H
#define ensightBinaryStream_H
#include "ensightStream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightBinaryStream Declaration
\*---------------------------------------------------------------------------*/
class ensightBinaryStream
:
public ensightStream
{
// Private data
//- Output file stream
autoPtr<std::ofstream> str_;
// Private Member Functions
//- Disallow default bitwise copy construct
ensightBinaryStream(const ensightBinaryStream&) = delete;
//- Disallow default bitwise assignment
void operator=(const ensightBinaryStream&) = delete;
public:
// Constructors
//- Construct from components
ensightBinaryStream(const fileName& f)
:
ensightStream(f),
str_
(
new std::ofstream
(
f.c_str(),
ios_base::out | ios_base::binary | ios_base::trunc
)
)
{}
//- Destructor
virtual ~ensightBinaryStream()
{}
// Member Functions
virtual void write(const char* val)
{
char buffer[80];
strncpy(buffer, val, 80);
str_().write(buffer, 80*sizeof(char));
}
virtual void write(const int val)
{
str_().write(reinterpret_cast<const char*>(&val), sizeof(int));
}
virtual void write(const scalarField& sf)
{
if (sf.size())
{
List<float> temp(sf.size());
forAll(sf, i)
{
temp[i] = float(sf[i]);
}
str_().write
(
reinterpret_cast<const char*>(temp.begin()),
sf.size()*sizeof(float)
);
}
}
virtual void write(const List<int>& sf)
{
str_().write
(
reinterpret_cast<const char*>(sf.begin()),
sf.size()*sizeof(int)
);
}
virtual void writePartHeader(const label partI)
{
write("part");
write(partI);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

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

View File

@ -1,816 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "ensightFile.H"
#include "ensightField.H"
#include "fvMesh.H"
#include "volFields.H"
#include "OFstream.H"
#include "IOmanip.H"
#include "volPointInterpolation.H"
#include "ensightBinaryStream.H"
#include "ensightAsciiStream.H"
#include "globalIndex.H"
#include "ensightPTraits.H"
#include "zeroGradientFvPatchField.H"
using namespace Foam;
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>>
volField
(
const fvMeshSubset& meshSubsetter,
const GeometricField<Type, fvPatchField, volMesh>& vf
)
{
if (meshSubsetter.hasSubMesh())
{
tmp<GeometricField<Type, fvPatchField, volMesh>> tfld
(
meshSubsetter.interpolate(vf)
);
tfld.ref().checkOut();
tfld.ref().rename(vf.name());
return tfld;
}
else
{
return vf;
}
}
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>>
volField
(
const fvMeshSubset& meshSubsetter,
const typename GeometricField<Type, fvPatchField, volMesh>::Internal& df
)
{
// Construct volField (with zeroGradient) from dimensioned field
IOobject io(df);
io.readOpt() = IOobject::NO_READ;
io.writeOpt() = IOobject::NO_WRITE;
io.registerObject() = false;
tmp<GeometricField<Type, fvPatchField, volMesh>> tvf
(
new GeometricField<Type, fvPatchField, volMesh>
(
io,
df.mesh(),
dimensioned<Type>("0", df.dimensions(), Zero),
zeroGradientFvPatchField<Type>::typeName
)
);
tvf.ref().primitiveFieldRef() = df;
tvf.ref().correctBoundaryConditions();
if (meshSubsetter.hasSubMesh())
{
const GeometricField<Type, fvPatchField, volMesh>& vf = tvf();
tmp<GeometricField<Type, fvPatchField, volMesh>> tfld
(
meshSubsetter.interpolate(vf)
);
tfld.ref().checkOut();
tfld.ref().rename(vf.name());
return tfld;
}
else
{
return tvf;
}
}
//template<class Container>
//void readAndConvertField
//(
// const fvMeshSubset& meshSubsetter,
// const IOobject& io,
// const fvMesh& mesh,
// const ensightMesh& eMesh,
// const fileName& dataDir,
// const label timeIndex,
// const bool nodeValues,
// Ostream& ensightCaseFile
//)
//{
// Container fld(io, mesh);
// ensightField<typename Container::value_type>
// (
// volField<typename Container::value_type>(meshSubsetter, fld),
// eMesh,
// dataDir,
// timeIndex,
// nodeValues,
// ensightCaseFile
// );
//}
template<class Type>
Field<Type> map
(
const Field<Type>& vf,
const labelList& map1,
const labelList& map2
)
{
Field<Type> mf(map1.size() + map2.size());
forAll(map1, i)
{
mf[i] = vf[map1[i]];
}
label offset = map1.size();
forAll(map2, i)
{
mf[i + offset] = vf[map2[i]];
}
return mf;
}
template<class Type>
void writeField
(
const char* key,
const Field<Type>& vf,
ensightStream& os
)
{
if (returnReduce(vf.size(), sumOp<label>()) > 0)
{
if (Pstream::master())
{
os.write(key);
for (direction i=0; i < pTraits<Type>::nComponents; ++i)
{
label cmpt = ensightPTraits<Type>::componentOrder[i];
os.write(vf.component(cmpt));
for (int slave=1; slave<Pstream::nProcs(); slave++)
{
IPstream fromSlave(Pstream::scheduled, slave);
scalarField slaveData(fromSlave);
os.write(slaveData);
}
}
}
else
{
for (direction i=0; i < pTraits<Type>::nComponents; ++i)
{
label cmpt = ensightPTraits<Type>::componentOrder[i];
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster<< vf.component(cmpt);
}
}
}
}
template<class Type>
bool writePatchField
(
const Field<Type>& pf,
const label patchi,
const label ensightPatchi,
const faceSets& boundaryFaceSet,
const ensightMesh::nFacePrimitives& nfp,
ensightStream& os
)
{
if (nfp.nTris || nfp.nQuads || nfp.nPolys)
{
if (Pstream::master())
{
os.writePartHeader(ensightPatchi);
}
writeField
(
"tria3",
Field<Type>(pf, boundaryFaceSet.tris),
os
);
writeField
(
"quad4",
Field<Type>(pf, boundaryFaceSet.quads),
os
);
writeField
(
"nsided",
Field<Type>(pf, boundaryFaceSet.polys),
os
);
return true;
}
else
{
return false;
}
}
template<class Type>
void writePatchField
(
const word& fieldName,
const Field<Type>& pf,
const word& patchName,
const ensightMesh& eMesh,
const fileName& dataDir,
const label timeIndex,
Ostream& ensightCaseFile
)
{
const List<faceSets>& boundaryFaceSets = eMesh.boundaryFaceSets();
const wordList& allPatchNames = eMesh.allPatchNames();
const HashTable<ensightMesh::nFacePrimitives>&
nPatchPrims = eMesh.nPatchPrims();
label ensightPatchi = eMesh.patchPartOffset();
label patchi = -1;
forAll(allPatchNames, i)
{
if (allPatchNames[i] == patchName)
{
patchi = i;
break;
}
ensightPatchi++;
}
ensightStream* filePtr(nullptr);
if (Pstream::master())
{
// TODO: verify that these are indeed valid ensight variable names
const word varName = patchName + '.' + fieldName;
const fileName postFileName = ensightFile::subDir(timeIndex)/varName;
// the data/ITER subdirectory must exist
mkDir(dataDir/postFileName.path());
if (timeIndex == 0)
{
const fileName dirName = dataDir.name()/ensightFile::mask();
ensightCaseFile.setf(ios_base::left);
ensightCaseFile
<< ensightPTraits<Type>::typeName << " per "
<< setw(20)
<< "element:"
<< " 1 "
<< setw(15)
<< varName.c_str() << ' '
<< (dirName/varName).c_str()
<< nl;
}
if (eMesh.format() == IOstream::BINARY)
{
filePtr = new ensightBinaryStream
(
dataDir/postFileName
);
}
else
{
filePtr = new ensightAsciiStream
(
dataDir/postFileName
);
}
filePtr->write(ensightPTraits<Type>::typeName);
}
ensightStream& os = *filePtr;
if (patchi >= 0)
{
writePatchField
(
pf,
patchi,
ensightPatchi,
boundaryFaceSets[patchi],
nPatchPrims.find(patchName)(),
os
);
}
else
{
faceSets nullFaceSets;
writePatchField
(
Field<Type>(),
-1,
ensightPatchi,
nullFaceSets,
nPatchPrims.find(patchName)(),
os
);
}
if (filePtr) // on master only
{
delete filePtr;
}
}
template<class Type>
void ensightField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightMesh& eMesh,
const fileName& dataDir,
const label timeIndex,
Ostream& ensightCaseFile
)
{
Info<< ' ' << vf.name();
const fvMesh& mesh = eMesh.mesh();
const cellSets& meshCellSets = eMesh.meshCellSets();
const List<faceSets>& boundaryFaceSets = eMesh.boundaryFaceSets();
const wordList& allPatchNames = eMesh.allPatchNames();
const wordHashSet& patchNames = eMesh.patchNames();
const HashTable<ensightMesh::nFacePrimitives>&
nPatchPrims = eMesh.nPatchPrims();
const List<faceSets>& faceZoneFaceSets = eMesh.faceZoneFaceSets();
const wordHashSet& faceZoneNames = eMesh.faceZoneNames();
const HashTable<ensightMesh::nFacePrimitives>&
nFaceZonePrims = eMesh.nFaceZonePrims();
const labelList& tets = meshCellSets.tets;
const labelList& pyrs = meshCellSets.pyrs;
const labelList& prisms = meshCellSets.prisms;
const labelList& wedges = meshCellSets.wedges;
const labelList& hexes = meshCellSets.hexes;
const labelList& polys = meshCellSets.polys;
ensightStream* filePtr(nullptr);
if (Pstream::master())
{
const ensight::VarName varName(vf.name());
const fileName postFileName = ensightFile::subDir(timeIndex)/varName;
// the data/ITER subdirectory must exist
mkDir(dataDir/postFileName.path());
if (timeIndex == 0)
{
const fileName dirName = dataDir.name()/ensightFile::mask();
ensightCaseFile.setf(ios_base::left);
ensightCaseFile
<< ensightPTraits<Type>::typeName
<< " per element: 1 "
<< setw(15)
<< varName.c_str() << ' '
<< (dirName/varName).c_str()
<< nl;
}
if (eMesh.format() == IOstream::BINARY)
{
filePtr = new ensightBinaryStream
(
dataDir/postFileName
);
}
else
{
filePtr = new ensightAsciiStream
(
dataDir/postFileName
);
}
filePtr->write(ensightPTraits<Type>::typeName);
}
ensightStream& os = *filePtr;
if (patchNames.empty())
{
eMesh.barrier();
if (Pstream::master())
{
os.writePartHeader(1);
}
writeField
(
"hexa8",
map(vf, hexes, wedges),
os
);
writeField
(
"penta6",
Field<Type>(vf, prisms),
os
);
writeField
(
"pyramid5",
Field<Type>(vf, pyrs),
os
);
writeField
(
"tetra4",
Field<Type>(vf, tets),
os
);
writeField
(
"nfaced",
Field<Type>(vf, polys),
os
);
}
label ensightPatchi = eMesh.patchPartOffset();
forAll(allPatchNames, patchi)
{
const word& patchName = allPatchNames[patchi];
eMesh.barrier();
if (patchNames.empty() || patchNames.found(patchName))
{
if
(
writePatchField
(
vf.boundaryField()[patchi],
patchi,
ensightPatchi,
boundaryFaceSets[patchi],
nPatchPrims.find(patchName)(),
os
)
)
{
ensightPatchi++;
}
}
}
// write faceZones, if requested
if (faceZoneNames.size())
{
// Interpolates cell values to faces - needed only when exporting
// faceZones...
GeometricField<Type, fvsPatchField, surfaceMesh> sf
(
linearInterpolate(vf)
);
forAllConstIter(wordHashSet, faceZoneNames, iter)
{
const word& faceZoneName = iter.key();
eMesh.barrier();
const label zoneID = mesh.faceZones().findZoneID(faceZoneName);
const faceZone& fz = mesh.faceZones()[zoneID];
// Prepare data to write
label nIncluded = 0;
forAll(fz, i)
{
if (eMesh.faceToBeIncluded(fz[i]))
{
++nIncluded;
}
}
Field<Type> values(nIncluded);
// Loop on the faceZone and store the needed field values
label j = 0;
forAll(fz, i)
{
label facei = fz[i];
if (mesh.isInternalFace(facei))
{
values[j] = sf[facei];
++j;
}
else
{
if (eMesh.faceToBeIncluded(facei))
{
label patchi = mesh.boundaryMesh().whichPatch(facei);
const polyPatch& pp = mesh.boundaryMesh()[patchi];
label patchFacei = pp.whichFace(facei);
Type value = sf.boundaryField()[patchi][patchFacei];
values[j] = value;
++j;
}
}
}
if
(
writePatchField
(
values,
zoneID,
ensightPatchi,
faceZoneFaceSets[zoneID],
nFaceZonePrims.find(faceZoneName)(),
os
)
)
{
ensightPatchi++;
}
}
}
if (filePtr) // on master only
{
delete filePtr;
}
}
template<class Type>
void ensightPointField
(
const GeometricField<Type, pointPatchField, pointMesh>& pf,
const ensightMesh& eMesh,
const fileName& dataDir,
const label timeIndex,
Ostream& ensightCaseFile
)
{
Info<< ' ' << pf.name();
const fvMesh& mesh = eMesh.mesh();
const wordList& allPatchNames = eMesh.allPatchNames();
const wordHashSet& patchNames = eMesh.patchNames();
const wordHashSet& faceZoneNames = eMesh.faceZoneNames();
ensightStream* filePtr(nullptr);
if (Pstream::master())
{
const ensight::VarName varName(pf.name());
const fileName postFileName = ensightFile::subDir(timeIndex)/varName;
// the data/ITER subdirectory must exist
mkDir(dataDir/postFileName.path());
if (timeIndex == 0)
{
const fileName dirName = dataDir.name()/ensightFile::mask();
ensightCaseFile.setf(ios_base::left);
ensightCaseFile
<< ensightPTraits<Type>::typeName
<< " per "
<< setw(20)
<< " node:"
<< " 1 "
<< setw(15)
<< varName.c_str() << ' '
<< (dirName/varName).c_str()
<< nl;
}
if (eMesh.format() == IOstream::BINARY)
{
filePtr = new ensightBinaryStream
(
dataDir/postFileName
);
}
else
{
filePtr = new ensightAsciiStream
(
dataDir/postFileName
);
}
filePtr->write(ensightPTraits<Type>::typeName);
}
ensightStream& os = *filePtr;
if (eMesh.patchNames().empty())
{
eMesh.barrier();
if (Pstream::master())
{
os.writePartHeader(1);
}
writeField
(
"coordinates",
Field<Type>(pf.primitiveField(), eMesh.uniquePointMap()),
os
);
}
label ensightPatchi = eMesh.patchPartOffset();
forAll(allPatchNames, patchi)
{
const word& patchName = allPatchNames[patchi];
eMesh.barrier();
if (patchNames.empty() || patchNames.found(patchName))
{
const fvPatch& p = mesh.boundary()[patchi];
if (returnReduce(p.size(), sumOp<label>()) > 0)
{
// Renumber the patch points/faces into unique points
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPointsPtr =
mesh.globalData().mergePoints
(
p.patch().meshPoints(),
p.patch().meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels
);
if (Pstream::master())
{
os.writePartHeader(ensightPatchi);
}
writeField
(
"coordinates",
Field<Type>(pf.primitiveField(), uniqueMeshPointLabels),
os
);
ensightPatchi++;
}
}
}
// write faceZones, if requested
if (faceZoneNames.size())
{
forAllConstIter(wordHashSet, faceZoneNames, iter)
{
const word& faceZoneName = iter.key();
eMesh.barrier();
const label zoneID = mesh.faceZones().findZoneID(faceZoneName);
const faceZone& fz = mesh.faceZones()[zoneID];
if (returnReduce(fz().nPoints(), sumOp<label>()) > 0)
{
// Renumber the faceZone points/faces into unique points
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPointsPtr =
mesh.globalData().mergePoints
(
fz().meshPoints(),
fz().meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels
);
if (Pstream::master())
{
os.writePartHeader(ensightPatchi);
}
writeField
(
"coordinates",
Field<Type>
(
pf.primitiveField(),
uniqueMeshPointLabels
),
os
);
ensightPatchi++;
}
}
}
if (filePtr) // on master only
{
delete filePtr;
}
}
template<class Type>
void ensightField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightMesh& eMesh,
const fileName& dataDir,
const label timeIndex,
const bool nodeValues,
Ostream& ensightCaseFile
)
{
if (nodeValues)
{
tmp<GeometricField<Type, pointPatchField, pointMesh>> pfld
(
volPointInterpolation::New(vf.mesh()).interpolate(vf)
);
pfld.ref().rename(vf.name());
ensightPointField<Type>
(
pfld,
eMesh,
dataDir,
timeIndex,
ensightCaseFile
);
}
else
{
ensightField<Type>
(
vf,
eMesh,
dataDir,
timeIndex,
ensightCaseFile
);
}
}
// ************************************************************************* //

View File

@ -1,102 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
InApplication
foamToEnsight
Description
SourceFiles
ensightField.C
\*---------------------------------------------------------------------------*/
#ifndef ensightField_H
#define ensightField_H
#include "ensightMesh.H"
#include "fvMeshSubset.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Wrapper to get hold of the field or the subsetted field
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
volField
(
const Foam::fvMeshSubset&,
const Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>& vf
);
//- Wrapper to convert dimensionedInternalField to volField
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
volField
(
const Foam::fvMeshSubset&,
const typename Foam::GeometricField
<
Type,
Foam::fvPatchField,
Foam::volMesh
>::Internal& df
);
template<class Type>
void ensightField
(
const Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>& vf,
const Foam::ensightMesh& eMesh,
const Foam::fileName& dataDir,
const Foam::label timeIndex,
const bool nodeValues,
Foam::Ostream& ensightCaseFile
);
template<class Type>
void writePatchField
(
const Foam::word& fieldName,
const Foam::Field<Type>& pf,
const Foam::word& patchName,
const Foam::ensightMesh& eMesh,
const Foam::fileName& dataDir,
const Foam::label timeIndex,
Foam::Ostream& ensightCaseFile
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -25,36 +25,39 @@ 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 "cellSets.H"
#include "faceSets.H"
#include "HashTable.H"
#include "HashSet.H"
#include "PackedBoolList.H"
#include "wordReList.H"
#include "scalarField.H"
#include "cellShapeList.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"
#include <fstream>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
class fvMesh;
class argList;
class globalIndex;
class ensightStream;
class ensightMesh;
/*---------------------------------------------------------------------------*\
Class ensightMesh Declaration
@ -63,70 +66,34 @@ class ensightStream;
class ensightMesh
{
public:
// Forward declarations
class options;
//- 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
//- Writer options
const options* options_;
//- Reference to the OpenFOAM mesh
const fvMesh& mesh_;
//- Suppress patches
const bool noPatches_;
//- The volume cells (internalMesh)
ensightCells meshCells_;
//- Output selected patches only
const bool patches_;
const wordReList patchPatterns_;
//- Face elements per patch
HashTable<ensightFaces> boundaryPatchFaces_;
//- Output selected faceZones
const bool faceZones_;
const wordReList faceZonePatterns_;
//- Face elements per faceZone
HashTable<ensightFaces> faceZoneFaces_;
//- Ascii/Binary file output
const IOstream::streamFormat format_;
//- The list of patches to be output
Map<word> patchLookup_;
//- 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_;
//- Track if it needs an update
mutable bool needsUpdate_;
// Parallel merged points
@ -141,47 +108,66 @@ private:
labelList uniquePointMap_;
// Private Member Functions
//- Disallow default bitwise copy construct
ensightMesh(const ensightMesh&) = delete;
//- Clear some storage
void clear();
//- Disallow default bitwise assignment
void operator=(const ensightMesh&) = delete;
void writePoints
//- Inplace renumber of cell-shapes
static cellShapeList& renumberShapes
(
const scalarField& pointsComponent,
ensightStream& ensightGeometryFile
) const;
cellShapeList&,
const labelUList& pointToGlobal
);
cellShapeList map
static cellShapeList map
(
const cellShapeList& cellShapes,
const labelList& prims,
const labelList& pointToGlobal
) const;
const cellShapeList&,
const labelUList& prims,
const labelUList& pointToGlobal
);
cellShapeList map
//- Write list of faces
static void writeFaceList
(
const cellShapeList& cellShapes,
const labelList& hexes,
const labelList& wedges,
const labelList& pointToGlobal
) const;
const faceList&,
ensightGeoFile&
);
void writePrims
//- Write list of faces
static void writeFaceList
(
const cellShapeList& cellShapes,
ensightStream& ensightGeometryFile
) const;
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,
ensightStream& ensightGeometryFile
ensightGeoFile&
) const;
void writePolysNPointsPerFace
@ -189,7 +175,7 @@ private:
const labelList& polys,
const cellList& cellFaces,
const faceList& faces,
ensightStream& ensightGeometryFile
ensightGeoFile&
) const;
void writePolysPoints
@ -198,80 +184,91 @@ private:
const cellList& cellFaces,
const faceList& faces,
const labelList& faceOwner,
ensightStream& ensightGeometryFile
ensightGeoFile&
) const;
void writeAllPolys
void writePolysConnectivity
(
const labelList& addr,
const labelList& pointToGlobal,
ensightStream& ensightGeometryFile
ensightGeoFile&
) const;
void writeAllPrims
void writeCellConnectivity
(
const char* key,
const label nPrims,
const cellShapeList& cellShapes,
ensightStream& ensightGeometryFile
const ensightCells&,
const labelList& pointToGlobal,
ensightGeoFile&
) const;
void writeFacePrims
void writeCellConnectivity
(
const faceList& patchFaces,
ensightStream& ensightGeometryFile
ensightCells::elemType elemType,
const ensightCells&,
const labelList& pointToGlobal,
ensightGeoFile&
) const;
void writeAllFacePrims
void writeFaceConnectivity
(
const char* key,
const labelList& prims,
const label nPrims,
const faceList& patchFaces,
ensightStream& ensightGeometryFile
ensightFaces::elemType elemType,
const label nTotal,
const faceList& faceLst,
const labelList& addr,
ensightGeoFile&
) const;
void writeNSidedNPointsPerFace
void writeFaceConnectivity
(
const faceList& patchFaces,
ensightStream& ensightGeometryFile
ensightFaces::elemType elemType,
const label nTotal,
const faceList& faceLst,
ensightGeoFile&
) const;
void writeNSidedPoints
void writeFaceConnectivity
(
const faceList& patchFaces,
ensightStream& ensightGeometryFile
const ensightFaces&,
const faceList& faceLst,
ensightGeoFile&,
const bool raw = false
) const;
void writeAllNSided
(
const labelList& prims,
const label nPrims,
const faceList& patchFaces,
ensightStream& ensightGeometryFile
) const;
void writeAllPoints
(
const label ensightPartI,
const label partId,
const word& ensightPartName,
const label nTotal,
const pointField& uniquePoints,
const label nPoints,
ensightStream& ensightGeometryFile
ensightGeoFile&
) const;
//- Disallow default bitwise copy construct
ensightMesh(const ensightMesh&) = delete;
//- Disallow default bitwise assignment
void operator=(const ensightMesh&) = delete;
public:
// Constructors
//- Construct from fvMesh
//- Construct from components
ensightMesh
(
const fvMesh& mesh,
const options& opts
);
//- Construct from fvMesh with all default options
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
);
@ -282,108 +279,164 @@ public:
// Member Functions
// Access
// Access
const fvMesh& mesh() const
{
return mesh_;
}
//- Reference to the underlying fvMesh
inline const fvMesh& mesh() const;
IOstream::streamFormat format() const
{
return format_;
}
//- Reference to the writer/mesh options
inline const ensightMesh::options& option() const;
const cellSets& meshCellSets() const
{
return meshCellSets_;
}
//- Ascii/Binary file output
inline IOstream::streamFormat format() const;
const List<faceSets>& boundaryFaceSets() const
{
return boundaryFaceSets_;
}
//- Using internalMesh?
inline bool useInternalMesh() const;
const wordList& allPatchNames() const
{
return allPatchNames_;
}
//- Using deprecated order? (hex prism pyr tet poly)
inline bool deprecatedOrder() const;
const wordHashSet& patchNames() const
{
return patchNames_;
}
//- The volume cells (internalMesh)
inline const ensightCells& meshCells() const;
const HashTable<nFacePrimitives>& nPatchPrims() const
{
return nPatchPrims_;
}
//- The list of patches to be output
inline const Map<word>& patches() const;
const List<faceSets>& faceZoneFaceSets() const
{
return faceZoneFaceSets_;
}
//- Face elements per selected patch
inline const HashTable<ensightFaces>& boundaryPatchFaces() const;
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_;
}
//- Face elements per selected faceZone.
// To be output in sorted order.
inline const HashTable<ensightFaces>& faceZoneFaces() const;
// Parallel point merging
// Parallel point merging
//- Global numbering for merged points
const globalIndex& globalPoints() const
{
return globalPointsPtr_();
}
//- Global numbering for merged points
const globalIndex& globalPoints() const
{
return globalPointsPtr_();
}
//- From mesh point to global merged point
const labelList& pointToGlobal() const
{
return pointToGlobal_;
}
//- From mesh point to global merged point
const labelList& pointToGlobal() const
{
return pointToGlobal_;
}
//- Local points that are unique
const labelList& uniquePointMap() const
{
return uniquePointMap_;
}
//- 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();
//- 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;
//- 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&);
};
@ -393,6 +446,8 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ensightMeshI.H"
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -21,58 +21,70 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::faceSets
Description
\*---------------------------------------------------------------------------*/
#ifndef faceSets_H
#define faceSets_H
#include "labelList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
inline const Foam::fvMesh& Foam::ensightMesh::mesh() const
{
return mesh_;
}
/*---------------------------------------------------------------------------*\
Class faceSets Declaration
\*---------------------------------------------------------------------------*/
class faceSets
inline const Foam::ensightMesh::options& Foam::ensightMesh::option() const
{
public:
label nTris;
label nQuads;
label nPolys;
labelList tris;
labelList quads;
labelList polys;
return *options_;
}
// Constructors
//- Construct null
faceSets()
:
nTris(0),
nQuads(0),
nPolys(0)
{}
};
inline Foam::IOstream::streamFormat Foam::ensightMesh::format() const
{
return options_->format();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
inline bool Foam::ensightMesh::useInternalMesh() const
{
return options_->useInternalMesh();
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
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());
}
#endif
// ************************************************************************* //

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

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

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -21,68 +21,73 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
InApplication
foamToEnsight
Namespace
ensightOutput
Description
A collection of global functions for writing ensight file content.
SourceFiles
ensightCloud.C
ensightCloudTemplates.C
ensightOutputCloud.C
ensightOutputCloudTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef ensightCloud_H
#define ensightCloud_H
#ifndef ensightOutputCloud_H
#define ensightOutputCloud_H
#include "ensightFile.H"
#include "fvMesh.H"
#include "Cloud.H"
#include "IOobject.H"
#include "ensightMesh.H"
#include "autoPtr.H"
#include "IOField.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace ensightCloud
{
void ensightParticlePositions
//- Write cloud positions
void writePositions
(
const fvMesh& mesh,
const fileName& dataDir,
const label timeIndex,
const word& cloudName,
const bool dataExists,
const IOstream::streamFormat format
const bool exists,
autoPtr<ensightFile>& output
);
//- Write cloud field, returning true if the field is non-empty.
template<class Type>
void ensightCloudField
(
const IOobject& fieldObject,
const fileName& dataDir,
const label timeIndex,
const word& cloudName,
const label cloudNo,
Ostream& ensightCaseFile,
const bool dataExists,
const IOstream::streamFormat format
);
template<class Type>
void writeCloudField
bool writeCloudField
(
const IOField<Type>& field,
ensightFile& os
);
}
//- Write cloud field from IOobject, always returning true.
template<class Type>
bool writeCloudField
(
const IOobject& fieldObject,
const bool exists,
autoPtr<ensightFile>& output
);
} // namespace ensightCloud
} // namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightCloudTemplates.C"
#include "ensightOutputCloudTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

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

View File

@ -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

@ -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)
{
const IOobject obj = *fieldIter();
const IOobject& obj = *fieldIter();
// Add field and field type
cloudIter().insert

View File

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

View File

@ -0,0 +1,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;
}
}
// ************************************************************************* //