/*---------------------------------------------------------------------------*\ ========= | \\ / 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 "faMeshReconstructor.H" #include "globalIndex.H" #include "globalMeshData.H" #include "edgeHashes.H" #include "Time.H" #include "PstreamCombineReduceOps.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // int Foam::faMeshReconstructor::debug = 0; // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // void Foam::faMeshReconstructor::calcAddressing ( const labelUList& fvFaceProcAddr ) { const globalIndex globalFaceNum(procMesh_.nFaces()); // ---------------------- // boundaryProcAddressing // // Trivial since non-processor boundary ordering is identical const label nPatches = procMesh_.boundary().size(); faBoundaryProcAddr_ = identity(nPatches); // Mark processor patches for ( label patchi = procMesh_.boundary().nNonProcessor(); patchi < nPatches; ++patchi ) { faBoundaryProcAddr_[patchi] = -1; } // ------------------ // faceProcAddressing // // Transcribe/rewrite based on finiteVolume faceProcAddressing faFaceProcAddr_ = procMesh_.faceLabels(); // From local faceLabels to proc values for (label& facei : faFaceProcAddr_) { // Use finiteVolume info, ignoring face flips facei = mag(fvFaceProcAddr[facei] - 1); } // Make global consistent. // Starting at '0', without gaps in numbering etc. // - the sorted order is the obvious solution { globalFaceNum.gather(faFaceProcAddr_, singlePatchFaceLabels_); const labelList globalOrder(Foam::sortedOrder(singlePatchFaceLabels_)); singlePatchFaceLabels_ = labelList(singlePatchFaceLabels_, globalOrder); // Set first face to be zero relative to the finiteArea patch // ie, local-face numbering with the first being 0 on any given patch { label patchFirstMeshfacei ( singlePatchFaceLabels_.empty() ? 0 : singlePatchFaceLabels_.first() ); Pstream::scatter(patchFirstMeshfacei); for (label& facei : faFaceProcAddr_) { facei -= patchFirstMeshfacei; } } PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking); if (Pstream::master()) { // Determine the respective local portions of the global ordering labelList procTargets(globalFaceNum.size()); for (const label proci : Pstream::allProcs()) { labelList::subList ( globalFaceNum.range(proci), procTargets ) = proci; } labelList procStarts(globalFaceNum.offsets()); labelList procOrders(globalFaceNum.size()); for (const label globali : globalOrder) { const label proci = procTargets[globali]; procOrders[procStarts[proci]++] = (globali - globalFaceNum.localStart(proci)); } // Send the local portions for (const int proci : Pstream::subProcs()) { SubList