mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'master' of /home/dm4/OpenFOAM/OpenFOAM-dev
This commit is contained in:
@ -26,177 +26,7 @@ License
|
||||
#include "pairGAMGAgglomeration.H"
|
||||
#include "lduAddressing.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::tmp<Foam::labelField> Foam::pairGAMGAgglomeration::agglomerate
|
||||
(
|
||||
label& nCoarseCells,
|
||||
const lduAddressing& fineMatrixAddressing,
|
||||
const scalarField& faceWeights
|
||||
)
|
||||
{
|
||||
const label nFineCells = fineMatrixAddressing.size();
|
||||
|
||||
const labelUList& upperAddr = fineMatrixAddressing.upperAddr();
|
||||
const labelUList& lowerAddr = fineMatrixAddressing.lowerAddr();
|
||||
|
||||
// For each cell calculate faces
|
||||
labelList cellFaces(upperAddr.size() + lowerAddr.size());
|
||||
labelList cellFaceOffsets(nFineCells + 1);
|
||||
|
||||
// memory management
|
||||
{
|
||||
labelList nNbrs(nFineCells, 0);
|
||||
|
||||
forAll(upperAddr, facei)
|
||||
{
|
||||
nNbrs[upperAddr[facei]]++;
|
||||
}
|
||||
|
||||
forAll(lowerAddr, facei)
|
||||
{
|
||||
nNbrs[lowerAddr[facei]]++;
|
||||
}
|
||||
|
||||
cellFaceOffsets[0] = 0;
|
||||
forAll(nNbrs, celli)
|
||||
{
|
||||
cellFaceOffsets[celli+1] = cellFaceOffsets[celli] + nNbrs[celli];
|
||||
}
|
||||
|
||||
// reset the whole list to use as counter
|
||||
nNbrs = 0;
|
||||
|
||||
forAll(upperAddr, facei)
|
||||
{
|
||||
cellFaces
|
||||
[
|
||||
cellFaceOffsets[upperAddr[facei]] + nNbrs[upperAddr[facei]]
|
||||
] = facei;
|
||||
|
||||
nNbrs[upperAddr[facei]]++;
|
||||
}
|
||||
|
||||
forAll(lowerAddr, facei)
|
||||
{
|
||||
cellFaces
|
||||
[
|
||||
cellFaceOffsets[lowerAddr[facei]] + nNbrs[lowerAddr[facei]]
|
||||
] = facei;
|
||||
|
||||
nNbrs[lowerAddr[facei]]++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// go through the faces and create clusters
|
||||
|
||||
tmp<labelField> tcoarseCellMap(new labelField(nFineCells, -1));
|
||||
labelField& coarseCellMap = tcoarseCellMap();
|
||||
|
||||
nCoarseCells = 0;
|
||||
|
||||
for (label celli=0; celli<nFineCells; celli++)
|
||||
{
|
||||
if (coarseCellMap[celli] < 0)
|
||||
{
|
||||
label matchFaceNo = -1;
|
||||
scalar maxFaceWeight = -GREAT;
|
||||
|
||||
// check faces to find ungrouped neighbour with largest face weight
|
||||
for
|
||||
(
|
||||
label faceOs=cellFaceOffsets[celli];
|
||||
faceOs<cellFaceOffsets[celli+1];
|
||||
faceOs++
|
||||
)
|
||||
{
|
||||
label facei = cellFaces[faceOs];
|
||||
|
||||
// I don't know whether the current cell is owner or neighbour.
|
||||
// Therefore I'll check both sides
|
||||
if
|
||||
(
|
||||
coarseCellMap[upperAddr[facei]] < 0
|
||||
&& coarseCellMap[lowerAddr[facei]] < 0
|
||||
&& faceWeights[facei] > maxFaceWeight
|
||||
)
|
||||
{
|
||||
// Match found. Pick up all the necessary data
|
||||
matchFaceNo = facei;
|
||||
maxFaceWeight = faceWeights[facei];
|
||||
}
|
||||
}
|
||||
|
||||
if (matchFaceNo >= 0)
|
||||
{
|
||||
// Make a new group
|
||||
coarseCellMap[upperAddr[matchFaceNo]] = nCoarseCells;
|
||||
coarseCellMap[lowerAddr[matchFaceNo]] = nCoarseCells;
|
||||
nCoarseCells++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No match. Find the best neighbouring cluster and
|
||||
// put the cell there
|
||||
label clusterMatchFaceNo = -1;
|
||||
scalar clusterMaxFaceCoeff = -GREAT;
|
||||
|
||||
for
|
||||
(
|
||||
label faceOs=cellFaceOffsets[celli];
|
||||
faceOs<cellFaceOffsets[celli+1];
|
||||
faceOs++
|
||||
)
|
||||
{
|
||||
label facei = cellFaces[faceOs];
|
||||
|
||||
if (faceWeights[facei] > clusterMaxFaceCoeff)
|
||||
{
|
||||
clusterMatchFaceNo = facei;
|
||||
clusterMaxFaceCoeff = faceWeights[facei];
|
||||
}
|
||||
}
|
||||
|
||||
if (clusterMatchFaceNo >= 0)
|
||||
{
|
||||
// Add the cell to the best cluster
|
||||
coarseCellMap[celli] = max
|
||||
(
|
||||
coarseCellMap[upperAddr[clusterMatchFaceNo]],
|
||||
coarseCellMap[lowerAddr[clusterMatchFaceNo]]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check that all cells are part of clusters,
|
||||
// if not create single-cell "clusters" for each
|
||||
for (label celli=0; celli<nFineCells; celli++)
|
||||
{
|
||||
if (coarseCellMap[celli] < 0)
|
||||
{
|
||||
coarseCellMap[celli] = nCoarseCells;
|
||||
nCoarseCells++;
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse the map ordering to improve the next level of agglomeration
|
||||
// (doesn't always help and is sometimes detrimental)
|
||||
nCoarseCells--;
|
||||
|
||||
forAll(coarseCellMap, celli)
|
||||
{
|
||||
coarseCellMap[celli] = nCoarseCells - coarseCellMap[celli];
|
||||
}
|
||||
|
||||
nCoarseCells++;
|
||||
|
||||
return tcoarseCellMap;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
|
||||
|
||||
void Foam::pairGAMGAgglomeration::agglomerate
|
||||
(
|
||||
@ -285,4 +115,187 @@ void Foam::pairGAMGAgglomeration::agglomerate
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tmp<Foam::labelField> Foam::pairGAMGAgglomeration::agglomerate
|
||||
(
|
||||
label& nCoarseCells,
|
||||
const lduAddressing& fineMatrixAddressing,
|
||||
const scalarField& faceWeights
|
||||
)
|
||||
{
|
||||
const label nFineCells = fineMatrixAddressing.size();
|
||||
|
||||
const labelUList& upperAddr = fineMatrixAddressing.upperAddr();
|
||||
const labelUList& lowerAddr = fineMatrixAddressing.lowerAddr();
|
||||
|
||||
// For each cell calculate faces
|
||||
labelList cellFaces(upperAddr.size() + lowerAddr.size());
|
||||
labelList cellFaceOffsets(nFineCells + 1);
|
||||
|
||||
// memory management
|
||||
{
|
||||
labelList nNbrs(nFineCells, 0);
|
||||
|
||||
forAll(upperAddr, facei)
|
||||
{
|
||||
nNbrs[upperAddr[facei]]++;
|
||||
}
|
||||
|
||||
forAll(lowerAddr, facei)
|
||||
{
|
||||
nNbrs[lowerAddr[facei]]++;
|
||||
}
|
||||
|
||||
cellFaceOffsets[0] = 0;
|
||||
forAll(nNbrs, celli)
|
||||
{
|
||||
cellFaceOffsets[celli+1] = cellFaceOffsets[celli] + nNbrs[celli];
|
||||
}
|
||||
|
||||
// reset the whole list to use as counter
|
||||
nNbrs = 0;
|
||||
|
||||
forAll(upperAddr, facei)
|
||||
{
|
||||
cellFaces
|
||||
[
|
||||
cellFaceOffsets[upperAddr[facei]] + nNbrs[upperAddr[facei]]
|
||||
] = facei;
|
||||
|
||||
nNbrs[upperAddr[facei]]++;
|
||||
}
|
||||
|
||||
forAll(lowerAddr, facei)
|
||||
{
|
||||
cellFaces
|
||||
[
|
||||
cellFaceOffsets[lowerAddr[facei]] + nNbrs[lowerAddr[facei]]
|
||||
] = facei;
|
||||
|
||||
nNbrs[lowerAddr[facei]]++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// go through the faces and create clusters
|
||||
|
||||
tmp<labelField> tcoarseCellMap(new labelField(nFineCells, -1));
|
||||
labelField& coarseCellMap = tcoarseCellMap();
|
||||
|
||||
nCoarseCells = 0;
|
||||
label celli;
|
||||
|
||||
for (label cellfi=0; cellfi<nFineCells; cellfi++)
|
||||
{
|
||||
// Change cell ordering depending on direction for this level
|
||||
celli = forward_ ? cellfi : nFineCells - cellfi - 1;
|
||||
|
||||
if (coarseCellMap[celli] < 0)
|
||||
{
|
||||
label matchFaceNo = -1;
|
||||
scalar maxFaceWeight = -GREAT;
|
||||
|
||||
// check faces to find ungrouped neighbour with largest face weight
|
||||
for
|
||||
(
|
||||
label faceOs=cellFaceOffsets[celli];
|
||||
faceOs<cellFaceOffsets[celli+1];
|
||||
faceOs++
|
||||
)
|
||||
{
|
||||
label facei = cellFaces[faceOs];
|
||||
|
||||
// I don't know whether the current cell is owner or neighbour.
|
||||
// Therefore I'll check both sides
|
||||
if
|
||||
(
|
||||
coarseCellMap[upperAddr[facei]] < 0
|
||||
&& coarseCellMap[lowerAddr[facei]] < 0
|
||||
&& faceWeights[facei] > maxFaceWeight
|
||||
)
|
||||
{
|
||||
// Match found. Pick up all the necessary data
|
||||
matchFaceNo = facei;
|
||||
maxFaceWeight = faceWeights[facei];
|
||||
}
|
||||
}
|
||||
|
||||
if (matchFaceNo >= 0)
|
||||
{
|
||||
// Make a new group
|
||||
coarseCellMap[upperAddr[matchFaceNo]] = nCoarseCells;
|
||||
coarseCellMap[lowerAddr[matchFaceNo]] = nCoarseCells;
|
||||
nCoarseCells++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No match. Find the best neighbouring cluster and
|
||||
// put the cell there
|
||||
label clusterMatchFaceNo = -1;
|
||||
scalar clusterMaxFaceCoeff = -GREAT;
|
||||
|
||||
for
|
||||
(
|
||||
label faceOs=cellFaceOffsets[celli];
|
||||
faceOs<cellFaceOffsets[celli+1];
|
||||
faceOs++
|
||||
)
|
||||
{
|
||||
label facei = cellFaces[faceOs];
|
||||
|
||||
if (faceWeights[facei] > clusterMaxFaceCoeff)
|
||||
{
|
||||
clusterMatchFaceNo = facei;
|
||||
clusterMaxFaceCoeff = faceWeights[facei];
|
||||
}
|
||||
}
|
||||
|
||||
if (clusterMatchFaceNo >= 0)
|
||||
{
|
||||
// Add the cell to the best cluster
|
||||
coarseCellMap[celli] = max
|
||||
(
|
||||
coarseCellMap[upperAddr[clusterMatchFaceNo]],
|
||||
coarseCellMap[lowerAddr[clusterMatchFaceNo]]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that all cells are part of clusters,
|
||||
// if not create single-cell "clusters" for each
|
||||
for (label cellfi=0; cellfi<nFineCells; cellfi++)
|
||||
{
|
||||
// Change cell ordering depending on direction for this level
|
||||
celli = forward_ ? cellfi : nFineCells - cellfi - 1;
|
||||
|
||||
if (coarseCellMap[celli] < 0)
|
||||
{
|
||||
coarseCellMap[celli] = nCoarseCells;
|
||||
nCoarseCells++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!forward_)
|
||||
{
|
||||
nCoarseCells--;
|
||||
|
||||
forAll(coarseCellMap, celli)
|
||||
{
|
||||
coarseCellMap[celli] = nCoarseCells - coarseCellMap[celli];
|
||||
}
|
||||
|
||||
nCoarseCells++;
|
||||
}
|
||||
|
||||
// Reverse the map ordering for the next level
|
||||
// to improve the next level of agglomeration
|
||||
forward_ = !forward_;
|
||||
|
||||
return tcoarseCellMap;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -29,7 +29,8 @@ License
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(pairGAMGAgglomeration, 0);
|
||||
defineTypeNameAndDebug(pairGAMGAgglomeration, 0);
|
||||
bool pairGAMGAgglomeration::forward_(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -56,6 +56,9 @@ class pairGAMGAgglomeration
|
||||
//- Number of levels to merge, 1 = don't merge, 2 = merge pairs etc.
|
||||
label mergeLevels_;
|
||||
|
||||
//- Direction of cell loop for the current level
|
||||
static bool forward_;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
@ -97,7 +100,6 @@ public:
|
||||
const lduAddressing& fineMatrixAddressing,
|
||||
const scalarField& faceWeights
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -230,7 +230,8 @@ class GAMGSolver
|
||||
const lduMatrix& m,
|
||||
const FieldField<Field, scalar>& interfaceBouCoeffs,
|
||||
const lduInterfaceFieldPtrsList& interfaces,
|
||||
const scalarField& source,
|
||||
const labelList& restrictAddressing,
|
||||
const scalarField& psiC,
|
||||
const direction cmpt
|
||||
) const;
|
||||
|
||||
|
||||
@ -34,7 +34,8 @@ void Foam::GAMGSolver::interpolate
|
||||
const lduMatrix& m,
|
||||
const FieldField<Field, scalar>& interfaceBouCoeffs,
|
||||
const lduInterfaceFieldPtrsList& interfaces,
|
||||
const scalarField& source,
|
||||
const labelList& restrictAddressing,
|
||||
const scalarField& psiC,
|
||||
const direction cmpt
|
||||
) const
|
||||
{
|
||||
@ -80,6 +81,30 @@ void Foam::GAMGSolver::interpolate
|
||||
{
|
||||
psiPtr[celli] = -ApsiPtr[celli]/(diagPtr[celli]);
|
||||
}
|
||||
|
||||
register const label nCCells = psiC.size();
|
||||
scalarField corrC(nCCells, 0);
|
||||
scalarField diagC(nCCells, 0);
|
||||
|
||||
for (register label celli=0; celli<nCells; celli++)
|
||||
{
|
||||
corrC[restrictAddressing[celli]] += diagPtr[celli]*psiPtr[celli];
|
||||
diagC[restrictAddressing[celli]] += diagPtr[celli];
|
||||
//corrC[restrictAddressing[celli]] += psiPtr[celli]/diagPtr[celli];
|
||||
//diagC[restrictAddressing[celli]] += 1.0/diagPtr[celli];
|
||||
//corrC[restrictAddressing[celli]] += psiPtr[celli];
|
||||
//diagC[restrictAddressing[celli]] += 1.0;
|
||||
}
|
||||
|
||||
for (register label ccelli=0; ccelli<nCCells; ccelli++)
|
||||
{
|
||||
corrC[ccelli] = psiC[ccelli] - corrC[ccelli]/diagC[ccelli];
|
||||
}
|
||||
|
||||
for (register label celli=0; celli<nCells; celli++)
|
||||
{
|
||||
psiPtr[celli] += corrC[restrictAddressing[celli]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -313,7 +313,7 @@ void Foam::GAMGSolver::Vcycle
|
||||
scalarField& ACfRef =
|
||||
const_cast<scalarField&>(ACf.operator const scalarField&());
|
||||
|
||||
if (interpolateCorrection_)
|
||||
if (interpolateCorrection_ && leveli < coarsestLevel - 2)
|
||||
{
|
||||
interpolate
|
||||
(
|
||||
@ -322,7 +322,8 @@ void Foam::GAMGSolver::Vcycle
|
||||
matrixLevels_[leveli],
|
||||
interfaceLevelsBouCoeffs_[leveli],
|
||||
interfaceLevels_[leveli],
|
||||
coarseSources[leveli],
|
||||
agglomeration_.restrictAddressing(leveli + 1),
|
||||
coarseCorrFields[leveli + 1],
|
||||
cmpt
|
||||
);
|
||||
}
|
||||
@ -382,7 +383,8 @@ void Foam::GAMGSolver::Vcycle
|
||||
matrix_,
|
||||
interfaceBouCoeffs_,
|
||||
interfaces_,
|
||||
finestResidual,
|
||||
agglomeration_.restrictAddressing(0),
|
||||
coarseCorrFields[0],
|
||||
cmpt
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user