diff --git a/applications/test/globalIndex/Make/files b/applications/test/globalIndex/Make/files new file mode 100644 index 0000000000..6d7dd88f14 --- /dev/null +++ b/applications/test/globalIndex/Make/files @@ -0,0 +1,4 @@ +globalIndex.C +globalIndexTest.C + +EXE = $(FOAM_USER_APPBIN)/globalIndexTest diff --git a/applications/test/globalIndex/Make/options b/applications/test/globalIndex/Make/options new file mode 100644 index 0000000000..90f18e878f --- /dev/null +++ b/applications/test/globalIndex/Make/options @@ -0,0 +1 @@ +EXE_INC = /* -DFULLDEBUG -g -O0 */ diff --git a/applications/test/globalIndex/globalIndexTest.C b/applications/test/globalIndex/globalIndexTest.C new file mode 100644 index 0000000000..60650cd93a --- /dev/null +++ b/applications/test/globalIndex/globalIndexTest.C @@ -0,0 +1,171 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + +Application + globalIndexTest + +Description + Simple demonstration and test application for the globalIndex class. + +\*---------------------------------------------------------------------------*/ + +#include "globalIndex.H" +#include "argList.H" +#include "Time.H" +#include "polyMesh.H" +#include "IOstreams.H" +#include "OStringStream.H" +#include "IStringStream.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ +# include "setRootCase.H" +# include "createTime.H" +# include "createPolyMesh.H" + + // Global numbering of cells (proc0 elements first, then proc1, etc.) + globalIndex globalNumbering(mesh.nCells()); + + if (globalNumbering.localSize() != mesh.nCells()) + { + FatalErrorIn(args.executable()) + << "Problem." << abort(FatalError); + } + + + if (!Pstream::parRun()) + { + WarningIn(args.executable()) + << "globalIndex class is only useful in parallel code." + << endl; + } + + // convert from local to global and back. + for (label cellI = 0; cellI < mesh.nCells(); cellI++) + { + // to global index + label globalCellI = globalNumbering.toGlobal(cellI); + + // and back + label procI = globalNumbering.whichProcID(globalCellI); + label localCellI = globalNumbering.toLocal(globalCellI); + + if (procI != Pstream::myProcNo() || localCellI != cellI) + { + FatalErrorIn(args.executable()) + << "Problem. cellI:" << cellI << " localCellI:" << localCellI + << " procI:" << procI << abort(FatalError); + } + + if (!globalNumbering.isLocal(globalCellI)) + { + FatalErrorIn(args.executable()) + << "Problem. cellI:" << cellI << " globalCellI:" << globalCellI + << " not local" << abort(FatalError); + } + } + + + // Try whichProcID on a few borderline cases. + + if (mesh.nCells() < 1) + { + FatalErrorIn(args.executable()) + << "Test needs to be run on a case with at least one" + << " cell per processor." << abort(FatalError); + } + + if (Pstream::myProcNo() > 0) + { + // We already checked that toGlobal(0) maps back correctly to myProcNo + // so now check that the index one before maps to the previous processor + label prevProcCellI = globalNumbering.toGlobal(0)-1; + label procI = globalNumbering.whichProcID(prevProcCellI); + + if (procI != Pstream::myProcNo()-1) + { + FatalErrorIn(args.executable()) + << "Problem. global:" << prevProcCellI + << " expected on processor:" << Pstream::myProcNo()-1 + << " but is calculated to be on procI:" << procI + << abort(FatalError); + } + + if (globalNumbering.isLocal(prevProcCellI)) + { + FatalErrorIn(args.executable()) + << "Problem. globalCellI:" << prevProcCellI + << " calculated as local" << abort(FatalError); + } + + if (!globalNumbering.isLocal(procI, prevProcCellI)) + { + FatalErrorIn(args.executable()) + << "Problem. globalCellI:" << prevProcCellI + << " not calculated as local on processor:" << procI + << abort(FatalError); + } + } + + + if (Pstream::myProcNo() < Pstream::nProcs()-1) + { + label nextProcCellI = globalNumbering.toGlobal(mesh.nCells()-1)+1; + label procI = globalNumbering.whichProcID(nextProcCellI); + + if (procI != Pstream::myProcNo()+1) + { + FatalErrorIn(args.executable()) + << "Problem. global:" << nextProcCellI + << " expected on processor:" << Pstream::myProcNo()+1 + << " but is calculated to be on procI:" << procI + << abort(FatalError); + } + + if (globalNumbering.isLocal(nextProcCellI)) + { + FatalErrorIn(args.executable()) + << "Problem. globalCellI:" << nextProcCellI + << " calculated as local" << abort(FatalError); + } + + if (!globalNumbering.isLocal(procI, nextProcCellI)) + { + FatalErrorIn(args.executable()) + << "Problem. globalCellI:" << nextProcCellI + << " not calculated as local on processor:" << procI + << abort(FatalError); + } + } + + return 0; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.C b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.C index 54cfc5eea5..37481760ba 100644 --- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.C +++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.C @@ -30,7 +30,7 @@ License Foam::globalIndex::globalIndex(const label localSize) : - offsets_(Pstream::nProcs()) + offsets_(Pstream::nProcs()+1) { labelList localSizes(Pstream::nProcs()); localSizes[Pstream::myProcNo()] = localSize; @@ -38,7 +38,8 @@ Foam::globalIndex::globalIndex(const label localSize) Pstream::scatterList(localSizes); // just to balance out comms label offset = 0; - forAll(offsets_, procI) + offsets_[0] = 0; + for (label procI = 0; procI < Pstream::nProcs(); procI++) { label oldOffset = offset; offset += localSizes[procI]; @@ -51,7 +52,7 @@ Foam::globalIndex::globalIndex(const label localSize) << "). Please recompile with larger datatype for label." << exit(FatalError); } - offsets_[procI] = offset; + offsets_[procI+1] = offset; } } diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.H b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.H index e394f679d0..4bf4f4a4ba 100644 --- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.H +++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.H @@ -64,7 +64,7 @@ class globalIndex { // Private data - //- Start off procI+1. (so like CompactListList) + //- Start of procI. Size is nProcs()+1. (so like CompactListList) labelList offsets_; @@ -81,10 +81,6 @@ public: // Member Functions - ////- Start of procI+1 data - //inline const labelList& offsets() const; - - // Queries relating to my processor //- my local size diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndexI.H b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndexI.H index d7c44107c6..f00fbbeb81 100644 --- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndexI.H +++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndexI.H @@ -28,26 +28,15 @@ License // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -//inline const Foam::labelList& Foam::globalIndex::offsets() const -//{ -// return offsets_; -//} - - inline Foam::label Foam::globalIndex::offset(const label procI) const { - return (procI == 0 ? 0 : offsets_[procI-1]); + return offsets_[procI]; } inline Foam::label Foam::globalIndex::localSize(const label procI) const { - return - ( - procI == 0 - ? offsets_[procI] - : offsets_[procI] - offsets_[procI-1] - ); + return offsets_[procI+1] - offsets_[procI]; } @@ -59,7 +48,7 @@ inline Foam::label Foam::globalIndex::localSize() const inline Foam::label Foam::globalIndex::size() const { - return offsets_[Pstream::nProcs()-1]; + return offsets_[Pstream::nProcs()]; } @@ -69,7 +58,7 @@ inline Foam::label Foam::globalIndex::toGlobal const label i ) const { - return(procI == 0 ? i : i + offsets_[procI-1]); + return i + offsets_[procI]; } @@ -82,9 +71,7 @@ inline Foam::label Foam::globalIndex::toGlobal(const label i) const //- Is on local processor inline bool Foam::globalIndex::isLocal(const label procI, const label i) const { - return - (i < offsets_[procI]) - && (i >= (procI == 0 ? 0 : offsets_[procI-1])); + return i >= offsets_[procI] && i < offsets_[procI+1]; } @@ -97,9 +84,9 @@ inline bool Foam::globalIndex::isLocal(const label i) const inline Foam::label Foam::globalIndex::toLocal(const label procI, const label i) const { - label localI = (procI == 0 ? i : i - offsets_[procI-1]); + label localI = i - offsets_[procI]; - if (localI < 0 || i >= offsets_[procI]) + if (localI < 0 || i >= offsets_[procI+1]) { FatalErrorIn("globalIndex::toLocal(const label, const label)") << "Global " << i << " does not belong on processor " @@ -118,9 +105,7 @@ inline Foam::label Foam::globalIndex::toLocal(const label i) const inline Foam::label Foam::globalIndex::whichProcID(const label i) const { - label index = findLower(offsets_, i+1); - - if (index == Pstream::nProcs()-1) + if (i < 0 || i >= offsets_[Pstream::nProcs()]) { FatalErrorIn("globalIndex::whichProcID(const label)") << "Global " << i << " does not belong on any processor." @@ -128,7 +113,7 @@ inline Foam::label Foam::globalIndex::whichProcID(const label i) const << abort(FatalError); } - return index+1; + return findLower(offsets_, i+1); }