/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see .
\*---------------------------------------------------------------------------*/
#include "STARCDMeshReader.H"
#include "oldCyclicPolyPatch.H"
#include "emptyPolyPatch.H"
#include "wallPolyPatch.H"
#include "symmetryPolyPatch.H"
#include "cellModeller.H"
#include "ListOps.H"
#include "IFstream.H"
#include "IOMap.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const char* const Foam::meshReaders::STARCD::defaultBoundaryName =
"Default_Boundary_Region";
const char* const Foam::meshReaders::STARCD::defaultSolidBoundaryName =
"Default_Boundary_Solid";
bool Foam::meshReaders::STARCD::keepSolids = false;
const int Foam::meshReaders::STARCD::starToFoamFaceAddr[4][6] =
{
{ 4, 5, 2, 3, 0, 1 }, // 11 = pro-STAR hex
{ 0, 1, 4, -1, 2, 3 }, // 12 = pro-STAR prism
{ 3, -1, 2, -1, 1, 0 }, // 13 = pro-STAR tetra
{ 0, -1, 4, 2, 1, 3 } // 14 = pro-STAR pyramid
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::meshReaders::STARCD::readToNewline(IFstream& is)
{
char ch = '\n';
do
{
(is).get(ch);
}
while ((is) && ch != '\n');
}
bool Foam::meshReaders::STARCD::readHeader(IFstream& is, word fileSignature)
{
if (!is.good())
{
FatalErrorInFunction
<< abort(FatalError);
}
word header;
label majorVersion;
is >> header;
is >> majorVersion;
// skip the rest of the line
readToNewline(is);
// add other checks ...
if (header != fileSignature)
{
Info<< "header mismatch " << fileSignature << " " << is.name()
<< endl;
}
return true;
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::meshReaders::STARCD::readAux(const objectRegistry& registry)
{
boundaryRegion_.readDict(registry);
cellTable_.readDict(registry);
}
// read in the points from the .vrt file
//
/*---------------------------------------------------------------------------*\
Line 1:
PROSTAR_VERTEX [newline]
Line 2:
0 0 0 0 0 0 0 [newline]
Body:
[newline]
\*---------------------------------------------------------------------------*/
void Foam::meshReaders::STARCD::readPoints
(
const fileName& inputName,
const scalar scaleFactor
)
{
const word fileSignature = "PROSTAR_VERTEX";
label nPoints = 0, maxId = 0;
// Pass 1:
// get # points and maximum vertex label
{
IFstream is(inputName);
readHeader(is, fileSignature);
label lineLabel;
scalar x, y, z;
while ((is >> lineLabel).good())
{
nPoints++;
maxId = max(maxId, lineLabel);
is >> x >> y >> z;
}
}
Info<< "Number of points = " << nPoints << endl;
// set sizes and reset to invalid values
points_.setSize(nPoints);
mapToFoamPointId_.setSize(maxId+1);
//- Original Point number for a given vertex
// might need again in the future
//// labelList origPointId(nPoints);
//// origPointId = -1;
mapToFoamPointId_ = -1;
// Pass 2:
// construct pointList and conversion table
// from Star vertex numbers to Foam point labels
if (nPoints > 0)
{
IFstream is(inputName);
readHeader(is, fileSignature);
label lineLabel;
label pointI = 0;
while ((is >> lineLabel).good())
{
is >> points_[pointI].x()
>> points_[pointI].y()
>> points_[pointI].z();
// might need again in the future
//// origPointId[pointI] = lineLabel;
mapToFoamPointId_[lineLabel] = pointI;
pointI++;
}
if (nPoints > pointI)
{
nPoints = pointI;
points_.setSize(nPoints);
// might need again in the future
//// origPointId.setSize(nPoints);
}
if (scaleFactor > 1.0 + SMALL || scaleFactor < 1.0 - SMALL)
{
points_ *= scaleFactor;
}
}
else
{
FatalErrorInFunction
<< "no points in file " << inputName
<< abort(FatalError);
}
}
// read in the cells from the .cel file
//
/*---------------------------------------------------------------------------*\
Line 1:
PROSTAR_CELL [newline]
Line 2:
0 0 0 0 0 0 0 [newline]
Body:
[newline]
..
..
with shapeId:
* 1 = point
* 2 = line
* 3 = shell
* 11 = hexa
* 12 = prism
* 13 = tetra
* 14 = pyramid
* 255 = polyhedron
with typeId
* 1 = fluid
* 2 = solid
* 3 = baffle
* 4 = shell
* 5 = line
* 6 = point
For primitive cell shapes, the number of vertices will never exceed 8 (hexa)
and corresponds to .
For polyhedral, includes an index table comprising beg/end pairs
for each cell face.
Strictly speaking, we only need the cellModeller for adding boundaries.
\*---------------------------------------------------------------------------*/
void Foam::meshReaders::STARCD::readCells(const fileName& inputName)
{
const word fileSignature = "PROSTAR_CELL";
label nFluids = 0, nSolids = 0, nBaffles = 0, nShells = 0;
label maxId = 0;
bool unknownVertices = false;
// Pass 1:
// count nFluids, nSolids, nBaffle, nShell and maxId
// also see if polyhedral cells were used
{
IFstream is(inputName);
readHeader(is, fileSignature);
label lineLabel, shapeId, nLabels, cellTableId, typeId;
while ((is >> lineLabel).good())
{
label starCellId = lineLabel;
is >> shapeId
>> nLabels
>> cellTableId
>> typeId;
// skip the rest of the line
readToNewline(is);
// max 8 indices per line
while (nLabels > 0)
{
readToNewline(is);
nLabels -= 8;
}
if (typeId == starcdFluidType)
{
nFluids++;
maxId = max(maxId, starCellId);
if (!cellTable_.found(cellTableId))
{
cellTable_.setName(cellTableId);
cellTable_.setMaterial(cellTableId, "fluid");
}
}
else if (typeId == starcdSolidType)
{
nSolids++;
if (keepSolids)
{
maxId = max(maxId, starCellId);
}
if (!cellTable_.found(cellTableId))
{
cellTable_.setName(cellTableId);
cellTable_.setMaterial(cellTableId, "solid");
}
}
else if (typeId == starcdBaffleType)
{
// baffles have no cellTable entry
nBaffles++;
maxId = max(maxId, starCellId);
}
else if (typeId == starcdShellType)
{
nShells++;
if (!cellTable_.found(cellTableId))
{
cellTable_.setName(cellTableId);
cellTable_.setMaterial(cellTableId, "shell");
}
}
}
}
Info<< "Number of fluids = " << nFluids << nl
<< "Number of baffles = " << nBaffles << nl;
if (keepSolids)
{
Info<< "Number of solids = " << nSolids << nl;
}
else
{
Info<< "Ignored solids = " << nSolids << nl;
}
Info<< "Ignored shells = " << nShells << endl;
label nCells;
if (keepSolids)
{
nCells = nFluids + nSolids;
}
else
{
nCells = nFluids;
}
cellFaces_.setSize(nCells);
cellShapes_.setSize(nCells);
cellTableId_.setSize(nCells);
// information for the interfaces
baffleFaces_.setSize(nBaffles);
// extra space for baffles
origCellId_.setSize(nCells + nBaffles);
mapToFoamCellId_.setSize(maxId+1);
mapToFoamCellId_ = -1;
// avoid undefined shapes for polyhedra
cellShape genericShape(*unknownModel, labelList(0));
// Pass 2:
// construct cellFaces_ and possibly cellShapes_
if (nCells <= 0)
{
FatalErrorInFunction
<< "no cells in file " << inputName
<< abort(FatalError);
}
else
{
IFstream is(inputName);
readHeader(is, fileSignature);
labelList starLabels(64);
label lineLabel, shapeId, nLabels, cellTableId, typeId;
label cellI = 0;
label baffleI = 0;
while ((is >> lineLabel).good())
{
label starCellId = lineLabel;
is >> shapeId
>> nLabels
>> cellTableId
>> typeId;
if (nLabels > starLabels.size())
{
starLabels.setSize(nLabels);
}
starLabels = -1;
// read indices - max 8 per line
for (label i = 0; i < nLabels; ++i)
{
if ((i % 8) == 0)
{
is >> lineLabel;
}
is >> starLabels[i];
}
// skip solid cells
if (typeId == starcdSolidType && !keepSolids)
{
continue;
}
// determine the foam cell shape
const cellModel* curModelPtr = NULL;
// fluid/solid cells
switch (shapeId)
{
case starcdHex:
curModelPtr = hexModel;
break;
case starcdPrism:
curModelPtr = prismModel;
break;
case starcdTet:
curModelPtr = tetModel;
break;
case starcdPyr:
curModelPtr = pyrModel;
break;
}
if (curModelPtr)
{
// primitive cell - use shapes
// convert orig vertex Id to point label
bool isBad = false;
for (label i=0; i < nLabels; ++i)
{
label pointId = mapToFoamPointId_[starLabels[i]];
if (pointId < 0)
{
Info<< "Cells inconsistent with vertex file. "
<< "Star vertex " << starLabels[i]
<< " does not exist" << endl;
isBad = true;
unknownVertices = true;
}
starLabels[i] = pointId;
}
if (isBad)
{
continue;
}
// record original cell number and lookup
origCellId_[cellI] = starCellId;
mapToFoamCellId_[starCellId] = cellI;
cellTableId_[cellI] = cellTableId;
cellShapes_[cellI] = cellShape
(
*curModelPtr,
SubList