2010-05-12 13:27:55 +00:00
|
|
|
/*---------------------------------------------------------------------------*\
|
|
|
|
========= |
|
2013-12-11 16:09:41 +00:00
|
|
|
\\ / F ield | foam-extend: Open Source CFD
|
2015-05-17 13:32:07 +00:00
|
|
|
\\ / O peration | Version: 3.2
|
|
|
|
\\ / A nd | Web: http://www.foam-extend.org
|
|
|
|
\\/ M anipulation | For copyright notice see file Copyright
|
2010-05-12 13:27:55 +00:00
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
License
|
2013-12-11 16:09:41 +00:00
|
|
|
This file is part of foam-extend.
|
2010-05-12 13:27:55 +00:00
|
|
|
|
2013-12-11 16:09:41 +00:00
|
|
|
foam-extend is free software: you can redistribute it and/or modify it
|
2010-05-12 13:27:55 +00:00
|
|
|
under the terms of the GNU General Public License as published by the
|
2013-12-11 16:09:41 +00:00
|
|
|
Free Software Foundation, either version 3 of the License, or (at your
|
2010-05-12 13:27:55 +00:00
|
|
|
option) any later version.
|
|
|
|
|
2013-12-11 16:09:41 +00:00
|
|
|
foam-extend 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.
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2013-12-11 16:09:41 +00:00
|
|
|
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
Description
|
|
|
|
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
#include "hexBlock.H"
|
|
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
|
|
|
|
namespace Foam
|
|
|
|
{
|
|
|
|
|
|
|
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
|
|
|
|
|
|
label hexBlock::vtxLabel(label a, label b, label c) const
|
|
|
|
{
|
|
|
|
return (a + b*(xDim_ + 1) + c*(xDim_ + 1)*(yDim_ + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
|
|
|
|
|
|
// Construct from components
|
|
|
|
hexBlock::hexBlock(const label nx, const label ny, const label nz)
|
|
|
|
:
|
|
|
|
xDim_(nx),
|
|
|
|
yDim_(ny),
|
|
|
|
zDim_(nz),
|
|
|
|
blockHandedness_(noPoints),
|
|
|
|
points_((xDim_ + 1)*(yDim_ + 1)*(zDim_ + 1))
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
|
|
|
|
|
|
void hexBlock::readPoints(Istream& is)
|
|
|
|
{
|
|
|
|
forAll (points_, i)
|
|
|
|
{
|
|
|
|
is >> points_[i].x() >> points_[i].y() >> points_[i].z();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Calculate the handedness of the block
|
|
|
|
vector i = points_[xDim_] - points_[0];
|
|
|
|
vector j = points_[(xDim_ + 1)*yDim_] - points_[0];
|
|
|
|
vector k = points_[(xDim_ + 1)*(yDim_ + 1)*zDim_] - points_[0];
|
|
|
|
|
|
|
|
if (((i ^ j) & k) > 0)
|
|
|
|
{
|
|
|
|
Info << "right-handed block" << endl;
|
|
|
|
blockHandedness_ = right;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Info << "left-handed block" << endl;
|
|
|
|
blockHandedness_ = left;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
labelListList hexBlock::blockCells() const
|
|
|
|
{
|
|
|
|
labelListList result(xDim_*yDim_*zDim_);
|
|
|
|
|
|
|
|
label cellNo = 0;
|
|
|
|
|
|
|
|
if (blockHandedness_ == right)
|
|
|
|
{
|
|
|
|
for (label k = 0; k <= zDim_ - 1; k++)
|
|
|
|
{
|
|
|
|
for (label j = 0; j <= yDim_ - 1; j++)
|
|
|
|
{
|
|
|
|
for (label i = 0; i <= xDim_ - 1; i++)
|
|
|
|
{
|
|
|
|
labelList& hexLabels = result[cellNo];
|
|
|
|
hexLabels.setSize(8);
|
|
|
|
|
|
|
|
hexLabels[0] = vtxLabel(i, j, k);
|
|
|
|
hexLabels[1] = vtxLabel(i+1, j, k);
|
|
|
|
hexLabels[2] = vtxLabel(i+1, j+1, k);
|
|
|
|
hexLabels[3] = vtxLabel(i, j+1, k);
|
|
|
|
hexLabels[4] = vtxLabel(i, j, k+1);
|
|
|
|
hexLabels[5] = vtxLabel(i+1, j, k+1);
|
|
|
|
hexLabels[6] = vtxLabel(i+1, j+1, k+1);
|
|
|
|
hexLabels[7] = vtxLabel(i, j+1, k+1);
|
|
|
|
|
|
|
|
cellNo++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (blockHandedness_ == left)
|
|
|
|
{
|
|
|
|
for (label k = 0; k <= zDim_ - 1; k++)
|
|
|
|
{
|
|
|
|
for (label j = 0; j <= yDim_ - 1; j++)
|
|
|
|
{
|
|
|
|
for (label i = 0; i <= xDim_ - 1; i++)
|
|
|
|
{
|
|
|
|
labelList& hexLabels = result[cellNo];
|
|
|
|
hexLabels.setSize(8);
|
|
|
|
|
|
|
|
hexLabels[0] = vtxLabel(i, j, k+1);
|
|
|
|
hexLabels[1] = vtxLabel(i+1, j, k+1);
|
|
|
|
hexLabels[2] = vtxLabel(i+1, j+1, k+1);
|
|
|
|
hexLabels[3] = vtxLabel(i, j+1, k+1);
|
|
|
|
hexLabels[4] = vtxLabel(i, j, k);
|
|
|
|
hexLabels[5] = vtxLabel(i+1, j, k);
|
|
|
|
hexLabels[6] = vtxLabel(i+1, j+1, k);
|
|
|
|
hexLabels[7] = vtxLabel(i, j+1, k);
|
|
|
|
|
|
|
|
cellNo++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FatalErrorIn("hexBlock::cellShapes()")
|
|
|
|
<< "Unable to determine block handedness as points "
|
|
|
|
<< "have not been read in yet"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Return block patch faces given direction and range limits
|
|
|
|
// From the cfx manual: direction
|
|
|
|
// 0 = solid (3-D patch),
|
|
|
|
// 1 = high i, 2 = high j, 3 = high k
|
|
|
|
// 4 = low i, 5 = low j, 6 = low k
|
|
|
|
faceList hexBlock::patchFaces(const label direc, const labelList& range) const
|
|
|
|
{
|
|
|
|
if (range.size() != 6)
|
|
|
|
{
|
|
|
|
FatalErrorIn
|
|
|
|
(
|
|
|
|
"patchFaces(const label direc, const labelList& range) const"
|
|
|
|
) << "Invalid size of the range array: " << range.size()
|
|
|
|
<< ". Should be 6 (xMin, xMax, yMin, yMax, zMin, zMax"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
label xMinRange = range[0];
|
|
|
|
label xMaxRange = range[1];
|
|
|
|
label yMinRange = range[2];
|
|
|
|
label yMaxRange = range[3];
|
|
|
|
label zMinRange = range[4];
|
|
|
|
label zMaxRange = range[5];
|
|
|
|
|
|
|
|
faceList result(0);
|
|
|
|
|
|
|
|
switch (direc)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
// high i = xmax
|
|
|
|
|
|
|
|
result.setSize
|
|
|
|
(
|
|
|
|
(yMaxRange - yMinRange + 1)*(zMaxRange - zMinRange + 1)
|
|
|
|
);
|
|
|
|
|
|
|
|
label p = 0;
|
|
|
|
for (label k = zMinRange - 1; k <= zMaxRange - 1; k++)
|
|
|
|
{
|
|
|
|
for (label j = yMinRange - 1; j <= yMaxRange - 1; j++)
|
|
|
|
{
|
|
|
|
result[p].setSize(4);
|
|
|
|
|
|
|
|
// set the points
|
|
|
|
result[p][0] = vtxLabel(xDim_, j, k);
|
|
|
|
result[p][1] = vtxLabel(xDim_, j+1, k);
|
|
|
|
result[p][2] = vtxLabel(xDim_, j+1, k+1);
|
|
|
|
result[p][3] = vtxLabel(xDim_, j, k+1);
|
|
|
|
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result.setSize(p);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
// high j = ymax
|
|
|
|
result.setSize
|
|
|
|
(
|
|
|
|
(xMaxRange - xMinRange + 1)*(zMaxRange - zMinRange + 1)
|
|
|
|
);
|
|
|
|
|
|
|
|
label p = 0;
|
|
|
|
for (label i = xMinRange - 1; i <= xMaxRange - 1; i++)
|
|
|
|
{
|
|
|
|
for (label k = zMinRange - 1; k <= zMaxRange - 1; k++)
|
|
|
|
{
|
|
|
|
result[p].setSize(4);
|
|
|
|
|
|
|
|
// set the points
|
|
|
|
result[p][0] = vtxLabel(i, yDim_, k);
|
|
|
|
result[p][1] = vtxLabel(i, yDim_, k + 1);
|
|
|
|
result[p][2] = vtxLabel(i + 1, yDim_, k + 1);
|
|
|
|
result[p][3] = vtxLabel(i + 1, yDim_, k);
|
|
|
|
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result.setSize(p);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
// high k = zmax
|
|
|
|
result.setSize
|
|
|
|
(
|
|
|
|
(xMaxRange - xMinRange + 1)*(yMaxRange - yMinRange + 1)
|
|
|
|
);
|
|
|
|
|
|
|
|
label p = 0;
|
|
|
|
for (label i = xMinRange - 1; i <= xMaxRange - 1; i++)
|
|
|
|
{
|
|
|
|
for (label j = yMinRange - 1; j <= yMaxRange - 1; j++)
|
|
|
|
{
|
|
|
|
result[p].setSize(4);
|
|
|
|
|
|
|
|
// set the points
|
|
|
|
result[p][0] = vtxLabel(i, j, zDim_);
|
|
|
|
result[p][1] = vtxLabel(i + 1, j, zDim_);
|
|
|
|
result[p][2] = vtxLabel(i + 1, j + 1, zDim_);
|
|
|
|
result[p][3] = vtxLabel(i, j + 1, zDim_);
|
|
|
|
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result.setSize(p);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
// low i = xmin
|
|
|
|
result.setSize
|
|
|
|
(
|
|
|
|
(yMaxRange - yMinRange + 1)*(zMaxRange - zMinRange + 1)
|
|
|
|
);
|
|
|
|
|
|
|
|
label p = 0;
|
|
|
|
for (label k = zMinRange - 1; k <= zMaxRange - 1; k++)
|
|
|
|
{
|
|
|
|
for (label j = yMinRange - 1; j <= yMaxRange - 1; j++)
|
|
|
|
{
|
|
|
|
result[p].setSize(4);
|
|
|
|
|
|
|
|
// set the points
|
|
|
|
result[p][0] = vtxLabel(0, j, k);
|
|
|
|
result[p][1] = vtxLabel(0, j, k + 1);
|
|
|
|
result[p][2] = vtxLabel(0, j + 1, k + 1);
|
|
|
|
result[p][3] = vtxLabel(0, j + 1, k);
|
|
|
|
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result.setSize(p);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
// low j = ymin
|
|
|
|
result.setSize
|
|
|
|
(
|
|
|
|
(xMaxRange - xMinRange + 1)*(zMaxRange - zMinRange + 1)
|
|
|
|
);
|
|
|
|
|
|
|
|
label p = 0;
|
|
|
|
for (label i = xMinRange - 1; i <= xMaxRange - 1; i++)
|
|
|
|
{
|
|
|
|
for (label k = zMinRange - 1; k <= zMaxRange - 1; k++)
|
|
|
|
{
|
|
|
|
result[p].setSize(4);
|
|
|
|
|
|
|
|
// set the points
|
|
|
|
result[p][0] = vtxLabel(i, 0, k);
|
|
|
|
result[p][1] = vtxLabel(i + 1, 0, k);
|
|
|
|
result[p][2] = vtxLabel(i + 1, 0, k + 1);
|
|
|
|
result[p][3] = vtxLabel(i, 0, k + 1);
|
|
|
|
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result.setSize(p);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 6:
|
|
|
|
{
|
|
|
|
// low k = zmin
|
|
|
|
result.setSize
|
|
|
|
(
|
|
|
|
(xMaxRange - xMinRange + 1)*(yMaxRange - yMinRange + 1)
|
|
|
|
);
|
|
|
|
|
|
|
|
label p = 0;
|
|
|
|
for (label i = xMinRange - 1; i <= xMaxRange - 1; i++)
|
|
|
|
{
|
|
|
|
for (label j = yMinRange - 1; j <= yMaxRange - 1; j++)
|
|
|
|
{
|
|
|
|
result[p].setSize(4);
|
|
|
|
|
|
|
|
// set the points
|
|
|
|
result[p][0] = vtxLabel(i, j, 0);
|
|
|
|
result[p][1] = vtxLabel(i, j + 1, 0);
|
|
|
|
result[p][2] = vtxLabel(i + 1, j + 1, 0);
|
|
|
|
result[p][3] = vtxLabel(i + 1, j, 0);
|
|
|
|
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result.setSize(p);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
FatalErrorIn
|
|
|
|
(
|
|
|
|
"patchFaces(const label direc, const labelList& range) const"
|
|
|
|
) << "direction out of range (1 to 6): " << direc
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Correct the face orientation based on the handedness of the block.
|
|
|
|
// Do nothing for the right-handed block
|
|
|
|
if (blockHandedness_ == noPoints)
|
|
|
|
{
|
|
|
|
FatalErrorIn
|
|
|
|
(
|
|
|
|
"patchFaces(const label direc, const labelList& range) const"
|
|
|
|
) << "Unable to determine block handedness as points "
|
|
|
|
<< "have not been read in yet"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
else if (blockHandedness_ == left)
|
|
|
|
{
|
|
|
|
// turn all faces inside out
|
|
|
|
forAll (result, faceI)
|
|
|
|
{
|
|
|
|
result[faceI] = result[faceI].reverseFace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
|
|
|
|
} // End namespace Foam
|
|
|
|
|
|
|
|
// ************************************************************************* //
|