/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org \\ / A nd | Copyright (C) 2011-2024 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 "meshRefinement.H" #include "volMesh.H" #include "volFields.H" #include "surfaceMesh.H" #include "syncTools.H" #include "Time.H" #include "refinementHistory.H" #include "refinementSurfaces.H" #include "refinementFeatures.H" #include "decompositionMethod.H" #include "regionSplit.H" #include "fvMeshDistribute.H" #include "indirectPrimitivePatch.H" #include "polyTopoChange.H" #include "removeCells.H" #include "polyDistributionMap.H" #include "localPointRegion.H" #include "pointMesh.H" #include "pointFields.H" #include "slipPointPatchFields.H" #include "fixedValuePointPatchFields.H" #include "calculatedPointPatchFields.H" #include "cyclicSlipPointPatchFields.H" #include "processorPointPatch.H" #include "globalIndex.H" #include "meshTools.H" #include "OFstream.H" #include "geomDecomp.H" #include "Random.H" #include "searchableSurfaces.H" #include "treeBoundBox.H" #include "fvMeshTools.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { defineTypeNameAndDebug(meshRefinement, 0); template<> const char* Foam::NamedEnum < Foam::meshRefinement::IOdebugType, 5 >::names[] = { "mesh", "intersections", "featureSeeds", "attraction", "layerInfo" }; template<> const char* Foam::NamedEnum < Foam::meshRefinement::IOoutputType, 1 >::names[] = { "layerInfo" }; template<> const char* Foam::NamedEnum < Foam::meshRefinement::IOwriteType, 5 >::names[] = { "mesh", "noRefinement", "scalarLevels", "layerSets", "layerFields" }; } const Foam::NamedEnum Foam::meshRefinement::IOdebugTypeNames; const Foam::NamedEnum Foam::meshRefinement::IOoutputTypeNames; const Foam::NamedEnum Foam::meshRefinement::IOwriteTypeNames; Foam::meshRefinement::writeType Foam::meshRefinement::writeLevel_; Foam::meshRefinement::outputType Foam::meshRefinement::outputLevel_; // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // void Foam::meshRefinement::calcNeighbourData ( labelList& neiLevel, pointField& neiCc ) const { const labelList& cellLevel = meshCutter_.cellLevel(); const pointField& cellCentres = mesh_.cellCentres(); const label nBoundaryFaces = mesh_.nFaces() - mesh_.nInternalFaces(); if (neiLevel.size() != nBoundaryFaces || neiCc.size() != nBoundaryFaces) { FatalErrorInFunction << nBoundaryFaces << " neiLevel:" << neiLevel.size() << abort(FatalError); } const polyBoundaryMesh& patches = mesh_.boundaryMesh(); labelHashSet addedPatchIDSet(meshedPatches()); forAll(patches, patchi) { const polyPatch& pp = patches[patchi]; const labelUList& faceCells = pp.faceCells(); const vectorField::subField faceCentres = pp.faceCentres(); const vectorField::subField faceAreas = pp.faceAreas(); label bFacei = pp.start() - mesh_.nInternalFaces(); if (pp.coupled()) { forAll(faceCells, i) { neiLevel[bFacei] = cellLevel[faceCells[i]]; neiCc[bFacei] = cellCentres[faceCells[i]]; bFacei++; } } else if (addedPatchIDSet.found(patchi)) { // Face was introduced from cell-cell intersection. Try to // reconstruct other side cell(centre). Three possibilities: // - cells same size. // - preserved cell smaller. Not handled. // - preserved cell larger. forAll(faceCells, i) { // Extrapolate the face centre. const vector fn = faceAreas[i]/(mag(faceAreas[i]) + vSmall); const label own = faceCells[i]; const label ownLevel = cellLevel[own]; const label faceLevel = meshCutter_.faceLevel(pp.start() + i); // Normal distance from face centre to cell centre scalar d = ((faceCentres[i] - cellCentres[own]) & fn); if (faceLevel > ownLevel) { // Other cell more refined. Adjust normal distance d *= 0.5; } neiLevel[bFacei] = faceLevel; // Calculate other cell centre by extrapolation neiCc[bFacei] = faceCentres[i] + d*fn; bFacei++; } } else { forAll(faceCells, i) { neiLevel[bFacei] = cellLevel[faceCells[i]]; neiCc[bFacei] = faceCentres[i]; bFacei++; } } } // Swap coupled boundaries. Apply separation to cc since is coordinate. syncTools::swapBoundaryFacePositions(mesh_, neiCc); syncTools::swapBoundaryFaceList(mesh_, neiLevel); } void Foam::meshRefinement::updateIntersections(const labelList& changedFaces) { const pointField& cellCentres = mesh_.cellCentres(); // Stats on edges to test. Count proc faces only once. PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh_)); { label nMasterFaces = 0; forAll(isMasterFace, facei) { if (isMasterFace.get(facei) == 1) { nMasterFaces++; } } reduce(nMasterFaces, sumOp