extended the conversion library and utilities

library:
  * routines for managing cellTable and boundaryRegion
  * writing ensight files and parts
  * mesh reader/writer for STARCD

utils:
  * star4ToFoam
  * foamToStarMesh
  * foamToEnsightParts
This commit is contained in:
Mark Olesen
2008-07-04 16:26:22 +02:00
parent 129e7c45cb
commit c7a7dc443c
56 changed files with 10176 additions and 6 deletions

View File

@ -0,0 +1,3 @@
foamToStarMesh.C
EXE = $(FOAM_APPBIN)/foamToStarMesh

View File

@ -0,0 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/conversion/lnInclude
EXE_LIBS = \
-lconversion

View File

@ -0,0 +1,171 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Application
foamToStarMesh
Description
Reads an OpenFOAM mesh and writes a pro-STAR (v4) bnd/cel/vrt format.
Usage
- foamToStarMesh [OPTION] \n
Reads an OpenFOAM mesh and writes a pro-STAR (v4) bnd/cel/vrt format.
@param -noBnd \n
Suppress writing the @c .bnd file
@param -scale \<factor\>\n
Specify an alternative geometry scaling factor.
The default is @b 1000 (scale @em [m] to @em [mm]).
@param -surface \n
Extract the surface of the volume mesh only.
This can be useful, for example, for surface morphing in an external
package.
@param -tri \n
Extract a triangulated surface.
The @b -surface options is implicitly selected.
Note
The cellTable information available in the files
@c constant/cellTable and @c constant/polyMesh/cellTableId
will be used if available. Otherwise the cellZones are used when
creating the cellTable information.
See Also
Foam::cellTable, Foam::meshWriter and Foam::meshWriters::STARCD
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Time.H"
#include "polyMesh.H"
#include "STARCDMeshWriter.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noParallel();
argList::validOptions.insert("scale", "scale");
argList::validOptions.insert("noBnd", "");
argList::validOptions.insert("tri", "");
argList::validOptions.insert("surface", "");
# include "addTimeOptions.H"
# include "setRootCase.H"
# include "createTime.H"
// Get times list
instantList Times = runTime.times();
// set startTime and endTime depending on -time and -latestTime options
# include "checkTimeOptions.H"
runTime.setTime(Times[startTime], startTime);
bool surfaceOnly = false;
if (args.options().found("surface") or args.options().found("tri"))
{
surfaceOnly = true;
}
fileName exportName = meshWriter::defaultMeshName;
if (surfaceOnly)
{
exportName = meshWriter::defaultSurfaceName;
}
if (args.options().found("case"))
{
exportName += '-' + args.globalCaseName();
}
// default: rescale from [m] to [mm]
scalar scaleFactor = 1000;
if (args.options().found("scale"))
{
scaleFactor = readScalar(IStringStream(args.options()["scale"])());
if (scaleFactor <= 0)
{
scaleFactor = 1;
}
}
# include "createPolyMesh.H"
// bool firstCheck = true;
for (label timeI = startTime; timeI < endTime; ++timeI)
{
runTime.setTime(Times[timeI], timeI);
# include "getTimeIndex.H"
polyMesh::readUpdateState state = mesh.readUpdate();
if (timeI == startTime || state != polyMesh::UNCHANGED)
{
meshWriters::STARCD writer(mesh, scaleFactor);
if (args.options().found("noBnd"))
{
writer.noBoundary();
}
fileName meshName(exportName);
if (state != polyMesh::UNCHANGED)
{
meshName += '_' + runTime.timeName();
}
if (surfaceOnly)
{
if (args.options().found("tri"))
{
writer.writeSurface(meshName, true);
}
else
{
writer.writeSurface(meshName);
}
}
else
{
writer.write(meshName);
}
}
Info<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
// Read time index from */uniform/time, but treat 0 and constant specially
word timeName = "0";
if
(
runTime.timeName() != "constant"
&& runTime.timeName() != "0"
)
{
IOobject io
(
"time",
runTime.timeName(),
"uniform",
runTime,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE,
false
);
if (io.headerOk())
{
IOdictionary timeObject
(
IOobject
(
"time",
runTime.timeName(),
"uniform",
runTime,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
)
);
label index;
timeObject.lookup("index") >> index;
timeName = Foam::name(index);
}
else
{
timeName = runTime.timeName();
// Info<< "skip ... missing entry " << io.objectPath() << endl;
// continue;
}
}
Info<< "\nTime [" << timeName << "] = " << runTime.timeName() << nl;

View File

@ -0,0 +1,3 @@
star4ToFoam.C
EXE = $(FOAM_APPBIN)/star4ToFoam

View File

@ -0,0 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/conversion/lnInclude
EXE_LIBS = \
-lconversion

View File

@ -0,0 +1,113 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Application
star4ToFoam
Description
Converts a Star-CD (v4) pro-STAR mesh into OpenFOAM format.
Usage
- star4ToFoam [OPTION] ccmMesh\n
convert pro-STAR mesh to OpenFOAM
@param -ascii \n
Write in ASCII format instead of binary
@param -scale \<factor\>\n
Specify an alternative geometry scaling factor.
The default is @b 0.001 (scale @em [mm] to @em [m]).
@param -solids \n
Treat any solid cells present just like fluid cells.
The default is to discard them.
Note
- baffles are written as interfaces for later use
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Time.H"
#include "STARCDMeshReader.H"
#include "OFstream.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noParallel();
argList::validArgs.append("pro-STAR prefix");
argList::validOptions.insert("ascii", "");
argList::validOptions.insert("scale", "scale");
argList::validOptions.insert("solids", "");
argList args(argc, argv);
Time runTime(args.rootPath(), args.caseName());
stringList const& params = args.additionalArgs();
// default rescale from [mm] to [m]
scalar scaleFactor = 0.001;
if (args.options().found("scale"))
{
scaleFactor = readScalar(IStringStream(args.options()["scale"])());
if (scaleFactor <= 0)
{
scaleFactor = 1;
}
}
if (args.options().found("solids"))
{
meshReaders::STARCD::keepSolids = true;
}
// default to binary output, unless otherwise specified
IOstream::streamFormat format = IOstream::BINARY;
if (args.options().found("ascii"))
{
format = IOstream::ASCII;
}
// increase the precision of the points data
IOstream::defaultPrecision(10);
// remove extensions and/or trailing '.'
fileName prefix = fileName(params[0]).lessExt();
meshReaders::STARCD reader(prefix, runTime, scaleFactor);
autoPtr<polyMesh> mesh = reader.mesh(runTime);
reader.writeMesh(mesh, format);
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -5,5 +5,5 @@ EXE_INC = \
EXE_LIBS = \
-lfiniteVolume \
-llagrangian \
-llagrangian

View File

@ -24,6 +24,15 @@ License
Description
Translates FOAM data to EnSight format
Usage
- foamToEnsight [OPTION] \n
Translates OpenFOAM data to Ensight format
@param -ascii \n
Write Ensight data in ASCII format instead of "C Binary"
Note
Parallel support for cloud data is not supported
\*---------------------------------------------------------------------------*/
@ -74,16 +83,16 @@ bool inFileNameList
int main(int argc, char *argv[])
{
argList::validOptions.insert("patches", "patch list");
argList::validOptions.insert("binary", "" );
argList::validOptions.insert("ascii", "" );
# include "addTimeOptions.H"
# include "setRootCase.H"
// Check options
bool binary = false;
if (args.options().found("binary"))
bool binary = true;
if (args.options().found("ascii"))
{
binary = true;
binary = false;
}
# include "createTime.H"

View File

@ -0,0 +1,3 @@
foamToEnsightParts.C
EXE = $(FOAM_APPBIN)/foamToEnsightParts

View File

@ -0,0 +1,9 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/conversion/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-llagrangian \
-lconversion

View File

@ -0,0 +1,19 @@
// check for lagrangian/positions information in the final directory
bool hasLagrangian = false;
if (timeDirs.size() > 1)
{
IOobject io
(
"positions",
timeDirs[timeDirs.size() - 1].name(),
"lagrangian",
mesh,
IOobject::NO_READ
);
if (io.headerOk())
{
hasLagrangian = true;
}
}

View File

@ -0,0 +1,20 @@
// check for "points" in all of the result directories
bool hasMovingMesh = false;
if (timeDirs.size() > 1)
{
hasMovingMesh = true;
for (label i=0; i < timeDirs.size() && hasMovingMesh; ++i)
{
IOobject io
(
"points",
timeDirs[i].name(),
polyMesh::meshSubDir,
mesh,
IOobject::NO_READ
);
hasMovingMesh = io.headerOk();
}
}

View File

@ -0,0 +1,15 @@
// check that the spray variable is present for this time
//
bool hasSprayField = true;
{
IOobject ioHeader
(
fieldName,
mesh.time().timeName(),
"lagrangian",
mesh,
IOobject::NO_READ
);
hasSprayField = ioHeader.headerOk();
}

View File

@ -0,0 +1,23 @@
// check that the variable is present for all times
//
bool hasValidField = true;
{
for (label i=0; i < timeDirs.size() && hasValidField; ++i)
{
if (fieldName.size() > 2 && fieldName(fieldName.size() - 2, 2) == "_0")
{
hasValidField = false;
break;
}
IOobject ioHeader
(
fieldName,
timeDirs[i].name(),
mesh,
IOobject::NO_READ
);
hasValidField = ioHeader.headerOk();
}
}

View File

@ -0,0 +1,91 @@
// write time values to case file
{
scalar timeCorrection = 0;
if (timeDirs[0].value() < 0)
{
timeCorrection = - timeDirs[0].value();
Info<< "Correcting time values. Adding " << timeCorrection << endl;
}
caseFile.setf(ios_base::scientific, ios_base::floatfield);
caseFile.precision(5);
// time set 1 - geometry and volume fields
if (fieldFileNumbers.size())
{
caseFile
<< "time set: " << 1 << nl
<< "number of steps: " << fieldFileNumbers.size() << nl
<< "filename numbers:" << nl;
label count = 0;
forAll (fieldFileNumbers, i)
{
caseFile
<< " " << setw(12) << fieldFileNumbers[i];
if (++count % 6 == 0)
{
caseFile << nl;
}
}
caseFile
<< nl << "time values:" << nl;
count = 0;
forAll (fieldFileNumbers, i)
{
caseFile
<< " " << setw(12)
<< timeIndices[fieldFileNumbers[i]] + timeCorrection;
if (++count % 6 == 0)
{
caseFile << nl;
}
}
caseFile << nl << nl;
}
// time set 2 - lagrangian fields
if (hasLagrangian && sprayFileNumbers.size())
{
caseFile
<< "time set: " << 2 << nl
<< "number of steps: " << sprayFileNumbers.size() << nl
<< "filename numbers:" << nl;
label count = 0;
forAll (sprayFileNumbers, i)
{
caseFile
<< " " << setw(12) << sprayFileNumbers[i];
if (++count % 6 == 0)
{
caseFile << nl;
}
}
caseFile
<< nl << "time values:" << nl;
count = 0;
forAll (sprayFileNumbers, i)
{
caseFile
<< " " << setw(12)
<< timeIndices[sprayFileNumbers[i]] + timeCorrection;
if (++count % 6 == 0)
{
caseFile << nl;
}
}
caseFile << nl << nl;
}
caseFile << "# end" << nl;
}

View File

@ -0,0 +1,233 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
$Date: 2008/04/02 11:37:10 $
\*---------------------------------------------------------------------------*/
#include "ensightOutputFunctions.H"
#include "passiveParticle.H"
#include "Cloud.H"
#include "IOField.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "OFstream.H"
#include "IOmanip.H"
namespace Foam
{
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
template<class Type>
void ensightCaseEntry
(
OFstream& caseFile,
const IOobject& fieldObject,
const fileName& dataMask,
bool measured
)
{
caseFile.setf(ios_base::left);
if (measured)
{
caseFile
<< pTraits<Type>::typeName
<< " per measured node: 2 "
<< setw(15)
<< ("s" + fieldObject.name()).c_str()
<< " "
<< (dataMask/"lagrangian"/fieldObject.name()).c_str()
<< nl;
}
else
{
caseFile
<< pTraits<Type>::typeName
<< " per element: "
<< setw(15) << fieldObject.name()
<< " "
<< (dataMask/fieldObject.name()).c_str()
<< nl;
}
}
void ensightParticlePositions
(
const polyMesh& mesh,
const fileName& dataDir,
const fileName& subDir,
IOstream::streamFormat format
)
{
Cloud<passiveParticle> parcels(mesh);
fileName lagrangianDir = subDir/"lagrangian";
fileName postFileName = lagrangianDir/"positions";
// the ITER/lagrangian subdirectory must exist
mkDir(dataDir/lagrangianDir);
ensightFile os(dataDir/postFileName, format);
// tag binary format (just like geometry files)
os.writeBinaryHeader();
os.write(postFileName);
os.newline();
os.write("particle coordinates");
os.newline();
os.write(parcels.size(), 8); // unusual width
os.newline();
// binary write is Ensight6 - first ids, then positions
if (format == IOstream::BINARY)
{
forAll (parcels, i)
{
os.write(i+1);
}
forAllIter(Cloud<passiveParticle>, parcels, elmnt)
{
const vector& p = elmnt().position();
os.write(p.x());
os.write(p.y());
os.write(p.z());
}
}
else
{
label nParcels = 0;
forAllIter(Cloud<passiveParticle>, parcels, elmnt)
{
const vector& p = elmnt().position();
os.write(++nParcels, 8); // unusual width
os.write(p.x());
os.write(p.y());
os.write(p.z());
os.newline();
}
}
}
template<class Type>
void ensightSprayField
(
const IOobject& fieldObject,
const fileName& dataDir,
const fileName& subDir,
IOstream::streamFormat format
)
{
Info<< " " << fieldObject.name() << flush;
fileName lagrangianDir = subDir/"lagrangian";
fileName postFileName = lagrangianDir/fieldObject.name();
string title = postFileName + " with " + pTraits<Type>::typeName + " values";
ensightFile os(dataDir/postFileName, format);
os.write(title);
os.newline();
IOField<Type> field(fieldObject);
// 6 values per line
label count = 0;
forAll(field, i)
{
Type val = field[i];
if (mag(val) < 1.0e-90)
{
val = pTraits<Type>::zero;
}
for (direction cmpt=0; cmpt < pTraits<Type>::nComponents; cmpt++)
{
os.write( component(val, cmpt) );
}
count += pTraits<Type>::nComponents;
if (count % 6 == 0)
{
os.newline();
}
}
// add final newline if required
if (count % 6)
{
os.newline();
}
}
//- write generalized field components
template <class Type>
void ensightVolField
(
const ensightParts& partsList,
const IOobject& fieldObject,
const fvMesh& mesh,
const fileName& dataDir,
const fileName& subDir,
IOstream::streamFormat format
)
{
Info<< " " << fieldObject.name() << flush;
fileName postFileName = subDir/fieldObject.name();
ensightFile os(dataDir/postFileName, format);
os.write(postFileName);
os.newline();
// ie, volField<Type>
partsList.writeField
(
os,
GeometricField<Type, fvPatchField, volMesh>
(
fieldObject,
mesh
)
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // end namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,100 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
miscellaneous collection of functions and template related
to Ensight data
SourceFiles
ensightOutputFunctions.C
\*---------------------------------------------------------------------------*/
#ifndef ensightOutputFunctions_H
#define ensightOutputFunctions_H
#include "ensightFile.H"
#include "polyMesh.H"
#include "IOobject.H"
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
void ensightCaseEntry
(
OFstream& caseFile,
const IOobject& fieldObject,
const fileName& dataMask,
bool measured = false
);
void ensightParticlePositions
(
const polyMesh& mesh,
const fileName& dataDir,
const fileName& subDir,
IOstream::streamFormat format
);
//- write spray parcels
template<class Type>
void ensightSprayField
(
const IOobject& fieldObject,
const fileName& dataDir,
const fileName& subDir,
IOstream::streamFormat format
);
//- write generalized field components
template<class Type>
void ensightVolField
(
const ensightParts& partsList,
const IOobject& fieldObject,
const fvMesh& mesh,
const fileName& dataDir,
const fileName& subDir,
IOstream::streamFormat format
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // end namespace Foam
#ifdef NoRepository
# include "ensightOutputFunctions.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,499 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Application
foamToEnsightParts
Description
Translates OpenFOAM data to Ensight format.
An Ensight part is created for each cellZone and patch.
Usage
- foamToEnsightParts [OPTION] \n
Translates OpenFOAM data to Ensight format
@param -ascii \n
Write Ensight data in ASCII format instead of "C Binary"
@param -zeroTime \n
Include the often incomplete initial conditions.
Note
- no parallel data.
- writes to @a Ensight directory to avoid collisions with foamToEnsight.
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "timeSelector.H"
#include "volFields.H"
#include "OFstream.H"
#include "IOmanip.H"
#include "IOobjectList.H"
#include "scalarIOField.H"
#include "tensorIOField.H"
#include "ensightParts.H"
#include "ensightOutputFunctions.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
// with -constant and -zeroTime
timeSelector::addOptions(true, false);
argList::noParallel();
argList::validOptions.insert("ascii", "");
const label nTypes = 2;
const word fieldTypes[] =
{
volScalarField::typeName,
volVectorField::typeName
};
const label nSprayFieldTypes = 2;
const word sprayFieldTypes[] =
{
scalarIOField::typeName,
vectorIOField::typeName
};
# include "setRootCase.H"
# include "createTime.H"
// get times list
instantList timeDirs = timeSelector::select0(runTime, args);
// default to binary output, unless otherwise specified
IOstream::streamFormat format = IOstream::BINARY;
if (args.options().found("ascii"))
{
format = IOstream::ASCII;
}
fileName ensightDir = args.rootPath()/args.globalCaseName()/"Ensight";
fileName dataDir = ensightDir/"data";
fileName caseFileName = "Ensight.case";
fileName dataMask = fileName("data")/ensightFile::mask();
// Ensight and Ensight/data directories must exist
if (dir(ensightDir))
{
rmDir(ensightDir);
}
mkDir(ensightDir);
mkDir(dataDir);
# include "createMesh.H"
// Construct the list of ensight parts for the entire mesh
ensightParts partsList(mesh);
// write summary information
{
OFstream partsInfoFile(ensightDir/"partsInfo");
partsInfoFile
<< "// summary of ensight parts" << nl << nl;
partsList.writeSummary(partsInfoFile);
}
# include "checkHasMovingMesh.H"
# include "checkHasLagrangian.H"
// only take the objects that exists at the end of the calculation
IOobjectList objects(mesh, timeDirs[timeDirs.size()-1].name());
IOobjectList sprayObjects(mesh, timeDirs[timeDirs.size()-1].name(), "lagrangian");
// write single geometry or one per time step
fileName geometryFileName("geometry");
if (hasMovingMesh)
{
geometryFileName = dataMask/geometryFileName;
}
// the case file is always ASCII
Info << "write case: " << caseFileName.c_str() << endl;
OFstream caseFile(ensightDir/caseFileName, IOstream::ASCII);
caseFile.setf(ios_base::left);
caseFile
<< "FORMAT" << nl
<< setw(16) << "type:" << "ensight gold" << nl << nl
<< "GEOMETRY" << nl
<< setw(16) << "model: 1" << geometryFileName.c_str() << nl;
if (hasLagrangian)
{
caseFile
<< setw(16) << "measured: 2"
<< fileName(dataMask/"lagrangian"/"positions").c_str() << nl;
}
caseFile
<< nl << "VARIABLE" << nl;
label nFieldTime = timeDirs.size();
if (nFieldTime < 0)
{
nFieldTime = 0;
}
List<label> fieldFileNumbers(nFieldTime);
List<label> sprayFileNumbers(nFieldTime);
// map used times used
Map<scalar> timeIndices;
nFieldTime = 0;
label nSprayTime = 0;
forAll(timeDirs, timeI)
{
runTime.setTime(timeDirs[timeI], timeI);
# include "getTimeIndex.H"
fieldFileNumbers[nFieldTime++] = timeIndex;
// the data/ITER subdirectory must exist
fileName subDir = ensightFile::subDir(timeIndex);
mkDir(dataDir/subDir);
// place a timestamp in the directory for future reference
{
OFstream timeStamp(dataDir/subDir/"time");
timeStamp
<< "# timestep time" << nl
<< subDir.c_str() << " " << runTime.timeName() << nl;
}
# include "moveMesh.H"
if (nFieldTime == 1 || mesh.moving())
{
if (hasMovingMesh)
{
geometryFileName = dataDir/subDir/"geometry";
}
if (mesh.moving())
{
partsList.recalculate(mesh);
}
ensightGeoFile geoFile(ensightDir/geometryFileName, format);
partsList.writeGeometry(geoFile);
Info << nl;
}
Info<< "write volume field: " << flush;
for (label i=0; i < nTypes; i++)
{
wordList fieldNames = objects.names(fieldTypes[i]);
forAll (fieldNames, fieldI)
{
word fieldName = fieldNames[fieldI];
# include "checkHasValidField.H"
if (!hasValidField)
{
continue;
}
IOobject fieldObject
(
fieldName,
mesh.time().timeName(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
);
if (fieldTypes[i] == volScalarField::typeName)
{
if (nFieldTime == 1)
{
ensightCaseEntry<scalar>
(
caseFile,
fieldObject,
dataMask
);
}
ensightVolField<scalar>
(
partsList,
fieldObject,
mesh,
dataDir,
subDir,
format
);
}
else if (fieldTypes[i] == volVectorField::typeName)
{
if (nFieldTime == 1)
{
ensightCaseEntry<vector>
(
caseFile,
fieldObject,
dataMask
);
}
ensightVolField<vector>
(
partsList,
fieldObject,
mesh,
dataDir,
subDir,
format
);
}
else if (fieldTypes[i] == volSphericalTensorField::typeName)
{
if (nFieldTime == 1)
{
ensightCaseEntry<sphericalTensor>
(
caseFile,
fieldObject,
dataMask
);
}
ensightVolField<sphericalTensor>
(
partsList,
fieldObject,
mesh,
dataDir,
subDir,
format
);
}
else if (fieldTypes[i] == volSymmTensorField::typeName)
{
if (nFieldTime == 1)
{
ensightCaseEntry<symmTensor>
(
caseFile,
fieldObject,
dataMask
);
}
ensightVolField<symmTensor>
(
partsList,
fieldObject,
mesh,
dataDir,
subDir,
format
);
}
else if (fieldTypes[i] == volTensorField::typeName)
{
if (nFieldTime == 1)
{
ensightCaseEntry<tensor>
(
caseFile,
fieldObject,
dataMask
);
}
ensightVolField<tensor>
(
partsList,
fieldObject,
mesh,
dataDir,
subDir,
format
);
}
}
}
Info<< endl;
if (hasLagrangian)
{
// check that the positions field is present for this time
{
IOobject ioHeader
(
"positions",
mesh.time().timeName(),
"lagrangian",
mesh,
IOobject::NO_READ
);
if (ioHeader.headerOk())
{
sprayFileNumbers[nSprayTime++] = timeIndex;
}
}
Info<< "write spray field: " << flush;
ensightParticlePositions
(
mesh,
dataDir,
subDir,
format
);
for (label i=0; i < nSprayFieldTypes; i++)
{
wordList fieldNames = sprayObjects.names(sprayFieldTypes[i]);
forAll (fieldNames, fieldI)
{
word fieldName = fieldNames[fieldI];
# include "checkHasSprayField.H"
if (!hasSprayField)
{
continue;
}
IOobject fieldObject
(
fieldName,
mesh.time().timeName(),
"lagrangian",
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
);
if (sprayFieldTypes[i] == scalarIOField::typeName)
{
if (nSprayTime == 1)
{
ensightCaseEntry<scalar>
(
caseFile,
fieldObject,
dataMask,
true
);
}
ensightSprayField<scalar>
(
fieldObject,
dataDir,
subDir,
format
);
}
else if (sprayFieldTypes[i] == vectorIOField::typeName)
{
if (nSprayTime == 1)
{
ensightCaseEntry<vector>
(
caseFile,
fieldObject,
dataMask,
true
);
}
ensightSprayField<vector>
(
fieldObject,
dataDir,
subDir,
format
);
}
else if (sprayFieldTypes[i] == tensorIOField::typeName)
{
if (nSprayTime == 1)
{
ensightCaseEntry<tensor>
(
caseFile,
fieldObject,
dataMask,
true
);
}
ensightSprayField<tensor>
(
fieldObject,
dataDir,
subDir,
format
);
}
}
}
Info<< endl;
}
}
fieldFileNumbers.setSize(nFieldTime);
sprayFileNumbers.setSize(nSprayTime);
// add time values
caseFile << nl << "TIME" << nl;
# include "ensightCaseTimes.H"
Info<< "\nEnd\n"<< endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
// Read time index from */uniform/time,
// but treat 0 and constant specially
label timeIndex = 0;
if
(
runTime.timeName() != "constant"
&& runTime.timeName() != "0"
)
{
IOobject io
(
"time",
runTime.timeName(),
"uniform",
runTime,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE,
false
);
if (io.headerOk())
{
IOdictionary timeObject
(
IOobject
(
"time",
runTime.timeName(),
"uniform",
runTime,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
)
);
timeObject.lookup("index") >> timeIndex;
}
else
{
Info<< "skip ... missing entry " << io.objectPath() << endl;
continue;
}
}
timeIndices.insert(timeIndex, timeDirs[timeI].value());
Info<< "\nTime [" << timeIndex << "] = " << runTime.timeName() << nl;

View File

@ -0,0 +1,28 @@
{
IOobject ioPoints
(
"points",
runTime.timeName(),
polyMesh::meshSubDir,
mesh
);
if (ioPoints.headerOk())
{
// Reading new points
pointIOField newPoints
(
IOobject
(
"points",
mesh.time().timeName(),
polyMesh::meshSubDir,
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
mesh.movePoints(newPoints);
}
}

View File

@ -1,3 +1,24 @@
ensight/file/ensightFile.C
ensight/file/ensightGeoFile.C
ensight/part/ensightPart.C
ensight/part/ensightPartIO.C
ensight/part/ensightPartCells.C
ensight/part/ensightPartFaces.C
ensight/part/ensightParts.C
meshTables/boundaryRegion.C
meshTables/cellTable.C
meshReader/meshReader.C
meshReader/meshReaderAux.C
meshReader/calcPointCells.C
meshReader/createPolyCells.C
meshReader/createPolyBoundary.C
meshReader/starcd/STARCDMeshReader.C
meshWriter/meshWriter.C
meshWriter/starcd/STARCDMeshWriter.C
polyDualMesh/polyDualMesh.C
LIB = $(FOAM_LIBBIN)/libconversion

View File

@ -1,5 +1,7 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
LIB_LIBS = \
-lfiniteVolume \
-lmeshTools

View File

@ -0,0 +1,298 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "ensightFile.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// allow undef in results
bool Foam::ensightFile::allowUndef_ = false;
// value to represent undef in results
Foam::scalar Foam::ensightFile::undefValue_ = Foam::floatScalarVGREAT;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from pathname
Foam::ensightFile::ensightFile
(
const fileName& pathname,
IOstream::streamFormat format
)
:
OFstream(pathname, format)
{
// ascii formatting specs
setf
(
ios_base::scientific,
ios_base::floatfield
);
precision(5);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightFile::~ensightFile()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::ensightFile::allowUndef()
{
return allowUndef_;
}
bool Foam::ensightFile::allowUndef(bool value)
{
bool old = allowUndef_;
allowUndef_ = value;
return old;
}
Foam::scalar Foam::ensightFile::undefValue(const scalar& value)
{
// enable its use too
allowUndef_ = true;
scalar old = undefValue_;
undefValue_ = value;
return old;
}
// binary write
Foam::Ostream& Foam::ensightFile::write
(
const char* buf,
std::streamsize count
)
{
stream().write(buf, count);
return *this;
}
// write string as "%80s" or as binary
Foam::Ostream& Foam::ensightFile::write
(
const string& value
)
{
char buf[80];
for (string::size_type i = 0; i < 80; ++i)
{
buf[i] = 0;
}
string::size_type n = value.size();
if (n >= 80)
{
n = 79;
}
for (string::size_type i = 0; i < n; ++i)
{
buf[i] = value[i];
}
if (format() == IOstream::BINARY)
{
write
(
reinterpret_cast<char const *>(buf),
sizeof(buf)
);
}
else
{
stream() << buf;
}
return *this;
}
// write integer as "%10d" or as binary
Foam::Ostream& Foam::ensightFile::write
(
const label& value
)
{
if (format() == IOstream::BINARY)
{
unsigned int ivalue(value);
write
(
reinterpret_cast<char const *>(&ivalue),
sizeof(ivalue)
);
}
else
{
stream().width(10);
stream() << value;
}
return *this;
}
// write integer with specified width or as binary
Foam::Ostream& Foam::ensightFile::write
(
const label& value,
const label fieldWidth
)
{
if (format() == IOstream::BINARY)
{
unsigned int ivalue(value);
write
(
reinterpret_cast<char const *>(&ivalue),
sizeof(ivalue)
);
}
else
{
stream().width(fieldWidth);
stream() << value;
}
return *this;
}
// write float as "%12.5e" or as binary
Foam::Ostream& Foam::ensightFile::write
(
const scalar& value
)
{
if (format() == IOstream::BINARY)
{
float fvalue(value);
write
(
reinterpret_cast<char const *>(&fvalue),
sizeof(fvalue)
);
}
else
{
stream().width(12);
stream() << value;
}
return *this;
}
// Add carriage return to ascii stream
void Foam::ensightFile::newline()
{
if (format() == IOstream::ASCII)
{
stream() << nl;
}
}
// write undef value
Foam::Ostream& Foam::ensightFile::writeUndef()
{
write(undefValue_);
return *this;
}
// write element keyword with trailing newline, optionally with undef
Foam::Ostream& Foam::ensightFile::writeKeyword
(
const string& key
)
{
if (allowUndef_)
{
write(key + " undef");
newline();
write(undefValue_);
newline();
}
else
{
write(key);
newline();
}
return *this;
}
// write "C Binary" for binary files
Foam::Ostream& Foam::ensightFile::writeBinaryHeader()
{
if (format() == IOstream::BINARY)
{
write("C Binary");
}
return *this;
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
// '*' mask appropriate for subDir
Foam::string Foam::ensightFile::mask()
{
char buf[16] = "********";
return buf;
}
// consistent zero-padded numbers for subdirectories
Foam::string Foam::ensightFile::subDir(const label n)
{
char buf[16];
sprintf(buf, "%08d", n);
return buf;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,130 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::ensightFile
Description
Ensight output with specialized write() for strings, integers and floats.
Correctly handles binary write as well.
\*---------------------------------------------------------------------------*/
#ifndef ensightFile_H
#define ensightFile_H
#include "OFstream.H"
#include "IOstream.H"
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightFile Declaration
\*---------------------------------------------------------------------------*/
class ensightFile
:
public OFstream
{
//- allow undef in results
static bool allowUndef_;
//- value to represent undef in results
static scalar undefValue_;
//- Disallow default bitwise assignment
void operator=(const ensightFile&);
//- Disallow default copy constructor
ensightFile(const ensightFile&);
public:
// Constructors
//- Construct from pathname
ensightFile
(
const fileName& pathname,
IOstream::streamFormat format=IOstream::BINARY
);
// Destructor
~ensightFile();
// Access
//- Return setting for whether 'undef' values are allowed in results
static bool allowUndef();
//- '*' mask appropriate for subDir
static string mask();
//- consistent zero-padded numbers for subdirectories
static string subDir(const label);
// Edit
static bool allowUndef(bool);
//- Assign the value to represent undef in the results
// Returns the previous value
// NB: do not use values larger than floatScalarVGREAT
static scalar undefValue(const scalar&);
// Output
//- binary write
virtual Ostream& write(const char* buf, std::streamsize count);
//- write element keyword with trailing newline, optionally with undef
virtual Ostream& writeKeyword(const string& key);
//- write "C Binary" for binary files (eg, geometry/measured)
Ostream& writeBinaryHeader();
//- write undef value
Ostream& writeUndef();
//- write string as "%80s" or as binary
Ostream& write(const string& value);
//- write integer as "%10d" or as binary
Ostream& write(const label& value);
//- write integer with specified width or as binary
Ostream& write(const label& value, const label fieldWidth);
//- write float as "%12.5e" or as binary
Ostream& write(const scalar& value);
//- Add carriage return to ascii stream
void newline();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
#endif
// ************************************************************************* //

View File

@ -0,0 +1,70 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "ensightGeoFile.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from pathname
Foam::ensightGeoFile::ensightGeoFile
(
const fileName& pathname,
IOstream::streamFormat format
)
:
ensightFile(pathname, format)
{
writeBinaryHeader();
write("Ensight Geometry File"); newline();
write("====================="); newline();
write("node id assign"); newline();
write("element id assign"); newline();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightGeoFile::~ensightGeoFile()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// write keyword with trailing newline
Foam::Ostream& Foam::ensightGeoFile::writeKeyword
(
const string& key
)
{
write(key);
newline();
return *this;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,80 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::ensightGeoFile
Description
Specialized Ensight output with extra geometry file header
\*---------------------------------------------------------------------------*/
#ifndef ensightGeoFile_H
#define ensightGeoFile_H
#include "ensightFile.H"
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightGeoFile Declaration
\*---------------------------------------------------------------------------*/
class ensightGeoFile
:
public ensightFile
{
//- Disallow default bitwise assignment
void operator=(const ensightGeoFile&);
//- Disallow default copy constructor
ensightGeoFile(const ensightGeoFile&);
public:
// Constructors
//- Construct from pathname
ensightGeoFile
(
const fileName& pathname,
IOstream::streamFormat format=IOstream::BINARY
);
// Destructor
~ensightGeoFile();
// Output
//- write keyword with trailing newline
virtual Ostream& writeKeyword(const string& key);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
#endif
// ************************************************************************* //

View File

@ -0,0 +1,231 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*----------------------------------------------------------------------------*/
#include "ensightPart.H"
#include "addToRunTimeSelectionTable.H"
#include "dictionary.H"
#include "ListOps.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(ensightPart, 0);
defineTemplateTypeNameAndDebug(IOPtrList<ensightPart>, 0);
defineRunTimeSelectionTable(ensightPart, istream);
}
Foam::List<Foam::word> Foam::ensightPart::elemTypes_(0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
//- check for fully defined fields
bool Foam::ensightPart::isFieldDefined
(
const List<scalar>& field
) const
{
forAll(elemLists_, elemI)
{
const labelList& idList = elemLists_[elemI];
forAll(idList, i)
{
label id = idList[i];
if (id >= field.size() || isnan(field[id]))
{
return false;
}
}
}
return true;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Null constructor
Foam::ensightPart::ensightPart
()
:
number_(0),
name_(""),
elemLists_(0),
offset_(0),
size_(0),
isCellData_(true),
matId_(0),
meshPtr_(0)
{}
// Construct empty part with number and description
Foam::ensightPart::ensightPart
(
label partNumber,
const string& partDescription
)
:
number_(partNumber),
name_(partDescription),
elemLists_(0),
offset_(0),
size_(0),
isCellData_(true),
matId_(0),
meshPtr_(0)
{}
// Construct empty part with number and description
Foam::ensightPart::ensightPart
(
label partNumber,
const string& partDescription,
const polyMesh& pMesh
)
:
number_(partNumber),
name_(partDescription),
elemLists_(0),
offset_(0),
size_(0),
isCellData_(true),
matId_(0),
meshPtr_(&pMesh)
{}
// Construct as copy
Foam::ensightPart::ensightPart
(
const ensightPart& part
)
:
number_(part.number_),
name_(part.name_),
elemLists_(part.elemLists_),
offset_(part.offset_),
size_(part.size_),
isCellData_(part.isCellData_),
matId_(part.matId_),
meshPtr_(part.meshPtr_)
{}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
// runtime selection
Foam::autoPtr<Foam::ensightPart> Foam::ensightPart::New(Istream& is)
{
word partType(is);
istreamConstructorTable::iterator cstrIter =
istreamConstructorTablePtr_->find(partType);
if (cstrIter == istreamConstructorTablePtr_->end())
{
FatalIOErrorIn
(
"ensightPart::New(Istream&)",
is
) << "unknown ensightPart type " << partType << endl << endl
<< "Valid ensightPart types are :" << endl
<< istreamConstructorTablePtr_->toc()
<< exit(FatalIOError);
}
return autoPtr<ensightPart>(cstrIter()(is));
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightPart::~ensightPart()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// reconstruct from Istream
void Foam::ensightPart::reconstruct(Istream& is)
{
dictionary dict(is);
dict.lookup("id") >> number_;
dict.lookup("name") >> name_;
dict.readIfPresent("offset", offset_);
// populate elemLists_
elemLists_.setSize(elementTypes().size());
forAll(elementTypes(), elemI)
{
word key(elementTypes()[elemI]);
if (dict.found(key))
{
dict.lookup(key) >> elemLists_[elemI];
}
else
{
elemLists_[elemI].clear();
}
size_ += elemLists_[elemI].size();
}
is.check("ensightPart::reconstruct(Istream&)");
}
// renumber elements
void Foam::ensightPart::renumber(labelList const& origId)
{
// transform to global values first
if (offset_)
{
forAll(elemLists_, elemI)
{
labelList& idList = elemLists_[elemI];
forAll(idList, i)
{
idList[i] += offset_;
}
}
offset_ = 0;
}
if (origId.size())
{
forAll(elemLists_, elemI)
{
inplaceRenumber(origId, elemLists_[elemI]);
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,353 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::ensightPart
Description
Base class for ensightPartCells and ensightPartFaces
SourceFiles
ensightPart.C
ensightPartIO.C
ensightPartI.H
\*---------------------------------------------------------------------------*/
#ifndef ensightPart_H
#define ensightPart_H
#include "ensightFile.H"
#include "ensightGeoFile.H"
#include "typeInfo.H"
#include "labelList.H"
#include "polyMesh.H"
#include "Field.H"
#include "IOPtrList.H"
#include "IOstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightPart Declaration
\*---------------------------------------------------------------------------*/
class ensightPart
{
// Private data
// Static data members
static List<word> elemTypes_;
// Private Member Functions
protected:
// Protected data
//- part number
label number_;
//- part name (or description)
string name_;
//- simple labelList with a name
labelListList elemLists_;
//- start offset for elemLists_
label offset_;
//- number of elements in this part
label size_;
//- cell or face data
bool isCellData_;
//- material id (numeric)
label matId_;
//- mesh reference used
const polyMesh* meshPtr_;
// Protected Classes
//- track the points used by the part and map global to local indices
class localPoints
{
public:
//- number of points used
label nPoints;
//- map global to local indices
labelList list;
// null constructor
localPoints()
:
nPoints(0),
list(0)
{}
// construct for mesh points
localPoints(const polyMesh& pMesh)
:
nPoints(0),
list(pMesh.points().size(), -1)
{}
};
// Protected Member Functions
//- reconstruct contents from Istream
void reconstruct(Istream&);
//- check for fully defined fields
bool isFieldDefined(const List<scalar>&) const;
//- write the part header
void writeHeader(ensightFile&, bool withDescription=false) const;
//- write a scalar field for idList
void writeFieldList
(
ensightFile& os,
const List<scalar>& field,
const labelList& idList
) const;
//- track points used
virtual localPoints calcLocalPoints() const
{
return localPoints();
}
//- write connectivities
virtual void writeConnectivity
(
ensightGeoFile& os,
const string& key,
const labelList& idList,
const labelList& pointMap
) const
{}
public:
//- Runtime type information
TypeName("ensightPart");
// Public data
// Constructors
//- Construct null
ensightPart();
//- Construct empty part with number and description
ensightPart(label partNumber, const string& partDescription);
//- Construct empty part with number and description
ensightPart
(
label partNumber,
const string& partDescription,
const polyMesh& pMesh
);
//- Construct as copy
ensightPart(const ensightPart&);
// Selectors
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
ensightPart,
istream,
(
Istream& is
),
(is)
);
//- Construct and return clone
autoPtr<ensightPart> clone() const
{
return autoPtr<ensightPart>(new ensightPart(*this));
};
//- Construct on freestore from Istream
static autoPtr<ensightPart> New(Istream& is);
// Destructor
virtual ~ensightPart();
// Static members
virtual List<word> const& elementTypes() const
{
return elemTypes_;
}
// Access
//- number of elements in this part
label size() const
{
return size_;
}
//- represents cell data
bool isCellData() const
{
return isCellData_;
}
//- represents face data
bool isFaceData() const
{
return !isCellData_;
}
//- part number
label number() const
{
return number_;
}
//- part name or description
const string& name() const
{
return name_;
}
//- material id
label materialId() const
{
return matId_;
}
//- non-const access
void name(const string& value)
{
name_ = value;
}
void materialId(const label value)
{
matId_ = value;
}
//- offset for element ids
label offset() const
{
return offset_;
}
// Edit
//- renumber elements
void renumber(labelList const&);
//- write summary information about the object
bool writeSummary(Ostream&) const;
//- write reconstruction information for the object
bool writeData(Ostream&) const;
//- write geometry
void writeGeometry(ensightGeoFile&) const;
//- write scalar field
void writeScalarField
(
ensightFile&,
const List<scalar>& field
) const;
//- write vector field components
void writeVectorField
(
ensightFile&,
const List<scalar>& field0,
const List<scalar>& field1,
const List<scalar>& field2
) const;
//- write generalized field components
template <class Type>
void writeField
(
ensightFile&,
const Field<Type>&
) const;
// Member Operators
//- Disallow default bitwise assignment
void operator=(const ensightPart&)
{
notImplemented("ensightPart::operator=(const ensightPart&)");
}
// IOstream Operators
//- write data (reconstruction information)
friend Ostream& operator<<(Ostream&, const ensightPart&);
//- write geometry
friend ensightGeoFile& operator<<
(
ensightGeoFile&,
const ensightPart&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "ensightPartI.H"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,454 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*----------------------------------------------------------------------------*/
#include "ensightPartCells.H"
#include "addToRunTimeSelectionTable.H"
#include "IOstream.H"
#include "IStringStream.H"
#include "dictionary.H"
#include "cellModeller.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(ensightPartCells, 0);
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream);
}
// names for addressable ensight element types
Foam::List<Foam::word> Foam::ensightPartCells::elemTypes_
(
IStringStream
(
"(tetra4 pyramid5 penta6 hexa8 nfaced)"
)()
);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// classify the cell types, track the points used
void Foam::ensightPartCells::classify
(
const labelList& idList
)
{
// References to cell shape models
const cellModel& tet = *(cellModeller::lookup("tet"));
const cellModel& pyr = *(cellModeller::lookup("pyr"));
const cellModel& prism = *(cellModeller::lookup("prism"));
const cellModel& hex = *(cellModeller::lookup("hex"));
const polyMesh& mesh = *meshPtr_;
const cellShapeList& cellShapes = mesh.cellShapes();
offset_ = 0;
size_ = mesh.nCells();
bool limited = false;
if (&idList)
{
limited = true;
size_ = idList.size();
}
// count the shapes
label nTet = 0;
label nPyr = 0;
label nPrism = 0;
label nHex = 0;
label nPoly = 0;
// TODO: allow tet-decomposition of polyhedral cells
#if 0
label nTetDecomp = 0;
label nPyrDecomp = 0;
#endif
for (label listI = 0; listI < size_; ++listI)
{
label cellId = listI;
if (limited)
{
cellId = idList[listI];
}
const cellShape& cellShape = cellShapes[cellId];
const cellModel& cellModel = cellShape.model();
if (cellModel == tet)
{
nTet++;
}
else if (cellModel == pyr)
{
nPyr++;
}
else if (cellModel == prism)
{
nPrism++;
}
else if (cellModel == hex)
{
nHex++;
}
else
{
nPoly++;
// TODO: allow tet-decomposition of polyhedral cells
#if 0
const cell& cFaces = mesh.cells()[cellI];
forAll(cFaces, cFaceI)
{
const face& f = mesh.faces()[cFaces[cFaceI]];
label nQuads = 0;
label nTris = 0;
f.nTrianglesQuads(mesh.points(), nTris, nQuads);
nTetDecomp += nTris;
nPyrDecomp += nQuads;
}
nAddCells--;
nAddPoints++;
#endif
}
}
// we can avoid double looping, but at the cost of allocation
labelList tetCells(nTet);
labelList pyramidCells(nPyr);
labelList prismCells(nPrism);
labelList hexCells(nHex);
labelList polyCells(nPoly);
nTet = 0,
nPyr = 0;
nPrism = 0;
nHex = 0;
nPoly = 0;
// classify the shapes
for (label listI = 0; listI < size_; ++listI)
{
label cellId = listI;
if (limited)
{
cellId = idList[listI];
}
const cellShape& cellShape = cellShapes[cellId];
const cellModel& cellModel = cellShape.model();
if (cellModel == tet)
{
tetCells[nTet++] = cellId;
}
else if (cellModel == pyr)
{
pyramidCells[nPyr++] = cellId;
}
else if (cellModel == prism)
{
prismCells[nPrism++] = cellId;
}
else if (cellModel == hex)
{
hexCells[nHex++] = cellId;
}
else
{
polyCells[nPoly++] = cellId;
// TODO: allow tet-decomposition of polyhedral cells
#if 0
// Mapping from additional point to cell
addPointCellLabels_[api] = cellId;
const cell& cFaces = mesh.cells()[cellId];
forAll(cFaces, cFaceI)
{
const face& f = mesh.faces()[cFaces[cFaceI]];
label nQuads = 0;
label nTris = 0;
f.nTrianglesQuads(mesh.points(), nTris, nQuads);
nTetDecomp += nTris;
nPyrDecomp += nQuads;
}
nAddCells--;
nAddPoints++;
#endif
}
}
// MUST match with elementTypes
elemLists_.setSize(elementTypes().size());
elemLists_[tetra4Elements].transfer( tetCells );
elemLists_[pyramid5Elements].transfer( pyramidCells );
elemLists_[penta6Elements].transfer( prismCells );
elemLists_[hexa8Elements].transfer( hexCells );
elemLists_[nfacedElements].transfer( polyCells );
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct empty part with number and description
Foam::ensightPartCells::ensightPartCells
(
label partNumber,
const string& partDescription
)
:
ensightPart(partNumber, partDescription)
{}
// Construct from polyMesh without zones
Foam::ensightPartCells::ensightPartCells
(
label partNumber,
const polyMesh& pMesh
)
:
ensightPart(partNumber, "cells", pMesh)
{
classify();
}
// Construct from polyMesh and list of (non-zoned) cells
Foam::ensightPartCells::ensightPartCells
(
label partNumber,
const polyMesh& pMesh,
const labelList& idList
)
:
ensightPart(partNumber, "cells", pMesh)
{
classify(idList);
}
// Construct from polyMesh and cellZone
Foam::ensightPartCells::ensightPartCells
(
label partNumber,
const polyMesh& pMesh,
const cellZone& cZone
)
:
ensightPart(partNumber, cZone.name(), pMesh)
{
classify(cZone);
}
// Construct as copy
Foam::ensightPartCells::ensightPartCells
(
const ensightPartCells& part
)
:
ensightPart(part)
{}
// Construct from Istream
Foam::ensightPartCells::ensightPartCells
(
Istream& is
)
:
ensightPart()
{
reconstruct(is);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightPartCells::~ensightPartCells()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// track the points used
Foam::ensightPart::localPoints Foam::ensightPartCells::calcLocalPoints() const
{
const polyMesh& mesh = *meshPtr_;
localPoints ptList(mesh);
labelList& usedPoints = ptList.list;
label nPoints = 0;
forAll(elemLists_, typeI)
{
const labelList& idList = elemLists_[typeI];
// add all points from cells
forAll(idList, i)
{
label id = idList[i] + offset_;
const labelList& cFaces = mesh.cells()[id];
forAll(cFaces, cFaceI)
{
const face& f = mesh.faces()[cFaces[cFaceI]];
forAll(f, fp)
{
if (usedPoints[f[fp]] == -1)
{
usedPoints[f[fp]] = nPoints++;
}
}
}
}
}
// this is not absolutely necessary, but renumber anyhow
nPoints = 0;
forAll(usedPoints, ptI)
{
if (usedPoints[ptI] > -1)
{
usedPoints[ptI] = nPoints++;
}
}
ptList.nPoints = nPoints;
return ptList;
}
// write cell connectivities
void Foam::ensightPartCells::writeConnectivity
(
ensightGeoFile& os,
const string& key,
const labelList& idList,
const labelList& pointMap
) const
{
os.writeKeyword(key);
os.write(idList.size());
os.newline();
const polyMesh& mesh = *meshPtr_;
// write polyhedral
if (word(key) == "nfaced")
{
const faceList& meshFaces = mesh.faces();
// write the number of faces per element
forAll(idList, i)
{
label id = idList[i] + offset_;
const labelList& cFace = mesh.cells()[id];
os.write( cFace.size() );
os.newline();
}
// write the number of points per element face
forAll(idList, i)
{
label id = idList[i] + offset_;
const labelList& cFace = mesh.cells()[id];
forAll(cFace, faceI)
{
const face& cf = meshFaces[cFace[faceI]];
os.write( cf.size() );
os.newline();
}
}
// write the points describing each element face
forAll(idList, i)
{
label id = idList[i] + offset_;
const labelList& cFace = mesh.cells()[id];
forAll(cFace, faceI)
{
const face& cf = meshFaces[cFace[faceI]];
forAll(cf, ptI)
{
// convert global -> local index
// (note: Ensight indices start with 1)
os.write( pointMap[cf[ptI]] + 1);
}
os.newline();
}
}
}
else
{
// write primitive
const cellShapeList& cellShapes = mesh.cellShapes();
forAll(idList, i)
{
label id = idList[i] + offset_;
const cellShape& cellPoints = cellShapes[id];
// convert global -> local index
// (note: Ensight indices start with 1)
forAll(cellPoints, ptI)
{
os.write( pointMap[cellPoints[ptI]] + 1 );
}
os.newline();
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,162 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::ensightPartCells
Description
An implementation of ensightPart to hold volume mesh cells.
SourceFiles
ensightPartCells.C
\*---------------------------------------------------------------------------*/
#ifndef ensightPartCells_H
#define ensightPartCells_H
#include "ensightPart.H"
#include "typeInfo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightPartCells Declaration
\*---------------------------------------------------------------------------*/
class ensightPartCells
:
public ensightPart
{
// Private data
// Private Member Functions
//- Disallow default bitwise assignment
void operator=(const ensightPartCells&);
//- classify the cell types
void classify(const labelList& idLabels = labelList::null());
//- track points used
virtual localPoints calcLocalPoints() const;
//- track the points used
// virtual void makeLocalPointMap();
//- element connectivity
virtual void writeConnectivity
(
ensightGeoFile& os,
const string& key,
const labelList& idList,
const labelList& pointMap
) const;
protected:
//- addressable Ensight element types
enum elemType
{
tetra4Elements,
pyramid5Elements,
penta6Elements,
hexa8Elements,
nfacedElements
};
// Static data members
static List<word> elemTypes_;
public:
//- Runtime type information
TypeName("ensightCells");
// Constructors
//- Construct empty part with number and description
ensightPartCells(label partNumber, const string& partDescription);
//- Construct from polyMesh without zones
ensightPartCells(label partNumber, const polyMesh&);
//- Construct from polyMesh and list of (non-zoned) cells
ensightPartCells
(
label partNumber,
const polyMesh&,
const labelList&
);
//- Construct from polyMesh and cellZone
ensightPartCells
(
label partNumber,
const polyMesh&,
const cellZone&
);
//- Construct as copy
ensightPartCells(const ensightPartCells&);
//- Construct from Istream
ensightPartCells(Istream&);
//- Construct on freestore from Istream
static autoPtr<ensightPartCells> New(Istream& is)
{
return autoPtr<ensightPartCells>(new ensightPartCells(is));
}
// Destructor
virtual ~ensightPartCells();
// Member Functions
//- static listing of the element types
virtual List<word> const& elementTypes() const
{
return elemTypes_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,263 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*----------------------------------------------------------------------------*/
#include "ensightPartFaces.H"
#include "addToRunTimeSelectionTable.H"
#include "IOstreams.H"
#include "IStringStream.H"
#include "dictionary.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(ensightPartFaces, 0);
addToRunTimeSelectionTable(ensightPart, ensightPartFaces, istream);
}
// names for addressable ensight element types
Foam::List<Foam::word> Foam::ensightPartFaces::elemTypes_
(
IStringStream
(
"(tria3 quad4 nsided)"
)()
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct empty part with number and description
Foam::ensightPartFaces::ensightPartFaces
(
label partNumber,
const string& partDescription
)
:
ensightPart(partNumber, partDescription)
{
isCellData_ = false;
}
// Construct from polyMesh and polyPatch
Foam::ensightPartFaces::ensightPartFaces
(
label partNumber,
const polyMesh& pMesh,
const polyPatch& pPatch
)
:
ensightPart(partNumber, pPatch.name(), pMesh)
{
isCellData_ = false;
offset_ = pPatch.start();
size_ = pPatch.size();
// count the shapes
label nTri = 0;
label nQuad = 0;
label nPoly = 0;
forAll (pPatch, patchfaceI)
{
const face& f = pMesh.faces()[patchfaceI + offset_];
if (f.size() == 3)
{
nTri++;
}
else if (f.size() == 4)
{
nQuad++;
}
else
{
nPoly++;
}
}
// we can avoid double looping, but at the cost of allocation
labelList triCells(nTri);
labelList quadCells(nQuad);
labelList polygonCells(nPoly);
nTri = 0;
nQuad = 0;
nPoly = 0;
// classify the shapes
forAll(pPatch, patchfaceI)
{
const face& f = pMesh.faces()[patchfaceI + offset_];
if (f.size() == 3)
{
triCells[nTri++] = patchfaceI;
}
else if (f.size() == 4)
{
quadCells[nQuad++] = patchfaceI;
}
else
{
polygonCells[nPoly++] = patchfaceI;
}
}
// MUST match with elementTypes
elemLists_.setSize(elementTypes().size());
elemLists_[tria3Elements].transfer( triCells );
elemLists_[quad4Elements].transfer( quadCells );
elemLists_[nsidedElements].transfer( polygonCells );
}
// Construct as copy
Foam::ensightPartFaces::ensightPartFaces
(
const ensightPartFaces &part
)
:
ensightPart(part)
{}
// Construct from Istream
Foam::ensightPartFaces::ensightPartFaces
(
Istream& is
)
:
ensightPart()
{
isCellData_ = false;
reconstruct(is);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightPartFaces::~ensightPartFaces()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// track the points used
Foam::ensightPart::localPoints Foam::ensightPartFaces::calcLocalPoints() const
{
const polyMesh& mesh = *meshPtr_;
localPoints ptList(mesh);
labelList& usedPoints = ptList.list;
label nPoints = 0;
forAll(elemLists_, typeI)
{
const labelList& idList = elemLists_[typeI];
// add all points from faces
forAll(idList, i)
{
label id = idList[i] + offset_;
const face& f = mesh.faces()[id];
forAll(f, fp)
{
if (usedPoints[f[fp]] == -1)
{
usedPoints[f[fp]] = nPoints++;
}
}
}
}
// this is not absolutely necessary, but renumber anyhow
nPoints = 0;
forAll(usedPoints, ptI)
{
if (usedPoints[ptI] > -1)
{
usedPoints[ptI] = nPoints++;
}
}
ptList.nPoints = nPoints;
return ptList;
}
// write face connectivities
void Foam::ensightPartFaces::writeConnectivity
(
ensightGeoFile& os,
const string& key,
const labelList& idList,
const labelList& pointMap
) const
{
os.writeKeyword(key);
os.write(idList.size());
os.newline();
const faceList& meshFaces = meshPtr_->faces();
// write (polygon) face sizes
if (word(key) == "nsided")
{
// write the number of points per face
forAll(idList, i)
{
label id = idList[i] + offset_;
const face& f = meshFaces[id];
os.write( f.size() );
os.newline();
}
}
// write the points describing the face
forAll(idList, i)
{
label id = idList[i] + offset_;
const face& f = meshFaces[id];
// convert global -> local index
// (note: Ensight indices start with 1)
forAll(f, fp)
{
os.write( pointMap[f[fp]] + 1 );
}
os.newline();
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,142 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::ensightPartFaces
Description
An implementation of ensightPart to hold volume mesh faces.
SourceFiles
ensightPartFaces.C
\*---------------------------------------------------------------------------*/
#ifndef ensightPartFaces_H
#define ensightPartFaces_H
#include "ensightPart.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightPartFaces Declaration
\*---------------------------------------------------------------------------*/
class ensightPartFaces
:
public ensightPart
{
// Private data
// Private Member Functions
//- Disallow default bitwise assignment
void operator=(const ensightPartFaces&);
//- track points used
virtual localPoints calcLocalPoints() const;
//- element connectivity
virtual void writeConnectivity
(
ensightGeoFile& os,
const string& key,
const labelList& idList,
const labelList& pointMap
) const;
protected:
//- addressable ensight element types
enum elemType
{
tria3Elements,
quad4Elements,
nsidedElements
};
// Static data members
static List<word> elemTypes_;
public:
//- Runtime type information
TypeName("ensightFaces");
// Constructors
//- Construct empty part with number and description
ensightPartFaces(label partNumber, const string& partDescription);
//- Construct from polyMesh and polyPatch
ensightPartFaces
(
label partNumber,
const polyMesh&,
const polyPatch&
);
//- Construct as copy
ensightPartFaces(const ensightPartFaces&);
//- Construct from Istream
ensightPartFaces(Istream&);
//- Construct on freestore from Istream
static autoPtr<ensightPartFaces> New(Istream& is)
{
return autoPtr<ensightPartFaces>(new ensightPartFaces(is));
}
// Destructor
virtual ~ensightPartFaces();
// Member Functions
//- static listing of the element types
virtual List<word> const& elementTypes() const
{
return elemTypes_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,71 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
Template to write generalized field components
\*---------------------------------------------------------------------------*/
#include "ensightPart.H"
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
// write generalized field components
template <class Type>
void Foam::ensightPart::writeField
(
ensightFile& os,
const Field<Type>& field
) const
{
if (size() && field.size())
{
writeHeader(os);
forAll(elementTypes(), elemI)
{
const labelList& idList = elemLists_[elemI];
if (idList.size())
{
os.writeKeyword( elementTypes()[elemI] );
for
(
direction cmpt=0;
cmpt < pTraits<Type>::nComponents;
cmpt++
)
{
writeFieldList(os, field.component(cmpt), idList);
}
}
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,264 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
Output for ensightPart
\*---------------------------------------------------------------------------*/
#include "ensightPart.H"
#include "dictionary.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// write the part header
void Foam::ensightPart::writeHeader
(
ensightFile& os,
bool withDescription
) const
{
os.write("part");
os.newline();
os.write(number() + 1); // Ensight starts with 1
os.newline();
if (withDescription)
{
os.write(name());
os.newline();
}
}
// write scalar field for idList
void Foam::ensightPart::writeFieldList
(
ensightFile& os,
const List<scalar>& field,
const List<label>& idList
) const
{
forAll(idList, i)
{
if (idList[i] >= field.size() || isnan(field[idList[i]]))
{
os.writeUndef();
}
else
{
os.write(field[idList[i]]);
}
os.newline();
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// write summary information about the object
bool Foam::ensightPart::writeSummary
(
Ostream& os
) const
{
os << indent << type() << nl
<< indent << token::BEGIN_BLOCK << incrIndent << nl;
// Ensight starts with 1
os.writeKeyword("id") << (number() + 1) << token::END_STATEMENT << nl;
os.writeKeyword("name") << name() << token::END_STATEMENT << nl;
os.writeKeyword("offset") << offset() << token::END_STATEMENT << nl;
os.writeKeyword("size") << size() << token::END_STATEMENT << nl;
os << decrIndent << indent << token::END_BLOCK << nl << endl;
return true;
}
// write reconstruction information for the object
bool Foam::ensightPart::writeData
(
Ostream& os
) const
{
os << indent << type() << nl
<< indent << token::BEGIN_BLOCK << incrIndent << nl;
os.writeKeyword("id") << number() << token::END_STATEMENT << nl;
os.writeKeyword("name") << name() << token::END_STATEMENT << nl;
os.writeKeyword("offset") << offset() << token::END_STATEMENT << nl;
forAll(elementTypes(), typeI)
{
word key(elementTypes()[typeI]);
if (elemLists_[typeI].size())
{
elemLists_[typeI].writeEntry(key, os);
}
}
os << decrIndent << indent << token::END_BLOCK << nl << endl;
return true;
}
// write geometry by components
void Foam::ensightPart::writeGeometry
(
ensightGeoFile& os
) const
{
if (size() && meshPtr_)
{
const polyMesh& mesh = *meshPtr_;
const pointField& meshPoints = mesh.points();
localPoints ptList = calcLocalPoints();
labelList& pointMap = ptList.list;
writeHeader(os, true);
// write points
os.writeKeyword("coordinates");
os.write(ptList.nPoints);
os.newline();
for (direction cmpt=0; cmpt < vector::nComponents; cmpt++)
{
forAll(pointMap, ptI)
{
if (pointMap[ptI] > -1)
{
os.write( meshPoints[ptI].component(cmpt) );
os.newline();
}
}
}
// write parts
forAll(elementTypes(), elemI)
{
if (elemLists_[elemI].size())
{
writeConnectivity
(
os,
elementTypes()[elemI],
elemLists_[elemI],
pointMap
);
}
}
}
}
// write scalar field
void Foam::ensightPart::writeScalarField
(
ensightFile& os,
const List<scalar>& field
) const
{
if (size() && field.size() && (os.allowUndef() || isFieldDefined(field)))
{
writeHeader(os);
forAll(elementTypes(), elemI)
{
const labelList& idList = elemLists_[elemI];
if (idList.size())
{
os.writeKeyword( elementTypes()[elemI] );
writeFieldList(os, field, idList);
}
}
}
}
// write vector field components
void Foam::ensightPart::writeVectorField
(
ensightFile& os,
const List<scalar>& field0,
const List<scalar>& field1,
const List<scalar>& field2
) const
{
if (size() && field0.size() && (os.allowUndef() || isFieldDefined(field0)))
{
writeHeader(os);
forAll(elementTypes(), elemI)
{
const labelList& idList = elemLists_[elemI];
if (idList.size())
{
os.writeKeyword( elementTypes()[elemI] );
writeFieldList(os, field0, idList);
writeFieldList(os, field1, idList);
writeFieldList(os, field2, idList);
}
}
}
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const ensightPart& part
)
{
part.writeData(os);
return os;
}
Foam::ensightGeoFile& Foam::operator<<
(
ensightGeoFile& os,
const ensightPart& part
)
{
part.writeGeometry(os);
return os;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,342 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*----------------------------------------------------------------------------*/
#include "ensightParts.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from polyMesh
Foam::ensightParts::ensightParts
(
const polyMesh& pMesh
)
:
partsList_()
{
recalculate(pMesh);
}
// Construct from IOobject
Foam::ensightParts::ensightParts
(
const IOobject& ioObj
)
:
partsList_()
{
IOPtrList<ensightPart> ioList(ioObj);
partsList_.transfer(ioList);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightParts::~ensightParts()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// clear old information and construct anew from polyMesh
void Foam::ensightParts::recalculate
(
const polyMesh& pMesh
)
{
partsList_.clear();
// extra space for unzoned cells
label nPart =
(
pMesh.cellZones().size()
+ pMesh.boundaryMesh().size()
+ 1
);
partsList_.setSize(nPart);
nPart = 0;
label nZoneCells = 0;
// do cell zones
forAll(pMesh.cellZones(), zoneI)
{
const cellZone& cZone = pMesh.cellZones()[zoneI];
nZoneCells += cZone.size();
if (cZone.size())
{
partsList_.set
(
nPart,
new ensightPartCells
(
nPart,
pMesh,
cZone
)
);
nPart++;
}
}
// collect unzoned cells
// special case: no zones at all - do entire mesh
if (nZoneCells == 0)
{
partsList_.set
(
nPart,
new ensightPartCells
(
nPart,
pMesh
)
);
nPart++;
}
else if (pMesh.nCells() > nZoneCells)
{
// determine which cells are not in a cellZone
labelList unzoned(pMesh.nCells(), -1);
forAll(pMesh.cellZones(), zoneI)
{
const labelList& idList = pMesh.cellZones()[zoneI];
forAll(idList, i)
{
unzoned[idList[i]] = idList[i];
}
}
label nUnzoned = 0;
forAll(unzoned, i)
{
if (unzoned[i] < 0)
{
unzoned[nUnzoned] = i;
nUnzoned++;
}
}
unzoned.setSize(nUnzoned);
if (unzoned.size())
{
partsList_.set
(
nPart,
new ensightPartCells
(
nPart,
pMesh,
unzoned
)
);
nPart++;
}
}
// do boundaries, skipping empty and processor patches
forAll(pMesh.boundaryMesh(), patchI)
{
const polyPatch& pPatch = pMesh.boundaryMesh()[patchI];
if
(
pPatch.size()
&& typeid(pPatch) != typeid(processorPolyPatch)
)
{
partsList_.set
(
nPart,
new ensightPartFaces
(
nPart,
pMesh,
pPatch
)
);
nPart++;
}
}
// truncate to correct size
partsList_.setSize(nPart);
}
// renumber elements
void Foam::ensightParts::renumber
(
const labelList& origCellId,
const labelList& origFaceId
)
{
forAll(partsList_, partI)
{
if (partsList_[partI].isCellData())
{
partsList_[partI].renumber(origCellId);
}
else
{
partsList_[partI].renumber(origFaceId);
}
}
}
// write the geometry
void Foam::ensightParts::writeGeometry
(
ensightGeoFile& os
) const
{
// with some feedback
Info<< "write geometry part:" << nl << flush;
forAll(partsList_, partI)
{
Info<< " " << partI << flush;
partsList_[partI].writeGeometry(os);
}
}
// write summary information about the objects
bool Foam::ensightParts::writeSummary
(
Ostream& os
) const
{
forAll(partsList_, partI)
{
partsList_[partI].writeSummary(os);
}
return true;
}
void Foam::ensightParts::writeData
(
Ostream& os
) const
{
// Write size of list
os << nl << partsList_.size();
// Write beginning of contents
os << nl << token::BEGIN_LIST;
// Write list contents
forAll(partsList_, i)
{
os << nl << partsList_[i];
}
// Write end of contents
os << nl << token::END_LIST << nl;
// Check state of IOstream
os.check("Ostream& operator<<(Ostream&, const PtrList&)");
}
// write scalar field
void Foam::ensightParts::writeScalarField
(
ensightFile& os,
const List<scalar>& field,
bool useFaceData
) const
{
forAll(partsList_, partI)
{
if
(
useFaceData
? partsList_[partI].isFaceData()
: partsList_[partI].isCellData()
)
{
partsList_[partI].writeScalarField(os,field);
}
}
}
// write vector field components
void Foam::ensightParts::writeVectorField
(
ensightFile& os,
const List<scalar>& field0,
const List<scalar>& field1,
const List<scalar>& field2,
bool useFaceData
) const
{
forAll(partsList_, partI)
{
if
(
useFaceData
? partsList_[partI].isFaceData()
: partsList_[partI].isCellData()
)
{
partsList_[partI].writeVectorField(os, field0, field1, field2);
}
}
}
// * * * * * * * * * * * * * * * Member operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
Foam::ensightGeoFile& Foam::operator<<
(
ensightGeoFile& os,
const ensightParts& parts
)
{
parts.writeGeometry(os);
return os;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,158 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::ensightParts
Description
A collection of several ensightPart elements
SourceFiles
ensightParts.C
ensightPartsI.H
\*---------------------------------------------------------------------------*/
#ifndef ensightParts_H
#define ensightParts_H
#include "ensightPart.H"
#include "ensightPartFaces.H"
#include "ensightPartCells.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightParts Declaration
\*---------------------------------------------------------------------------*/
class ensightParts
{
// Private Data
//- list of parts
PtrList<ensightPart> partsList_;
// Private Member Functions
//- Disallow default bitwise copy construct
ensightParts(const ensightParts&);
//- Disallow default bitwise assignment
void operator=(const ensightParts&);
public:
// Constructors
//- Construct from polyMesh
ensightParts(const polyMesh&);
//- Construct from IOobject
ensightParts(const IOobject&);
// Destructor
~ensightParts();
//- clear old information and construct anew from polyMesh
void recalculate(const polyMesh&);
//- renumber elements
void renumber
(
const labelList& origCellId,
const labelList& origFaceId
);
//- number of parts
label size() const
{
return partsList_.size();
}
//- write the geometry
void writeGeometry(ensightGeoFile&) const;
//- write summary information about the objects
bool writeSummary(Ostream&) const;
//- write the lists
void writeData(Ostream&) const;
//- write scalar field
void writeScalarField
(
ensightFile&,
const List<scalar>& field,
bool useFaceData = false
) const;
//- write vector field components
void writeVectorField
(
ensightFile&,
const List<scalar>& field0,
const List<scalar>& field1,
const List<scalar>& field2,
bool useFaceData = false
) const;
//- write generalized field components
template <class Type>
void writeField
(
ensightFile&,
const GeometricField<Type, fvPatchField, volMesh>&
) const;
// Friend Operators
friend ensightGeoFile& operator<<
(
ensightGeoFile&,
const ensightParts&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "ensightPartsI.H"
#endif
#endif
// ************************************************************************* //

View File

@ -0,0 +1,77 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
Template to write generalized field components
\*---------------------------------------------------------------------------*/
#include "ensightParts.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// write generalized field components
template <class Type>
void Foam::ensightParts::writeField
(
ensightFile& os,
const GeometricField<Type, fvPatchField, volMesh>& field
) const
{
// find offset to patch parts (ie, the first face data)
label patchOffset = 0;
forAll(partsList_, partI)
{
if (partsList_[partI].isFaceData())
{
patchOffset = partI;
break;
}
}
forAll(partsList_, partI)
{
label patchI = partI - patchOffset;
if (partsList_[partI].isCellData())
{
partsList_[partI].writeField
(
os,
field
);
}
else if (patchI < field.boundaryField().size())
{
partsList_[partI].writeField
(
os,
field.boundaryField()[patchI]
);
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,95 @@
With pro-STAR version v4, the input formats have changed radically.
* Easier to parse space-delimited input formats
* No arbitrary or integral couples
* No trimmed or degenerate cells
* Support for polyhedral cells
* Boundaries are directly connected to cell and faces
Since the boundaries are now connected directly to the faces,
we now must be concerned with cell face notation otherwise we perform the
incorrect lookup.
Fortunately, there are only 4 primitive shapes to be concerned with.
Hexa:
Foam pro-STAR
~~~~~~~~~~~~~~ ~~~~~~~~~~~
Face 0 (0 4 7 3) -> F5: (0 4 7 3)
Face 1 (1 2 6 5) -> F6: (1 2 6 5)
Face 2 (0 1 5 4) -> F3: (0 1 5 4)
Face 3 (3 7 6 2) -> F4: (2 3 7 6)
Face 4 (0 3 2 1) -> F1: (0 3 2 1)
Face 5 (4 5 6 7) -> F2: (4 5 6 7)
Prism:
Foam pro-STAR
~~~~~~~~~~~~~~ ~~~~~~~~~~~
Face 0 (0 2 1) -> F1: (0 2 1)
Face 1 (3 4 5) -> F2: (3 4 5)
Face 2 (0 3 5 2) -> F5: (0 3 5 2)
Face 3 (1 2 5 4) -> F6: (1 2 5 4)
Face 4 (0 1 4 3) -> F3: (0 1 4 3)
Tetra:
Foam pro-STAR
~~~~~~~~~~~~~~ ~~~~~~~~~~~
Face 0 (1 2 3) -> F6: (1 2 3)
Face 1 (0 3 2) -> F5: (0 3 2)
Face 2 (0 1 3) -> F3: (0 1 3)
Face 3 (0 2 1) -> F1: (0 2 1)
Pyramid:
Foam pro-STAR
~~~~~~~~~~~~~~ ~~~~~~~~~~~
Face 0 (0 3 2 1) -> F1: (0 3 2 1)
Face 1 (0 4 3) -> F5: (0 4 3)
Face 2 (3 4 2) -> F4: (2 3 4)
Face 3 (1 2 4) -> F6: (1 2 4)
Face 4 (0 1 4) -> F3: (0 1 4)
Noting that several faces are skipped over in the pro-STAR definitions,
simply introducing a new cell modeller will be a problem.
Instead, subtract 1 from the pro-STAR faces and use lookup tables.
Here are the pro-STAR macro snippets used for creating the primitive cells:
! hexa
v 10 0 0 0
v 11 1 0 0
v 12 1 1 0
v 13 0 1 0
v 14 0 0 1
v 15 1 0 1
v 16 1 1 1
v 17 0 1 1
c hexa 10 11 12 13 14 15 16 17
! prism
v 20 0 0 0
v 21 1 0 0
v 22 1 1 0
v 23 0 0 1
v 24 1 0 1
v 25 1 1 1
c prism 20 21 22 23 24 25
! tet
v 30 0 0 0
v 31 1 0 0
v 32 1 1 0
v 33 0.75 0.75 1
c tetra 30 31 32 33
! pyramid
v 40 0 0 0
v 41 1 0 0
v 42 1 1 0
v 43 0 1 0
v 44 0.5 0.5 1
c pyra 40 41 42 43 44
! list faces
flist all

View File

@ -0,0 +1,183 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
calculate point cells - ie, the cells attached to each point
- remove unused points, adjust pointCells and cellFaces accordingly
\*---------------------------------------------------------------------------*/
#include "meshReader.H"
// for transition - in case someone really relied on the old behaviour
#undef LEAVE_UNUSED_POINTS
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::meshReader::calcPointCells() const
{
const static label UNIT_POINT_CELLS = 12;
if (pointCellsPtr_)
{
FatalErrorIn("meshReader::calcPointCells() const")
<< "pointCells already calculated"
<< abort(FatalError);
}
label nPoints = points().size();
pointCellsPtr_ = new labelListList(nPoints);
labelListList& ptCells = *pointCellsPtr_;
forAll(ptCells, i)
{
ptCells[i].setSize(UNIT_POINT_CELLS);
}
// Initialize the list of labels which will hold the count of the
// actual number of cells per point during the analysis
labelList cellCount(nPoints, 0);
// Note. Unlike the standard point-cell algorithm, which asks the cell for
// the supporting point labels, we need to work based on the cell faces.
// This is because some of the faces do not come from the cell shape.
// It is also advantageous to remove duplicates from the point-cell
// addressing, because this removes a lot of waste later.
faceListList& cFaces = cellFaces();
// For each cell
forAll(cFaces, cellI)
{
const faceList& faces = cFaces[cellI];
forAll(faces, i)
{
// For each vertex
const labelList& labels = faces[i];
forAll(labels, j)
{
// Set working point label
label curPoint = labels[j];
labelList& curPointCells = ptCells[curPoint];
label curCount = cellCount[curPoint];
// check if the cell has been added before
bool found = false;
for (label f = 0; f < curCount; f++)
{
if (curPointCells[f] == cellI)
{
found = true;
break;
}
}
if (!found)
{
// If the list of pointCells is not big enough, double it
if (curPointCells.size() <= curCount)
{
curPointCells.setSize(curPointCells.size()*2);
}
// Enter the cell label in the point's cell list
curPointCells[curCount] = cellI;
// Increment the cell count for the point addressed
cellCount[curPoint]++;
}
}
}
}
// report and remove unused points
// - adjust points, pointCells, and cellFaces accordingly
label pointI = 0;
labelList oldToNew(nPoints, -1);
forAll(ptCells, i)
{
ptCells[i].setSize(cellCount[i]);
if (cellCount[i] > 0)
{
oldToNew[i] = pointI++;
}
}
// report unused points
if (nPoints > pointI)
{
#ifdef LEAVE_UNUSED_POINTS
FatalErrorIn("meshReader::calcPointCells() const")
<< "mesh has " << (nPoints - pointI)
<< " points that were declared but not used" << endl;
#else
Info<< "removing " << (nPoints - pointI) << " unused points" << endl;
nPoints = pointI;
// adjust points and truncate
inplaceReorder(oldToNew, points());
points().setSize(nPoints);
// adjust pointCells and truncate
inplaceReorder(oldToNew, ptCells);
ptCells.setSize(nPoints);
// adjust cellFaces - this could be faster
// For each cell
forAll(cFaces, cellI)
{
faceList& faces = cFaces[cellI];
// For each face
forAll(faces, i)
{
inplaceRenumber(oldToNew, faces[i]);
}
}
#endif
}
}
const Foam::labelListList& Foam::meshReader::pointCells() const
{
if (!pointCellsPtr_)
{
calcPointCells();
}
return *pointCellsPtr_;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,450 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
boundary faces
- use pointCells when searching for connectivity
- initialize the cell connectivity with '-1'
- find both cell faces corresponding to the baffles and mark them
to prevent a connection
- standard connectivity checks
- added baffle and monitoring support
\*---------------------------------------------------------------------------*/
#include "meshReader.H"
#include "Time.H"
#include "polyPatch.H"
#include "emptyPolyPatch.H"
#include "preservePatchTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// add in boundary face
void Foam::meshReader::addPolyBoundaryFace
(
const label cellId,
const label cellFaceId,
const label nCreatedFaces
)
{
#ifdef DEBUG_BOUNDARY
Info<< nCreatedFaces
<< " add bnd for cell " << cellId
<< " face " << cellFaceId
<< " (original cell " << origCellId_[cellId] << ")"
<< endl;
#endif
// standard case: volume cells
const face& thisFace = cellFaces_[cellId][cellFaceId];
// Debugging
if (cellPolys_[cellId][cellFaceId] > nInternalFaces_)
{
Info<< "meshReader::createPolyBoundary(): "
<< "Problem with face: " << thisFace << endl
<< "Probably multiple definitions "
<< "of a single boundary face." << endl
<< endl;
}
else if (cellPolys_[cellId][cellFaceId] >= 0)
{
Info<< "meshReader::createPolyBoundary(): "
<< "Problem with face: " << thisFace << endl
<< "Probably trying to define a boundary face "
<< "on a previously matched internal face." << endl
<< "Internal face: "
<< meshFaces_[cellPolys_[cellId][cellFaceId]]
<< endl;
}
meshFaces_[nCreatedFaces] = thisFace;
cellPolys_[cellId][cellFaceId] = nCreatedFaces;
}
// add in boundary face
void Foam::meshReader::addPolyBoundaryFace
(
const cellFaceIdentifier& identifier,
const label nCreatedFaces
)
{
addPolyBoundaryFace(identifier.cell, identifier.face, nCreatedFaces);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::meshReader::createPolyBoundary()
{
label nBoundaryFaces = 0;
label nMissingFaces = 0;
label nInterfaces = 0;
const faceListList& cFaces = cellFaces();
// determine number of non-patched faces:
forAll(cellPolys_, cellI)
{
cell& curCell = cellPolys_[cellI];
forAll(curCell, fI)
{
if (curCell[fI] < 0)
{
nMissingFaces++;
}
}
}
forAll(boundaryIds_, patchI)
{
nBoundaryFaces += boundaryIds_[patchI].size();
}
Info<< nl
<< "There are " << nMissingFaces
<< " faces to be patched and " << nBoundaryFaces
<< " specified - collect missed boundaries to final patch" << endl;
patchStarts_.setSize(boundaryIds_.size());
patchSizes_.setSize(boundaryIds_.size());
label nCreatedFaces = nInternalFaces_;
label baffleOffset = cFaces.size();
interfaces_.setSize(baffleIds_.size());
nBoundaryFaces = 0;
forAll(boundaryIds_, patchI)
{
const List<cellFaceIdentifier>& idList = boundaryIds_[patchI];
patchStarts_[patchI] = nCreatedFaces;
// write each baffle side separately
if (patchPhysicalTypes_[patchI] == "baffle")
{
label count = 0;
for (label side = 0; side < 2; ++side)
{
label position = nInterfaces;
forAll(idList, bndI)
{
label baffleI = idList[bndI].cell - baffleOffset;
if
(
baffleI >= 0
&& baffleI < baffleFaces_.size()
&& baffleIds_[baffleI].size()
)
{
addPolyBoundaryFace
(
baffleIds_[baffleI][side],
nCreatedFaces
);
// remove applied boundaries (2nd pass)
if (side == 1)
{
baffleIds_[baffleI].clear();
}
interfaces_[position][side] = nCreatedFaces;
nBoundaryFaces++;
nCreatedFaces++;
position++;
count++;
}
}
}
nInterfaces += (count - (count % 2)) / 2;
}
else if (patchPhysicalTypes_[patchI] == "monitoring")
{
// translate the "monitoring" pseudo-boundaries to face sets
List<label> monitoring(idList.size());
label monitorI = 0;
forAll(idList, bndI)
{
label cellId = idList[bndI].cell;
label faceId = idList[bndI].face;
// standard case: volume cells
if (cellId < baffleOffset)
{
label faceNr = cellPolys_[cellId][faceId];
if (faceNr >= 0)
{
monitoring[monitorI++] = faceNr;
}
}
}
monitoringSets_.insert(patchNames_[patchI], monitoring);
}
else
{
forAll(idList, bndI)
{
// standard case: volume cells
if (idList[bndI].cell < baffleOffset)
{
addPolyBoundaryFace
(
idList[bndI],
nCreatedFaces
);
nBoundaryFaces++;
nCreatedFaces++;
}
}
}
patchSizes_[patchI] = nCreatedFaces - patchStarts_[patchI];
}
// add in missing faces
Info<< "Missing faces added to patch after face "
<< nCreatedFaces << ":" <<endl;
nMissingFaces = 0;
// look for baffles first - keep them together at the start of the patch
for (label side = 0; side < 2; ++side)
{
label position = nInterfaces;
forAll(baffleIds_, baffleI)
{
if (baffleIds_[baffleI].size())
{
// add each side for each baffle
addPolyBoundaryFace
(
baffleIds_[baffleI][side],
nCreatedFaces
);
interfaces_[position][side] = nCreatedFaces;
// remove applied boundaries (2nd pass)
if (side == 1)
{
baffleIds_[baffleI].clear();
}
nMissingFaces++;
nCreatedFaces++;
position++;
}
}
}
nInterfaces += (nMissingFaces - (nMissingFaces % 2)) / 2;
// scan for any other missing faces
forAll(cellPolys_, cellI)
{
const labelList& curFaces = cellPolys_[cellI];
forAll(curFaces, cellFaceI)
{
if (curFaces[cellFaceI] < 0)
{
// just report the first few
if (nMissingFaces < 4)
{
const face& thisFace = cFaces[cellI][cellFaceI];
Info<< " cell " << cellI << " face " << cellFaceI
<< " (original cell " << origCellId_[cellI] << ")"
<< " face: " << thisFace
<< endl;
}
else if (nMissingFaces == 5)
{
Info<< " ..." << nl << endl;
}
addPolyBoundaryFace(cellI, cellFaceI, nCreatedFaces);
nMissingFaces++;
nCreatedFaces++;
}
}
}
Info<< "Added " << nMissingFaces << " unmatched faces" << endl;
if (nMissingFaces > 0)
{
patchSizes_[patchSizes_.size() - 1] = nMissingFaces;
}
else
{
patchStarts_.setSize(patchStarts_.size() - 1);
}
// reset the size of the face list
meshFaces_.setSize(nCreatedFaces);
// check the mesh for face mismatch
// (faces addressed once or more than twice)
labelList markupFaces(meshFaces_.size(), 0);
forAll(cellPolys_, cellI)
{
const labelList& curFaces = cellPolys_[cellI];
forAll(curFaces, faceI)
{
markupFaces[curFaces[faceI]]++;
}
}
for (label i = nInternalFaces_; i < markupFaces.size(); i++)
{
markupFaces[i]++;
}
label nProblemFaces = 0;
forAll(markupFaces, faceI)
{
if (markupFaces[faceI] != 2)
{
const face& problemFace = meshFaces_[faceI];
Info<< "meshReader::createPolyBoundary() : "
<< "problem with face " << faceI << ": addressed "
<< markupFaces[faceI] << " times (should be 2!). Face: "
<< problemFace << endl;
nProblemFaces++;
}
}
if (nProblemFaces > 0)
{
Info<< "Number of incorrectly matched faces: "
<< nProblemFaces << endl;
}
// adjust for missing members
if (nInterfaces < interfaces_.size())
{
interfaces_.setSize(nInterfaces);
}
Info<< "Number of boundary faces: " << nBoundaryFaces << nl
<< "Total number of faces: " << nCreatedFaces << nl
<< "Number of interfaces: " << nInterfaces << endl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::List<Foam::polyPatch*>
Foam::meshReader::polyBoundaryPatches(const polyMesh& mesh)
{
label nUsed = 0, nEmpty = 0;
label nPatches = patchStarts_.size();
// avoid empty patches - move to the end of the lists and truncate
labelList oldToNew = identity(nPatches);
forAll(patchSizes_, patchI)
{
if (patchSizes_[patchI] > 0)
{
oldToNew[patchI] = nUsed++;
}
else
{
nEmpty++;
oldToNew[patchI] = nPatches - nEmpty;
}
}
nPatches = nUsed;
if (nEmpty)
{
Info<< "Removing " << nEmpty << " empty patches" << endl;
inplaceReorder(oldToNew, patchTypes_);
inplaceReorder(oldToNew, patchNames_);
inplaceReorder(oldToNew, patchStarts_);
inplaceReorder(oldToNew, patchSizes_);
}
patchTypes_.setSize(nPatches);
patchNames_.setSize(nPatches);
patchStarts_.setSize(nPatches);
patchSizes_.setSize(nPatches);
List<polyPatch*> p(nPatches);
// Default boundary patch types
word defaultFacesType(emptyPolyPatch::typeName);
// we could consider dropping this entirely
preservePatchTypes
(
mesh,
mesh.instance(),
mesh.meshDir(),
patchNames_,
patchTypes_,
"defaultFaces",
defaultFacesType,
patchPhysicalTypes_
);
forAll(patchStarts_, patchI)
{
p[patchI] = polyPatch::New
(
patchTypes_[patchI],
patchNames_[patchI],
patchSizes_[patchI],
patchStarts_[patchI],
patchI,
mesh.boundaryMesh()
).ptr();
}
return p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,330 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
create cellPolys
- use pointCells when searching for connectivity
- initialize the cell connectivity with '-1'
- find both cell faces corresponding to the baffles and mark them
to prevent a connection
- standard connectivity checks
- added baffle support
\*---------------------------------------------------------------------------*/
#include "meshReader.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::meshReader::createPolyCells()
{
// loop through all cell faces and create connectivity. This will produce
// a global face list and will describe all cells as lists of face labels
const faceListList& cFaces = cellFaces();
// count the maximum number of faces and set the size of the cellPolys_
cellPolys_.setSize(cFaces.size());
label maxFaces = 0;
forAll(cellPolys_, cellI)
{
cellPolys_[cellI].setSize(cFaces[cellI].size(), -1);
maxFaces += cFaces[cellI].size();
}
Info<< "Maximum possible number of faces in mesh: " << maxFaces << endl;
meshFaces_.setSize(maxFaces);
// set reference to point-cell addressing
const labelListList& ptCells = pointCells();
// size the baffle lists and initialize to -1
baffleIds_.setSize(baffleFaces_.size());
forAll(baffleIds_, baffleI)
{
baffleIds_[baffleI].setSize(2);
}
// block off baffles first
//
// To prevent internal faces, we'll mark the cell faces
// with negative cell ids (offset by nCells).
// eg,
// cellI = -(nCells + baffleI)
//
// To distinguish these from the normal '-1' marker, we require
// cellI = -(nCells + baffleI) < -1
//
// This condition is met provided that nCells > 1.
// ie., baffles require at least 2 volume cells
label baffleOffset = cFaces.size();
forAll(baffleFaces_, baffleI)
{
label cellI = -(baffleOffset + baffleI);
const face& curFace = baffleFaces_[baffleI];
// get the list of labels
const labelList& curPoints = curFace;
// a baffle is a single face - only need to match one face
// get the list of cells sharing this point
const labelList& curNeighbours = ptCells[curPoints[0]];
label nNeighbours = 0;
// For all neighbours
forAll(curNeighbours, neiI)
{
label curNei = curNeighbours[neiI];
// get the list of search faces
const faceList& searchFaces = cFaces[curNei];
forAll(searchFaces, neiFaceI)
{
int cmp = face::compare(curFace, searchFaces[neiFaceI]);
if (cmp)
{
// maintain baffle orientation
// side0: baffle normal same as attached face
// side1: baffle normal opposite from attached face
//
label side = 0;
if (cmp < 0)
{
side = 1;
}
#ifdef DEBUG_FACE_ORDERING
Info<< "cmp " << cmp << " matched " << curFace
<< " with " << searchFaces[neiFaceI]
<< endl;
Info<< "match " << baffleI
<< " (" << origCellId_[baffleOffset+baffleI] << ")"
<< " side " << side
<< " against cell " << curNei
<< " face " << neiFaceI
<< " curFace " << curFace[1]
<< " neiFace " << searchFaces[neiFaceI][1]
<< endl;
#endif
if (baffleIds_[baffleI][side].unused())
{
baffleIds_[baffleI][side] = cellFaceIdentifier
(
curNei,
neiFaceI
);
nNeighbours++;
}
else
{
Info<< "multiple matches for side " << side
<< " of baffle " << baffleI
<< " (original cell "
<< origCellId_[baffleOffset+baffleI] << ")"
<< endl;
}
break;
}
}
if (nNeighbours >= 2) break;
}
if (nNeighbours == 2)
{
for (label side = 0; side < nNeighbours; ++side)
{
label neiCell = baffleIds_[baffleI][side].cell;
label neiFace = baffleIds_[baffleI][side].face;
if (baffleIds_[baffleI][side].used())
{
cellPolys_[neiCell][neiFace] = cellI;
}
}
}
else
{
Info<< "drop baffle " << baffleI
<< " (original cell "
<< origCellId_[baffleOffset+baffleI] << ")"
<< " with " << nNeighbours << " neighbours" << endl;
baffleFaces_[baffleI].clear();
baffleIds_[baffleI].clear();
}
}
#ifdef DEBUG_CELLPOLY
Info<< "cellPolys_" << cellPolys_ << endl;
Info<< "baffleFaces_" << baffleFaces_ << endl;
Info<< "baffleIds_" << baffleIds_ << endl;
#endif
bool found = false;
nInternalFaces_ = 0;
forAll(cFaces, cellI)
{
// Note:
// Insertion cannot be done in one go as the faces need to be
// added into the list in the increasing order of neighbour
// cells. Therefore, all neighbours will be detected first
// and then added in the correct order.
const faceList& curFaces = cFaces[cellI];
// Record the neighbour cell
labelList neiCells(curFaces.size(), -1);
// Record the face of neighbour cell
labelList faceOfNeiCell(curFaces.size(), -1);
label nNeighbours = 0;
// For all faces ...
forAll(curFaces, faceI)
{
// Skip already matched faces or those tagged by baffles
if (cellPolys_[cellI][faceI] != -1) continue;
found = false;
const face& curFace = curFaces[faceI];
// get the list of labels
const labelList& curPoints = curFace;
// For all points
forAll(curPoints, pointI)
{
// get the list of cells sharing this point
const labelList& curNeighbours = ptCells[curPoints[pointI]];
// For all neighbours
forAll(curNeighbours, neiI)
{
label curNei = curNeighbours[neiI];
// reject neighbours with the lower label. This should
// also reject current cell.
if (curNei > cellI)
{
// get the list of search faces
const faceList& searchFaces = cFaces[curNei];
forAll(searchFaces, neiFaceI)
{
if (searchFaces[neiFaceI] == curFace)
{
// Record the neighbour cell and face
neiCells[faceI] = curNei;
faceOfNeiCell[faceI] = neiFaceI;
nNeighbours++;
#ifdef DEBUG_FACE_ORDERING
Info<< " cell " << cellI
<< " face " << faceI
<< " point " << pointI
<< " nei " << curNei
<< " neiFace " << neiFaceI
<< endl;
#endif
found = true;
break;
}
}
if (found) break;
}
if (found) break;
}
if (found) break;
} // End of current points
} // End of current faces
// Add the faces in the increasing order of neighbours
for (label neiSearch = 0; neiSearch < nNeighbours; neiSearch++)
{
// Find the lowest neighbour which is still valid
label nextNei = -1;
label minNei = cellPolys_.size();
forAll(neiCells, ncI)
{
if (neiCells[ncI] > -1 && neiCells[ncI] < minNei)
{
nextNei = ncI;
minNei = neiCells[ncI];
}
}
if (nextNei > -1)
{
// Add the face to the list of faces
meshFaces_[nInternalFaces_] = curFaces[nextNei];
// Mark for owner
cellPolys_[cellI][nextNei] = nInternalFaces_;
// Mark for neighbour
cellPolys_[neiCells[nextNei]][faceOfNeiCell[nextNei]] =
nInternalFaces_;
// Stop the neighbour from being used again
neiCells[nextNei] = -1;
// Increment number of faces counter
nInternalFaces_++;
}
else
{
FatalErrorIn("meshReader::createPolyCells()")
<< "Error in internal face insertion"
<< abort(FatalError);
}
}
}
#ifdef DEBUG_CELLPOLY
Info<< "cellPolys = " << cellPolys_ << endl;
#endif
// don't reset the size of internal faces, because more faces will be
// added in createPolyBoundary()
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,254 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "meshReader.H"
#include "Time.H"
#include "polyMesh.H"
#include "faceSet.H"
#include "emptyPolyPatch.H"
#include "cellModeller.H"
#include "demandDrivenData.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Pointers to cell shape models
const Foam::cellModel* Foam::meshReader::unknownModel = Foam::cellModeller::
lookup
(
"unknown"
);
const Foam::cellModel* Foam::meshReader::tetModel = Foam::cellModeller::
lookup
(
"tet"
);
const Foam::cellModel* Foam::meshReader::pyrModel = Foam::cellModeller::
lookup
(
"pyr"
);
const Foam::cellModel* Foam::meshReader::prismModel = Foam::cellModeller::
lookup
(
"prism"
);
const Foam::cellModel* Foam::meshReader::hexModel = Foam::cellModeller::
lookup
(
"hex"
);
// * * * * * * * * * * * * * * Static Functions * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// attach cellZones based on the cellTable Id
// - any other values can be extracted later from the cellTable dictionary
void Foam::meshReader::addCellZones
(
polyMesh& mesh
) const
{
cellTable_.addCellZones(mesh, cellTableId_);
warnDuplicates("cellZones", mesh.cellZones().names());
}
// attach faceZones based on the monitoring boundary conditions
void Foam::meshReader::addFaceZones
(
polyMesh& mesh
) const
{
label nZone = monitoringSets_.size();
mesh.faceZones().setSize(nZone);
if (!nZone)
{
return;
}
nZone = 0;
for
(
HashTable<List<label>, word, string::hash>::const_iterator
iter = monitoringSets_.begin();
iter != monitoringSets_.end();
++iter
)
{
Info<< "faceZone " << nZone
<< " (size: " << iter().size() << ") name: "
<< iter.key() << endl;
mesh.faceZones().set
(
nZone,
new faceZone
(
iter.key(),
iter(),
List<bool>(iter().size(), false),
nZone,
mesh.faceZones()
)
);
nZone++;
}
mesh.faceZones().writeOpt() = IOobject::AUTO_WRITE;
warnDuplicates("faceZones", mesh.faceZones().names());
}
// create and access the polyMesh
Foam::autoPtr<Foam::polyMesh> Foam::meshReader::mesh
(
const objectRegistry& registry
)
{
readGeometry();
Info<< "Creating a polyMesh" << endl;
createPolyCells();
Info<< "Number of internal faces: " << nInternalFaces_ << endl;
createPolyBoundary();
clearExtraStorage();
autoPtr<polyMesh> mesh
(
new polyMesh
(
IOobject
(
polyMesh::defaultRegion,
"constant",
registry
),
points(),
meshFaces_,
cellPolys_
)
);
// adding patches also checks the mesh
mesh().addPatches(polyBoundaryPatches(mesh));
warnDuplicates("boundaries", mesh().boundaryMesh().names());
addCellZones(mesh());
addFaceZones(mesh());
return mesh;
}
//- write the polyMesh
void Foam::meshReader::writeMesh
(
const polyMesh& mesh,
IOstream::streamFormat fmt
) const
{
fileName meshDir = mesh.objectRegistry::path()/mesh.meshDir();
// remove some directories and files - this should be easier
mesh.removeFiles(mesh.instance());
if (dir(meshDir/"sets"))
{
rmDir(meshDir/"sets");
}
Info<< "Writing polyMesh" << endl;
mesh.writeObject
(
fmt,
IOstream::currentVersion,
IOstream::UNCOMPRESSED
);
writeAux(mesh);
}
// Clear extra storage before creation of the mesh to reduce the memory usage
void Foam::meshReader::clearExtraStorage()
{
cellFaces_.clear();
baffleFaces_.clear();
boundaryIds_.clear();
baffleIds_.clear();
deleteDemandDrivenData(pointCellsPtr_);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::meshReader::meshReader
(
const fileName& fileOrPrefix,
const scalar scaleFactor
)
:
pointCellsPtr_(NULL),
nInternalFaces_(0),
patchStarts_(0),
patchSizes_(0),
interfaces_(0),
baffleIds_(0),
meshFaces_(0),
cellPolys_(0),
geometryFile_(fileOrPrefix),
scaleFactor_(scaleFactor),
points_(0),
origCellId_(0),
boundaryIds_(0),
patchTypes_(0),
patchNames_(0),
patchPhysicalTypes_(0),
cellFaces_(0),
baffleFaces_(0),
cellTableId_(0),
cellTable_()
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::meshReader::~meshReader()
{
deleteDemandDrivenData(pointCellsPtr_);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,319 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Namespace
Foam::meshReaders
Description
A namespace for holding various types of mesh readers.
Class
Foam::meshReader
Description
This class supports creating polyMeshes with baffles.
The derived classes are responsible for providing the protected data.
This implementation is somewhat messy, but could/should be restructured
to provide a more generalized reader (at the moment it has been written
for converting pro-STAR data).
The meshReader supports cellTable information (see new user's guide entry).
Note
The boundary definitions are given as cell/face.
SourceFiles
calcPointCells.C
createPolyBoundary.C
createPolyCells.C
meshReader.C
meshReaderAux.C
\*---------------------------------------------------------------------------*/
#ifndef meshReader_H
#define meshReader_H
#include "polyMesh.H"
#include "HashTable.H"
#include "IOstream.H"
#include "cellTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class meshReader Declaration
\*---------------------------------------------------------------------------*/
class meshReader
{
protected:
//- identify cell faces in terms of cell Id and face Id
class cellFaceIdentifier
{
public:
//- cell Id
label cell;
//- face Id
label face;
//- Construct null
cellFaceIdentifier() : cell(-1), face(-1) {}
//- Construct from cell/face components
cellFaceIdentifier(label c, label f) : cell(c), face(f) {}
// Check
//- used if cell or face are non-negative
bool used() const
{
return (cell >= 0 && face >= 0);
}
//- unsed if cell or face are negative
bool unused() const
{
return (cell < 0 || face < 0);
}
// Member Operators
bool operator!=(const cellFaceIdentifier& cf) const
{
return (cell != cf.cell || face != cf.face);
}
bool operator==(const cellFaceIdentifier& cf) const
{
return (cell == cf.cell && face == cf.face);
}
// IOstream Operators
friend Ostream& operator<<(Ostream& os, const cellFaceIdentifier& cf)
{
os << "(" << cf.cell << "/" << cf.face << ")";
return os;
}
};
private:
// Private data
//- Point-cell addressing. Used for topological analysis
// Warning. This point cell addressing list potentially contains
// duplicate cell entries. Use additional checking
mutable labelListList* pointCellsPtr_;
//- Number of internal faces for polyMesh
label nInternalFaces_;
//- Polyhedral mesh boundary patch start indices and dimensions
labelList patchStarts_;
labelList patchSizes_;
//- association between two faces
List<labelPair> interfaces_;
//- list of cells/faces id pairs for each baffle
List<List<cellFaceIdentifier> > baffleIds_;
//- Global face list for polyMesh
faceList meshFaces_;
//- Cells as polyhedra for polyMesh
cellList cellPolys_;
//- Face sets for monitoring
HashTable<List<label>, word, string::hash> monitoringSets_;
// Private Member Functions
//- Disallow default bitwise copy construct
meshReader(const meshReader&);
//- Disallow default bitwise assignment
void operator=(const meshReader&);
//- Calculate pointCells
void calcPointCells() const;
const labelListList& pointCells() const;
//- Make polyhedral cells and global faces if the mesh is polyhedral
void createPolyCells();
//- add in boundary face
void addPolyBoundaryFace
(
const label cellId,
const label cellFaceId,
const label nCreatedFaces
);
//- add in boundary face
void addPolyBoundaryFace
(
const cellFaceIdentifier& identifier,
const label nCreatedFaces
);
//- add cellZones based on cellTable Id
void addCellZones(polyMesh&) const;
//- add faceZones based on monitoring boundary conditions
void addFaceZones(polyMesh&) const;
//- Make polyhedral boundary from shape boundary
// (adds more faces to the face list)
void createPolyBoundary();
//- Add polyhedral boundary
List<polyPatch*> polyBoundaryPatches(const polyMesh&);
//- Clear extra storage before creation of the mesh to remove
// a memory peak
void clearExtraStorage();
void writeInterfaces(const objectRegistry&) const;
// write List<label> in constant/polyMesh
void writeMeshLabelList
(
const objectRegistry& registry,
const word& propertyName,
const labelList& list,
IOstream::streamFormat fmt = IOstream::ASCII
) const;
//- Return list of faces for every cell
faceListList& cellFaces() const
{
return const_cast<faceListList&>(cellFaces_);
}
protected:
// Protected data
//- Pointers to cell shape models
static const cellModel* unknownModel;
static const cellModel* tetModel;
static const cellModel* pyrModel;
static const cellModel* prismModel;
static const cellModel* hexModel;
//- referenced filename
fileName geometryFile_;
//- geometry scaling
scalar scaleFactor_;
//- Points supporting the mesh
pointField points_;
//- lookup original Cell number for a given cell
labelList origCellId_;
//- identify boundary faces by cells and their faces
// for each patch
List<List<cellFaceIdentifier> > boundaryIds_;
//- Boundary patch types
wordList patchTypes_;
//- Boundary patch names
wordList patchNames_;
//- Boundary patch physical types
wordList patchPhysicalTypes_;
//- List of faces for every cell
faceListList cellFaces_;
//- List of each baffle face
faceList baffleFaces_;
// cell table id for each cell
labelList cellTableId_;
// cell table persistent data saved as a dictionary
cellTable cellTable_;
// Member Functions
//- subclasses are required to supply this information
virtual bool readGeometry
(
const scalar scaleFactor = 1.0
) = 0;
//- Return mesh points
pointField& points() const
{
return const_cast<pointField&>(points_);
}
public:
// Static Members
//- warn about repeated names
static void warnDuplicates(const word& context, const wordList&);
// Constructors
//- Construct from fileName
meshReader(const fileName&, const scalar scaleFactor = 1.0);
// Destructor
virtual ~meshReader();
// Member Functions
//- create and return polyMesh
virtual autoPtr<polyMesh> mesh(const objectRegistry&);
//- Write auxiliary information
void writeAux(const objectRegistry&) const;
//- Write mesh
void writeMesh
(
const polyMesh&,
IOstream::streamFormat fmt = IOstream::BINARY
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
#endif
// ************************************************************************* //

View File

@ -0,0 +1,188 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*----------------------------------------------------------------------------*/
#include "meshReader.H"
#include "IOMap.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Static Functions * * * * * * * * * * * * * //
// warn about duplicate names
void Foam::meshReader::warnDuplicates
(
const word& context,
const wordList& list
)
{
HashTable<label> hashed(list.size());
bool duplicates = false;
forAll(list, listI)
{
// check duplicate name
HashTable<label>::iterator iter = hashed.find(list[listI]);
if (iter != hashed.end())
{
(*iter)++;
duplicates = true;
}
else
{
hashed.insert(list[listI], 1);
}
}
// warn about duplicate names
if (duplicates)
{
Info << nl << "WARNING: " << context << " with identical names:";
forAllConstIter(HashTable<label>, hashed, iter)
{
if (*iter > 1)
{
Info << " " << iter.key();
}
}
Info << nl << endl;
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// write interface (baffle) mapping
void Foam::meshReader::writeInterfaces(const objectRegistry& registry) const
{
// write constant/polyMesh/interface
IOList<labelList> ioObj
(
IOobject
(
"interfaces",
"constant",
polyMesh::meshSubDir,
registry,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
)
);
ioObj.note() = "as yet unsupported interfaces (baffles)";
Info<< "Writing " << ioObj.name() << " to " << ioObj.objectPath() << endl;
OFstream os(ioObj.objectPath());
ioObj.writeHeader(os);
os << interfaces_
<< "// ************************************************************************* //"
<< endl;
}
// write List<label> in constant/polyMesh
// this is crucial for later conversion back to ccm/starcd
void Foam::meshReader::writeMeshLabelList
(
const objectRegistry& registry,
const word& propertyName,
const labelList& list,
IOstream::streamFormat fmt
) const
{
// write constant/polyMesh/propertyName
IOList<label> ioObj
(
IOobject
(
propertyName,
"constant",
polyMesh::meshSubDir,
registry,
IOobject::NO_READ,
IOobject::AUTO_WRITE,
false
),
list
);
ioObj.note() = "persistent data for star-cd <-> foam translation";
Info<< "Writing " << ioObj.name() << " to " << ioObj.objectPath() << endl;
// NOTE:
// the cellTableId is an integer and almost always < 1000, thus ASCII
// will be compacter than binary and makes external scripting easier
//
ioObj.writeObject
(
fmt,
IOstream::currentVersion,
IOstream::UNCOMPRESSED
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::meshReader::writeAux(const objectRegistry& registry) const
{
cellTable_.writeDict(registry);
writeInterfaces(registry);
// write origCellId as List<label>
writeMeshLabelList
(
registry,
"origCellId",
origCellId_,
IOstream::BINARY
);
// write cellTableId as List<label>
// this is crucial for later conversion back to ccm/starcd
writeMeshLabelList
(
registry,
"cellTableId",
cellTableId_,
IOstream::ASCII
);
}
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,176 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::meshReaders::STARCD
Description
Read pro-STAR vrt/cel/bnd files.
The protected data in meshReader are filled.
Starting with pro-STAR version 4, the files have become easier to read.
- vertices are space-delimited.
- the cell format is logical.
- trimmed and degenerate cells are saved as polyhedral.
- the boundaries corresponds to cells and their faces.
SourceFiles
STARCDMeshReader.C
\*---------------------------------------------------------------------------*/
#ifndef STARCDMeshReader_H
#define STARCDMeshReader_H
# include "meshReader.H"
# include "boundaryRegion.H"
# include "cellShape.H"
# include "IFstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace meshReaders
{
/*---------------------------------------------------------------------------*\
Class meshReaders::STARCD Declaration
\*---------------------------------------------------------------------------*/
class STARCD
:
public meshReader
{
protected:
// Private Data
static const char* defaultBoundaryName;
static const char* defaultSolidBoundaryName;
//- Face addressing from pro-STAR faces -> OpenFOAM faces
static const int starToFoamFaceAddr[4][6];
//- Cell shapes
cellShapeList cellShapes_;
//- Point labels (imported Point numbering not necessarily contiguous)
labelList mapToFoamPointId_;
//- Cell labels (imported Cell numbering not necessarily contiguous)
labelList mapToFoamCellId_;
//- boundary region data
boundaryRegion boundaryRegion_;
// Private Member Functions
//- Disallow default bitwise copy construct
STARCD(const STARCD&);
//- Disallow default bitwise assignment
void operator=(const STARCD&);
//- Read the mesh from the file(s)
virtual bool readGeometry(const scalar scaleFactor = 1.0);
//- read points from file
void readPoints(const fileName&, const scalar scaleFactor);
//- read cell connectivities from file
virtual void readCells(const fileName&);
//- remove unused points
void cullPoints();
//- read boundary (cell/face) definitions
void readBoundary(const fileName&);
//- read auxiliary data from constant/{boundaryRegion,cellTable}
void readAux(const objectRegistry&);
//- read and discard to newline
static void readToNewline(IFstream&);
//- read header
static bool readHeader(IFstream&, word fileSignature);
protected:
enum cellType
{
starcdFluidType = 1,
starcdSolidType = 2,
starcdBaffleType = 3,
starcdShellType = 4,
starcdLineType = 5,
starcdPointType = 6
};
enum shapeType
{
starcdPoint = 1,
starcdLine = 2,
starcdShell = 3,
starcdHex = 11,
starcdPrism = 12,
starcdTet = 13,
starcdPyr = 14,
starcdPoly = 255
};
public:
//- keep solids (default false)
static bool keepSolids;
// Constructors
//- Construct from case name
STARCD
(
const fileName& prefix,
const objectRegistry&,
const scalar scaleFactor = 1.0
);
// Destructor
virtual ~STARCD();
// Member Functions
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace meshReaders
} // End namespace Foam
#endif
// ************************************************************************* //

View File

@ -0,0 +1,25 @@
Star-CD uses a so-called 'cell table' to organize properties. The ccm and
star4 converters preserve this information as a Map of dictionaries under
"constant/cellTable" and as cell data under "constant/polyMesh/cellTableId".
The combination of both files allows subsequent creating of cellSets and
cellZones for any combination of properties (eg, porosities and solids).
Additionally, the reverse converters can use this information when
converting foam meshes back to the Star-CD formats.
The names of the dictionary elements (eg, Label, MaterialType, etc) are
chosen to match those used by the ccm-format.
Here is a sample dictionary entry:
<int> // unique positive int
{
Label <word>; // optional
MaterialType <word>; // optional (fluid|solid)
MaterialId <int>; // optional
PorosityId <int>; // optional
GroupId <int>; // optional
SpinId <int>; // optional
}

View File

@ -0,0 +1,268 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "boundaryRegion.H"
#include "IOMap.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::boundaryRegion::boundaryRegion()
:
Map<dictionary>()
{}
// read constant/boundaryRegion (IOMap<dictionary>)
Foam::boundaryRegion::boundaryRegion
(
const objectRegistry& registry,
const word& name,
const fileName& instance
)
:
Map<dictionary>()
{
readDict(registry, name, instance);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::boundaryRegion::~boundaryRegion()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::label Foam::boundaryRegion::append(const dictionary& dict)
{
label maxId = -1;
forAllConstIter(Map<dictionary>, *this, iter)
{
if (maxId < iter.key())
{
maxId = iter.key();
}
}
insert(++maxId, dict);
return maxId;
}
Foam::Map<Foam::word>
Foam::boundaryRegion::names() const
{
Map<word> lookup;
forAllConstIter(Map<dictionary>, *this, iter)
{
word value = "boundaryRegion_" + Foam::name(iter.key());
iter().readIfPresent("Label", value);
lookup.insert(iter.key(), value);
}
return lookup;
}
Foam::Map<Foam::word>
Foam::boundaryRegion::boundaryTypes() const
{
Map<word> lookup;
forAllConstIter(Map<dictionary>, *this, iter)
{
word value = "patch";
iter().readIfPresent("BoundaryType", value);
lookup.insert(iter.key(), value);
}
return lookup;
}
Foam::label Foam::boundaryRegion::findIndex(const word& name) const
{
forAllConstIter(Map<dictionary>, *this, iter)
{
word theName;
if (iter().readIfPresent("Label", theName))
{
if (theName == name)
{
return iter.key();
}
}
}
return -1;
}
Foam::word Foam::boundaryRegion::boundaryType(const word& name) const
{
word bndType = "patch";
label id = this->findIndex(name);
if (id >= 0)
{
const dictionary& dict = operator[](id);
dict.readIfPresent("BoundaryType", bndType);
}
return bndType;
}
// read constant/boundaryRegion (IOMap<dictionary>)
void Foam::boundaryRegion::readDict
(
const objectRegistry& registry,
const word& name,
const fileName& instance
)
{
clear();
// read constant/dictName
IOMap<dictionary> ioObj
(
IOobject
(
name,
instance,
registry,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE,
false
)
);
if (ioObj.headerOk())
{
*this = ioObj;
}
else
{
Info<< "no constant/boundaryRegion information available" << endl;
}
}
// write constant/boundaryRegion for later reuse
void Foam::boundaryRegion::writeDict
(
const objectRegistry& registry,
const word& name,
const fileName& instance
) const
{
// write constant/dictName
IOMap<dictionary> ioObj
(
IOobject
(
name,
instance,
registry,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
)
);
ioObj.note() = "persistent data for thirdParty mesh <-> OpenFOAM translation";
Info<< "Writing " << ioObj.name() << " to " << ioObj.objectPath() << endl;
OFstream os(ioObj.objectPath());
ioObj.writeHeader(os);
os << *this;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::boundaryRegion::operator=(const boundaryRegion& rhs)
{
Map<dictionary>::operator=(rhs);
}
void Foam::boundaryRegion::operator=(const Map<dictionary>& rhs)
{
Map<dictionary>::operator=(rhs);
}
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
void Foam::boundaryRegion::rename(const dictionary& dict)
{
if (!dict.size())
{
return;
}
Map<word> mapping;
forAllConstIter(dictionary, dict, iter)
{
word oldName(iter().stream());
label id = this->findIndex(oldName);
if (id >= 0)
{
mapping.insert(id, iter().keyword());
}
}
if (mapping.size())
{
forAllConstIter(Map<word>, mapping, iter)
{
label id = iter.key();
word oldName(operator[](id).lookup("Label"));
word newName(iter());
dictionary newDict(operator[](id));
newDict.remove("Label");
newDict.add("Label", newName);
this->set(id, newDict);
Info<< "rename patch: " << newName << " <- " << oldName << endl;
}
}
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,165 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::boundaryRegion
Description
The boundaryRegion persistent data saved as a Map<dictionary>.
The meshReader supports boundaryRegion information.
The <tt>constant/boundaryRegion</tt> file is an @c IOMap<dictionary>
that is used to save the information persistently.
It contains the boundaryRegion information of the following form:
@verbatim
(
INT
{
BoundaryType WORD;
Label WORD;
}
...
)
@endverbatim
SourceFiles
boundaryRegion.C
\*---------------------------------------------------------------------------*/
#ifndef boundaryRegion_H
#define boundaryRegion_H
#include "polyMesh.H"
#include "Map.H"
#include "dictionary.H"
#include "labelList.H"
#include "wordList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class boundaryRegion Declaration
\*---------------------------------------------------------------------------*/
class boundaryRegion
:
public Map<dictionary>
{
// Private data
// Private Member Functions
//- Disallow default bitwise copy construct
boundaryRegion(const boundaryRegion&);
public:
// Static Members
// Constructors
//- Construct null
boundaryRegion();
//- Construct read from registry, name. instance
boundaryRegion
(
const objectRegistry&,
const word& name = "boundaryRegion",
const fileName& instance = "constant"
);
// Destructor
~boundaryRegion();
// Member Functions
//- Append to the end, return index
label append(const dictionary&);
//- Return index corresponding to patch 'name'
// returns -1 if not found
label findIndex(const word& name) const;
//- Return a Map of (id => name)
Map<word> names() const;
//- Return a Map of (id => type)
Map<word> boundaryTypes() const;
//- Return BoundaryType corresponding to patch 'name'
word boundaryType(const word& name) const;
//- Read constant/boundaryRegion
void readDict
(
const objectRegistry&,
const word& name = "boundaryRegion",
const fileName& instance = "constant"
);
//- Write constant/boundaryRegion for later reuse
void writeDict
(
const objectRegistry&,
const word& name = "boundaryRegion",
const fileName& instance = "constant"
) const;
// Member Operators
//- Assignment
void operator=(const boundaryRegion&);
//- Assign from Map<dictionary>
void operator=(const Map<dictionary>&);
// Friend Functions
//- Rename regions
// each dictionary entry is a single word:
// @verbatim
// newPatchName originalName;
// @endverbatim
void rename(const dictionary&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
#endif
// ************************************************************************* //

View File

@ -0,0 +1,587 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
\*---------------------------------------------------------------------------*/
#include "cellTable.H"
#include "IOMap.H"
#include "OFstream.H"
#include "wordList.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const char* const Foam::cellTable::defaultMaterial_ = "fluid";
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
//- map from cellTable Id -> zone number (unmapped = -1)
Foam::labelList Foam::cellTable::zoneMap() const
{
label maxId = 0;
forAllConstIter(Map<dictionary>, *this, iter)
{
if (maxId < iter.key())
{
maxId = iter.key();
}
}
label zoneI = 0;
labelList list(maxId+1, -1);
forAllConstIter(Map<dictionary>, *this, iter)
{
list[iter.key()] = zoneI++;
}
return list;
}
Foam::wordList Foam::cellTable::namesList() const
{
Map<word> lookup = names();
wordList lst(lookup.size());
label n = 0;
forAllConstIter(Map<word>, lookup, iter)
{
lst[n] = iter();
}
lst.setSize(n);
return lst;
}
// add required entries - MaterialType
void Foam::cellTable::addDefaults()
{
forAllIter(Map<dictionary>, *this, iter)
{
if (!iter().found("MaterialType"))
{
iter().add("MaterialType", defaultMaterial_);
}
}
}
void Foam::cellTable::setEntry
(
const label& id,
const word& keyWord,
const word& value
)
{
dictionary dict;
dict.add(keyWord, value);
iterator iter = find(id);
if (iter != end())
{
iter().merge(dict);
}
else
{
insert(id, dict);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cellTable::cellTable()
:
Map<dictionary>()
{}
// read constant/cellTable (IOMap<dictionary>)
Foam::cellTable::cellTable
(
const objectRegistry& registry,
const word& name,
const fileName& instance
)
:
Map<dictionary>()
{
readDict(registry, name, instance);
}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cellTable::~cellTable()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::label Foam::cellTable::append(const dictionary& dict)
{
label maxId = -1;
forAllConstIter(Map<dictionary>, *this, iter)
{
if (maxId < iter.key())
{
maxId = iter.key();
}
}
insert(++maxId, dict);
return maxId;
}
Foam::Map<Foam::word>
Foam::cellTable::names() const
{
Map<word> lookup;
forAllConstIter(Map<dictionary>, *this, iter)
{
word theName = "cellTable_" + Foam::name(iter.key());
iter().readIfPresent("Label", theName);
lookup.insert(iter.key(), theName);
}
return lookup;
}
Foam::word Foam::cellTable::name(const label& id) const
{
const_iterator iter = find(id);
word theName = "cellTable_" + Foam::name(id);
if (iter != end())
{
iter().readIfPresent("Label", theName);
}
return theName;
}
Foam::label Foam::cellTable::findIndex(const word& name) const
{
forAllConstIter(Map<dictionary>, *this, iter)
{
word theName;
if (iter().readIfPresent("Label", theName))
{
if (theName == name)
{
return iter.key();
}
}
}
return -1;
}
Foam::Map<Foam::word>
Foam::cellTable::selectType(const word& materialType) const
{
Map<word> lookup;
forAllConstIter(Map<dictionary>, *this, iter)
{
word matl(defaultMaterial_);
iter().readIfPresent("MaterialType", matl);
if (matl == materialType)
{
word theName = "cellTable_" + Foam::name(iter.key());
iter().readIfPresent("Label", theName);
lookup.insert(iter.key(), theName);
}
}
return lookup;
}
Foam::Map<Foam::word>
Foam::cellTable::fluids() const
{
return selectType("fluid");
}
Foam::Map<Foam::word>
Foam::cellTable::solids() const
{
return selectType("solid");
}
Foam::Map<Foam::word>
Foam::cellTable::shells() const
{
return selectType("shell");
}
Foam::Map<Foam::word>
Foam::cellTable::materialTypes() const
{
Map<word> lookup;
forAllConstIter(Map<dictionary>, *this, iter)
{
word matlType(defaultMaterial_);
iter().readIfPresent("MaterialType", matlType);
lookup.insert(iter.key(), matlType);
}
return lookup;
}
//- assign material Type
void Foam::cellTable::setMaterial(const label& id, const word& matlType)
{
setEntry(id, "MaterialType", matlType);
}
void Foam::cellTable::setName(const label& id, const word& name)
{
setEntry(id, "Label", name);
}
void Foam::cellTable::setName(const label& id)
{
iterator iter = find(id);
if (iter == end() || !iter().found("Label"))
{
setName(id, "cellTable_" + ::Foam::name(id));
}
}
// read constant/cellTable (IOMap<dictionary>)
void Foam::cellTable::readDict
(
const objectRegistry& registry,
const word& name,
const fileName& instance
)
{
clear();
// read constant/dictName
IOMap<dictionary> ioObj
(
IOobject
(
name,
instance,
registry,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE,
false
)
);
if (ioObj.headerOk())
{
*this = ioObj;
addDefaults();
}
else
{
Info<< "no constant/cellTable information available" << endl;
}
}
// write constant/cellTable for later reuse
void Foam::cellTable::writeDict
(
const objectRegistry& registry,
const word& name,
const fileName& instance
) const
{
// write constant/dictName
IOMap<dictionary> ioObj
(
IOobject
(
name,
instance,
registry,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
)
);
ioObj.note() = "persistent data for thirdParty mesh <-> OpenFOAM translation";
Info<< "Writing " << ioObj.name() << " to " << ioObj.objectPath() << endl;
OFstream os(ioObj.objectPath());
ioObj.writeHeader(os);
os << *this;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::cellTable::operator=(const cellTable& rhs)
{
Map<dictionary>::operator=(rhs);
addDefaults();
}
void Foam::cellTable::operator=(const Map<dictionary>& rhs)
{
Map<dictionary>::operator=(rhs);
addDefaults();
}
void Foam::cellTable::operator=(const polyMesh& mesh)
{
Map<dictionary> zoneDict;
// create cellTableId and cellTable based on cellZones
label nZoneCells = 0;
wordList zoneNames = mesh.cellZones().names();
label unZonedType = zoneNames.size() + 1;
// do cell zones
forAll(mesh.cellZones(), zoneI)
{
const cellZone& cZone = mesh.cellZones()[zoneI];
nZoneCells += cZone.size();
dictionary dict;
dict.add("Label", zoneNames[zoneI]);
zoneDict.insert(zoneI + 1, dict);
}
// collect unzoned cells
// special case: no zones at all - do entire mesh
if (nZoneCells == 0)
{
zoneDict.clear();
unZonedType = 1;
}
if (mesh.nCells() > nZoneCells)
{
zoneDict.insert
(
unZonedType,
dictionary
(
IStringStream("Label cells;")()
)
);
}
Map<dictionary>::operator=(zoneDict);
addDefaults();
}
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
// attach cellZones based on the cellTable Id
// - any other values can be extracted later from the cellTable dictionary
void Foam::cellTable::addCellZones
(
polyMesh& mesh,
const labelList& tableIds
) const
{
labelList typeToZone = zoneMap();
wordList zoneNames = namesList();
List<DynamicList<label> > zoneCells(size());
forAll(tableIds, cellI)
{
label zoneI = typeToZone[tableIds[cellI]];
if (zoneI >= 0)
{
zoneCells[zoneI].append(cellI);
}
}
// avoid empty zones
labelList zoneUsed(zoneCells.size());
label nZone = 0;
forAll(zoneCells, zoneI)
{
zoneCells[zoneI].shrink();
if (zoneCells[zoneI].size() > 0)
{
zoneUsed[nZone++] = zoneI;
}
}
zoneUsed.setSize(nZone);
mesh.cellZones().clear();
if (nZone <= 1)
{
Info<< "cellZones not used" << endl;
return;
}
mesh.cellZones().setSize(nZone);
forAll(zoneUsed, zoneI)
{
const label origZoneI = zoneUsed[zoneI];
Info<< "cellZone " << zoneI
<< " (size: " << zoneCells[origZoneI].size() << ") name: "
<< zoneNames[origZoneI] << endl;
mesh.cellZones().set
(
zoneI,
new cellZone
(
zoneNames[origZoneI],
zoneCells[origZoneI],
zoneI,
mesh.cellZones()
)
);
}
mesh.cellZones().writeOpt() = IOobject::AUTO_WRITE;
}
void Foam::cellTable::combine(const dictionary& dict, labelList& tableIds)
{
if (!dict.size())
{
return;
}
bool remap = false;
labelList mapping(identity(max(this->toc()) + 1));
forAllConstIter (dictionary, dict, iter)
{
wordList zoneNames(iter().stream());
labelList zoneIndex(zoneNames.size());
label nElem = 0;
forAll (zoneNames, zoneI)
{
zoneIndex[nElem] = this->findIndex(zoneNames[zoneI]);
if (zoneIndex[nElem] >= 0)
{
if (zoneI != nElem)
{
zoneNames[nElem] = zoneNames[zoneI];
}
++nElem;
}
}
zoneIndex.setSize(nElem);
zoneNames.setSize(nElem);
if (nElem)
{
remap = true;
label targetId = this->findIndex(iter().keyword());
Info<< "combine cellTable: " << iter().keyword();
if (targetId >= 0)
{
Info<< " += (";
}
else
{
Info<< " = (";
}
forAll (zoneNames, zoneI)
{
Info<< " " << zoneNames[zoneI];
}
Info<< " )" << endl;
// re-use the first element if possible
if (targetId < 0)
{
targetId = min(zoneIndex);
dictionary newDict(operator[](targetId));
newDict.remove("Label");
newDict.add("Label", iter().keyword());
this->set(targetId, newDict);
}
forAll (zoneIndex, zoneI)
{
label idx = zoneIndex[zoneI];
if (idx != targetId && idx >= 0)
{
mapping[idx] = targetId;
this->erase(idx);
}
}
}
}
if (remap)
{
inplaceRenumber(mapping, tableIds);
}
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,207 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::cellTable
Description
The cellTable persistent data saved as a Map<dictionary>.
The meshReader supports cellTable information.
The <tt>constant/cellTable</tt> file is an @c IOMap<dictionary> that is
used to save the information persistently. It contains the cellTable
information of the following form:
@verbatim
(
ID
{
Label WORD;
MaterialType WORD;
MaterialId INT;
PorosityId INT;
ColorIdx INT;
...
}
...
)
@endverbatim
If the @a Label is missing, a value <tt>cellTable_{ID}</tt> will be
inferred. If the @a MaterialType is missing, the value @a fluid will
be inferred.
SourceFiles
cellTable.C
\*---------------------------------------------------------------------------*/
#ifndef cellTable_H
#define cellTable_H
#include "polyMesh.H"
#include "Map.H"
#include "dictionary.H"
#include "labelList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cellTable Declaration
\*---------------------------------------------------------------------------*/
class cellTable
:
public Map<dictionary>
{
// Private data
static const char* const defaultMaterial_;
// Private Member Functions
//- Map from cellTable ID => zone number (unmapped = -1)
labelList zoneMap() const;
//- A contiguous list of cellTable names
List<word> namesList() const;
//- Add required entries - MaterialType
void addDefaults();
void setEntry(const label& id, const word& keyWord, const word& value);
//- Disallow default bitwise copy construct
cellTable(const cellTable&);
public:
// Static Members
// Constructors
//- Construct null
cellTable();
//- Construct read from registry, name. instance
cellTable
(
const objectRegistry&,
const word& name = "cellTable",
const fileName& instance = "constant"
);
// Destructor
~cellTable();
// Member Functions
//- Append to the end, return index
label append(const dictionary&);
//- Return index corresponding to name
// returns -1 if not found
label findIndex(const word& name) const;
//- Return the name corresponding to id
// returns cellTable_ID if not otherwise defined
word name(const label& id) const;
//- Return a Map of (id => name)
Map<word> names() const;
//- Return a Map of (id => name) for materialType (fluid | solid | shell)
Map<word> selectType(const word& materialType) const;
//- Return a Map of (id => name) for fluids
Map<word> fluids() const;
//- Return a Map of (id => name) for shells
Map<word> shells() const;
//- Return a Map of (id => name) for solids
Map<word> solids() const;
//- Return a Map of (id => fluid|solid|shell)
Map<word> materialTypes() const;
//- Assign material Type
void setMaterial(const label&, const word&);
//- Assign name
void setName(const label&, const word&);
//- Assign default name if not already set
void setName(const label&);
//- Read constant/cellTable
void readDict
(
const objectRegistry&,
const word& name = "cellTable",
const fileName& instance = "constant"
);
//- write constant/cellTable for later reuse
void writeDict
(
const objectRegistry&,
const word& name = "cellTable",
const fileName& instance = "constant"
) const;
// Member Operators
//- Assignment
void operator=(const cellTable&);
//- Assign from Map<dictionary>
void operator=(const Map<dictionary>&);
//- Assign from cellZones
void operator=(const polyMesh&);
// Friend Functions
//- Classify tableIds into cellZones according to the cellTable
void addCellZones(polyMesh&, const labelList& tableIds) const;
//- Combine tableIds together
// each dictionary entry is a wordList
void combine(const dictionary&, labelList& tableIds);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
#endif
// ************************************************************************* //

View File

@ -0,0 +1,106 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*----------------------------------------------------------------------------*/
#include "meshWriter.H"
#include "cellModeller.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Pointers to cell shape models
const Foam::cellModel* Foam::meshWriter::unknownModel = Foam::cellModeller::
lookup
(
"unknown"
);
const Foam::cellModel* Foam::meshWriter::tetModel = Foam::cellModeller::
lookup
(
"tet"
);
const Foam::cellModel* Foam::meshWriter::pyrModel = Foam::cellModeller::
lookup
(
"pyr"
);
const Foam::cellModel* Foam::meshWriter::prismModel = Foam::cellModeller::
lookup
(
"prism"
);
const Foam::cellModel* Foam::meshWriter::hexModel = Foam::cellModeller::
lookup
(
"hex"
);
Foam::string Foam::meshWriter::defaultMeshName = "meshExport";
Foam::string Foam::meshWriter::defaultSurfaceName = "surfExport";
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::meshWriter::meshWriter
(
const polyMesh& mesh,
const scalar scaleFactor
)
:
mesh_(mesh),
scaleFactor_(scaleFactor),
writeBoundary_(true),
boundaryRegion_(),
cellTable_(),
cellTableId_()
{}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::meshWriter::~meshWriter()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,218 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Namespace
Foam::meshWriters
Description
A namespace for holding various types of mesh writers.
Class
Foam::meshWriter
Description
write OpenFOAM meshes and/or results to another CFD format
- currently just STAR-CD
@par Files
"constant/boundaryRegion" is an IOMap<dictionary> that contains
the boundary type and names. eg,
@verbatim
(
0
{
BoundaryType wall;
Label Default_Boundary_Region;
}
1
{
BoundaryType inlet;
Label inlet_1;
}
...
4
{
BoundaryType pressure;
Label outlet;
}
)
@endverbatim
SourceFiles
meshWriterI.H
meshWriter.C
meshWriterIO.C
\*---------------------------------------------------------------------------*/
#ifndef meshWriter_H
#define meshWriter_H
#include "polyMesh.H"
#include "boundaryRegion.H"
#include "cellTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class meshWriter Declaration
\*---------------------------------------------------------------------------*/
class meshWriter
{
// Private data
// Private Member Functions
//- Disallow default bitwise copy construct
meshWriter(const meshWriter&);
//- Disallow default bitwise assignment
void operator=(const meshWriter&);
protected:
// Protected data
//- mesh reference
const polyMesh& mesh_;
//- scaling factor for points (eg, [m] -> [mm])
scalar scaleFactor_;
//- write bnd file
bool writeBoundary_;
//- boundaryRegion persistent data saved as a dictionary
boundaryRegion boundaryRegion_;
//- cellTable persistent data saved as a dictionary
cellTable cellTable_;
// cellTable IDs for each cell
labelList cellTableId_;
//- Pointers to cell shape models
static const cellModel* unknownModel;
static const cellModel* tetModel;
static const cellModel* pyrModel;
static const cellModel* prismModel;
static const cellModel* hexModel;
public:
// Static data members
static string defaultMeshName;
static string defaultSurfaceName;
// Constructors
//- create a writer obejct
meshWriter
(
const polyMesh&,
const scalar scaleFactor = 1.0
);
// Selectors
// Destructor
virtual ~meshWriter();
// Member Functions
// Access
// Check
// Edit
//- set points scaling
void scaleFactor(const scalar scaling)
{
scaleFactor_ = scaling;
}
//- suppress writing bnd file
void noBoundary()
{
writeBoundary_ = false;
}
// Write
//- write volume mesh
// subclass must to supply this method
virtual bool write
(
const fileName& timeName = fileName::null
) const = 0;
//- write surface mesh with optional triangulation
// subclass could supply this information
virtual bool writeSurface
(
const fileName& timeName = fileName::null,
const bool& triangulate = false
) const
{
return false;
}
// Member Operators
// Friend Functions
// Friend Operators
// IOstream Operators
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// #include "meshWriterI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,757 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "STARCDMeshWriter.H"
#include "Time.H"
#include "SortableList.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// special boundary regions
const char* Foam::meshWriters::STARCD::defaultBoundaryName =
"Default_Boundary_Region";
// face addressing from foam faces -> pro-STAR faces for primitive shapes
const Foam::label Foam::meshWriters::STARCD::foamToStarFaceAddr[4][6] =
{
{ 4, 5, 2, 3, 0, 1 }, // 11 = pro-STAR hex
{ 0, 1, 4, 5, 2, -1 }, // 12 = pro-STAR prism
{ 5, 4, 2, 0, -1, -1 }, // 13 = pro-STAR tetra
{ 0, 4, 3, 5, 2, -1 } // 14 = pro-STAR pyramid
};
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::label Foam::meshWriters::STARCD::findDefaultBoundary() const
{
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
label id = -1;
// find Default_Boundary_Region if it exists
forAll(patches, patchI)
{
if (defaultBoundaryName == patches[patchI].name())
{
id = patchI;
break;
}
}
return id;
}
void Foam::meshWriters::STARCD::getCellTable()
{
// read constant/polyMesh/propertyName
IOList<label> ioList
(
IOobject
(
"cellTableId",
"constant",
polyMesh::meshSubDir,
mesh_,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE,
false
)
);
bool useCellZones = false;
cellTableId_.setSize(mesh_.nCells(), -1);
// get information from constant/polyMesh/cellTableId if possible
if (ioList.headerOk())
{
if (ioList.size() == mesh_.nCells())
{
cellTableId_.transfer(ioList);
if (!cellTable_.size())
{
Info<< "no cellTable information available" << endl;
}
}
else
{
WarningIn("STARCD::getCellTable()")
<< ioList.objectPath() << " has incorrect number of cells "
<< " - use cellZone information"
<< endl;
ioList.clear();
useCellZones = true;
}
}
else
{
useCellZones = true;
}
if (useCellZones)
{
if (!cellTable_.size())
{
Info<< "created cellTable from cellZones" << endl;
cellTable_ = mesh_;
}
// track if there are unzoned cells
label nUnzoned = mesh_.nCells();
// get the cellZone <-> cellTable correspondence
Info<< "matching cellZones to cellTable" << endl;
forAll (mesh_.cellZones(), zoneI)
{
const cellZone& cZone = mesh_.cellZones()[zoneI];
if (cZone.size())
{
nUnzoned -= cZone.size();
label tableId = cellTable_.findIndex(cZone.name());
if (tableId < 0)
{
dictionary dict;
dict.add("Label", cZone.name());
dict.add("MaterialType", "fluid");
tableId = cellTable_.append(dict);
}
forAll (cZone, i)
{
cellTableId_[cZone[i]] = tableId;
}
}
}
if (nUnzoned)
{
dictionary dict;
dict.add("Label", "__unZonedCells__");
dict.add("MaterialType", "fluid");
label tableId = cellTable_.append(dict);
forAll (cellTableId_, i)
{
if (cellTableId_[i] < 0)
{
cellTableId_[i] = tableId;
}
}
}
}
}
// Prostar 4+ header format
void Foam::meshWriters::STARCD::writeHeader
(
Ostream& os,
const char* filetype
)
{
os << "PROSTAR_" << filetype << nl
<< 4000
<< " " << 0
<< " " << 0
<< " " << 0
<< " " << 0
<< " " << 0
<< " " << 0
<< " " << 0
<< endl;
}
void Foam::meshWriters::STARCD::writePoints
(
const fileName& prefix
) const
{
OFstream os(prefix + ".vrt");
writeHeader(os, "VERTEX");
// Set the precision of the points data to 10
os.precision(10);
// force decimal point for Fortran input
os.setf(std::ios::showpoint);
const pointField& points = mesh_.points();
Info<< "Writing " << os.name() << " : "
<< points.size() << " points" << endl;
forAll(points, ptI)
{
// convert [m] -> [mm]
os
<< ptI + 1 << " "
<< scaleFactor_ * points[ptI].x() << " "
<< scaleFactor_ * points[ptI].y() << " "
<< scaleFactor_ * points[ptI].z() << nl;
}
os.flush();
}
void Foam::meshWriters::STARCD::writeCells
(
const fileName& prefix
) const
{
OFstream os(prefix + ".cel");
writeHeader(os, "CELL");
// this is what we seem to need
// map foam cellModeller index -> star shape
Map<label> shapeLookupIndex;
shapeLookupIndex.insert(hexModel->index(), 11);
shapeLookupIndex.insert(prismModel->index(), 12);
shapeLookupIndex.insert(tetModel->index(), 13);
shapeLookupIndex.insert(pyrModel->index(), 14);
const cellShapeList& shapes = mesh_.cellShapes();
const cellList& cells = mesh_.cells();
const faceList& faces = mesh_.faces();
const labelList& owner = mesh_.faceOwner();
Info<< "Writing " << os.name() << " : "
<< cells.size() << " cells" << endl;
forAll(cells, cellId)
{
label tableId = cellTableId_[cellId];
label materialType = 1; // 1(fluid)
if (cellTable_.found(tableId))
{
const dictionary& dict = cellTable_[tableId];
if (dict.found("MaterialType"))
{
word matType;
dict.lookup("MaterialType") >> matType;
if (matType == "solid")
{
materialType = 2;
}
}
}
const cellShape& shape = shapes[cellId];
label mapIndex = shape.model().index();
// a registered primitive type
if (shapeLookupIndex.found(mapIndex))
{
label shapeId = shapeLookupIndex[mapIndex];
const labelList& vrtList = shapes[cellId];
os << cellId + 1
<< " " << shapeId
<< " " << vrtList.size()
<< " " << tableId
<< " " << materialType;
// primitives have <= 8 vertices, but prevent overrun anyhow
// indent following lines for ease of reading
label count = 0;
forAll(vrtList, i)
{
if ((count % 8) == 0)
{
os << nl
<< " " << cellId + 1;
}
os << " " << vrtList[i] + 1;
count++;
}
os << endl;
}
else
{
label shapeId = 255; // treat as general polyhedral
const labelList& cFaces = cells[cellId];
// create (beg,end) indices
List<label> indices(cFaces.size() + 1);
indices[0] = indices.size();
label count = indices.size();
// determine the total number of vertices
forAll(cFaces, faceI)
{
count += faces[cFaces[faceI]].size();
indices[faceI+1] = count;
}
os << cellId + 1
<< " " << shapeId
<< " " << count
<< " " << tableId
<< " " << materialType;
// write indices - max 8 per line
// indent following lines for ease of reading
count = 0;
forAll(indices, i)
{
if ((count % 8) == 0)
{
os << nl
<< " " << cellId + 1;
}
os << " " << indices[i];
count++;
}
// write faces - max 8 per line
forAll(cFaces, faceI)
{
label meshFace = cFaces[faceI];
face f;
if (owner[meshFace] == cellId)
{
f = faces[meshFace];
}
else
{
f = faces[meshFace].reverseFace();
}
forAll(f, i)
{
if ((count % 8) == 0)
{
os << nl
<< " " << cellId + 1;
}
os << " " << f[i] + 1;
count++;
}
}
os << endl;
}
}
}
void Foam::meshWriters::STARCD::writeBoundary
(
const fileName& prefix
) const
{
OFstream os(prefix + ".bnd");
writeHeader(os, "BOUNDARY");
const cellShapeList& shapes = mesh_.cellShapes();
const cellList& cells = mesh_.cells();
const faceList& faces = mesh_.faces();
const labelList& owner = mesh_.faceOwner();
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
// this is what we seem to need
// these MUST correspond to foamToStarFaceAddr
//
Map<label> faceLookupIndex;
faceLookupIndex.insert(hexModel->index(), 0);
faceLookupIndex.insert(prismModel->index(), 1);
faceLookupIndex.insert(tetModel->index(), 2);
faceLookupIndex.insert(pyrModel->index(), 3);
Info<< "Writing " << os.name() << " : "
<< (mesh_.nFaces() - patches[0].start()) << " boundaries" << endl;
label defaultId = findDefaultBoundary();
//
// write boundary faces - skip Default_Boundary_Region entirely
//
label boundId = 0;
forAll(patches, patchI)
{
label regionId = patchI;
if (regionId == defaultId)
{
continue; // skip - already written
}
else if (defaultId == -1 || regionId < defaultId)
{
regionId++;
}
label patchStart = patches[patchI].start();
label patchSize = patches[patchI].size();
word bndType = boundaryRegion_.boundaryType(patches[patchI].name());
for
(
label faceI = patchStart;
faceI < (patchStart + patchSize);
++faceI
)
{
label cellId = owner[faceI];
const labelList& cFaces = cells[cellId];
const cellShape& shape = shapes[cellId];
label cellFaceId = findIndex(cFaces, faceI);
// Info<< "cell " << cellId + 1 << " face " << faceI
// << " == " << faces[faceI]
// << " is index " << cellFaceId << " from " << cFaces;
// Unfortunately, the order of faces returned by
// primitiveMesh::cells() is not necessarily the same
// as defined by primitiveMesh::cellShapes()
// Thus, for registered primitive types, do the lookup ourselves.
// Finally, the cellModel face number is re-mapped to the
// STAR-CD local face number
label mapIndex = shape.model().index();
// a registered primitive type
if (faceLookupIndex.found(mapIndex))
{
const faceList sFaces = shape.faces();
forAll(sFaces, sFaceI)
{
if (faces[faceI] == sFaces[sFaceI])
{
cellFaceId = sFaceI;
break;
}
}
mapIndex = faceLookupIndex[mapIndex];
cellFaceId = foamToStarFaceAddr[mapIndex][cellFaceId];
}
// Info<< endl;
boundId++;
os
<< boundId
<< " " << cellId + 1
<< " " << cellFaceId + 1
<< " " << regionId
<< " " << 0
<< " " << bndType.c_str()
<< endl;
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::meshWriters::STARCD::STARCD
(
const polyMesh& mesh,
const scalar scaleFactor
)
:
meshWriter(mesh, scaleFactor)
{
boundaryRegion_.readDict(mesh_);
cellTable_.readDict(mesh_);
getCellTable();
}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::meshWriters::STARCD::~STARCD()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::meshWriters::STARCD::rmFiles
(
const fileName& baseName
) const
{
rm(baseName + ".vrt");
rm(baseName + ".cel");
rm(baseName + ".bnd");
rm(baseName + ".inp");
}
bool Foam::meshWriters::STARCD::write
(
const fileName& meshName
) const
{
fileName baseName(meshName);
if (!baseName.size())
{
baseName = meshWriter::defaultMeshName;
if
(
mesh_.time().timeName() != "0"
&& mesh_.time().timeName() != "constant"
)
{
baseName += "_" + mesh_.time().timeName();
}
}
rmFiles(baseName);
writePoints(baseName);
writeCells(baseName);
if (writeBoundary_)
{
writeBoundary(baseName);
}
return true;
}
bool Foam::meshWriters::STARCD::writeSurface
(
const fileName& meshName,
const bool& triangulate
) const
{
fileName baseName(meshName);
if (!baseName.size())
{
baseName = meshWriter::defaultSurfaceName;
if
(
mesh_.time().timeName() != "0"
&& mesh_.time().timeName() != "constant"
)
{
baseName += "_" + mesh_.time().timeName();
}
}
rmFiles(baseName);
OFstream celFile(baseName + ".cel");
writeHeader(celFile, "CELL");
Info << "Writing " << celFile.name() << endl;
// mesh and patch info
const pointField& points = mesh_.points();
const labelList& owner = mesh_.faceOwner();
const faceList& meshFaces = mesh_.faces();
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
label shapeId = 3; // shell/baffle element
label typeId = 4; // 4(shell)
// remember which points need to be written
labelHashSet pointHash;
// write boundary faces as normal STAR-CD mesh
if (triangulate)
{
// cell Id has no particular meaning - just increment
// use the cellTable id from the patch Number
label cellId = 0;
forAll(patches, patchI)
{
label patchStart = patches[patchI].start();
label patchSize = patches[patchI].size();
label ctableId = patchI + 1;
for
(
label faceI = patchStart;
faceI < (patchStart + patchSize);
++faceI
)
{
const face& f = meshFaces[faceI];
label nTri = f.nTriangles(points);
faceList triFaces;
// triangulate polygons, but not quads
if (nTri <= 2)
{
triFaces.setSize(1);
triFaces[0] = f;
}
else
{
triFaces.setSize(nTri);
nTri = 0;
f.triangles(points, nTri, triFaces);
}
forAll(triFaces, faceI)
{
const labelList& vrtList = triFaces[faceI];
celFile
<< cellId + 1 << " "
<< shapeId << " "
<< vrtList.size() << " "
<< ctableId << " "
<< typeId;
// must be 3 (triangle) but could be quad
label count = 0;
forAll(vrtList, i)
{
if ((count % 8) == 0)
{
celFile
<< nl
<< " " << cellId + 1;
}
// remember which points we'll need to write
pointHash.insert(vrtList[i]);
celFile << " " << vrtList[i] + 1;
count++;
}
celFile << endl;
cellId++;
}
}
}
}
else
{
// cell Id is the OpenFOAM face Id
// use the cellTable id from the face owner
// - allows separation of parts
forAll(patches, patchI)
{
label patchStart = patches[patchI].start();
label patchSize = patches[patchI].size();
for
(
label faceI = patchStart;
faceI < (patchStart + patchSize);
++faceI
)
{
const labelList& vrtList = meshFaces[faceI];
label cellId = faceI;
celFile
<< cellId + 1 << " "
<< shapeId << " "
<< vrtList.size() << " "
<< cellTableId_[owner[faceI]] << " "
<< typeId;
// likely <= 8 vertices, but prevent overrun anyhow
label count = 0;
forAll(vrtList, i)
{
if ((count % 8) == 0)
{
celFile
<< nl
<< " " << cellId + 1;
}
// remember which points we'll need to write
pointHash.insert(vrtList[i]);
celFile << " " << vrtList[i] + 1;
count++;
}
celFile << endl;
}
}
}
OFstream vrtFile(baseName + ".vrt");
writeHeader(vrtFile, "VERTEX");
vrtFile.precision(10);
vrtFile.setf(std::ios::showpoint); // force decimal point for Fortran
Info << "Writing " << vrtFile.name() << endl;
// build sorted table of contents
SortableList<label> toc(pointHash.size());
{
label i = 0;
forAllConstIter(labelHashSet, pointHash, iter)
{
toc[i++] = iter.key();
}
}
toc.sort();
pointHash.clear();
// write points in sorted order
forAll(toc, i)
{
label vrtId = toc[i];
vrtFile
<< vrtId + 1
<< " " << scaleFactor_ * points[vrtId].x()
<< " " << scaleFactor_ * points[vrtId].y()
<< " " << scaleFactor_ * points[vrtId].z()
<< endl;
}
return true;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -0,0 +1,167 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::meshWriters::STARCD
Description
Writes polyMesh in pro-STAR (v4) bnd/cel/vrt format
Alternatively, extracts the surface of the FOAM mesh into
pro-STAR (v4) .cel/.vrt/ format.
This can be useful, for example, for surface morphing in an external
package.
The cellTableId and cellTable information are used (if available).
Otherwise the cellZones are used (if available).
SourceFiles
STARCDMeshWriter.C
\*---------------------------------------------------------------------------*/
#ifndef STARCDMeshWriter_H
#define STARCDMeshWriter_H
#include "meshWriter.H"
#include "IOstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace meshWriters
{
/*---------------------------------------------------------------------------*\
Class meshWriters::STARCD Declaration
\*---------------------------------------------------------------------------*/
class STARCD
:
public meshWriter
{
// Private Data
static const char* defaultBoundaryName;
// Private Member Functions
//- Disallow default bitwise copy construct
STARCD(const STARCD&);
//- Disallow default bitwise assignment
void operator=(const STARCD&);
//- pro-STAR 4+ header format
static void writeHeader(Ostream&, const char* filetype);
//- write points
void writePoints(const fileName& baseName) const;
//- write cells
void writeCells(const fileName& baseName) const;
//- write boundary
void writeBoundary(const fileName& baseName) const;
void getCellTable();
label findDefaultBoundary() const;
public:
// Static data members
//- Face addressing from OpenFOAM faces -> pro-STAR faces
static const label foamToStarFaceAddr[4][6];
// Constructors
//- open a file for writing
STARCD
(
const polyMesh&,
const scalar scaleFactor = 1.0
);
// Selectors
// Destructor
virtual ~STARCD();
// Member Functions
// Access
// Check
// Edit
// Write
//- Remove STAR-CD files for the baseName
void rmFiles(const fileName& baseName) const;
//- write volume mesh
virtual bool write
(
const fileName& meshName = fileName::null
) const;
//- write surface mesh with optional triangulation
virtual bool writeSurface
(
const fileName& meshName = fileName::null,
const bool& triangulate = false
) const;
// Member Operators
// Friend Functions
// Friend Operators
// IOstream Operators
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace meshWriters
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //