/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright held by original author \\/ 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 "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 // ************************************************************************* //