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 // Momentum equation
fvVectorMatrix UEqn fvVectorMatrix UEqn
( (
fvm::div(phi, U) fvm::ddt(U)
+ fvm::div(phi, U)
+ turbulence->divDevReff(U) + turbulence->divDevReff(U)
); );

View file

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

View file

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

View file

@ -37,7 +37,6 @@ Author
#include "vector2D.H" #include "vector2D.H"
#include "coeffFields.H" #include "coeffFields.H"
#include "BlockSolverPerformance.H" #include "BlockSolverPerformance.H"
// #include "BlockGaussSeidelSolver.H"
// #include "BlockBiCGStabSolver.H" // #include "BlockBiCGStabSolver.H"
// #include "BlockCGSolver.H" // #include "BlockCGSolver.H"
#include "BlockGMRESSolver.H" #include "BlockGMRESSolver.H"
@ -78,7 +77,8 @@ Foam::coarseBlockAmgLevel<Type>::coarseBlockAmgLevel
matrixPtr_, matrixPtr_,
dict dict
) )
) ),
Ax_()
{} {}
@ -221,12 +221,23 @@ void Foam::coarseBlockAmgLevel<Type>::solve
return; 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()) if (matrixPtr_->symmetric())
{ {
topLevelDict.add("preconditioner", "Cholesky"); topLevelDict.add("preconditioner", "Cholesky");
coarseSolverPerf = coarseSolverPerf =
//BlockGaussSeidelSolver<Type>
// BlockCGSolver<Type> // BlockCGSolver<Type>
BlockGMRESSolver<Type> BlockGMRESSolver<Type>
( (
@ -240,7 +251,6 @@ void Foam::coarseBlockAmgLevel<Type>::solve
topLevelDict.add("preconditioner", "Cholesky"); topLevelDict.add("preconditioner", "Cholesky");
coarseSolverPerf = coarseSolverPerf =
//BlockGaussSeidelSolver<Type>
// BlockBiCGStabSolver<Type> // BlockBiCGStabSolver<Type>
BlockGMRESSolver<Type> BlockGMRESSolver<Type>
( (
@ -250,6 +260,9 @@ void Foam::coarseBlockAmgLevel<Type>::solve
).solve(x, b); ).solve(x, b);
} }
// Restore debug
BlockLduMatrix<Type>::debug = oldDebug;
// Escape cases of top-level solver divergence // Escape cases of top-level solver divergence
if if
( (
@ -267,11 +280,6 @@ void Foam::coarseBlockAmgLevel<Type>::solve
// Print top level correction failure as info for user // Print top level correction failure as info for user
coarseSolverPerf.print(); coarseSolverPerf.print();
} }
if (BlockLduMatrix<Type>::debug >= 2)
{
coarseSolverPerf.print();
}
} }
@ -283,18 +291,22 @@ void Foam::coarseBlockAmgLevel<Type>::scaleX
Field<Type>& xBuffer Field<Type>& xBuffer
) const ) 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 matrixPtr_->Amul(Ax_, x);
Field<Type> Ax(x.size());
matrixPtr_->Amul #if 0
(
reinterpret_cast<Field<Type>&>(Ax),
x
);
// Variant 1 (old): scale complete x with a single scaling factor
scalar scalingFactorNum = sumProd(x, b); scalar scalingFactorNum = sumProd(x, b);
scalar scalingFactorDenom = sumProd(x, Ax); scalar scalingFactorDenom = sumProd(x, Ax_);
vector2D scalingVector(scalingFactorNum, scalingFactorDenom); vector2D scalingVector(scalingFactorNum, scalingFactorDenom);
reduce(scalingVector, sumOp<vector2D>()); reduce(scalingVector, sumOp<vector2D>());
@ -318,8 +330,50 @@ void Foam::coarseBlockAmgLevel<Type>::scaleX
else else
{ {
// Regular scaling // 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 //- Smoother
autoPtr<BlockLduSmoother<Type> > smootherPtr_; autoPtr<BlockLduSmoother<Type> > smootherPtr_;
//- Ax buffer
mutable Field<Type> Ax_;
// Private Member Functions // Private Member Functions
@ -91,6 +94,9 @@ public:
//- Runtime type information //- Runtime type information
TypeName("coarseBlockAmgLevel"); TypeName("coarseBlockAmgLevel");
// Constructors
//- Construct from components //- Construct from components
coarseBlockAmgLevel coarseBlockAmgLevel
( (

View file

@ -74,7 +74,8 @@ Foam::fineBlockAmgLevel<Type>::fineBlockAmgLevel
matrix, matrix,
dict dict
) )
) ),
Ax_()
{} {}
@ -184,7 +185,6 @@ void Foam::fineBlockAmgLevel<Type>::solve
// Create artificial dictionary for finest solution // Create artificial dictionary for finest solution
dictionary finestDict; dictionary finestDict;
// finestDict.add("nDirections", "5");
finestDict.add("minIter", 1); finestDict.add("minIter", 1);
finestDict.add("maxIter", 1000); finestDict.add("maxIter", 1000);
finestDict.add("tolerance", tolerance); finestDict.add("tolerance", tolerance);
@ -201,11 +201,6 @@ void Foam::fineBlockAmgLevel<Type>::solve
matrix_, matrix_,
finestDict finestDict
).solve(x, b); ).solve(x, b);
if (BlockLduMatrix<Type>::debug >= 2)
{
coarseSolverPerf.print();
}
} }
else else
{ {
@ -218,11 +213,6 @@ void Foam::fineBlockAmgLevel<Type>::solve
matrix_, matrix_,
finestDict finestDict
).solve(x, b); ).solve(x, b);
if (BlockLduMatrix<Type>::debug >= 2)
{
coarseSolverPerf.print();
}
} }
} }
@ -235,26 +225,31 @@ void Foam::fineBlockAmgLevel<Type>::scaleX
Field<Type>& xBuffer Field<Type>& xBuffer
) const ) const
{ {
// KRJ: 2013-02-05: Removed subfield, creating a new field // 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 matrix_.Amul(Ax_, x);
(
reinterpret_cast<Field<Type>&>(Ax), #if 0
x
);
scalar scalingFactorNum = sumProd(x, b); scalar scalingFactorNum = sumProd(x, b);
scalar scalingFactorDenom = sumProd(x, Ax); scalar scalingFactorDenom = sumProd(x, Ax_);
vector scalingVector(scalingFactorNum, scalingFactorDenom, 0); vector2D scalingVector(scalingFactorNum, scalingFactorDenom);
reduce(scalingVector, sumOp<vector>()); reduce(scalingVector, sumOp<vector2D>());
// Scale x // Scale x
if 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]) || mag(scalingVector[0]) < mag(scalingVector[1])
) )
{ {
@ -268,8 +263,48 @@ void Foam::fineBlockAmgLevel<Type>::scaleX
else else
{ {
// Regular scaling // 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 //- Smoother
autoPtr<BlockLduSmoother<Type> > smootherPtr_; autoPtr<BlockLduSmoother<Type> > smootherPtr_;
//- Ax buffer
mutable Field<Type> Ax_;
// Private Member Functions // Private Member Functions
@ -96,6 +99,8 @@ public:
TypeName("fineBlockAmgLevel"); TypeName("fineBlockAmgLevel");
// Constructors
//- Construct from components //- Construct from components
fineBlockAmgLevel fineBlockAmgLevel
( (

View file

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