Merge branch 'update-renumbering-methods' into 'develop'

ENH: adjust renumbering methods, extend renumberMesh options

See merge request Development/openfoam!669
This commit is contained in:
Kutalmış Berçin 2024-03-06 22:20:54 +00:00
commit 05194796ef
35 changed files with 1626 additions and 933 deletions

View File

@ -1,112 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2312 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
note "mesh renumbering dictionary";
object renumberMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Write maps from renumbered back to original mesh
writeMaps true;
// Optional entry: sort cells on coupled boundaries to last for use with
// e.g. nonBlockingGaussSeidel.
sortCoupledFaceCells false;
// Optional entry: renumber on a block-by-block basis. It uses a
// blockCoeffs dictionary to construct a decompositionMethod to do
// a block subdivision) and then applies the renumberMethod to each
// block in turn. This can be used in large cases to keep the blocks
// fitting in cache with all the cache misses bunched at the end.
// This number is the approximate size of the blocks - this gets converted
// to a number of blocks that is the input to the decomposition method.
//blockSize 1000;
// Optional entry: sort points into internal and boundary points
//orderPoints false;
// Optional: suppress renumbering cellSets,faceSets,pointSets
//renumberSets false;
//method CuthillMcKee;
//method Sloan;
//method manual;
method random;
//method structured;
//method spring;
//method zoltan; // only if compiled with zoltan support
//CuthillMcKeeCoeffs
//{
// // Reverse CuthillMcKee (RCM) or plain
// reverse true;
//}
manualCoeffs
{
// In system directory: new-to-original (i.e. order) labelIOList
dataFile "cellMap";
}
// For extruded (i.e. structured in one direction) meshes
structuredCoeffs
{
// Patches that mesh was extruded from. These determine the starting
// layer of cells
patches (movingWall);
// Method to renumber the starting layer of cells
method random;
// Renumber in columns (depthFirst) or in layers
depthFirst true;
// Reverse ordering
reverse false;
}
springCoeffs
{
// Maximum jump of cell indices. Is fraction of number of cells
maxCo 0.01;
// Limit the amount of movement; the fraction maxCo gets decreased
// with every iteration
freezeFraction 0.999;
// Maximum number of iterations
maxIter 1000;
}
blockCoeffs
{
method scotch;
//method hierarchical;
//hierarchicalCoeffs
//{
// n (1 2 1);
// delta 0.001;
// order xyz;
//}
}
zoltanCoeffs
{
ORDER_METHOD LOCAL_HSFC;
}
// ************************************************************************* //

View File

@ -1,26 +0,0 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
. ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments # (error catching)
. ${WM_PROJECT_DIR:?}/wmake/scripts/sysFunctions # General system functions
. ${WM_PROJECT_DIR:?}/wmake/scripts/have_zoltan
#------------------------------------------------------------------------------
unset COMP_FLAGS LINK_FLAGS
if findLibrary "$FOAM_LIBBIN/libSloanRenumber" > /dev/null
then
echo " found libSloanRenumber -- enabling sloan renumbering support."
export LINK_FLAGS="$LINK_FLAGS -lSloanRenumber"
fi
if findLibrary "$FOAM_LIBBIN/libzoltanRenumber" > /dev/null && have_zoltan
then
echo " found libzoltanRenumber -- enabling zoltan renumbering support."
export COMP_FLAGS="$COMP_FLAGS -DHAVE_ZOLTAN"
export LINK_FLAGS="$LINK_FLAGS -lzoltanRenumber -L$ZOLTAN_LIB_DIR -lzoltan"
fi
wmake $targetType
#------------------------------------------------------------------------------

View File

@ -1,21 +1,22 @@
EXE_INC = \
$(COMP_FLAGS) \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/renumber/renumberMethods/lnInclude \
-I$(LIB_SRC)/renumber/zoltanRenumber/lnInclude \
-I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \
-I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
-I$(LIB_SRC)/parallel/reconstruct/reconstruct/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfileFormats \
-lmeshTools \
-ldynamicMesh \
-lfiniteVolume \
-lgenericPatchFields \
-lrenumberMethods \
-ldecompose \
-lreconstruct \
$(LINK_FLAGS) \
-ldecompositionMethods \
-L$(FOAM_LIBBIN)/dummy \
-lkahipDecomp -lmetisDecomp -lscotchDecomp

View File

@ -83,6 +83,7 @@ void Foam::domainDecompositionDryRun::writeVTK
writer.writeGeometry();
writer.beginCellData();
writer.writeCellData("procID", cellToProc);
writer.writeCellIDs();
Info<< "Wrote decomposition to "
<< this->mesh().time().relativePath(writer.output())

View File

@ -181,7 +181,7 @@ cleanCase()
# Debug output (blockMesh, decomposePar)
rm -f \
blockTopology.vtu blockFaces.vtp blockTopology.obj blockCentres.obj \
cellDist.vtu \
cellDist.vtu decomposePar.vtu renumberMesh.vtu \
0/cellDist
# From mpirunDebug

View File

@ -1,7 +1,7 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2312 |
| \\ / O peration | Version: v2406 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
@ -15,8 +15,12 @@ FoamFile
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Write maps from renumbered back to original mesh
writeMaps false;
// Additional libraries
//libs (SloanRenumber);
//libs (zoltanRenumber);
// Optional entry: write maps from renumbered back to original mesh
writeMaps false;
// Optional entry: sort cells on coupled boundaries to last for use with
// e.g. nonBlockingGaussSeidel.
@ -36,61 +40,66 @@ sortCoupledFaceCells false;
method CuthillMcKee;
//method Sloan;
//method RCM; // == reverseCuthillMcKee;
//method Sloan; //<- libs (zoltanRenumber);
//method manual;
//method random;
//method structured;
//method spring;
//method zoltan; // only if compiled with zoltan support
//method zoltan; //<- libs (zoltanRenumber);
//CuthillMcKeeCoeffs
//{
// // Reverse CuthillMcKee (RCM) or plain
// reverse true;
// // Plain or reverse CuthillMcKee (RCM)
// reverse true;
//}
manualCoeffs
{
// In system directory: new-to-original (i.e. order) labelIOList
dataFile "cellMap";
dataFile "cellMap";
}
// For extruded (i.e. structured in one direction) meshes
structuredCoeffs
{
// Patches that mesh was extruded from. These determine the starting
// layer of cells
patches (movingWall);
// Patches that mesh was extruded from.
// These determine the starting layer of cells
patches (movingWall);
// Method to renumber the starting layer of cells
method random;
method random;
// Renumber in columns (depthFirst) or in layers
depthFirst true;
depthFirst true;
// Reverse ordering
reverse false;
reverse false;
}
springCoeffs
{
// Maximum jump of cell indices. Is fraction of number of cells
maxCo 0.01;
maxCo 0.01;
// Limit the amount of movement; the fraction maxCo gets decreased
// with every iteration
freezeFraction 0.999;
// Maximum number of iterations
maxIter 1000;
maxIter 1000;
// Enable/disable verbosity
verbose true;
}
blockCoeffs
{
method scotch;
//method hierarchical;
method scotch;
//method hierarchical;
//hierarchicalCoeffs
//{
// n (1 2 1);

34
etc/config.sh/zoltan Normal file
View File

@ -0,0 +1,34 @@
#----------------------------------*-sh-*--------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd | www.openfoam.com
# \\/ M anipulation |
#------------------------------------------------------------------------------
# Copyright (C) 2024 OpenCFD Ltd.
#------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
#
# File
# etc/config.sh/zoltan
# - sourced during wmake process only.
#
# Description
# Setup for ZOLTAN include/libraries (usually ThirdParty installation).
#
# To disable its use: ZOLTAN_VERSION=zoltan-none
# For system-wide installations: ZOLTAN_VERSION=zoltan-system
#
# Note
# A csh version is not needed, since the values here are only sourced
# during the wmake process
#
#------------------------------------------------------------------------------
# USER EDITABLE PART: Changes made here may be lost with the next upgrade
export ZOLTAN_VERSION=Zoltan-3.901
export ZOLTAN_ARCH_PATH=$WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER$WM_PRECISION_OPTION$WM_LABEL_OPTION/$ZOLTAN_VERSION
# END OF (NORMAL) USER EDITABLE PART
#------------------------------------------------------------------------------

View File

@ -72,6 +72,7 @@ wmakeLnInclude -u fvOptions
wmake $targetType lagrangian/basic
wmake $targetType lagrangian/distributionModels
renumber/Allwmake $targetType $*
parallel/Allwmake $targetType $*
wmake $targetType dynamicFvMesh
@ -100,7 +101,6 @@ wmake $targetType fvMotionSolver
# snappyHexMesh uses overset voxelMesh
mesh/Allwmake $targetType $*
renumber/Allwmake $targetType $*
fvAgglomerationMethods/Allwmake $targetType $*
wmake $targetType waveModels

View File

@ -21,6 +21,7 @@ fi
warning="==> skip zoltanRenumber"
if have_zoltan
then
echo "zoltan - $ZOLTAN_ARCH_PATH"
wmake $targetType zoltanRenumber || echo "$warning (build issues detected)"
else
echo "$warning (no library)"

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2017 OpenFOAM Foundation
Copyright (C) 2020-2023 OpenCFD Ltd.
Copyright (C) 2020-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -74,6 +74,9 @@ typedef adjacency_list
typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef graph_traits<Graph>::vertices_size_type size_type;
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(SloanRenumber, 0);
@ -89,6 +92,13 @@ namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::SloanRenumber::SloanRenumber(const bool reverse)
:
renumberMethod(),
reverse_(reverse)
{}
Foam::SloanRenumber::SloanRenumber(const dictionary& dict)
:
renumberMethod(dict),

View File

@ -55,16 +55,8 @@ class SloanRenumber
{
// Private Data
const bool reverse_;
// Private Member Functions
//- No copy construct
SloanRenumber(const SloanRenumber&) = delete;
//- No copy assignment
void operator=(const SloanRenumber&) = delete;
//- Use reverse indexing
bool reverse_;
public:
@ -75,6 +67,9 @@ public:
// Constructors
//- Default construct, optionally with reverse
explicit SloanRenumber(const bool reverse = false);
//- Construct given the renumber dictionary
explicit SloanRenumber(const dictionary& dict);
@ -85,6 +80,13 @@ public:
// Member Functions
//- Toggle reverse on/off
void reverse(bool on) noexcept { reverse_ = on; }
//- The renumbering method does not require a polyMesh
virtual bool needs_mesh() const { return false; }
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
// This is only defined for geometric renumberMethods.

View File

@ -30,11 +30,12 @@ License
#include "addToRunTimeSelectionTable.H"
#include "bandCompression.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(CuthillMcKeeRenumber, 0);
defineTypeName(CuthillMcKeeRenumber);
defineTypeName(reverseCuthillMcKeeRenumber);
addToRunTimeSelectionTable
(
@ -42,11 +43,34 @@ namespace Foam
CuthillMcKeeRenumber,
dictionary
);
addToRunTimeSelectionTable
(
renumberMethod,
reverseCuthillMcKeeRenumber,
dictionary
);
// Select under the name "RCM"
addNamedToRunTimeSelectionTable
(
renumberMethod,
reverseCuthillMcKeeRenumber,
dictionary,
RCM
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::CuthillMcKeeRenumber::CuthillMcKeeRenumber(const bool reverse)
:
renumberMethod(),
reverse_(reverse)
{}
Foam::CuthillMcKeeRenumber::CuthillMcKeeRenumber(const dictionary& dict)
:
renumberMethod(dict),
@ -58,19 +82,45 @@ Foam::CuthillMcKeeRenumber::CuthillMcKeeRenumber(const dictionary& dict)
{}
Foam::CuthillMcKeeRenumber::CuthillMcKeeRenumber
(
const dictionary& dict,
const bool reverse
)
:
renumberMethod(dict),
reverse_(reverse)
{}
Foam::reverseCuthillMcKeeRenumber::reverseCuthillMcKeeRenumber()
:
CuthillMcKeeRenumber(true) // reverse = true
{}
Foam::reverseCuthillMcKeeRenumber::reverseCuthillMcKeeRenumber
(
const dictionary& dict
)
:
CuthillMcKeeRenumber(dict, true) // reverse = true
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::labelList Foam::CuthillMcKeeRenumber::renumber
(
const polyMesh& mesh,
const pointField& points
const pointField&
) const
{
labelList orderedToOld = meshTools::bandCompression(mesh);
if (reverse_)
{
reverse(orderedToOld);
Foam::reverse(orderedToOld);
}
return orderedToOld;
@ -88,7 +138,7 @@ Foam::labelList Foam::CuthillMcKeeRenumber::renumber
if (reverse_)
{
reverse(orderedToOld);
Foam::reverse(orderedToOld);
}
return orderedToOld;
@ -98,14 +148,14 @@ Foam::labelList Foam::CuthillMcKeeRenumber::renumber
Foam::labelList Foam::CuthillMcKeeRenumber::renumber
(
const CompactListList<label>& cellCells,
const pointField& cc
const pointField&
) const
{
labelList orderedToOld = meshTools::bandCompression(cellCells);
if (reverse_)
{
reverse(orderedToOld);
Foam::reverse(orderedToOld);
}
return orderedToOld;
@ -115,14 +165,14 @@ Foam::labelList Foam::CuthillMcKeeRenumber::renumber
Foam::labelList Foam::CuthillMcKeeRenumber::renumber
(
const labelListList& cellCells,
const pointField& points
const pointField&
) const
{
labelList orderedToOld = meshTools::bandCompression(cellCells);
if (reverse_)
{
reverse(orderedToOld);
Foam::reverse(orderedToOld);
}
return orderedToOld;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
Copyright (C) 2022-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,7 +28,7 @@ Class
Foam::CuthillMcKeeRenumber
Description
Cuthill-McKee renumbering
Cuthill-McKee renumbering (CM or RCM)
SourceFiles
CuthillMcKeeRenumber.C
@ -53,29 +53,28 @@ class CuthillMcKeeRenumber
{
// Private Data
const bool reverse_;
// Private Member Functions
//- No copy construct
CuthillMcKeeRenumber(const CuthillMcKeeRenumber&) = delete;
//- No copy assignment
void operator=(const CuthillMcKeeRenumber&) = delete;
//- Use reverse indexing
bool reverse_;
public:
//- Runtime type information
TypeName("CuthillMcKee");
TypeNameNoDebug("CuthillMcKee");
// Constructors
//- Default construct, optionally with reverse
explicit CuthillMcKeeRenumber(const bool reverse = false);
//- Construct given the renumber dictionary
explicit CuthillMcKeeRenumber(const dictionary& dict);
//- Construct given the renumber dictionary (ignored)
//- and specified reverse handling
CuthillMcKeeRenumber(const dictionary& dict, const bool reverse);
//- Destructor
virtual ~CuthillMcKeeRenumber() = default;
@ -83,6 +82,13 @@ public:
// Member Functions
//- Toggle reverse on/off
void reverse(bool on) noexcept { reverse_ = on; }
//- The renumbering method does not require a polyMesh
virtual bool needs_mesh() const { return false; }
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
// This is only defined for geometric renumberMethods.
@ -97,8 +103,10 @@ public:
// Use the mesh connectivity (if needed)
virtual labelList renumber
(
//! Mesh connectivity (see globalMeshData::calcCellCells)
const polyMesh& mesh,
const pointField& cc
//! \em ignored
const pointField& cellCentres
) const;
//- Return the order in which cells need to be visited
@ -109,14 +117,17 @@ public:
(
const labelList& cellCells,
const labelList& offsets,
const pointField& cc
//! \em ignored
const pointField& cellCentres
) const;
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
virtual labelList renumber
(
//! Mesh connectivity
const CompactListList<label>& cellCells,
//! \em ignored
const pointField& cellCentres
) const;
@ -126,12 +137,43 @@ public:
// - the connections are across coupled patches
virtual labelList renumber
(
//! Mesh connectivity
const labelListList& cellCells,
//! \em ignored
const pointField& cellCentres
) const;
};
/*---------------------------------------------------------------------------*\
Class reverseCuthillMcKeeRenumber Declaration
\*---------------------------------------------------------------------------*/
//- Reverse Cuthill-McKee renumbering
class reverseCuthillMcKeeRenumber
:
public CuthillMcKeeRenumber
{
public:
//- Runtime type information
TypeNameNoDebug("reverseCuthillMcKee");
// Constructors
//- Default construct
reverseCuthillMcKeeRenumber();
//- Construct given the renumber dictionary (ignored)
explicit reverseCuthillMcKeeRenumber(const dictionary& dict);
//- Destructor
virtual ~reverseCuthillMcKeeRenumber() = default;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -1,7 +1,10 @@
renumberMethod/renumberMethod.C
manualRenumber/manualRenumber.C
CuthillMcKeeRenumber/CuthillMcKeeRenumber.C
noRenumber/noRenumber.C
randomRenumber/randomRenumber.C
CuthillMcKeeRenumber/CuthillMcKeeRenumber.C
springRenumber/springRenumber.C
structuredRenumber/structuredRenumber.C
structuredRenumber/OppositeFaceCellWaveBase.C

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2020-2022 OpenCFD Ltd.
Copyright (C) 2020-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,14 +28,13 @@ License
#include "manualRenumber.H"
#include "addToRunTimeSelectionTable.H"
#include "IFstream.H"
#include "labelIOList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(manualRenumber, 0);
defineTypeName(manualRenumber);
addToRunTimeSelectionTable
(
@ -48,12 +47,19 @@ namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::manualRenumber::manualRenumber(const fileName& file)
:
renumberMethod(),
dataFile_(file)
{}
Foam::manualRenumber::manualRenumber(const dictionary& dict)
:
renumberMethod(dict),
dataFile_
(
dict.optionalSubDict(typeName+"Coeffs").get<fileName>("dataFile")
dict.optionalSubDict(typeName + "Coeffs").get<fileName>("dataFile")
)
{}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
Copyright (C) 2022-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -55,23 +55,17 @@ class manualRenumber
fileName dataFile_;
// Private Member Functions
//- No copy construct
manualRenumber(const manualRenumber&) = delete;
//- No copy assignment
void operator=(const manualRenumber&) = delete;
public:
//- Runtime type information
TypeName("manual");
TypeNameNoDebug("manual");
// Constructors
//- Construct with given data file
explicit manualRenumber(const fileName& file);
//- Construct given the renumber dictionary
explicit manualRenumber(const dictionary& dict);
@ -82,6 +76,10 @@ public:
// Member Functions
//- The renumbering method needs a polyMesh (for its IOobject)
virtual bool needs_mesh() const { return true; }
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
virtual labelList renumber(const pointField&) const

View File

@ -0,0 +1,102 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "noRenumber.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeName(noRenumber);
addNamedToRunTimeSelectionTable
(
renumberMethod,
noRenumber,
dictionary,
none
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::noRenumber::noRenumber()
:
renumberMethod()
{}
Foam::noRenumber::noRenumber(const dictionary& dict)
:
renumberMethod(dict)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::labelList Foam::noRenumber::renumber
(
const pointField& cellCentres
) const
{
return Foam::identity(cellCentres.size());
}
Foam::labelList Foam::noRenumber::renumber
(
const polyMesh& mesh,
const pointField&
) const
{
return Foam::identity(mesh.nCells());
}
Foam::labelList Foam::noRenumber::renumber
(
const CompactListList<label>& cellCells,
const pointField&
) const
{
return Foam::identity(cellCells.size());
}
Foam::labelList Foam::noRenumber::renumber
(
const labelListList& cellCells,
const pointField&
) const
{
return Foam::identity(cellCells.size());
}
// ************************************************************************* //

View File

@ -0,0 +1,124 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::noRenumber
Description
A dummy renumber method, selected as \c none.
Method coefficients: \a none
SourceFiles
noRenumber.C
\*---------------------------------------------------------------------------*/
#ifndef Foam_noRenumber_H
#define Foam_noRenumber_H
#include "renumberMethod.H"
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class noRenumber Declaration
\*---------------------------------------------------------------------------*/
class noRenumber
:
public renumberMethod
{
public:
//- Runtime type information
TypeNameNoDebug("none");
// Constructors
//- Default construct
noRenumber();
//- Construct given the renumber dictionary (unused)
explicit noRenumber(const dictionary& dict);
//- Destructor
virtual ~noRenumber() = default;
// Member Functions
//- The renumbering method does not require a polyMesh
virtual bool needs_mesh() const { return false; }
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
virtual labelList renumber(const pointField&) const;
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
virtual labelList renumber
(
//! Mesh number of cells
const polyMesh& mesh,
//! \em ignored
const pointField& cellCentres
) const;
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
virtual labelList renumber
(
//! Mesh connectivity for number of cells
const CompactListList<label>& cellCells,
//! \em ignored
const pointField& cellCentres
) const;
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
virtual labelList renumber
(
//! Mesh connectivity for number of cells
const labelListList& cellCells,
//! \em ignored
const pointField& cellCentres
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2012 OpenFOAM Foundation
Copyright (C) 2021-2022 OpenCFD Ltd.
Copyright (C) 2021-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,11 +30,11 @@ License
#include "Random.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(randomRenumber, 0);
defineTypeName(randomRenumber);
addToRunTimeSelectionTable
(
@ -45,8 +45,39 @@ namespace Foam
}
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
labelList randomMap(const label nCells)
{
Random rndGen(0);
// Full coverage
labelList newToOld(Foam::identity(nCells));
// Fisher-Yates shuffle algorithm
for (label i = nCells - 1; i > 0; --i)
{
label j = rndGen.position<label>(0, i);
std::swap(newToOld[i], newToOld[j]);
}
return newToOld;
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::randomRenumber::randomRenumber()
:
renumberMethod()
{}
Foam::randomRenumber::randomRenumber(const dictionary& dict)
:
renumberMethod(dict)
@ -57,52 +88,40 @@ Foam::randomRenumber::randomRenumber(const dictionary& dict)
Foam::labelList Foam::randomRenumber::renumber
(
const pointField& points
const pointField& cellCentres
) const
{
Random rndGen(0);
labelList newToOld(identity(points.size()));
for (label iter = 0; iter < 10; iter++)
{
forAll(newToOld, i)
{
label j = rndGen.position<label>(0, newToOld.size()-1);
std::swap(newToOld[i], newToOld[j]);
}
}
return newToOld;
return randomMap(cellCentres.size());
}
Foam::labelList Foam::randomRenumber::renumber
(
const polyMesh& mesh,
const pointField& points
const pointField&
) const
{
return renumber(points);
return randomMap(mesh.nCells());
}
Foam::labelList Foam::randomRenumber::renumber
(
const CompactListList<label>& cellCells,
const pointField& points
const pointField&
) const
{
return renumber(points);
return randomMap(cellCells.size());
}
Foam::labelList Foam::randomRenumber::renumber
(
const labelListList& cellCells,
const pointField& points
const pointField&
) const
{
return renumber(points);
return randomMap(cellCells.size());
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2012 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
Copyright (C) 2022-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -51,24 +51,18 @@ class randomRenumber
:
public renumberMethod
{
// Private Member Functions
//- No copy construct
randomRenumber(const randomRenumber&) = delete;
//- No copy assignment
void operator=(const randomRenumber&) = delete;
public:
//- Runtime type information
TypeName("random");
TypeNameNoDebug("random");
// Constructors
//- Construct given the renumber dictionary
//- Default construct
randomRenumber();
//- Construct given the renumber dictionary (unused)
explicit randomRenumber(const dictionary& dict);
@ -78,19 +72,21 @@ public:
// Member Functions
//- The renumbering method does not require a polyMesh
virtual bool needs_mesh() const { return false; }
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
virtual labelList renumber(const pointField&) const;
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
virtual labelList renumber(const polyMesh&, const pointField&) const;
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
virtual labelList renumber
(
const CompactListList<label>& cellCells,
//! Mesh number of cells
const polyMesh& mesh,
//! \em ignored
const pointField& cellCentres
) const;
@ -98,7 +94,19 @@ public:
//- (ie. from ordered back to original cell label).
virtual labelList renumber
(
//! Mesh connectivity for number of cells
const CompactListList<label>& cellCells,
//! \em ignored
const pointField& cellCentres
) const;
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
virtual labelList renumber
(
//! Mesh connectivity for number of cells
const labelListList& cellCells,
//! \em ignored
const pointField& cellCentres
) const;
};

View File

@ -27,18 +27,30 @@ License
\*---------------------------------------------------------------------------*/
#include "renumberMethod.H"
#include "dlLibraryTable.H"
#include "globalMeshData.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(renumberMethod, 0);
defineTypeName(renumberMethod);
defineRunTimeSelectionTable(renumberMethod, dictionary);
}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
Foam::wordList Foam::renumberMethod::supportedMethods()
{
if (dictionaryConstructorTablePtr_)
{
return dictionaryConstructorTablePtr_->sortedToc();
}
return wordList();
}
Foam::autoPtr<Foam::renumberMethod> Foam::renumberMethod::New
(
const dictionary& dict
@ -48,6 +60,9 @@ Foam::autoPtr<Foam::renumberMethod> Foam::renumberMethod::New
//Info<< "Selecting renumberMethod " << methodType << endl;
// Load any additional libs (verbose = false)
dlLibraryTable::libs().open("libs", dict, false);
auto* ctorPtr = dictionaryConstructorTable(methodType);
if (!ctorPtr)
@ -67,6 +82,16 @@ Foam::autoPtr<Foam::renumberMethod> Foam::renumberMethod::New
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::labelList Foam::renumberMethod::renumber
(
const pointField&
) const
{
NotImplemented;
return labelList();
}
Foam::labelList Foam::renumberMethod::renumber
(
const polyMesh& mesh,

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
Copyright (C) 2022-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -41,6 +41,7 @@ SourceFiles
#include "polyMesh.H"
#include "pointField.H"
#include "CompactListList.H"
#include "wordList.H"
namespace Foam
{
@ -51,26 +52,10 @@ namespace Foam
class renumberMethod
{
protected:
// Protected Data
const dictionary& renumberDict_;
// Protected Member Functions
//- No copy construct
renumberMethod(const renumberMethod&) = delete;
//- No copy assignment
void operator=(const renumberMethod&) = delete;
public:
//- Runtime type information
TypeName("renumberMethod");
TypeNameNoDebug("renumberMethod");
// Declare run-time constructor selection tables
@ -87,23 +72,25 @@ public:
);
// Selectors
//- Return a reference to the selected renumbering method
static autoPtr<renumberMethod> New
(
const dictionary& renumberDict
);
// Constructors
//- Construct given the renumber dictionary
explicit renumberMethod(const dictionary& dict)
:
renumberDict_(dict)
//- Default construct
renumberMethod()
{}
//- Construct with renumber dictionary (which is currently unused)
explicit renumberMethod(const dictionary&)
{}
// Selectors
//- Construct/select a renumbering method
static autoPtr<renumberMethod> New(const dictionary& dict);
//- Return a list of the known methods
static wordList supportedMethods();
//- Destructor
virtual ~renumberMethod() = default;
@ -111,31 +98,25 @@ public:
// Member Functions
//- Does renumbering method require a polyMesh?
virtual bool needs_mesh() const { return false; }
// No topology
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
// This is only defined for geometric renumberMethods.
virtual labelList renumber(const pointField&) const
{
NotImplemented;
return labelList();
}
// This is only defined for geometric renumber methods.
virtual labelList renumber(const pointField&) const;
// Topology provided by mesh
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
// Use the mesh connectivity (if needed)
virtual labelList renumber(const polyMesh&, const pointField&) const;
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
// Addressing in losort addressing (= neighbour + offsets into
// neighbour)
virtual labelList renumber
(
const labelList& cellCells,
const labelList& offsets,
const pointField&
) const;
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
// Gets passed agglomeration map (from fine to coarse cells) and coarse
@ -151,6 +132,20 @@ public:
const pointField& coarsePoints
) const;
// Topology provided explicitly
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
// Addressing in losort addressing (= neighbour + offsets into
// neighbour)
virtual labelList renumber
(
const labelList& cellCells,
const labelList& offsets,
const pointField&
) const;
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
// Uses 'unpack' internally, so should be overloaded when possible

View File

@ -50,10 +50,11 @@ namespace Foam
Foam::springRenumber::springRenumber(const dictionary& dict)
:
renumberMethod(dict),
coeffsDict_(dict.optionalSubDict(typeName+"Coeffs")),
coeffsDict_(dict.optionalSubDict(typeName + "Coeffs")),
maxIter_(coeffsDict_.get<label>("maxIter")),
maxCo_(coeffsDict_.get<scalar>("maxCo")),
freezeFraction_(coeffsDict_.get<scalar>("freezeFraction"))
freezeFraction_(coeffsDict_.get<scalar>("freezeFraction")),
verbose_(coeffsDict_.getOrDefault("verbose", true))
{}
@ -71,10 +72,7 @@ Foam::labelList Foam::springRenumber::renumberImpl
// Move cells to the average 'position' of their neighbour.
scalarField position(nOldCells);
forAll(position, celli)
{
position[celli] = celli;
}
std::iota(position.begin(), position.end(), 0);
// Sum force per cell. Also reused for the displacement
scalarField sumForce(nOldCells);
@ -90,9 +88,9 @@ Foam::labelList Foam::springRenumber::renumberImpl
// << endl;
//Pout<< "Position :" << nl
// << " min : " << min(position) << nl
// << " max : " << max(position) << nl
// << " avg : " << average(position) << nl
// << " min : " << Foam::min(position) << nl
// << " max : " << Foam::max(position) << nl
// << " avg : " << Foam::average(position) << nl
// << endl;
// Sum force per cell.
@ -100,9 +98,8 @@ Foam::labelList Foam::springRenumber::renumberImpl
for (label oldCelli = 0; oldCelli < nOldCells; ++oldCelli)
{
const label celli = oldToNew[oldCelli];
const auto& neighbours = cellCells[oldCelli];
for (const label nbr : neighbours)
for (const label nbr : cellCells[oldCelli])
{
const label nbrCelli = oldToNew[nbr];
@ -111,35 +108,38 @@ Foam::labelList Foam::springRenumber::renumberImpl
}
//Pout<< "Force :" << nl
// << " min : " << min(sumForce) << nl
// << " max : " << max(sumForce) << nl
// << " avgMag : " << average(mag(sumForce)) << nl
// << " min : " << Foam::min(sumForce) << nl
// << " max : " << Foam::max(sumForce) << nl
// << " avgMag : " << Foam::average(mag(sumForce)) << nl
// << "DeltaT : " << deltaT << nl
// << endl;
// Limit displacement
scalar deltaT = maxCo / max(mag(sumForce));
Info<< "Iter:" << iter
<< " maxCo:" << maxCo
<< " deltaT:" << deltaT
<< " average force:" << average(mag(sumForce)) << endl;
if (verbose_)
{
Info<< "Iter:" << iter
<< " maxCo:" << maxCo
<< " deltaT:" << deltaT
<< " average force:" << average(mag(sumForce)) << endl;
}
// Determine displacement
scalarField& displacement = sumForce;
displacement *= deltaT;
//Pout<< "Displacement :" << nl
// << " min : " << min(displacement) << nl
// << " max : " << max(displacement) << nl
// << " avgMag : " << average(mag(displacement)) << nl
// << " min : " << Foam::min(displacement) << nl
// << " max : " << Foam::max(displacement) << nl
// << " avgMag : " << Foam::average(mag(displacement)) << nl
// << endl;
// Calculate new position and scale to be within original range
// (0..nCells-1) for ease of postprocessing.
position += displacement;
position -= min(position);
position *= (position.size()-1)/max(position);
position -= Foam::min(position);
position *= (position.size()-1)/Foam::max(position);
// Slowly freeze.
maxCo *= freezeFraction_;
@ -148,7 +148,7 @@ Foam::labelList Foam::springRenumber::renumberImpl
//writeOBJ("endPosition.obj", cellCells, position);
// Move cells to new position
labelList shuffle(sortedOrder(position));
labelList shuffle(Foam::sortedOrder(position));
// Reorder oldToNew
inplaceReorder(shuffle, oldToNew);

View File

@ -72,6 +72,9 @@ class springRenumber
const scalar freezeFraction_;
//- Verbose reporting of progress
bool verbose_;
// Private Member Functions

View File

@ -32,7 +32,7 @@ License
#include "fvMeshSubset.H"
#include "OppositeFaceCellWave.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
@ -59,7 +59,7 @@ Foam::structuredRenumber::structuredRenumber
patches_(coeffsDict_.get<wordRes>("patches")),
nLayers_(coeffsDict_.getOrDefault<label>("nLayers", labelMax)),
depthFirst_(coeffsDict_.get<bool>("depthFirst")),
reverse_(coeffsDict_.get<bool>("reverse")),
reverse_(coeffsDict_.getOrDefault("reverse", false)),
method_(renumberMethod::New(coeffsDict_))
{}
@ -70,10 +70,10 @@ bool Foam::structuredRenumber::layerLess::operator()
(
const label a,
const label b
)
) const
{
const topoDistanceData<label>& ta = distance_[a];
const topoDistanceData<label>& tb = distance_[b];
const auto& ta = distance_[a];
const auto& tb = distance_[b];
int dummy;
@ -273,7 +273,7 @@ Foam::labelList Foam::structuredRenumber::renumber
// Return furthest away cell first
if (reverse_)
{
reverse(orderedToOld);
Foam::reverse(orderedToOld);
}
return orderedToOld;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2016 OpenFOAM Foundation
Copyright (C) 2020-2022 OpenCFD Ltd.
Copyright (C) 2020-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -52,7 +52,7 @@ namespace Foam
template<class Type> class topoDistanceData;
/*---------------------------------------------------------------------------*\
Class structuredRenumber Declaration
Class structuredRenumber Declaration
\*---------------------------------------------------------------------------*/
class structuredRenumber
@ -63,8 +63,7 @@ public:
// Public Classes
//- Less function class that can be used for sorting according to
// column and layer
//- Function class for sorting according to column and layer
class layerLess
{
const bool depthFirst_;
@ -85,10 +84,12 @@ public:
distance_(distance)
{}
bool operator()(const label a, const label b);
bool operator()(const label a, const label b) const;
};
private:
// Private Data
const dictionary& coeffsDict_;
@ -131,6 +132,10 @@ public:
// Member Functions
//- Renumbering method requires a polyMesh
virtual bool needs_mesh() const { return true; }
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
// This is only defined for geometric renumberMethods.

View File

@ -1,3 +1,4 @@
zoltanRenumber.C
LIB = $(FOAM_LIBBIN)/libzoltanRenumber
/* Build with MPI dependency */
LIB = $(FOAM_MPI_LIBBIN)/libzoltanRenumber

View File

@ -8,5 +8,7 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude
LIB_LIBS = \
-L$(ZOLTAN_LIB_DIR) -lzoltan \
-lmeshTools
-lmeshTools \
-lrenumberMethods \
$(PLIBS) \
-L$(ZOLTAN_LIB_DIR) -lzoltan

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -57,7 +58,10 @@ SourceFiles
#include "polyMesh.H"
#include "globalMeshData.H"
#include "globalIndex.H"
#include "CStringList.H"
#include "uint.H"
#include <algorithm>
#include <numeric>
// Include MPI without any C++ bindings
#ifndef MPICH_SKIP_MPICXX
@ -71,7 +75,7 @@ SourceFiles
#include "zoltan.h"
#include <mpi.h>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
@ -86,43 +90,80 @@ namespace Foam
}
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
// [ZOLTAN_NUM_OBJ_FN]
// The number of graph vertices (locally)
static int get_number_of_vertices(void *data, int *ierr)
{
const Foam::polyMesh& mesh = *static_cast<const Foam::polyMesh*>(data);
*ierr = ZOLTAN_OK;
const auto& mesh = *static_cast<const Foam::polyMesh*>(data);
return mesh.nCells();
}
static void get_vertex_list(void *data, int sizeGID, int sizeLID,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int wgt_dim, float *obj_wgts, int *ierr)
// [ZOLTAN_OBJ_LIST_FN]
// The ids for the graph vertices
static void get_vertex_list
(
void *data,
int sizeGID, // (currently unused)
int sizeLID, // (currently unused)
ZOLTAN_ID_PTR global_ids,
ZOLTAN_ID_PTR local_ids,
int wgt_dim, // (currently unused)
float *obj_wgts, // (currently unused)
int *ierr
)
{
const Foam::polyMesh& mesh = *static_cast<const Foam::polyMesh*>(data);
*ierr = ZOLTAN_OK;
const auto& mesh = *static_cast<const Foam::polyMesh*>(data);
/* In this example, return the IDs of our vertices, but no weights.
* Zoltan will assume equally weighted vertices.
*/
const auto nCells = mesh.nCells();
wgt_dim = 0;
obj_wgts = nullptr;
// Offset for globally unique IDs
const auto myProci = Foam::UPstream::myProcNo();
const auto myProcOffset =
mesh.globalData().globalMeshCellAddr().localStart(myProci);
for (Foam::label i=0; i<mesh.nCells(); i++)
{
globalID[i] = i; // should be global
localID[i] = i;
}
// Global indices
std::iota(global_ids, (global_ids + nCells), ZOLTAN_ID_TYPE(myProcOffset));
// Local indices
std::iota(local_ids, (local_ids + nCells), ZOLTAN_ID_TYPE(0));
// No weights?
// Zoltan will assume equally weighted vertices.
// if (obj_wgts && wgt_dim > 0)
// {
// std::fill_n(obj_wgts, wgt_dim, float(1));
// }
}
static void get_num_edges_list(void *data, int sizeGID, int sizeLID,
int num_obj,
ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *numEdges, int *ierr)
// [ZOLTAN_NUM_EDGES_MULTI_FN]
// query function returns the number of edges in the communication
// graph of the application for each object in a list of objects.
// That is, for each object in the global_ids/local_ids arrays, the
// number of objects with which the given object must share
// information is returned.
static void get_num_edges_list
(
void *data,
int sizeGID,
int sizeLID,
int num_obj, // Number of graph vertices (mesh cells)
ZOLTAN_ID_PTR global_ids, // (currently unused)
ZOLTAN_ID_PTR local_ids, // rank-local vertex id (mesh cell id)
int *numEdges,
int *ierr
)
{
const Foam::polyMesh& mesh = *static_cast<const Foam::polyMesh*>(data);
*ierr = ZOLTAN_OK;
const auto& mesh = *static_cast<const Foam::polyMesh*>(data);
if ((sizeGID != 1) || (sizeLID != 1) || (num_obj != mesh.nCells()))
{
@ -130,32 +171,46 @@ static void get_num_edges_list(void *data, int sizeGID, int sizeLID,
return;
}
for (Foam::label i=0; i < num_obj ;i++)
{
Foam::label celli = localID[i];
const Foam::cell& cFaces = mesh.cells()[celli];
forAll(cFaces, cFacei)
{
Foam::label n = 0;
if (mesh.isInternalFace(cFaces[cFacei]))
{
n++;
}
numEdges[i] = n;
}
}
const Foam::label nCells = num_obj;
*ierr = ZOLTAN_OK;
for (Foam::label i=0; i < nCells; ++i)
{
const Foam::label celli = local_ids[i];
int numNbr = 0;
for (const auto facei : mesh.cells()[celli])
{
if (mesh.isInternalFace(facei))
{
++numNbr;
}
// TBD: check coupled etc
}
numEdges[i] = numNbr;
}
}
static void get_edge_list(void *data, int sizeGID, int sizeLID,
int num_obj, ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
int *num_edges,
ZOLTAN_ID_PTR nborGID, int *nborProc,
int wgt_dim, float *ewgts, int *ierr)
// [ZOLTAN_EDGE_LIST_MULTI_FN]
static void get_edge_list
(
void *data,
int sizeGID,
int sizeLID,
int num_obj,
ZOLTAN_ID_PTR global_ids, // (currently unused)
ZOLTAN_ID_PTR local_ids, // rank-local vertex id (mesh cell id)
int *num_edges,
ZOLTAN_ID_PTR nborGID,
int *nborProc,
int wgt_dim,
float *ewgts,
int *ierr
)
{
const Foam::polyMesh& mesh = *static_cast<const Foam::polyMesh*>(data);
*ierr = ZOLTAN_OK;
const auto& mesh = *static_cast<const Foam::polyMesh*>(data);
if
(
@ -169,20 +224,24 @@ static void get_edge_list(void *data, int sizeGID, int sizeLID,
return;
}
ZOLTAN_ID_TYPE* nextNbor = nborGID;
int* nextProc = nborProc;
float* nextWgt = ewgts;
// Offset for globally unique IDs
const auto myProci = Foam::UPstream::myProcNo();
const auto myProcOffset =
mesh.globalData().globalMeshCellAddr().localStart(myProci);
for (Foam::label i=0; i < num_obj; i++)
auto* nextNbor = nborGID;
auto* nextProc = nborProc;
auto* nextWgt = ewgts;
const Foam::label nCells = num_obj;
for (Foam::label i=0; i < nCells; ++i)
{
Foam::label celli = localID[i];
const Foam::label celli = local_ids[i];
int numNbr = 0;
const Foam::cell& cFaces = mesh.cells()[celli];
forAll(cFaces, cFacei)
for (const auto facei : mesh.cells()[celli])
{
Foam::label n = 0;
Foam::label facei = cFaces[cFacei];
if (mesh.isInternalFace(facei))
{
Foam::label nbr = mesh.faceOwner()[facei];
@ -191,32 +250,37 @@ static void get_edge_list(void *data, int sizeGID, int sizeLID,
nbr = mesh.faceNeighbour()[facei];
}
// Note: global index
*nextNbor++ = nbr;
*nextProc++ = 0;
*nextNbor++ = (nbr + myProcOffset); // global id
*nextProc++ = myProci; // rank-local connection
*nextWgt++ = 1.0;
n++;
}
if (n != num_edges[i])
{
*ierr = ZOLTAN_FATAL;
return;
++numNbr;
}
}
// Sanity check
if (numNbr != num_edges[i])
{
*ierr = ZOLTAN_FATAL;
return;
}
}
*ierr = ZOLTAN_OK;
}
// [ZOLTAN_NUM_GEOM_FN]
// The dimensionality of the mesh geometry (2D,3D, etc)
static int get_mesh_dim(void *data, int *ierr)
{
const Foam::polyMesh& mesh = *static_cast<const Foam::polyMesh*>(data);
*ierr = ZOLTAN_OK;
const auto& mesh = *static_cast<const Foam::polyMesh*>(data);
return mesh.nSolutionD();
}
// [ZOLTAN_GEOM_MULTI_FN]
// The geometric location of the graph vertices (mesh cellCentres)
static void get_geom_list
(
void *data,
@ -225,11 +289,12 @@ static void get_geom_list
int num_obj,
ZOLTAN_ID_PTR global_ids,
ZOLTAN_ID_PTR local_ids,
int num_dim,
double *geom_vec,
int num_dim, // dimensionality (2|3)
double *geom_vec, // [out] cellCentres
int *ierr
)
{
*ierr = ZOLTAN_OK;
const Foam::polyMesh& mesh = *static_cast<const Foam::polyMesh*>(data);
if
@ -244,26 +309,46 @@ static void get_geom_list
return;
}
double* p = geom_vec;
const Foam::Vector<Foam::label>& sol = mesh.solutionD();
const Foam::pointField& cc = mesh.cellCentres();
for (Foam::label celli = 0; celli < num_obj; celli++)
if (num_dim == 3)
{
const Foam::point& pt = cc[celli];
// Fast path for 3D - assumes that local_ids are still ordered
std::copy_n
(
reinterpret_cast<const Foam::point::cmptType*>(cc.cdata()),
(3*num_obj),
geom_vec
);
}
else
{
// [out] cellCentres
double* p = geom_vec;
for (Foam::direction cmpt = 0; cmpt < Foam::vector::nComponents; cmpt++)
const Foam::Vector<Foam::label>& sol = mesh.solutionD();
const Foam::label nCells = num_obj;
// Assumes that local_ids are still ordered
for (Foam::label celli = 0; celli < nCells; ++celli)
{
if (sol[cmpt] == 1)
const Foam::point& pt = cc[celli];
for
(
Foam::direction cmpt = 0;
cmpt < Foam::vector::nComponents;
++cmpt
)
{
*p++ = pt[cmpt];
if (sol[cmpt] == 1)
{
*p++ = pt[cmpt];
}
}
}
}
*ierr = ZOLTAN_OK;
}
@ -272,7 +357,7 @@ static void get_geom_list
Foam::zoltanRenumber::zoltanRenumber(const dictionary& dict)
:
renumberMethod(dict),
coeffsDict_(dict.optionalSubDict(typeName+"Coeffs"))
coeffsDict_(dict.optionalSubDict(typeName + "Coeffs"))
{}
@ -284,20 +369,15 @@ Foam::labelList Foam::zoltanRenumber::renumber
const pointField& points
) const
{
stringList args(1);
args[0] = "zoltanRenumber";
// Zoltan_Initialize will trigger MPI_Init() if not already done.
// - use UPstream::initNull() so that OpenFOAM also knows about MPI
int argc = args.size();
char* argv[argc];
for (label i = 0; i < argc; i++)
{
argv[i] = strdup(args[i].c_str());
}
UPstream::initNull();
CStringList args({"zoltan-renumber"});
float ver;
int rc = Zoltan_Initialize(argc, argv, &ver);
Foam::Pout<< "Initialised to " << ver << Foam::endl;
int rc = Zoltan_Initialize(args.size(), args.strings(), &ver);
if (rc != ZOLTAN_OK)
{
@ -307,24 +387,55 @@ Foam::labelList Foam::zoltanRenumber::renumber
struct Zoltan_Struct *zz = Zoltan_Create(MPI_COMM_WORLD);
polyMesh& mesh = const_cast<polyMesh&>(pMesh);
// const bool verbose = coeffsDict_.getOrDefault(verbose, false);
const bool verbose = true;
// Default order method
Zoltan_Set_Param(zz, "ORDER_METHOD", "LOCAL_HSFC");
if (false)
{
Info<< typeName << " : default ORDER_METHOD = LOCAL_HSFC" << nl
<< typeName << " : default ORDER_TYPE = LOCAL" << nl;
}
for (const entry& dEntry : coeffsDict_)
{
const word& key = dEntry.keyword();
// Internal keywords
if
(
key == "method"
|| key == "verbose"
)
{
continue;
}
if (!dEntry.isDict())
{
const word& key = dEntry.keyword();
const word value(dEntry.get<word>());
Info<< typeName << " : setting parameter " << key
<< " to " << value << endl;
if (verbose)
{
Info<< typeName
<< " : setting parameter "
<< key << " = " << value << nl;
}
Zoltan_Set_Param(zz, key.c_str(), value.c_str());
}
}
// Always use rank LOCAL ordering
Zoltan_Set_Param(zz, "ORDER_TYPE", "LOCAL");
// Set callbacks
polyMesh& mesh = const_cast<polyMesh&>(pMesh);
// Callbacks for graph vertex IDs
Zoltan_Set_Num_Obj_Fn(zz, get_number_of_vertices, &mesh);
Zoltan_Set_Obj_List_Fn(zz, get_vertex_list, &mesh);
@ -337,25 +448,26 @@ Foam::labelList Foam::zoltanRenumber::renumber
Zoltan_Set_Edge_List_Multi_Fn(zz, get_edge_list, &mesh);
const auto nCells = mesh.nCells();
//Note: !global indices
List<ZOLTAN_ID_TYPE> wantedCells(mesh.nCells());
List<ZOLTAN_ID_TYPE> globalIds(nCells);
List<ZOLTAN_ID_TYPE> oldToNew(nCells);
globalIndex globalCells(mesh.nCells());
forAll(wantedCells, i)
{
//wantedCells[i] = i;
wantedCells[i] = globalCells.toGlobal(i);
}
// Offset for globally unique IDs
const label myProci = UPstream::myProcNo();
const label myProcOffset =
mesh.globalData().globalMeshCellAddr().localStart(myProci);
List<ZOLTAN_ID_TYPE> oldToNew(mesh.nCells());
// Global indices
std::iota(globalIds.begin(), globalIds.end(), ZOLTAN_ID_TYPE(myProcOffset));
int err = Zoltan_Order
(
zz,
1, //int num_gid_entries,
mesh.globalData().nTotalCells(), //int num_obj,
wantedCells.begin(),
1, //int num_gid_entries,
nCells, //int num_obj,
globalIds.begin(),
oldToNew.begin()
);
@ -365,18 +477,22 @@ Foam::labelList Foam::zoltanRenumber::renumber
<< "Failed Zoltan_Order" << exit(FatalError);
}
for (label i = 0; i < argc; i++)
{
free(argv[i]);
}
Zoltan_Destroy(&zz);
// From global number to rank-local numbering
globalIds.clear();
labelList order(oldToNew.size());
forAll(order, i)
{
order[i] = oldToNew[i];
}
// From global to local (without checks)
std::transform
(
oldToNew.begin(),
oldToNew.end(),
order.begin(),
[=](const ZOLTAN_ID_TYPE id) -> label { return (id - myProcOffset); }
);
return order;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
Copyright (C) 2022-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -83,6 +83,10 @@ public:
// Member Functions
//- Renumbering method requires a polyMesh
virtual bool needs_mesh() const { return true; }
//- Return the order in which cells need to be visited
//- (ie. from ordered back to original cell label).
// This is only defined for geometric renumberMethods.

View File

@ -18,8 +18,7 @@ runParallel -s CuthillMcKee renumberMesh -overwrite $fileHandler
runParallel -s CuthillMcKee icoFoam $fileHandler
# Bit of bad renumbering and running
runParallel -s random renumberMesh \
-overwrite -dict system/renumberMeshDict-random $fileHandler
runParallel -s random renumberMesh -renumber-method random -overwrite $fileHandler
runParallel -s random icoFoam $fileHandler
# Pick up last result

View File

@ -1,109 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2312 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object renumberMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Write maps from renumbered back to original mesh
writeMaps true;
// Optional entry: sort cells on coupled boundaries to last for use with
// e.g. nonBlockingGaussSeidel.
sortCoupledFaceCells false;
// Optional entry: renumber on a block-by-block basis. It uses a
// blockCoeffs dictionary to construct a decompositionMethod to do
// a block subdivision) and then applies the renumberMethod to each
// block in turn. This can be used in large cases to keep the blocks
// fitting in cache with all the cache misses bunched at the end.
// This number is the approximate size of the blocks - this gets converted
// to a number of blocks that is the input to the decomposition method.
//blockSize 1000;
// Optional entry: sort points into internal and boundary points
//orderPoints false;
// Optional: suppress renumbering cellSets,faceSets,pointSets
//renumberSets false;
//method CuthillMcKee;
//method Sloan;
//method manual;
method random;
//method structured;
//method spring;
//method zoltan; // only if compiled with zoltan support
//CuthillMcKeeCoeffs
//{
// // Reverse CuthillMcKee (RCM) or plain
// reverse true;
//}
manualCoeffs
{
// In system directory: new-to-original (i.e. order) labelIOList
dataFile "cellMap";
}
// For extruded (i.e. structured in one direction) meshes
structuredCoeffs
{
// Patches that mesh was extruded from. These determine the starting
// layer of cells
patches (movingWall);
// Method to renumber the starting layer of cells
method random;
// Renumber in columns (depthFirst) or in layers
depthFirst true;
// Reverse ordering
reverse false;
}
springCoeffs
{
// Maximum jump of cell indices. Is fraction of number of cells
maxCo 0.01;
// Limit the amount of movement; the fraction maxCo gets decreased
// with every iteration
freezeFraction 0.999;
// Maximum number of iterations
maxIter 1000;
}
blockCoeffs
{
method scotch;
//method hierarchical;
//hierarchicalCoeffs
//{
// n (1 2 1);
//}
}
zoltanCoeffs
{
ORDER_METHOD LOCAL_HSFC;
}
// ************************************************************************* //

View File

@ -6,6 +6,5 @@ cd "${0%/*}" || exit # Run from this directory
cleanCase0
rm -rf constant/triSurface
rm -f cellDist.vtu
#------------------------------------------------------------------------------

View File

@ -5,7 +5,7 @@
# \\ / A nd | www.openfoam.com
# \\/ M anipulation |
#------------------------------------------------------------------------------
# Copyright (C) 2018-2020 OpenCFD Ltd.
# Copyright (C) 2018-2024 OpenCFD Ltd.
#------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@ -64,6 +64,9 @@ search_zoltan()
local prefix="${1:-system}"
local header library
local mpiPrefix="$MPI_ARCH_PATH"
local mpiName="${MPI_ARCH_PATH##*/}"
# ----------------------------------
if isNone "$prefix"
then
@ -71,11 +74,29 @@ search_zoltan()
return 1
elif hasAbsdir "$prefix"
then
header=$(findFirstFile "$prefix/include/$incName")
library=$(findExtLib "$libName")
header=$(findFirstFile \
"$prefix/include/$FOAM_MPI/$incName" \
"$prefix/include/zoltan/$incName" \
"$prefix/include/$incName" \
"$mpiPrefix/include/$incName" \
"$prefix/include/$mpiName/$incName" \
"$prefix/include/${mpiName}-$(uname -m)/$incName" \
)
library=$(findExtLib \
"$FOAM_MPI/$libName" \
"$libName" \
)
elif isSystem "$prefix"
then
header=$(findSystemInclude -name="$incName")
header=$(findFirstFile \
"/usr/local/include/zoltan/$incName" \
"/usr/local/include/$incName" \
"/usr/include/zoltan/$incName" \
"/usr/include/$incName" \
"$mpiPrefix/include/$incName" \
"/usr/include/$mpiName/$incName" \
"$prefix/include/${mpiName}-$(uname -m)/$incName" \
)
prefix=$(sysPrefix "$header")
else
unset prefix
@ -91,6 +112,7 @@ search_zoltan()
# Library
[ -n "$library" ] \
|| library=$(findLibrary -prefix="$prefix" -name="$libName") \
|| library=$(findLibrary -prefix="$mpiPrefix" -name="$libName") \
|| {
[ -n "$warn" ] && echo "$warn (no library)"
return 2
@ -99,6 +121,7 @@ search_zoltan()
# ----------------------------------
# OK
# echo "zoltan - $prefix"
export HAVE_ZOLTAN=true
export ZOLTAN_ARCH_PATH="$prefix"
export ZOLTAN_INC_DIR="${header%/*}" # Basename