/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2010-2010 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 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 "multiLevelDecomp.H" #include "addToRunTimeSelectionTable.H" #include "IFstream.H" #include "globalIndex.H" #include "mapDistribute.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { defineTypeNameAndDebug(multiLevelDecomp, 0); addToRunTimeSelectionTable ( decompositionMethod, multiLevelDecomp, dictionary ); } // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // Given a subset of cells determine the new global indices. The problem // is in the cells from neighbouring processors which need to be renumbered. void Foam::multiLevelDecomp::subsetGlobalCellCells ( const label nDomains, const label domainI, const labelList& dist, const labelListList& cellCells, const labelList& set, labelListList& subCellCells, labelList& cutConnections ) const { // Determine new index for cells by inverting subset labelList oldToNew(invert(cellCells.size(), set)); globalIndex globalCells(cellCells.size()); // Subset locally the elements for which I have data subCellCells = UIndirectList(cellCells, set); // Get new indices for neighbouring processors List > compactMap; mapDistribute map(globalCells, subCellCells, compactMap); map.distribute(oldToNew); labelList allDist(dist); map.distribute(allDist); // Now subCellCells contains indices into oldToNew which are the // new locations of the neighbouring cells. cutConnections.setSize(nDomains); cutConnections = 0; forAll(subCellCells, subCellI) { labelList& cCells = subCellCells[subCellI]; // Keep the connections to valid mapped cells label newI = 0; forAll(cCells, i) { label subCellI = oldToNew[cCells[i]]; if (subCellI == -1) { cutConnections[allDist[cCells[i]]]++; } else { cCells[newI++] = subCellI; } } cCells.setSize(newI); } } void Foam::multiLevelDecomp::decompose ( const labelListList& pointPoints, const pointField& points, const scalarField& pointWeights, const labelList& pointMap, // map back to original points const label levelI, labelField& finalDecomp ) { labelList dist ( methods_[levelI].decompose ( pointPoints, points, pointWeights ) ); forAll(pointMap, i) { label orig = pointMap[i]; finalDecomp[orig] += dist[i]; } if (levelI != methods_.size()-1) { // Recurse // Determine points per domain label n = methods_[levelI].nDomains(); labelListList domainToPoints(invertOneToMany(n, dist)); // 'Make space' for new levels of decomposition finalDecomp *= methods_[levelI+1].nDomains(); // Extract processor+local index from point-point addressing if (debug && Pstream::master()) { Pout<< "Decomposition at level " << levelI << " :" << endl; } for (label domainI = 0; domainI < n; domainI++) { // Extract elements for current domain const labelList domainPoints(findIndices(dist, domainI)); // Subset point-wise data. pointField subPoints(points, domainPoints); scalarField subWeights(pointWeights, domainPoints); labelList subPointMap(UIndirectList