FEATURE: Updates to coupled p-U solver, including ddt term and performance tuning. Author: Hrvoje Jasak. Merge: Dominik Christ.

This commit is contained in:
Dominik Christ 2015-04-22 10:55:59 +01:00
commit 4b50842cd9
8 changed files with 147 additions and 51 deletions

View file

@ -1,7 +1,8 @@
// Momentum equation
fvVectorMatrix UEqn
(
fvm::div(phi, U)
fvm::ddt(U)
+ fvm::div(phi, U)
+ turbulence->divDevReff(U)
);

View file

@ -45,7 +45,7 @@ volVector4Field Up
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
IOobject::NO_WRITE
),
mesh,
dimensionedVector4("zero", dimless, vector4::zero)

View file

@ -213,8 +213,6 @@ void Foam::BlockMatrixAgglomeration<Type>::calcAgglomeration()
}
}
reduce(nSolo, sumOp<label>());
if (nSolo > 0)
{
// Found solo equations
@ -222,7 +220,7 @@ void Foam::BlockMatrixAgglomeration<Type>::calcAgglomeration()
if (BlockLduMatrix<Type>::debug >= 2)
{
Info<< "Found " << nSolo << " weakly connected equations."
Pout<< "Found " << nSolo << " weakly connected equations."
<< endl;
}
}

View file

@ -37,7 +37,6 @@ Author
#include "vector2D.H"
#include "coeffFields.H"
#include "BlockSolverPerformance.H"
// #include "BlockGaussSeidelSolver.H"
// #include "BlockBiCGStabSolver.H"
// #include "BlockCGSolver.H"
#include "BlockGMRESSolver.H"
@ -78,7 +77,8 @@ Foam::coarseBlockAmgLevel<Type>::coarseBlockAmgLevel
matrixPtr_,
dict
)
)
),
Ax_()
{}
@ -221,12 +221,23 @@ void Foam::coarseBlockAmgLevel<Type>::solve
return;
}
// Switch of debug in top-level direct solve
label oldDebug = BlockLduMatrix<Type>::debug;
if (BlockLduMatrix<Type>::debug >= 3)
{
BlockLduMatrix<Type>::debug = 1;
}
else
{
BlockLduMatrix<Type>::debug = 0;
}
if (matrixPtr_->symmetric())
{
topLevelDict.add("preconditioner", "Cholesky");
coarseSolverPerf =
//BlockGaussSeidelSolver<Type>
// BlockCGSolver<Type>
BlockGMRESSolver<Type>
(
@ -240,7 +251,6 @@ void Foam::coarseBlockAmgLevel<Type>::solve
topLevelDict.add("preconditioner", "Cholesky");
coarseSolverPerf =
//BlockGaussSeidelSolver<Type>
// BlockBiCGStabSolver<Type>
BlockGMRESSolver<Type>
(
@ -250,6 +260,9 @@ void Foam::coarseBlockAmgLevel<Type>::solve
).solve(x, b);
}
// Restore debug
BlockLduMatrix<Type>::debug = oldDebug;
// Escape cases of top-level solver divergence
if
(
@ -267,11 +280,6 @@ void Foam::coarseBlockAmgLevel<Type>::solve
// Print top level correction failure as info for user
coarseSolverPerf.print();
}
if (BlockLduMatrix<Type>::debug >= 2)
{
coarseSolverPerf.print();
}
}
@ -283,18 +291,22 @@ void Foam::coarseBlockAmgLevel<Type>::scaleX
Field<Type>& xBuffer
) const
{
// KRJ: 2013-02-05: Removed subfield, creating a new field
// Initialise and size buffer to avoid multiple allocation.
// Buffer is created as private data of AMG level
// HJ, 26/Feb/2015
if (Ax_.empty())
{
Ax_.setSize(x.size());
}
// KRJ: 2013-02-05: Creating a new field not re-using
Field<Type> Ax(x.size());
matrixPtr_->Amul(Ax_, x);
matrixPtr_->Amul
(
reinterpret_cast<Field<Type>&>(Ax),
x
);
#if 0
// Variant 1 (old): scale complete x with a single scaling factor
scalar scalingFactorNum = sumProd(x, b);
scalar scalingFactorDenom = sumProd(x, Ax);
scalar scalingFactorDenom = sumProd(x, Ax_);
vector2D scalingVector(scalingFactorNum, scalingFactorDenom);
reduce(scalingVector, sumOp<vector2D>());
@ -318,8 +330,50 @@ void Foam::coarseBlockAmgLevel<Type>::scaleX
else
{
// Regular scaling
x *= scalingVector[0]/stabilise(scalingVector[1], SMALL);
x *= scalingVector[0]/stabilise(scalingVector[1], VSMALL);
}
#else
// Variant 2: scale each x individually
// HJ, 25/Feb/2015
Type scalingFactorNum = sumCmptProd(x, b);
Type scalingFactorDenom = sumCmptProd(x, Ax_);
Vector2D<Type> scalingVector(scalingFactorNum, scalingFactorDenom);
reduce(scalingVector, sumOp<Vector2D<Type> >());
Type scalingFactor = pTraits<Type>::one;
// Scale x
for (direction dir = 0; dir < pTraits<Type>::nComponents; dir++)
{
scalar num = component(scalingVector[0], dir);
scalar denom = component(scalingVector[1], dir);
if
(
mag(num) > GREAT || mag(denom) > GREAT
|| num*denom <= 0 || mag(num) < mag(denom)
)
{
// Factor = 1.0, no scaling
}
else if (mag(num) > 2*mag(denom))
{
setComponent(scalingFactor, dir) = 2;
}
else
{
// Regular scaling
setComponent(scalingFactor, dir) = num/stabilise(denom, VSMALL);
}
}
// Scale X
cmptMultiply(x, x, scalingFactor);
#endif
}

View file

@ -76,6 +76,9 @@ class coarseBlockAmgLevel
//- Smoother
autoPtr<BlockLduSmoother<Type> > smootherPtr_;
//- Ax buffer
mutable Field<Type> Ax_;
// Private Member Functions
@ -91,6 +94,9 @@ public:
//- Runtime type information
TypeName("coarseBlockAmgLevel");
// Constructors
//- Construct from components
coarseBlockAmgLevel
(

View file

@ -74,7 +74,8 @@ Foam::fineBlockAmgLevel<Type>::fineBlockAmgLevel
matrix,
dict
)
)
),
Ax_()
{}
@ -184,7 +185,6 @@ void Foam::fineBlockAmgLevel<Type>::solve
// Create artificial dictionary for finest solution
dictionary finestDict;
// finestDict.add("nDirections", "5");
finestDict.add("minIter", 1);
finestDict.add("maxIter", 1000);
finestDict.add("tolerance", tolerance);
@ -201,11 +201,6 @@ void Foam::fineBlockAmgLevel<Type>::solve
matrix_,
finestDict
).solve(x, b);
if (BlockLduMatrix<Type>::debug >= 2)
{
coarseSolverPerf.print();
}
}
else
{
@ -218,11 +213,6 @@ void Foam::fineBlockAmgLevel<Type>::solve
matrix_,
finestDict
).solve(x, b);
if (BlockLduMatrix<Type>::debug >= 2)
{
coarseSolverPerf.print();
}
}
}
@ -235,26 +225,31 @@ void Foam::fineBlockAmgLevel<Type>::scaleX
Field<Type>& xBuffer
) const
{
// KRJ: 2013-02-05: Removed subfield, creating a new field
Field<Type> Ax(x.size());
// Initialise and size buffer to avoid multiple allocation.
// Buffer is created as private data of AMG level
// HJ, 26/Feb/2015
if (Ax_.empty())
{
Ax_.setSize(x.size());
}
matrix_.Amul
(
reinterpret_cast<Field<Type>&>(Ax),
x
);
matrix_.Amul(Ax_, x);
#if 0
scalar scalingFactorNum = sumProd(x, b);
scalar scalingFactorDenom = sumProd(x, Ax);
scalar scalingFactorDenom = sumProd(x, Ax_);
vector scalingVector(scalingFactorNum, scalingFactorDenom, 0);
reduce(scalingVector, sumOp<vector>());
vector2D scalingVector(scalingFactorNum, scalingFactorDenom);
reduce(scalingVector, sumOp<vector2D>());
// Scale x
if
(
scalingVector[0]*scalingVector[1] <= 0
mag(scalingVector[0]) > GREAT
|| mag(scalingVector[1]) > GREAT
|| scalingVector[0]*scalingVector[1] <= 0
|| mag(scalingVector[0]) < mag(scalingVector[1])
)
{
@ -268,8 +263,48 @@ void Foam::fineBlockAmgLevel<Type>::scaleX
else
{
// Regular scaling
x *= scalingVector[0]/stabilise(scalingVector[1], SMALL);
x *= scalingVector[0]/stabilise(scalingVector[1], VSMALL);
}
#else
Type scalingFactorNum = sumCmptProd(x, b);
Type scalingFactorDenom = sumCmptProd(x, Ax_);
Vector2D<Type> scalingVector(scalingFactorNum, scalingFactorDenom);
reduce(scalingVector, sumOp<Vector2D<Type> >());
Type scalingFactor = pTraits<Type>::one;
// Scale x
for (direction dir = 0; dir < pTraits<Type>::nComponents; dir++)
{
scalar num = component(scalingVector[0], dir);
scalar denom = component(scalingVector[1], dir);
if
(
mag(num) > GREAT || mag(denom) > GREAT
|| num*denom <= 0 || mag(num) < mag(denom)
)
{
// Factor = 1.0, no scaling
}
else if (mag(num) > 2*mag(denom))
{
setComponent(scalingFactor, dir) = 2;
}
else
{
// Regular scaling
setComponent(scalingFactor, dir) = num/stabilise(denom, VSMALL);
}
}
// Scale X
cmptMultiply(x, x, scalingFactor);
#endif
}

View file

@ -80,6 +80,9 @@ class fineBlockAmgLevel
//- Smoother
autoPtr<BlockLduSmoother<Type> > smootherPtr_;
//- Ax buffer
mutable Field<Type> Ax_;
// Private Member Functions
@ -96,6 +99,8 @@ public:
TypeName("fineBlockAmgLevel");
// Constructors
//- Construct from components
fineBlockAmgLevel
(

View file

@ -113,9 +113,6 @@ Foam::BlockGMRESSolver<Type>::solve
scalar norm = this->normFactor(x, b);
// Multiplication helper
typename BlockCoeff<Type>::multiply mult;
Field<Type> wA(x.size());
// Calculate initial residual