mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
split of decompositionAgglomeration
This commit is contained in:
12
src/decompositionMethods/Allwmake
Executable file
12
src/decompositionMethods/Allwmake
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
cd ${0%/*} || exit 1 # run from this directory
|
||||
set -x
|
||||
|
||||
wmake libso decompositionMethods
|
||||
|
||||
if [ -d "$FOAM_MPI_LIBBIN" ]
|
||||
then
|
||||
(WM_OPTIONS=${WM_OPTIONS}$WM_MPLIB; wmake libso parMetisDecomp)
|
||||
fi
|
||||
|
||||
# ----------------------------------------------------------------- end-of-file
|
||||
8
src/decompositionMethods/decompositionMethods/Make/files
Normal file
8
src/decompositionMethods/decompositionMethods/Make/files
Normal file
@ -0,0 +1,8 @@
|
||||
decompositionMethod/decompositionMethod.C
|
||||
geomDecomp/geomDecomp.C
|
||||
simpleGeomDecomp/simpleGeomDecomp.C
|
||||
hierarchGeomDecomp/hierarchGeomDecomp.C
|
||||
metisDecomp/metisDecomp.C
|
||||
manualDecomp/manualDecomp.C
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/libdecompositionMethods
|
||||
@ -0,0 +1,6 @@
|
||||
EXE_INC = \
|
||||
-I$(WM_THIRD_PARTY_DIR)/metis-5.0pre2/include
|
||||
|
||||
LIB_LIBS = \
|
||||
-lmetis \
|
||||
-lGKlib
|
||||
@ -0,0 +1,173 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
InClass
|
||||
decompositionMethod
|
||||
|
||||
Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "decompositionMethod.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(decompositionMethod, 0);
|
||||
defineRunTimeSelectionTable(decompositionMethod, dictionary);
|
||||
defineRunTimeSelectionTable(decompositionMethod, dictionaryMesh);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::autoPtr<Foam::decompositionMethod> Foam::decompositionMethod::New
|
||||
(
|
||||
const dictionary& decompositionDict
|
||||
)
|
||||
{
|
||||
word decompositionMethodTypeName(decompositionDict.lookup("method"));
|
||||
|
||||
Info<< "Selecting decompositionMethod "
|
||||
<< decompositionMethodTypeName << endl;
|
||||
|
||||
dictionaryConstructorTable::iterator cstrIter =
|
||||
dictionaryConstructorTablePtr_->find(decompositionMethodTypeName);
|
||||
|
||||
if (cstrIter == dictionaryConstructorTablePtr_->end())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"decompositionMethod::New"
|
||||
"(const dictionary& decompositionDict)"
|
||||
) << "Unknown decompositionMethod "
|
||||
<< decompositionMethodTypeName << endl << endl
|
||||
<< "Valid decompositionMethods are : " << endl
|
||||
<< dictionaryConstructorTablePtr_->toc()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<decompositionMethod>(cstrIter()(decompositionDict));
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::decompositionMethod> Foam::decompositionMethod::New
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
)
|
||||
{
|
||||
word decompositionMethodTypeName(decompositionDict.lookup("method"));
|
||||
|
||||
Info<< "Selecting decompositionMethod "
|
||||
<< decompositionMethodTypeName << endl;
|
||||
|
||||
dictionaryMeshConstructorTable::iterator cstrIter =
|
||||
dictionaryMeshConstructorTablePtr_->find(decompositionMethodTypeName);
|
||||
|
||||
if (cstrIter == dictionaryMeshConstructorTablePtr_->end())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"decompositionMethod::New"
|
||||
"(const dictionary& decompositionDict, "
|
||||
"const polyMesh& mesh)"
|
||||
) << "Unknown decompositionMethod "
|
||||
<< decompositionMethodTypeName << endl << endl
|
||||
<< "Valid decompositionMethods are : " << endl
|
||||
<< dictionaryMeshConstructorTablePtr_->toc()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<decompositionMethod>(cstrIter()(decompositionDict, mesh));
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::decompositionMethod::decompose
|
||||
(
|
||||
const labelList& fineToCoarse,
|
||||
const pointField& coarsePoints
|
||||
)
|
||||
{
|
||||
// Decompose based on agglomerated points
|
||||
labelList coarseDistribution(decompose(coarsePoints));
|
||||
|
||||
// Rework back into decomposition for original mesh_
|
||||
labelList fineDistribution(fineToCoarse.size());
|
||||
|
||||
forAll(fineDistribution, i)
|
||||
{
|
||||
fineDistribution[i] = coarseDistribution[fineToCoarse[i]];
|
||||
}
|
||||
|
||||
return fineDistribution;
|
||||
}
|
||||
|
||||
|
||||
void Foam::decompositionMethod::calcCellCells
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const labelList& fineToCoarse,
|
||||
const label nCoarse,
|
||||
labelListList& cellCells
|
||||
)
|
||||
{
|
||||
if (fineToCoarse.size() != mesh.nCells())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"decompositionMethod::calcCellCells"
|
||||
"(const labelList&, labelListList&) const"
|
||||
) << "Only valid for mesh agglomeration." << exit(FatalError);
|
||||
}
|
||||
|
||||
List<DynamicList<label> > dynCellCells(nCoarse);
|
||||
|
||||
forAll(mesh.faceNeighbour(), faceI)
|
||||
{
|
||||
label own = fineToCoarse[mesh.faceOwner()[faceI]];
|
||||
label nei = fineToCoarse[mesh.faceNeighbour()[faceI]];
|
||||
|
||||
if (own != nei)
|
||||
{
|
||||
if (findIndex(dynCellCells[own], nei) == -1)
|
||||
{
|
||||
dynCellCells[own].append(nei);
|
||||
}
|
||||
if (findIndex(dynCellCells[nei], own) == -1)
|
||||
{
|
||||
dynCellCells[nei].append(own);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cellCells.setSize(dynCellCells.size());
|
||||
forAll(dynCellCells, coarseI)
|
||||
{
|
||||
cellCells[coarseI].transfer(dynCellCells[coarseI]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,191 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::decompositionMethod
|
||||
|
||||
Description
|
||||
Abstract base class for decomposition
|
||||
|
||||
SourceFiles
|
||||
decompositionMethod.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef decompositionMethod_H
|
||||
#define decompositionMethod_H
|
||||
|
||||
#include "polyMesh.H"
|
||||
#include "pointField.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class decompositionMethod Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class decompositionMethod
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
const dictionary& decompositionDict_;
|
||||
label nProcessors_;
|
||||
|
||||
|
||||
//- Helper: determine (non-parallel) cellCells from mesh agglomeration.
|
||||
static void calcCellCells
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const labelList& agglom,
|
||||
const label nCoarse,
|
||||
labelListList& cellCells
|
||||
);
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct and assignment
|
||||
decompositionMethod(const decompositionMethod&);
|
||||
void operator=(const decompositionMethod&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("decompositionMethod");
|
||||
|
||||
|
||||
// Declare run-time constructor selection tables
|
||||
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
decompositionMethod,
|
||||
dictionary,
|
||||
(
|
||||
const dictionary& decompositionDict
|
||||
),
|
||||
(decompositionDict)
|
||||
);
|
||||
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
decompositionMethod,
|
||||
dictionaryMesh,
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
),
|
||||
(decompositionDict, mesh)
|
||||
);
|
||||
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Return a reference to the selected decomposition method
|
||||
static autoPtr<decompositionMethod> New
|
||||
(
|
||||
const dictionary& decompositionDict
|
||||
);
|
||||
|
||||
//- Return a reference to the selected decomposition method
|
||||
static autoPtr<decompositionMethod> New
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct given the decomposition dictionary
|
||||
decompositionMethod(const dictionary& decompositionDict)
|
||||
:
|
||||
decompositionDict_(decompositionDict),
|
||||
nProcessors_
|
||||
(
|
||||
readLabel(decompositionDict.lookup("numberOfSubdomains"))
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
virtual ~decompositionMethod()
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Is method parallel aware (i.e. does it synchronize domains across
|
||||
// proc boundaries)
|
||||
virtual bool parallelAware() const = 0;
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Use the
|
||||
// mesh connectivity (if needed)
|
||||
virtual labelList decompose(const pointField&) = 0;
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Gets
|
||||
// passed agglomeration map (from fine to coarse cells) and coarse cell
|
||||
// location. Can be overridden by decomposers that provide this
|
||||
// functionality natively. Coarse cells are local to the processor
|
||||
// (if in parallel). If you want to have coarse cells spanning
|
||||
// processors use the next function below instead.
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelList& cellToRegion,
|
||||
const pointField& regionPoints
|
||||
);
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Explicitly
|
||||
// provided connectivity - does not use mesh_.
|
||||
// The connectivity is equal to mesh.cellCells() except for
|
||||
// - in parallel the cell numbers are global cell numbers (starting
|
||||
// from 0 at processor0 and then incrementing all through the
|
||||
// processors)
|
||||
// - the connections are across coupled patches
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelListList& globalCellCells,
|
||||
const pointField& cc
|
||||
) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,74 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "geomDecomp.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::geomDecomp::geomDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const word& derivedType
|
||||
)
|
||||
:
|
||||
decompositionMethod(decompositionDict),
|
||||
geomDecomDict_(decompositionDict.subDict(derivedType + "Coeffs")),
|
||||
n_(geomDecomDict_.lookup("n")),
|
||||
delta_(readScalar(geomDecomDict_.lookup("delta"))),
|
||||
rotDelta_(I)
|
||||
{
|
||||
// check that the case makes sense :
|
||||
|
||||
if (nProcessors_ != n_.x()*n_.y()*n_.z())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"geomDecomp::geomDecomp"
|
||||
"(const dictionary& decompositionDict)"
|
||||
) << "Wrong number of processor divisions in geomDecomp:" << nl
|
||||
<< "Number of domains : " << nProcessors_ << nl
|
||||
<< "Wanted decomposition : " << n_
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
scalar d = 1 - 0.5*delta_*delta_;
|
||||
scalar d2 = sqr(d);
|
||||
|
||||
scalar a = delta_;
|
||||
scalar a2 = sqr(a);
|
||||
|
||||
rotDelta_ = tensor
|
||||
(
|
||||
d2, -a*d, a,
|
||||
a*d - a2*d, a*a2 + d2, -2*a*d,
|
||||
a*d2 + a2, a*d - a2*d, d2 - a2
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,86 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::geomDecomp
|
||||
|
||||
Description
|
||||
Geometrical domain decomposition
|
||||
|
||||
SourceFiles
|
||||
geomDecomp.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef geomDecomp_H
|
||||
#define geomDecomp_H
|
||||
|
||||
#include "decompositionMethod.H"
|
||||
#include "Vector.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class geomDecomp Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class geomDecomp
|
||||
:
|
||||
public decompositionMethod
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
const dictionary& geomDecomDict_;
|
||||
|
||||
Vector<label> n_;
|
||||
scalar delta_;
|
||||
tensor rotDelta_;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct given the decomposition dictionary
|
||||
// and the derived type name
|
||||
geomDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const word& derivedType
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,467 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "hierarchGeomDecomp.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "PstreamReduceOps.H"
|
||||
#include "SortableList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(hierarchGeomDecomp, 0);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
decompositionMethod,
|
||||
hierarchGeomDecomp,
|
||||
dictionary
|
||||
);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
decompositionMethod,
|
||||
hierarchGeomDecomp,
|
||||
dictionaryMesh
|
||||
);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::hierarchGeomDecomp::setDecompOrder()
|
||||
{
|
||||
word order(geomDecomDict_.lookup("order"));
|
||||
|
||||
if (order.size() != 3)
|
||||
{
|
||||
FatalIOErrorIn
|
||||
(
|
||||
"hierarchGeomDecomp::hierarchGeomDecomp"
|
||||
"(const dictionary& decompositionDict)",
|
||||
decompositionDict_
|
||||
) << "number of characters in order (" << order << ") != 3"
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
for (label i = 0; i < 3; i++)
|
||||
{
|
||||
if (order[i] == 'x')
|
||||
{
|
||||
decompOrder_[i] = 0;
|
||||
}
|
||||
else if (order[i] == 'y')
|
||||
{
|
||||
decompOrder_[i] = 1;
|
||||
}
|
||||
else if (order[i] == 'z')
|
||||
{
|
||||
decompOrder_[i] = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorIn
|
||||
(
|
||||
"hierarchGeomDecomp::hierarchGeomDecomp"
|
||||
"(const dictionary& decompositionDict)",
|
||||
decompositionDict_
|
||||
) << "Illegal decomposition order " << order << endl
|
||||
<< "It should only contain x, y or z" << exit(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::hierarchGeomDecomp::findLower
|
||||
(
|
||||
const List<scalar>& l,
|
||||
const scalar t,
|
||||
const label initLow,
|
||||
const label initHigh
|
||||
)
|
||||
{
|
||||
if (initHigh <= initLow)
|
||||
{
|
||||
return initLow;
|
||||
}
|
||||
|
||||
label low = initLow;
|
||||
label high = initHigh;
|
||||
|
||||
while ((high - low) > 1)
|
||||
{
|
||||
label mid = (low + high)/2;
|
||||
|
||||
if (l[mid] < t)
|
||||
{
|
||||
low = mid;
|
||||
}
|
||||
else
|
||||
{
|
||||
high = mid;
|
||||
}
|
||||
}
|
||||
|
||||
// high and low can still differ by one. Choose best.
|
||||
|
||||
label tIndex = -1;
|
||||
|
||||
if (l[high-1] < t)
|
||||
{
|
||||
tIndex = high;
|
||||
}
|
||||
else
|
||||
{
|
||||
tIndex = low;
|
||||
}
|
||||
|
||||
return tIndex;
|
||||
}
|
||||
|
||||
|
||||
// Find position in values so between minIndex and this position there
|
||||
// are wantedSize elements.
|
||||
void Foam::hierarchGeomDecomp::findBinary
|
||||
(
|
||||
const label sizeTol,
|
||||
const List<scalar>& values,
|
||||
const label minIndex, // index of previous value
|
||||
const scalar minValue, // value at minIndex
|
||||
const scalar maxValue, // global max of values
|
||||
const scalar wantedSize, // wanted size
|
||||
|
||||
label& mid, // index where size of bin is
|
||||
// wantedSize (to within sizeTol)
|
||||
scalar& midValue // value at mid
|
||||
)
|
||||
{
|
||||
label low = minIndex;
|
||||
scalar lowValue = minValue;
|
||||
|
||||
scalar highValue = maxValue;
|
||||
// (one beyond) index of highValue
|
||||
label high = values.size();
|
||||
|
||||
// Safeguards to avoid infinite loop.
|
||||
label lowPrev = -1;
|
||||
label midPrev = -1;
|
||||
label highPrev = -1;
|
||||
|
||||
//while (low <= high)
|
||||
while (true)
|
||||
{
|
||||
label size = returnReduce(mid-minIndex, sumOp<label>());
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "low:" << low << " lowValue:" << lowValue
|
||||
<< " high:" << high << " highValue:" << highValue
|
||||
<< " mid:" << mid << " midValue:" << midValue << nl
|
||||
<< "globalSize:" << size << " wantedSize:" << wantedSize
|
||||
<< " sizeTol:" << sizeTol << endl;
|
||||
}
|
||||
|
||||
if (wantedSize < size - sizeTol)
|
||||
{
|
||||
high = mid;
|
||||
highValue = midValue;
|
||||
}
|
||||
else if (wantedSize > size + sizeTol)
|
||||
{
|
||||
low = mid;
|
||||
lowValue = midValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Update mid, midValue
|
||||
midValue = 0.5*(lowValue+highValue);
|
||||
mid = findLower(values, midValue, low, high);
|
||||
|
||||
// Safeguard if same as previous.
|
||||
bool hasNotChanged = (mid == midPrev) && (low == lowPrev) && (high == highPrev);
|
||||
if (returnReduce(hasNotChanged, andOp<bool>()))
|
||||
{
|
||||
WarningIn("hierarchGeomDecomp::findBinary(..)")
|
||||
<< "unable to find desired deomposition split, making do!"
|
||||
<< endl;
|
||||
break;
|
||||
}
|
||||
|
||||
midPrev = mid;
|
||||
lowPrev = low;
|
||||
highPrev = high;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sort points into bins according to one component. Recurses to next component.
|
||||
void Foam::hierarchGeomDecomp::sortComponent
|
||||
(
|
||||
const label sizeTol,
|
||||
const pointField& points,
|
||||
const labelList& current, // slice of points to decompose
|
||||
const direction componentIndex, // index in decompOrder_
|
||||
const label mult, // multiplication factor for finalDecomp
|
||||
labelList& finalDecomp
|
||||
)
|
||||
{
|
||||
// Current component
|
||||
label compI = decompOrder_[componentIndex];
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "sortComponent : Sorting slice of size " << current.size()
|
||||
<< " in component " << compI << endl;
|
||||
}
|
||||
|
||||
// Storage for sorted component compI
|
||||
SortableList<scalar> sortedCoord(current.size());
|
||||
|
||||
forAll(current, i)
|
||||
{
|
||||
label pointI = current[i];
|
||||
|
||||
sortedCoord[i] = points[pointI][compI];
|
||||
}
|
||||
sortedCoord.sort();
|
||||
|
||||
label globalCurrentSize = returnReduce(current.size(), sumOp<label>());
|
||||
|
||||
scalar minCoord = returnReduce
|
||||
(
|
||||
(
|
||||
sortedCoord.size()
|
||||
? sortedCoord[0]
|
||||
: GREAT
|
||||
),
|
||||
minOp<scalar>()
|
||||
);
|
||||
|
||||
scalar maxCoord = returnReduce
|
||||
(
|
||||
(
|
||||
sortedCoord.size()
|
||||
? sortedCoord[sortedCoord.size()-1]
|
||||
: -GREAT
|
||||
),
|
||||
maxOp<scalar>()
|
||||
);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "sortComponent : minCoord:" << minCoord
|
||||
<< " maxCoord:" << maxCoord << endl;
|
||||
}
|
||||
|
||||
// starting index (in sortedCoord) of bin (= local)
|
||||
label leftIndex = 0;
|
||||
// starting value of bin (= global since coordinate)
|
||||
scalar leftCoord = minCoord;
|
||||
|
||||
// Sort bins of size n
|
||||
for (label bin = 0; bin < n_[compI]; bin++)
|
||||
{
|
||||
// Now we need to determine the size of the bin (dx). This is
|
||||
// determined by the 'pivot' values - everything to the left of this
|
||||
// value goes in the current bin, everything to the right into the next
|
||||
// bins.
|
||||
|
||||
// Local number of elements
|
||||
label localSize = -1; // offset from leftOffset
|
||||
|
||||
// Value at right of bin (leftIndex+localSize-1)
|
||||
scalar rightCoord = -GREAT;
|
||||
|
||||
if (bin == n_[compI]-1)
|
||||
{
|
||||
// Last bin. Copy all.
|
||||
localSize = current.size()-leftIndex;
|
||||
rightCoord = maxCoord; // note: not used anymore
|
||||
}
|
||||
else if (Pstream::nProcs() == 1)
|
||||
{
|
||||
// No need for binary searching of bin size
|
||||
localSize = label(current.size()/n_[compI]);
|
||||
rightCoord = sortedCoord[leftIndex+localSize];
|
||||
}
|
||||
else
|
||||
{
|
||||
// For the current bin (starting at leftCoord) we want a rightCoord
|
||||
// such that the sum of all sizes are globalCurrentSize/n_[compI].
|
||||
// We have to iterate to obtain this.
|
||||
|
||||
label rightIndex = current.size();
|
||||
rightCoord = maxCoord;
|
||||
|
||||
// Calculate rightIndex/rightCoord to have wanted size
|
||||
findBinary
|
||||
(
|
||||
sizeTol,
|
||||
sortedCoord,
|
||||
leftIndex,
|
||||
leftCoord,
|
||||
maxCoord,
|
||||
globalCurrentSize/n_[compI], // wanted size
|
||||
|
||||
rightIndex,
|
||||
rightCoord
|
||||
);
|
||||
localSize = rightIndex - leftIndex;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "For component " << compI << ", bin " << bin
|
||||
<< " copying" << nl
|
||||
<< "from " << leftCoord << " at local index "
|
||||
<< leftIndex << nl
|
||||
<< "to " << rightCoord << " localSize:"
|
||||
<< localSize << nl
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
// Copy localSize elements starting from leftIndex.
|
||||
labelList slice(localSize);
|
||||
|
||||
forAll(slice, i)
|
||||
{
|
||||
label pointI = current[sortedCoord.indices()[leftIndex+i]];
|
||||
|
||||
// Mark point into correct bin
|
||||
finalDecomp[pointI] += bin*mult;
|
||||
|
||||
// And collect for next sorting action
|
||||
slice[i] = pointI;
|
||||
}
|
||||
|
||||
// Sort slice in next component
|
||||
if (componentIndex < 2)
|
||||
{
|
||||
string oldPrefix;
|
||||
if (debug)
|
||||
{
|
||||
oldPrefix = Pout.prefix();
|
||||
Pout.prefix() = " " + oldPrefix;
|
||||
}
|
||||
|
||||
sortComponent
|
||||
(
|
||||
sizeTol,
|
||||
points,
|
||||
slice,
|
||||
componentIndex+1,
|
||||
mult*n_[compI], // Multiplier to apply to decomposition.
|
||||
finalDecomp
|
||||
);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout.prefix() = oldPrefix;
|
||||
}
|
||||
}
|
||||
|
||||
// Step to next bin.
|
||||
leftIndex += localSize;
|
||||
leftCoord = rightCoord;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::hierarchGeomDecomp::hierarchGeomDecomp
|
||||
(
|
||||
const dictionary& decompositionDict
|
||||
)
|
||||
:
|
||||
geomDecomp(decompositionDict, typeName),
|
||||
decompOrder_()
|
||||
{
|
||||
setDecompOrder();
|
||||
}
|
||||
|
||||
|
||||
Foam::hierarchGeomDecomp::hierarchGeomDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh&
|
||||
)
|
||||
:
|
||||
geomDecomp(decompositionDict, hierarchGeomDecomp::typeName),
|
||||
decompOrder_()
|
||||
{
|
||||
setDecompOrder();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::labelList Foam::hierarchGeomDecomp::decompose
|
||||
(
|
||||
const pointField& points
|
||||
)
|
||||
{
|
||||
// construct a list for the final result
|
||||
labelList finalDecomp(points.size(), 0);
|
||||
|
||||
// Start off with every point sorted onto itself.
|
||||
labelList slice(points.size());
|
||||
forAll(slice, i)
|
||||
{
|
||||
slice[i] = i;
|
||||
}
|
||||
|
||||
pointField rotatedPoints = rotDelta_ & points;
|
||||
|
||||
|
||||
// Calculate tolerance of cell distribution. For large cases finding
|
||||
// distibution to the cell exact would cause too many iterations so allow
|
||||
// some slack.
|
||||
label allSize = points.size();
|
||||
reduce(allSize, sumOp<label>());
|
||||
|
||||
const label sizeTol = max(1, label(1E-3*allSize/nProcessors_));
|
||||
|
||||
// Sort recursive
|
||||
sortComponent
|
||||
(
|
||||
sizeTol,
|
||||
rotatedPoints,
|
||||
slice,
|
||||
0, // Sort first component in decompOrder.
|
||||
1, // Offset for different x bins.
|
||||
finalDecomp
|
||||
);
|
||||
|
||||
return finalDecomp;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,187 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::hierarchGeomDecomp
|
||||
|
||||
Description
|
||||
Does hierarchical decomposition of points. Works by first sorting the
|
||||
points in x direction into equal sized bins, then in y direction and
|
||||
finally in z direction.
|
||||
|
||||
Uses single array to hold decomposition which is indexed as if it is a
|
||||
3 dimensional array:
|
||||
|
||||
finalDecomp[i,j,k] is indexed as
|
||||
|
||||
i*n[0]*n[1] + j*n[1] + k
|
||||
|
||||
E.g. if we're sorting 'xyz': the first sort (over the x-component)
|
||||
determines in which x-domain the point goes. Then for each of the x-domains
|
||||
the points are sorted in y direction and each individual x-domain gets
|
||||
split into three y-domains. And similar for the z-direction.
|
||||
|
||||
Since the domains are of equal size the maximum difference in size is
|
||||
n[0]*n[1] (or n[1]*n[2]?) (small anyway)
|
||||
|
||||
|
||||
SourceFiles
|
||||
hierarchGeomDecomp.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef hierarchGeomDecomp_H
|
||||
#define hierarchGeomDecomp_H
|
||||
|
||||
#include "geomDecomp.H"
|
||||
#include "FixedList.H"
|
||||
#include "direction.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class hierarchGeomDecomp Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class hierarchGeomDecomp
|
||||
:
|
||||
public geomDecomp
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Decomposition order in terms of components.
|
||||
FixedList<direction, 3> decompOrder_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Convert ordering string ("xyz") into list of components.
|
||||
void setDecompOrder();
|
||||
|
||||
//- Find index of t in list inbetween indices left and right
|
||||
static label findLower
|
||||
(
|
||||
const List<scalar>&,
|
||||
const scalar t,
|
||||
const label left,
|
||||
const label right
|
||||
);
|
||||
|
||||
//- Find midValue (at local index mid) such that the number of
|
||||
// elements between mid and leftIndex are (globally summed) the
|
||||
// wantedSize. Binary search.
|
||||
static void findBinary
|
||||
(
|
||||
const label sizeTol, // size difference considered acceptible
|
||||
const List<scalar>&,
|
||||
const label leftIndex, // index of previous value
|
||||
const scalar leftValue, // value at leftIndex
|
||||
const scalar maxValue, // global max of values
|
||||
const scalar wantedSize, // wanted size
|
||||
label& mid, // index where size of bin is wantedSize
|
||||
scalar& midValue // value at mid
|
||||
);
|
||||
|
||||
//- Recursively sort in x,y,z (or rather acc. to decompOrder_)
|
||||
void sortComponent
|
||||
(
|
||||
const label sizeTol,
|
||||
const pointField&,
|
||||
const labelList& slice, // slice of points to decompose
|
||||
const direction componentIndex, // index in decompOrder_
|
||||
const label prevMult, // multiplication factor
|
||||
labelList& finalDecomp // overall decomposition
|
||||
);
|
||||
|
||||
|
||||
//- Disallow default bitwise copy construct and assignment
|
||||
void operator=(const hierarchGeomDecomp&);
|
||||
hierarchGeomDecomp(const hierarchGeomDecomp&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("hierarchical");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct given the decomposition dictionary
|
||||
hierarchGeomDecomp(const dictionary& decompositionDict);
|
||||
|
||||
//- Construct given the decomposition dictionary and mesh
|
||||
hierarchGeomDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
virtual ~hierarchGeomDecomp()
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- hierarchgeom is aware of processor boundaries
|
||||
virtual bool parallelAware() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Use the
|
||||
// mesh connectivity (if needed)
|
||||
virtual labelList decompose(const pointField&);
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Explicitly
|
||||
// provided connectivity - does not use mesh_.
|
||||
// The connectivity is equal to mesh.cellCells() except for
|
||||
// - in parallel the cell numbers are global cell numbers (starting
|
||||
// from 0 at processor0 and then incrementing all through the
|
||||
// processors)
|
||||
// - the connections are across coupled patches
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelListList& globalCellCells,
|
||||
const pointField& cc
|
||||
)
|
||||
{
|
||||
return decompose(cc);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,131 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Description
|
||||
Decomposition given a cell-to-processor association in a file
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "manualDecomp.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "IFstream.H"
|
||||
#include "labelIOList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(manualDecomp, 0);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
decompositionMethod,
|
||||
manualDecomp,
|
||||
dictionary
|
||||
);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
decompositionMethod,
|
||||
manualDecomp,
|
||||
dictionaryMesh
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::manualDecomp::manualDecomp(const dictionary& decompositionDict)
|
||||
:
|
||||
decompositionMethod(decompositionDict)
|
||||
{
|
||||
notImplemented("manualDecomp(const dictionary&)");
|
||||
}
|
||||
|
||||
|
||||
Foam::manualDecomp::manualDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
)
|
||||
:
|
||||
decompositionMethod(decompositionDict),
|
||||
meshPtr_(&mesh),
|
||||
decompDataFile_
|
||||
(
|
||||
decompositionDict.subDict(word(decompositionDict.lookup("method"))
|
||||
+ "Coeffs").lookup("dataFile")
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::labelList Foam::manualDecomp::decompose(const pointField& points)
|
||||
{
|
||||
const polyMesh& mesh = *meshPtr_;
|
||||
|
||||
labelIOList finalDecomp
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
decompDataFile_,
|
||||
mesh.facesInstance(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
// check if the final decomposition is OK
|
||||
|
||||
if (finalDecomp.size() != points.size())
|
||||
{
|
||||
FatalErrorIn("manualDecomp::decompose(const pointField&)")
|
||||
<< "Size of decomposition list does not correspond "
|
||||
<< "to the number of points. Size: "
|
||||
<< finalDecomp.size() << " Number of points: "
|
||||
<< points.size()
|
||||
<< ".\n" << "Manual decomposition data read from file "
|
||||
<< decompDataFile_ << "." << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
if (min(finalDecomp) < 0 || max(finalDecomp) > nProcessors_ - 1)
|
||||
{
|
||||
FatalErrorIn("labelList manualDecomp::decompose(const pointField&)")
|
||||
<< "According to the decomposition, cells assigned to "
|
||||
<< "impossible processor numbers. Min processor = "
|
||||
<< min(finalDecomp) << " Max processor = " << max(finalDecomp)
|
||||
<< ".\n" << "Manual decomposition data read from file "
|
||||
<< decompDataFile_ << "." << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return finalDecomp;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,130 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::manualDecomp
|
||||
|
||||
Description
|
||||
Decomposition given a cell-to-processor association in a file
|
||||
|
||||
SourceFiles
|
||||
manualDecomp.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef manualDecomp_H
|
||||
#define manualDecomp_H
|
||||
|
||||
#include "decompositionMethod.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class manualDecomp Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class manualDecomp
|
||||
:
|
||||
public decompositionMethod
|
||||
{
|
||||
// Private data
|
||||
|
||||
const polyMesh* meshPtr_;
|
||||
|
||||
fileName decompDataFile_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct and assignment
|
||||
void operator=(const manualDecomp&);
|
||||
manualDecomp(const manualDecomp&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("manual");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct given the decomposition dictionary
|
||||
manualDecomp(const dictionary& decompositionDict);
|
||||
|
||||
//- Construct given the decomposition dictionary and mesh
|
||||
manualDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
virtual ~manualDecomp()
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- manual decompose does not care about proc boundaries - is all
|
||||
// up to the user.
|
||||
virtual bool parallelAware() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Use the
|
||||
// mesh connectivity (if needed)
|
||||
virtual labelList decompose(const pointField&);
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Explicitly
|
||||
// provided connectivity - does not use mesh_.
|
||||
// The connectivity is equal to mesh.cellCells() except for
|
||||
// - in parallel the cell numbers are global cell numbers (starting
|
||||
// from 0 at processor0 and then incrementing all through the
|
||||
// processors)
|
||||
// - the connections are across coupled patches
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelListList& globalCellCells,
|
||||
const pointField& cc
|
||||
)
|
||||
{
|
||||
return decompose(cc);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,579 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "metisDecomp.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "floatScalar.H"
|
||||
#include "IFstream.H"
|
||||
#include "Time.H"
|
||||
#include "cyclicPolyPatch.H"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#define OMPI_SKIP_MPICXX
|
||||
# include "metis.h"
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(metisDecomp, 0);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
decompositionMethod,
|
||||
metisDecomp,
|
||||
dictionaryMesh
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
// Call Metis with options from dictionary.
|
||||
Foam::label Foam::metisDecomp::decompose
|
||||
(
|
||||
const List<int>& adjncy,
|
||||
const List<int>& xadj,
|
||||
|
||||
List<int>& finalDecomp
|
||||
)
|
||||
{
|
||||
// C style numbering
|
||||
int numFlag = 0;
|
||||
|
||||
// Method of decomposition
|
||||
// recursive: multi-level recursive bisection (default)
|
||||
// k-way: multi-level k-way
|
||||
word method("k-way");
|
||||
|
||||
// decomposition options. 0 = use defaults
|
||||
List<int> options(5, 0);
|
||||
|
||||
// processor weights initialised with no size, only used if specified in
|
||||
// a file
|
||||
Field<floatScalar> processorWeights;
|
||||
|
||||
// cell weights (so on the vertices of the dual)
|
||||
List<int> cellWeights;
|
||||
|
||||
// face weights (so on the edges of the dual)
|
||||
List<int> faceWeights;
|
||||
|
||||
// Check for user supplied weights and decomp options
|
||||
if (decompositionDict_.found("metisCoeffs"))
|
||||
{
|
||||
const dictionary& metisCoeffs =
|
||||
decompositionDict_.subDict("metisCoeffs");
|
||||
word weightsFile;
|
||||
|
||||
if (metisCoeffs.readIfPresent("method", method))
|
||||
{
|
||||
if (method != "recursive" && method != "k-way")
|
||||
{
|
||||
FatalErrorIn("metisDecomp::decompose()")
|
||||
<< "Method " << method << " in metisCoeffs in dictionary : "
|
||||
<< decompositionDict_.name()
|
||||
<< " should be 'recursive' or 'k-way'"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
Info<< "metisDecomp : Using Metis method " << method
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
if (metisCoeffs.readIfPresent("options", options))
|
||||
{
|
||||
if (options.size() != 5)
|
||||
{
|
||||
FatalErrorIn("metisDecomp::decompose()")
|
||||
<< "Number of options in metisCoeffs in dictionary : "
|
||||
<< decompositionDict_.name()
|
||||
<< " should be 5"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
Info<< "metisDecomp : Using Metis options " << options
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
if (metisCoeffs.readIfPresent("processorWeights", processorWeights))
|
||||
{
|
||||
processorWeights /= sum(processorWeights);
|
||||
|
||||
if (processorWeights.size() != nProcessors_)
|
||||
{
|
||||
FatalErrorIn("metisDecomp::decompose(const pointField&)")
|
||||
<< "Number of processor weights "
|
||||
<< processorWeights.size()
|
||||
<< " does not equal number of domains " << nProcessors_
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
if (metisCoeffs.readIfPresent("cellWeightsFile", weightsFile))
|
||||
{
|
||||
Info<< "metisDecomp : Using cell-based weights." << endl;
|
||||
|
||||
IOList<int> cellIOWeights
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
weightsFile,
|
||||
mesh_.time().timeName(),
|
||||
mesh_,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
)
|
||||
);
|
||||
cellWeights.transfer(cellIOWeights);
|
||||
|
||||
if (cellWeights.size() != xadj.size()-1)
|
||||
{
|
||||
FatalErrorIn("metisDecomp::decompose(const pointField&)")
|
||||
<< "Number of cell weights " << cellWeights.size()
|
||||
<< " does not equal number of cells " << xadj.size()-1
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
//- faceWeights disabled. Only makes sense for cellCells from mesh.
|
||||
//if (metisCoeffs.readIfPresent("faceWeightsFile", weightsFile))
|
||||
//{
|
||||
// Info<< "metisDecomp : Using face-based weights." << endl;
|
||||
//
|
||||
// IOList<int> weights
|
||||
// (
|
||||
// IOobject
|
||||
// (
|
||||
// weightsFile,
|
||||
// mesh_.time().timeName(),
|
||||
// mesh_,
|
||||
// IOobject::MUST_READ,
|
||||
// IOobject::AUTO_WRITE
|
||||
// )
|
||||
// );
|
||||
//
|
||||
// if (weights.size() != adjncy.size()/2)
|
||||
// {
|
||||
// FatalErrorIn("metisDecomp::decompose(const pointField&)")
|
||||
// << "Number of face weights " << weights.size()
|
||||
// << " does not equal number of internal faces "
|
||||
// << adjncy.size()/2
|
||||
// << exit(FatalError);
|
||||
// }
|
||||
//
|
||||
// // Assume symmetric weights. Keep same ordering as adjncy.
|
||||
// faceWeights.setSize(adjncy.size());
|
||||
//
|
||||
// labelList nFacesPerCell(mesh_.nCells(), 0);
|
||||
//
|
||||
// for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
|
||||
// {
|
||||
// label w = weights[faceI];
|
||||
//
|
||||
// label own = mesh_.faceOwner()[faceI];
|
||||
// label nei = mesh_.faceNeighbour()[faceI];
|
||||
//
|
||||
// faceWeights[xadj[own] + nFacesPerCell[own]++] = w;
|
||||
// faceWeights[xadj[nei] + nFacesPerCell[nei]++] = w;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
int numCells = xadj.size()-1;
|
||||
int nProcs = nProcessors_;
|
||||
|
||||
// output: cell -> processor addressing
|
||||
finalDecomp.setSize(numCells);
|
||||
|
||||
// output: number of cut edges
|
||||
int edgeCut = 0;
|
||||
|
||||
// Vertex weight info
|
||||
int wgtFlag = 0;
|
||||
int* vwgtPtr = NULL;
|
||||
int* adjwgtPtr = NULL;
|
||||
|
||||
if (cellWeights.size())
|
||||
{
|
||||
vwgtPtr = cellWeights.begin();
|
||||
wgtFlag += 2; // Weights on vertices
|
||||
}
|
||||
if (faceWeights.size())
|
||||
{
|
||||
adjwgtPtr = faceWeights.begin();
|
||||
wgtFlag += 1; // Weights on edges
|
||||
}
|
||||
|
||||
if (method == "recursive")
|
||||
{
|
||||
if (processorWeights.size())
|
||||
{
|
||||
METIS_WPartGraphRecursive
|
||||
(
|
||||
&numCells, // num vertices in graph
|
||||
const_cast<List<int>&>(xadj).begin(), // indexing into adjncy
|
||||
const_cast<List<int>&>(adjncy).begin(), // neighbour info
|
||||
vwgtPtr, // vertexweights
|
||||
adjwgtPtr, // no edgeweights
|
||||
&wgtFlag,
|
||||
&numFlag,
|
||||
&nProcs,
|
||||
processorWeights.begin(),
|
||||
options.begin(),
|
||||
&edgeCut,
|
||||
finalDecomp.begin()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
METIS_PartGraphRecursive
|
||||
(
|
||||
&numCells, // num vertices in graph
|
||||
const_cast<List<int>&>(xadj).begin(), // indexing into adjncy
|
||||
const_cast<List<int>&>(adjncy).begin(), // neighbour info
|
||||
vwgtPtr, // vertexweights
|
||||
adjwgtPtr, // no edgeweights
|
||||
&wgtFlag,
|
||||
&numFlag,
|
||||
&nProcs,
|
||||
options.begin(),
|
||||
&edgeCut,
|
||||
finalDecomp.begin()
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (processorWeights.size())
|
||||
{
|
||||
METIS_WPartGraphKway
|
||||
(
|
||||
&numCells, // num vertices in graph
|
||||
const_cast<List<int>&>(xadj).begin(), // indexing into adjncy
|
||||
const_cast<List<int>&>(adjncy).begin(), // neighbour info
|
||||
vwgtPtr, // vertexweights
|
||||
adjwgtPtr, // no edgeweights
|
||||
&wgtFlag,
|
||||
&numFlag,
|
||||
&nProcs,
|
||||
processorWeights.begin(),
|
||||
options.begin(),
|
||||
&edgeCut,
|
||||
finalDecomp.begin()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
METIS_PartGraphKway
|
||||
(
|
||||
&numCells, // num vertices in graph
|
||||
const_cast<List<int>&>(xadj).begin(), // indexing into adjncy
|
||||
const_cast<List<int>&>(adjncy).begin(), // neighbour info
|
||||
vwgtPtr, // vertexweights
|
||||
adjwgtPtr, // no edgeweights
|
||||
&wgtFlag,
|
||||
&numFlag,
|
||||
&nProcs,
|
||||
options.begin(),
|
||||
&edgeCut,
|
||||
finalDecomp.begin()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return edgeCut;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::metisDecomp::metisDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
)
|
||||
:
|
||||
decompositionMethod(decompositionDict),
|
||||
mesh_(mesh)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::labelList Foam::metisDecomp::decompose(const pointField& points)
|
||||
{
|
||||
if (points.size() != mesh_.nCells())
|
||||
{
|
||||
FatalErrorIn("metisDecomp::decompose(const pointField&)")
|
||||
<< "Can use this decomposition method only for the whole mesh"
|
||||
<< endl
|
||||
<< "and supply one coordinate (cellCentre) for every cell." << endl
|
||||
<< "The number of coordinates " << points.size() << endl
|
||||
<< "The number of cells in the mesh " << mesh_.nCells()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// Make Metis CSR (Compressed Storage Format) storage
|
||||
// adjncy : contains neighbours (= edges in graph)
|
||||
// xadj(celli) : start of information in adjncy for celli
|
||||
|
||||
List<int> xadj(mesh_.nCells()+1);
|
||||
|
||||
// Initialise the number of internal faces of the cells to twice the
|
||||
// number of internal faces
|
||||
label nInternalFaces = 2*mesh_.nInternalFaces();
|
||||
|
||||
// Check the boundary for coupled patches and add to the number of
|
||||
// internal faces
|
||||
const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
|
||||
|
||||
forAll(pbm, patchi)
|
||||
{
|
||||
if (isA<cyclicPolyPatch>(pbm[patchi]))
|
||||
{
|
||||
nInternalFaces += pbm[patchi].size();
|
||||
}
|
||||
}
|
||||
|
||||
// Create the adjncy array the size of the total number of internal and
|
||||
// coupled faces
|
||||
List<int> adjncy(nInternalFaces);
|
||||
|
||||
// Fill in xadj
|
||||
// ~~~~~~~~~~~~
|
||||
label freeAdj = 0;
|
||||
|
||||
for (label cellI = 0; cellI < mesh_.nCells(); cellI++)
|
||||
{
|
||||
xadj[cellI] = freeAdj;
|
||||
|
||||
const labelList& cFaces = mesh_.cells()[cellI];
|
||||
|
||||
forAll(cFaces, i)
|
||||
{
|
||||
label faceI = cFaces[i];
|
||||
|
||||
if
|
||||
(
|
||||
mesh_.isInternalFace(faceI)
|
||||
|| isA<cyclicPolyPatch>(pbm[pbm.whichPatch(faceI)])
|
||||
)
|
||||
{
|
||||
freeAdj++;
|
||||
}
|
||||
}
|
||||
}
|
||||
xadj[mesh_.nCells()] = freeAdj;
|
||||
|
||||
|
||||
// Fill in adjncy
|
||||
// ~~~~~~~~~~~~~~
|
||||
|
||||
labelList nFacesPerCell(mesh_.nCells(), 0);
|
||||
|
||||
// Internal faces
|
||||
for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
|
||||
{
|
||||
label own = mesh_.faceOwner()[faceI];
|
||||
label nei = mesh_.faceNeighbour()[faceI];
|
||||
|
||||
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
||||
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
||||
}
|
||||
|
||||
// Coupled faces. Only cyclics done.
|
||||
forAll(pbm, patchi)
|
||||
{
|
||||
if (isA<cyclicPolyPatch>(pbm[patchi]))
|
||||
{
|
||||
const unallocLabelList& faceCells = pbm[patchi].faceCells();
|
||||
|
||||
label sizeby2 = faceCells.size()/2;
|
||||
|
||||
for (label facei=0; facei<sizeby2; facei++)
|
||||
{
|
||||
label own = faceCells[facei];
|
||||
label nei = faceCells[facei + sizeby2];
|
||||
|
||||
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
||||
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Decompose using default weights
|
||||
List<int> finalDecomp;
|
||||
decompose(adjncy, xadj, finalDecomp);
|
||||
|
||||
// Copy back to labelList
|
||||
labelList decomp(finalDecomp.size());
|
||||
forAll(decomp, i)
|
||||
{
|
||||
decomp[i] = finalDecomp[i];
|
||||
}
|
||||
return decomp;
|
||||
}
|
||||
|
||||
|
||||
// From cell-cell connections to Metis format (like CompactListList)
|
||||
void Foam::metisDecomp::calcMetisCSR
|
||||
(
|
||||
const labelListList& cellCells,
|
||||
List<int>& adjncy,
|
||||
List<int>& xadj
|
||||
)
|
||||
{
|
||||
// Count number of internal faces
|
||||
label nConnections = 0;
|
||||
|
||||
forAll(cellCells, coarseI)
|
||||
{
|
||||
nConnections += cellCells[coarseI].size();
|
||||
}
|
||||
|
||||
// Create the adjncy array as twice the size of the total number of
|
||||
// internal faces
|
||||
adjncy.setSize(nConnections);
|
||||
|
||||
xadj.setSize(cellCells.size()+1);
|
||||
|
||||
|
||||
// Fill in xadj
|
||||
// ~~~~~~~~~~~~
|
||||
label freeAdj = 0;
|
||||
|
||||
forAll(cellCells, coarseI)
|
||||
{
|
||||
xadj[coarseI] = freeAdj;
|
||||
|
||||
const labelList& cCells = cellCells[coarseI];
|
||||
|
||||
forAll(cCells, i)
|
||||
{
|
||||
adjncy[freeAdj++] = cCells[i];
|
||||
}
|
||||
}
|
||||
xadj[cellCells.size()] = freeAdj;
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::metisDecomp::decompose
|
||||
(
|
||||
const labelList& agglom,
|
||||
const pointField& agglomPoints
|
||||
)
|
||||
{
|
||||
if (agglom.size() != mesh_.nCells())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"parMetisDecomp::decompose(const labelList&, const pointField&)"
|
||||
) << "Size of cell-to-coarse map " << agglom.size()
|
||||
<< " differs from number of cells in mesh " << mesh_.nCells()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// Make Metis CSR (Compressed Storage Format) storage
|
||||
// adjncy : contains neighbours (= edges in graph)
|
||||
// xadj(celli) : start of information in adjncy for celli
|
||||
List<int> adjncy;
|
||||
List<int> xadj;
|
||||
{
|
||||
// Get cellCells on coarse mesh.
|
||||
labelListList cellCells;
|
||||
calcCellCells
|
||||
(
|
||||
mesh_,
|
||||
agglom,
|
||||
agglomPoints.size(),
|
||||
cellCells
|
||||
);
|
||||
|
||||
calcMetisCSR(cellCells, adjncy, xadj);
|
||||
}
|
||||
|
||||
// Decompose using default weights
|
||||
List<int> finalDecomp;
|
||||
decompose(adjncy, xadj, finalDecomp);
|
||||
|
||||
|
||||
// Rework back into decomposition for original mesh_
|
||||
labelList fineDistribution(agglom.size());
|
||||
|
||||
forAll(fineDistribution, i)
|
||||
{
|
||||
fineDistribution[i] = finalDecomp[agglom[i]];
|
||||
}
|
||||
|
||||
return fineDistribution;
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::metisDecomp::decompose
|
||||
(
|
||||
const labelListList& globalCellCells,
|
||||
const pointField& cellCentres
|
||||
)
|
||||
{
|
||||
if (cellCentres.size() != globalCellCells.size())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"metisDecomp::decompose(const pointField&, const labelListList&)"
|
||||
) << "Inconsistent number of cells (" << globalCellCells.size()
|
||||
<< ") and number of cell centres (" << cellCentres.size()
|
||||
<< ")." << exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
// Make Metis CSR (Compressed Storage Format) storage
|
||||
// adjncy : contains neighbours (= edges in graph)
|
||||
// xadj(celli) : start of information in adjncy for celli
|
||||
|
||||
List<int> adjncy;
|
||||
List<int> xadj;
|
||||
calcMetisCSR(globalCellCells, adjncy, xadj);
|
||||
|
||||
|
||||
// Decompose using default weights
|
||||
List<int> finalDecomp;
|
||||
decompose(adjncy, xadj, finalDecomp);
|
||||
|
||||
// Copy back to labelList
|
||||
labelList decomp(finalDecomp.size());
|
||||
forAll(decomp, i)
|
||||
{
|
||||
decomp[i] = finalDecomp[i];
|
||||
}
|
||||
return decomp;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,147 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::metisDecomp
|
||||
|
||||
Description
|
||||
Metis domain decomposition
|
||||
|
||||
SourceFiles
|
||||
metisDecomp.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef metisDecomp_H
|
||||
#define metisDecomp_H
|
||||
|
||||
#include "decompositionMethod.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class metisDecomp Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class metisDecomp
|
||||
:
|
||||
public decompositionMethod
|
||||
{
|
||||
// Private data
|
||||
|
||||
const polyMesh& mesh_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
label decompose
|
||||
(
|
||||
const List<int>& adjncy,
|
||||
const List<int>& xadj,
|
||||
List<int>& finalDecomp
|
||||
);
|
||||
|
||||
//- Disallow default bitwise copy construct and assignment
|
||||
void operator=(const metisDecomp&);
|
||||
metisDecomp(const metisDecomp&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("metis");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct given the decomposition dictionary and mesh
|
||||
metisDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
virtual ~metisDecomp()
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
virtual bool parallelAware() const
|
||||
{
|
||||
// Metis does not know about proc boundaries
|
||||
return false;
|
||||
}
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Use the
|
||||
// mesh connectivity (if needed)
|
||||
virtual labelList decompose(const pointField&);
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Gets
|
||||
// passed agglomeration map (from fine to coarse cells) and coarse cell
|
||||
// location. Can be overridden by decomposers that provide this
|
||||
// functionality natively.
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelList& agglom,
|
||||
const pointField&
|
||||
);
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Explicitly
|
||||
// provided mesh connectivity.
|
||||
// The connectivity is equal to mesh.cellCells() except for
|
||||
// - in parallel the cell numbers are global cell numbers (starting
|
||||
// from 0 at processor0 and then incrementing all through the
|
||||
// processors)
|
||||
// - the connections are across coupled patches
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelListList& globalCellCells,
|
||||
const pointField& cc
|
||||
);
|
||||
|
||||
//- Helper to convert cellcells into Metis storage
|
||||
static void calcMetisCSR
|
||||
(
|
||||
const labelListList& globalCellCells,
|
||||
List<int>& adjncy,
|
||||
List<int>& xadj
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,183 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "simpleGeomDecomp.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "SortableList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(simpleGeomDecomp, 0);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
decompositionMethod,
|
||||
simpleGeomDecomp,
|
||||
dictionary
|
||||
);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
decompositionMethod,
|
||||
simpleGeomDecomp,
|
||||
dictionaryMesh
|
||||
);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// assignToProcessorGroup : given nCells cells and nProcGroup processor
|
||||
// groups to share them, how do we share them out? Answer : each group
|
||||
// gets nCells/nProcGroup cells, and the first few get one
|
||||
// extra to make up the numbers. This should produce almost
|
||||
// perfect load balancing
|
||||
|
||||
void Foam::simpleGeomDecomp::assignToProcessorGroup
|
||||
(
|
||||
labelList& processorGroup,
|
||||
const label nProcGroup
|
||||
)
|
||||
{
|
||||
label jump = processorGroup.size()/nProcGroup;
|
||||
label jumpb = jump + 1;
|
||||
label fstProcessorGroup = processorGroup.size() - jump*nProcGroup;
|
||||
|
||||
label ind = 0;
|
||||
label j = 0;
|
||||
|
||||
// assign cells to the first few processor groups (those with
|
||||
// one extra cell each
|
||||
for (j=0; j<fstProcessorGroup; j++)
|
||||
{
|
||||
for (register label k=0; k<jumpb; k++)
|
||||
{
|
||||
processorGroup[ind++] = j;
|
||||
}
|
||||
}
|
||||
|
||||
// and now to the `normal' processor groups
|
||||
for (; j<nProcGroup; j++)
|
||||
{
|
||||
for (register label k=0; k<jump; k++)
|
||||
{
|
||||
processorGroup[ind++] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::simpleGeomDecomp::simpleGeomDecomp(const dictionary& decompositionDict)
|
||||
:
|
||||
geomDecomp(decompositionDict, typeName)
|
||||
{}
|
||||
|
||||
|
||||
Foam::simpleGeomDecomp::simpleGeomDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh&
|
||||
)
|
||||
:
|
||||
geomDecomp(decompositionDict, typeName)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::labelList Foam::simpleGeomDecomp::decompose(const pointField& points)
|
||||
{
|
||||
// construct a list for the final result
|
||||
labelList finalDecomp(points.size());
|
||||
|
||||
labelList processorGroups(points.size());
|
||||
|
||||
labelList pointIndices(points.size());
|
||||
forAll(pointIndices, i) {pointIndices[i] = i;}
|
||||
|
||||
pointField rotatedPoints = rotDelta_ & points;
|
||||
|
||||
// and one to take the processor group id's. For each direction.
|
||||
// we assign the processors to groups of processors labelled
|
||||
// 0..nX to give a banded structure on the mesh. Then we
|
||||
// construct the actual processor number by treating this as
|
||||
// the units part of the processor number.
|
||||
sort
|
||||
(
|
||||
pointIndices,
|
||||
UList<scalar>::less(rotatedPoints.component(vector::X))
|
||||
);
|
||||
|
||||
assignToProcessorGroup(processorGroups, n_.x());
|
||||
|
||||
forAll(points, i)
|
||||
{
|
||||
finalDecomp[pointIndices[i]] = processorGroups[i];
|
||||
}
|
||||
|
||||
|
||||
// now do the same thing in the Y direction. These processor group
|
||||
// numbers add multiples of nX to the proc. number (columns)
|
||||
sort
|
||||
(
|
||||
pointIndices,
|
||||
UList<scalar>::less(rotatedPoints.component(vector::Y))
|
||||
);
|
||||
|
||||
assignToProcessorGroup(processorGroups, n_.y());
|
||||
|
||||
forAll(points, i)
|
||||
{
|
||||
finalDecomp[pointIndices[i]] += n_.x()*processorGroups[i];
|
||||
}
|
||||
|
||||
|
||||
// finally in the Z direction. Now we add multiples of nX*nY to give
|
||||
// layers
|
||||
sort
|
||||
(
|
||||
pointIndices,
|
||||
UList<scalar>::less(rotatedPoints.component(vector::Z))
|
||||
);
|
||||
|
||||
assignToProcessorGroup(processorGroups, n_.z());
|
||||
|
||||
forAll(points, i)
|
||||
{
|
||||
finalDecomp[pointIndices[i]] += n_.x()*n_.y()*processorGroups[i];
|
||||
}
|
||||
|
||||
|
||||
return finalDecomp;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,116 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::simpleGeomDecomp
|
||||
|
||||
Description
|
||||
|
||||
SourceFiles
|
||||
simpleGeomDecomp.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef simpleGeomDecomp_H
|
||||
#define simpleGeomDecomp_H
|
||||
|
||||
#include "geomDecomp.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class simpleGeomDecomp Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class simpleGeomDecomp
|
||||
:
|
||||
public geomDecomp
|
||||
{
|
||||
// Private Member Functions
|
||||
|
||||
void assignToProcessorGroup(labelList& processorGroup, const label);
|
||||
|
||||
//- Disallow default bitwise copy construct and assignment
|
||||
void operator=(const simpleGeomDecomp&);
|
||||
simpleGeomDecomp(const simpleGeomDecomp&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("simple");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct given the decomposition dictionary
|
||||
simpleGeomDecomp(const dictionary& decompositionDict);
|
||||
|
||||
//- Construct given the decomposition dictionary and mesh
|
||||
simpleGeomDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
virtual ~simpleGeomDecomp()
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
virtual bool parallelAware() const
|
||||
{
|
||||
// simple decomp does not attempt to do anything across proc
|
||||
// boundaries
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual labelList decompose(const pointField&);
|
||||
|
||||
//- Explicitly provided connectivity
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelListList& globalCellCells,
|
||||
const pointField& cc
|
||||
)
|
||||
{
|
||||
return decompose(cc);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
3
src/decompositionMethods/parMetisDecomp/Make/files
Normal file
3
src/decompositionMethods/parMetisDecomp/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
parMetisDecomp.C
|
||||
|
||||
LIB = $(FOAM_MPI_LIBBIN)/libparMetisDecompositionMethod
|
||||
12
src/decompositionMethods/parMetisDecomp/Make/options
Normal file
12
src/decompositionMethods/parMetisDecomp/Make/options
Normal file
@ -0,0 +1,12 @@
|
||||
include $(RULES)/mplib$(WM_MPLIB)
|
||||
|
||||
EXE_INC = \
|
||||
$(PFLAGS) $(PINC) \
|
||||
-I$(WM_THIRD_PARTY_DIR)/ParMetis-3.1/ParMETISLib \
|
||||
-I$(WM_THIRD_PARTY_DIR)/ParMetis-3.1 \
|
||||
-I../decompositionMethods/lnInclude
|
||||
|
||||
LIB_LIBS = \
|
||||
-L$(FOAM_MPI_LIBBIN) \
|
||||
-lmetis-parmetis \
|
||||
-lparmetis
|
||||
1001
src/decompositionMethods/parMetisDecomp/parMetisDecomp.C
Normal file
1001
src/decompositionMethods/parMetisDecomp/parMetisDecomp.C
Normal file
File diff suppressed because it is too large
Load Diff
156
src/decompositionMethods/parMetisDecomp/parMetisDecomp.H
Normal file
156
src/decompositionMethods/parMetisDecomp/parMetisDecomp.H
Normal file
@ -0,0 +1,156 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Class
|
||||
Foam::parMetisDecomp
|
||||
|
||||
Description
|
||||
|
||||
SourceFiles
|
||||
parMetisDecomp.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef parMetisDecomp_H
|
||||
#define parMetisDecomp_H
|
||||
|
||||
#include "decompositionMethod.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class parMetisDecomp Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class parMetisDecomp
|
||||
:
|
||||
public decompositionMethod
|
||||
{
|
||||
// Private data
|
||||
|
||||
const polyMesh& mesh_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Insert list in front of list.
|
||||
template<class Type>
|
||||
static void prepend(const UList<Type>&, List<Type>&);
|
||||
//- Insert list at end of list.
|
||||
template<class Type>
|
||||
static void append(const UList<Type>&, List<Type>&);
|
||||
|
||||
label decompose
|
||||
(
|
||||
Field<int>& xadj,
|
||||
Field<int>& adjncy,
|
||||
const pointField& cellCentres,
|
||||
Field<int>& cellWeights,
|
||||
Field<int>& faceWeights,
|
||||
const List<int>& options,
|
||||
|
||||
List<int>& finalDecomp
|
||||
);
|
||||
|
||||
|
||||
//- Disallow default bitwise copy construct and assignment
|
||||
void operator=(const parMetisDecomp&);
|
||||
parMetisDecomp(const parMetisDecomp&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("parMetis");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct given the decomposition dictionary and mesh
|
||||
parMetisDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
~parMetisDecomp()
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- parMetis handles Foam processor boundaries
|
||||
virtual bool parallelAware() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Use the
|
||||
// mesh connectivity (if needed)
|
||||
virtual labelList decompose(const pointField&);
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Gets
|
||||
// passed agglomeration map (from fine to coarse cells) and coarse cell
|
||||
// location. Can be overridden by decomposers that provide this
|
||||
// functionality natively.
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelList& agglom,
|
||||
const pointField&
|
||||
);
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Explicitly
|
||||
// provided mesh connectivity.
|
||||
// The connectivity is equal to mesh.cellCells() except for
|
||||
// - in parallel the cell numbers are global cell numbers (starting
|
||||
// from 0 at processor0 and then incrementing all through the
|
||||
// processors)
|
||||
// - the connections are across coupled patches
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelListList& globalCellCells,
|
||||
const pointField& cc
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "parMetisDecompTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,76 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "parMetisDecomp.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
// Insert at front of list
|
||||
template<class Type>
|
||||
void Foam::parMetisDecomp::prepend
|
||||
(
|
||||
const UList<Type>& extraLst,
|
||||
List<Type>& lst
|
||||
)
|
||||
{
|
||||
label nExtra = extraLst.size();
|
||||
|
||||
// Make space for initial elements
|
||||
lst.setSize(lst.size() + nExtra);
|
||||
for (label i = lst.size()-1; i >= nExtra; i--)
|
||||
{
|
||||
lst[i] = lst[i-nExtra];
|
||||
}
|
||||
|
||||
// Insert at front
|
||||
forAll(extraLst, i)
|
||||
{
|
||||
lst[i] = extraLst[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Insert at back of list
|
||||
template<class Type>
|
||||
void Foam::parMetisDecomp::append
|
||||
(
|
||||
const UList<Type>& extraLst,
|
||||
List<Type>& lst
|
||||
)
|
||||
{
|
||||
label sz = lst.size();
|
||||
|
||||
// Make space for initial elements
|
||||
lst.setSize(sz + extraLst.size());
|
||||
|
||||
// Insert at back
|
||||
forAll(extraLst, i)
|
||||
{
|
||||
lst[sz++] = extraLst[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user