diff --git a/src/finiteArea/Make/files b/src/finiteArea/Make/files index 85d56a5e87..2badfb337d 100644 --- a/src/finiteArea/Make/files +++ b/src/finiteArea/Make/files @@ -4,6 +4,7 @@ faMesh/faMeshDemandDrivenData.C faMesh/faMeshPatches.C faMesh/faMeshTopology.C faMesh/faMeshUpdate.C +faMesh/faMeshBoundaryHalo.C faMesh/faBoundaryMesh/faBoundaryMesh.C faPatches = faMesh/faPatches diff --git a/src/finiteArea/faMesh/faMesh.C b/src/finiteArea/faMesh/faMesh.C index 021b83a327..40763bce48 100644 --- a/src/finiteArea/faMesh/faMesh.C +++ b/src/finiteArea/faMesh/faMesh.C @@ -27,6 +27,7 @@ License \*---------------------------------------------------------------------------*/ #include "faMesh.H" +#include "faMeshBoundaryHalo.H" #include "faGlobalMeshData.H" #include "Time.H" #include "polyMesh.H" @@ -109,6 +110,36 @@ static labelList selectPatchFaces // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // +void Foam::faMesh::checkBoundaryEdgeLabelRange +( + const labelUList& edgeLabels +) const +{ + label nErrors = 0; + + for (const label edgei : edgeLabels) + { + if (edgei < nInternalEdges_ || edgei >= nEdges_) + { + if (!nErrors++) + { + FatalErrorInFunction + << "Boundary edge label out of range " + << nInternalEdges_ << ".." << (nEdges_-1) << nl + << " "; + } + + FatalError<< ' ' << edgei; + } + } + + if (nErrors) + { + FatalError << nl << exit(FatalError); + } +} + + void Foam::faMesh::initPatch() const { patchPtr_.reset @@ -120,6 +151,9 @@ void Foam::faMesh::initPatch() const ) ); bndConnectPtr_.reset(nullptr); + haloMapPtr_.reset(nullptr); + haloFaceCentresPtr_.reset(nullptr); + haloFaceNormalsPtr_.reset(nullptr); } @@ -168,10 +202,21 @@ void Foam::faMesh::setPrimitiveMeshData() } +void Foam::faMesh::clearHalo() const +{ + DebugInFunction << "Clearing halo information" << endl; + + haloMapPtr_.reset(nullptr); + haloFaceCentresPtr_.reset(nullptr); + haloFaceNormalsPtr_.reset(nullptr); +} + + void Foam::faMesh::clearGeomNotAreas() const { DebugInFunction << "Clearing geometry" << endl; + clearHalo(); patchPtr_.reset(nullptr); bndConnectPtr_.reset(nullptr); deleteDemandDrivenData(SPtr_); @@ -274,7 +319,11 @@ Foam::faMesh::faMesh(const polyMesh& pMesh) faceCurvaturesPtr_(nullptr), edgeTransformTensorsPtr_(nullptr), correctPatchPointNormalsPtr_(nullptr), - globalMeshDataPtr_(nullptr) + globalMeshDataPtr_(nullptr), + + haloMapPtr_(nullptr), + haloFaceCentresPtr_(nullptr), + haloFaceNormalsPtr_(nullptr) { DebugInFunction << "Creating from IOobject" << endl; @@ -368,7 +417,11 @@ Foam::faMesh::faMesh faceCurvaturesPtr_(nullptr), edgeTransformTensorsPtr_(nullptr), correctPatchPointNormalsPtr_(nullptr), - globalMeshDataPtr_(nullptr) + globalMeshDataPtr_(nullptr), + + haloMapPtr_(nullptr), + haloFaceCentresPtr_(nullptr), + haloFaceNormalsPtr_(nullptr) {} diff --git a/src/finiteArea/faMesh/faMesh.H b/src/finiteArea/faMesh/faMesh.H index 313db0517a..c18674b716 100644 --- a/src/finiteArea/faMesh/faMesh.H +++ b/src/finiteArea/faMesh/faMesh.H @@ -71,6 +71,7 @@ namespace Foam { // Forward Declarations +class faMeshBoundaryHalo; class faMeshLduAddressing; class faMeshMapper; class faPatchData; @@ -291,11 +292,20 @@ class faMesh mutable boolList* correctPatchPointNormalsPtr_; - // Other mesh-related data + // Other mesh-related data //- Parallel info mutable autoPtr globalMeshDataPtr_; + //- Mapping/swapping for boundary edge halo neighbours + mutable std::unique_ptr haloMapPtr_; + + //- Face centres for boundary edge halo neighbours + mutable std::unique_ptr haloFaceCentresPtr_; + + //- Face normals for boundary edge halo neighbours + mutable std::unique_ptr haloFaceNormalsPtr_; + // Static Private Data @@ -376,6 +386,9 @@ class faMesh //- Clear geometry but not the face areas void clearGeomNotAreas() const; + //- Clear boundary halo information + void clearHalo() const; + //- Clear geometry void clearGeom() const; @@ -386,6 +399,12 @@ class faMesh void clearOut() const; + // Halo handling + + //- Calculate halo centres/normals + void calcHaloFaceGeometry() const; + + // Helpers //- Create a single patch @@ -404,6 +423,32 @@ class faMesh ) const; + //- Fatal error if edge labels are out of range + void checkBoundaryEdgeLabelRange(const labelUList& edgeLabels) const; + + //- Extract list from contiguous (unordered) boundary data + //- to the locally sorted order. + template + List boundarySubset + ( + const UList& bndField, + const labelUList& edgeLabels + ) const + { + #ifdef FULLDEBUG + checkBoundaryEdgeLabelRange(edgeLabels); + #endif + // Like UIndirectList but with an offset + List result(edgeLabels.size()); + forAll(edgeLabels, i) + { + result[i] = bndField[edgeLabels[i] - nInternalEdges_]; + } + return result; + } + + + public: // Public Typedefs @@ -607,6 +652,21 @@ public: //- (does not include own proc) List boundaryProcSizes() const; + //- Mapping/swapping for boundary halo neighbours + const faMeshBoundaryHalo& boundaryHaloMap() const; + + //- Face centres of boundary halo neighbours + const pointField& haloFaceCentres() const; + + //- Face normals of boundary halo neighbours + const vectorField& haloFaceNormals() const; + + //- Face centres of boundary halo neighbours for specified patch + tmp haloFaceCentres(const label patchi) const; + + //- Face normals of boundary halo neighbours for specified patch + tmp haloFaceNormals(const label patchi) const; + // Mesh motion and morphing diff --git a/src/finiteArea/faMesh/faMeshBoundaryHalo.C b/src/finiteArea/faMesh/faMeshBoundaryHalo.C new file mode 100644 index 0000000000..81aa63c117 --- /dev/null +++ b/src/finiteArea/faMesh/faMeshBoundaryHalo.C @@ -0,0 +1,194 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 OpenCFD Ltd. +------------------------------------------------------------------------------- +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 "faMeshBoundaryHalo.H" +#include "faMesh.H" +#include "globalIndex.H" +#include "Pstream.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(faMeshBoundaryHalo, 0); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::faMeshBoundaryHalo::faMeshBoundaryHalo(const label comm) +: + mapDistributeBase(comm), + inputMeshFaces_(), + boundaryToCompact_() +{} + + +Foam::faMeshBoundaryHalo::faMeshBoundaryHalo(const faMesh& areaMesh) +: + mapDistributeBase(), + inputMeshFaces_(), + boundaryToCompact_() +{ + reset(areaMesh); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::faMeshBoundaryHalo::clear() +{ + static_cast(*this) = mapDistributeBase(); + + inputMeshFaces_.clear(); + boundaryToCompact_.clear(); +} + + +Foam::label Foam::faMeshBoundaryHalo::haloSize() const +{ + if (Pstream::parRun()) + { + return boundaryToCompact_.size(); + } + else + { + return inputMeshFaces_.size(); + } +} + + +void Foam::faMeshBoundaryHalo::reset(const faMesh& areaMesh) +{ + inputMeshFaces_.clear(); + boundaryToCompact_.clear(); + + const auto& procConnections = areaMesh.boundaryConnections(); + + if (!Pstream::parRun()) + { + // Serial - extract halo numbers directly + + inputMeshFaces_.resize(procConnections.size()); + + forAll(procConnections, connecti) + { + // Connected neighbour, non-parallel = must be local + const auto& tuple = procConnections[connecti]; + // const label nbrProci = tuple.first(); + const label nbrFacei = tuple.second(); + + inputMeshFaces_[connecti] = nbrFacei; + } + + return; + } + + const label nProcs = Pstream::nProcs(comm_); + const label myRank = Pstream::myProcNo(comm_); + + const globalIndex globalFaceNum(areaMesh.mesh().nFaces()); + + // Boundary inside faces in polyMesh face ids + const labelList insideFaces + ( + UIndirectList