/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 1991-2009 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 "primitiveMesh.H" #include "pyramidPointFaceRef.H" #include "ListOps.H" #include "mathematicalConstants.H" #include "SortableList.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // Foam::scalar Foam::primitiveMesh::closedThreshold_ = 1.0e-6; Foam::scalar Foam::primitiveMesh::aspectThreshold_ = 1000; Foam::scalar Foam::primitiveMesh::nonOrthThreshold_ = 70; // deg Foam::scalar Foam::primitiveMesh::skewThreshold_ = 4; // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // bool Foam::primitiveMesh::checkClosedBoundary(const bool report) const { if (debug) { Info<< "bool primitiveMesh::checkClosedBoundary(" << "const bool) const: " << "checking whether the boundary is closed" << endl; } // Loop through all boundary faces and sum up the face area vectors. // For a closed boundary, this should be zero in all vector components vector sumClosed(vector::zero); scalar sumMagClosedBoundary = 0; const vectorField& areas = faceAreas(); for (label faceI = nInternalFaces(); faceI < areas.size(); faceI++) { sumClosed += areas[faceI]; sumMagClosedBoundary += mag(areas[faceI]); } reduce(sumClosed, sumOp()); reduce(sumMagClosedBoundary, sumOp()); vector openness = sumClosed/(sumMagClosedBoundary + VSMALL); if (cmptMax(cmptMag(openness)) > closedThreshold_) { if (debug || report) { Info<< " ***Boundary openness " << openness << " possible hole in boundary description." << endl; } return true; } else { if (debug || report) { Info<< " Boundary openness " << openness << " OK." << endl; } return false; } } bool Foam::primitiveMesh::checkClosedCells ( const bool report, labelHashSet* setPtr, labelHashSet* aspectSetPtr ) const { if (debug) { Info<< "bool primitiveMesh::checkClosedCells(" << "const bool, labelHashSet*, labelHashSet*) const: " << "checking whether cells are closed" << endl; } // Check that all cells labels are valid const cellList& c = cells(); label nErrorClosed = 0; forAll (c, cI) { const cell& curCell = c[cI]; if (min(curCell) < 0 || max(curCell) > nFaces()) { if (setPtr) { setPtr->insert(cI); } nErrorClosed++; } } if (nErrorClosed > 0) { if (debug || report) { Info<< " ***Cells with invalid face labels found, number of cells " << nErrorClosed << endl; } return true; } // Loop through cell faces and sum up the face area vectors for each cell. // This should be zero in all vector components vectorField sumClosed(nCells(), vector::zero); vectorField sumMagClosed(nCells(), vector::zero); const labelList& own = faceOwner(); const labelList& nei = faceNeighbour(); const vectorField& areas = faceAreas(); forAll (own, faceI) { // Add to owner sumClosed[own[faceI]] += areas[faceI]; sumMagClosed[own[faceI]] += cmptMag(areas[faceI]); } forAll (nei, faceI) { // Subtract from neighbour sumClosed[nei[faceI]] -= areas[faceI]; sumMagClosed[nei[faceI]] += cmptMag(areas[faceI]); } label nOpen = 0; scalar maxOpennessCell = 0; label nAspect = 0; scalar maxAspectRatio = 0; const scalarField& vols = cellVolumes(); // Check the sums forAll (sumClosed, cellI) { scalar maxOpenness = 0; for(direction cmpt=0; cmpt closedThreshold_) { if (setPtr) { setPtr->insert(cellI); } nOpen++; } // Calculate the aspect ration as the maximum of Cartesian component // aspect ratio to the total area hydraulic area aspect ratio scalar aspectRatio = max ( cmptMax(sumMagClosed[cellI]) /(cmptMin(sumMagClosed[cellI]) + VSMALL), 1.0/6.0*cmptSum(sumMagClosed[cellI])/pow(vols[cellI], 2.0/3.0) ); maxAspectRatio = max(maxAspectRatio, aspectRatio); if (aspectRatio > aspectThreshold_) { if (aspectSetPtr) { aspectSetPtr->insert(cellI); } nAspect++; } } reduce(nOpen, sumOp