Compare commits

...

4 Commits

Author SHA1 Message Date
Kutalmis Bercin
fc20aa1c4d (Merge): INT: Integration of gmresSolver from foam-extend 2024-06-05 11:39:51 +01:00
Kutalmis Bercin
44f8550185 (Merge) TUT: longPipe: style changes 2024-06-05 11:39:46 +01:00
mattijs
ab1788ae33 ENH: simpleFoam: added gmres-using case. 2024-06-03 12:29:04 +01:00
mattijs
578cb2b67c INT: Integration of gmresSolver from foam-extend
(http://www.foam-extend.org)
2024-05-30 17:19:54 +01:00
16 changed files with 916 additions and 0 deletions

View File

@ -445,6 +445,7 @@ $(lduMatrix)/solvers/PBiCGStab/PBiCGStab.C
$(lduMatrix)/solvers/FPCG/FPCG.C
$(lduMatrix)/solvers/PPCG/PPCG.C
$(lduMatrix)/solvers/PPCR/PPCR.C
$(lduMatrix)/solvers/GMRES/gmresSolver.C
$(lduMatrix)/smoothers/GaussSeidel/GaussSeidelSmoother.C
$(lduMatrix)/smoothers/symGaussSeidel/symGaussSeidelSmoother.C

View File

@ -0,0 +1,317 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2010-2015 Hrvoje Jasak, Wikki 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/>.
Description
Preconditioned Generalised Minimal Residual solver with
run-time selectable preconditioning
\*---------------------------------------------------------------------------*/
#include "gmresSolver.H"
#include "scalarMatrices.H"
#include "PrecisionAdaptor.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(gmresSolver, 0);
lduMatrix::solver::addsymMatrixConstructorToTable<gmresSolver>
addgmresSolverSymMatrixConstructorToTable_;
lduMatrix::solver::addasymMatrixConstructorToTable<gmresSolver>
addgmresSolverAsymMatrixConstructorToTable_;
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::gmresSolver::givensRotation
(
const solveScalar& h,
const solveScalar& beta,
solveScalar& c,
solveScalar& s
) const
{
if (beta == 0)
{
c = 1;
s = 0;
}
else if (mag(beta) > mag(h))
{
scalar tau = -h/beta;
s = 1.0/Foam::sqrt(1.0 + sqr(tau));
c = s*tau;
}
else
{
scalar tau = -beta/h;
c = 1.0/Foam::sqrt(1.0 + sqr(tau));
s = c*tau;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
//- Construct from matrix and solver data stream
Foam::gmresSolver::gmresSolver
(
const word& fieldName,
const lduMatrix& matrix,
const FieldField<Field, scalar>& coupleBouCoeffs,
const FieldField<Field, scalar>& coupleIntCoeffs,
const lduInterfaceFieldPtrsList& interfaces,
const dictionary& dict
)
:
lduMatrix::solver
(
fieldName,
matrix,
coupleBouCoeffs,
coupleIntCoeffs,
interfaces,
dict
),
preconPtr_
(
lduMatrix::preconditioner::New
(
*this,
dict
)
),
nDirs_(dict.getLabel("nDirections"))
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::solverPerformance Foam::gmresSolver::scalarSolve
(
solveScalarField& x,
const solveScalarField& b,
const direction cmpt
) const
{
// Initialise the solverPerformance object to track solver performance
solverPerformance solverPerf
(
preconPtr_->type() + typeName, fieldName()
);
solveScalarField wA(x.size());
solveScalarField rA(x.size());
// Calculate initial residual
matrix_.Amul(wA, x, interfaceBouCoeffs_, interfaces_, cmpt);
// Use rA as scratch space when calculating the normalisation factor
solveScalar normFactor = this->normFactor(x, b, wA, rA);
if (lduMatrix::debug >= 2)
{
Info<< " Normalisation factor = " << normFactor << endl;
}
// Calculate residual
forAll (rA, i)
{
rA[i] = b[i] - wA[i];
}
solverPerf.initialResidual() =
gSumMag(rA, matrix().mesh().comm())
/normFactor;
solverPerf.finalResidual() = solverPerf.initialResidual();
// Note: GMRES cannot be forced to do minIter sweeps
// if the residual is zero, due to algorithmic reasons
// HJ, 22/Aug/2012
if (!solverPerf.checkConvergence(tolerance_, relTol_, log_))
{
typedef SquareMatrix<solveScalar> solveScalarSquareMatrix;
// Create the Hesenberg matrix
solveScalarSquareMatrix H(nDirs_, 0);
// Create y and b for Hessenberg matrix
solveScalarField yh(nDirs_, 0);
solveScalarField bh(nDirs_ + 1, 0);
// Givens rotation vectors
solveScalarField c(nDirs_, 0);
solveScalarField s(nDirs_, 0);
// Allocate Krylov space vectors
FieldField<Field, solveScalar> V(nDirs_ + 1);
forAll (V, i)
{
V.set(i, new solveScalarField(x.size(), 0));
}
do
{
// Execute preconditioning
preconPtr_->precondition(wA, rA, cmpt);
// Calculate beta and scale first vector
solveScalar beta = Foam::sqrt(gSumSqr(wA, matrix().mesh().comm()));
// Set initial rhs and bh[0] = beta
bh = 0;
bh[0] = beta;
for (label i = 0; i < nDirs_; ++i)
{
// Set search direction
V[i] = wA;
V[i] /= beta;
// Arnoldi's method
matrix_.Amul(rA, V[i], interfaceBouCoeffs_, interfaces_, cmpt);
// Execute preconditioning
preconPtr_->precondition(wA, rA, cmpt);
for (label j = 0; j <= i; ++j)
{
beta = gSumProd(wA, V[j], matrix().mesh().comm());
H[j][i] = beta;
forAll (wA, wI)
{
wA[wI] -= beta*V[j][wI];
}
}
beta = Foam::sqrt(gSumSqr(wA, matrix().mesh().comm()));
// Apply previous Givens rotations to new column of H.
for (label j = 0; j < i; ++j)
{
const solveScalar Hji = H[j][i];
H[j][i] = c[j]*Hji - s[j]*H[j + 1][i];
H[j + 1][i] = s[j]*Hji + c[j]*H[j + 1][i];
}
// Apply Givens rotation to current row.
givensRotation(H[i][i], beta, c[i], s[i]);
const solveScalar bhi = bh[i];
bh[i] = c[i]*bhi - s[i]*bh[i + 1];
bh[i + 1] = s[i]*bhi + c[i]*bh[i + 1];
H[i][i] = c[i]*H[i][i] - s[i]*beta;
}
// Back substitute to solve Hy = b
for (label i = nDirs_ - 1; i >= 0; i--)
{
solveScalar sum = bh[i];
for (label j = i + 1; j < nDirs_; ++j)
{
sum -= H[i][j]*yh[j];
}
yh[i] = sum/H[i][i];
}
// Update solution
for (label i = 0; i < nDirs_; ++i)
{
const solveScalarField& Vi = V[i];
const solveScalar& yi = yh[i];
forAll (x, psiI)
{
x[psiI] += yi*Vi[psiI];
}
}
// Re-calculate the residual
matrix_.Amul(wA, x, interfaceBouCoeffs_, interfaces_, cmpt);
forAll (rA, raI)
{
rA[raI] = b[raI] - wA[raI];
}
solverPerf.finalResidual() =
gSumMag(rA, matrix().mesh().comm())
/normFactor;
solverPerf.nIterations()++;
} while
(
(
++solverPerf.nIterations() < maxIter_
&& !solverPerf.checkConvergence(tolerance_, relTol_, log_)
)
|| solverPerf.nIterations() < minIter_
);
}
if (preconPtr_)
{
preconPtr_->setFinished(solverPerf);
}
matrix().setResidualField
(
ConstPrecisionAdaptor<scalar, solveScalar>(rA)(),
fieldName_,
false
);
return solverPerf;
}
Foam::solverPerformance Foam::gmresSolver::solve
(
scalarField& psi_s,
const scalarField& source,
const direction cmpt
) const
{
PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
return scalarSolve
(
tpsi.ref(),
ConstPrecisionAdaptor<solveScalar, scalar>(source)(),
cmpt
);
}
// ************************************************************************* //

View File

@ -0,0 +1,140 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2010-2015 Hrvoje Jasak, Wikki 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
gmresSolver
Group
grpLduMatrixSolvers
Description
Preconditioned Generalised Minimal Residual solver with
run-time selectable preconditioning
SourceFiles
gmresSolver.C
\*---------------------------------------------------------------------------*/
#ifndef Foam_gmresSolver_H
#define Foam_gmresSolver_H
#include "lduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class gmresSolver Declaration
\*---------------------------------------------------------------------------*/
class gmresSolver
:
public lduMatrix::solver
{
// Private Data
//- Preconditioner
autoPtr<lduMatrix::preconditioner> preconPtr_;
//- Krylov space dimension
label nDirs_;
//- Givens rotation
void givensRotation
(
const solveScalar& H,
const solveScalar& beta,
solveScalar& c,
solveScalar& s
) const;
public:
//- Runtime type information
TypeName("GMRES");
// Generated Methods
//- No copy construct
gmresSolver(const gmresSolver&) = delete;
//- No copy assignment
void operator=(const gmresSolver&) = delete;
// Constructors
//- Construct from matrix components and solver data stream
gmresSolver
(
const word& fieldName,
const lduMatrix& matrix,
const FieldField<Field, scalar>& coupleBouCoeffs,
const FieldField<Field, scalar>& coupleIntCoeffs,
const lduInterfaceFieldPtrsList& interfaces,
const dictionary& dict
);
// Destructor
virtual ~gmresSolver() = default;
// Member Functions
//- Solve the matrix with this solver
virtual solverPerformance scalarSolve
(
solveScalarField& psi,
const solveScalarField& source,
const direction cmpt=0
) const;
//- Solve the matrix with this solver
virtual solverPerformance solve
(
scalarField& x,
const scalarField& b,
const direction cmpt = 0
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2403 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
inlet
{
type fixedValue;
value uniform (0.1 0 0);
}
outlet
{
type zeroGradient;
}
upperWall
{
type noSlip;
}
lowerWall
{
type noSlip;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2403 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -2 0 0 0 0];
internalField uniform 0;
boundaryField
{
inlet
{
type zeroGradient;
}
outlet
{
type fixedValue;
value uniform 0;
}
upperWall
{
type zeroGradient;
}
lowerWall
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,8 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions # Tutorial clean functions
#------------------------------------------------------------------------------
cleanCase0
#------------------------------------------------------------------------------

View File

@ -0,0 +1,12 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
#------------------------------------------------------------------------------
./Allrun.pre
SOLVER=PCG runApplication -s PCG $(getApplication) # -debug-switch SolverPerformance=2
SOLVER=GMRES runApplication -s GMRES $(getApplication) # -debug-switch SolverPerformance=2
#------------------------------------------------------------------------------

View File

@ -0,0 +1,14 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
#------------------------------------------------------------------------------
./Allrun.pre
runApplication decomposePar
SOLVER=PCG runParallel -s PCG $(getApplication) # -debug-switch SolverPerformance=2
SOLVER=GMRES runParallel -s GMRES $(getApplication) # -debug-switch SolverPerformance=2
#------------------------------------------------------------------------------

View File

@ -0,0 +1,10 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
#------------------------------------------------------------------------------
restore0Dir
runApplication blockMesh
#------------------------------------------------------------------------------

View File

@ -0,0 +1,21 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2403 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object transportProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
transportModel Newtonian;
nu 1e-05;
// ************************************************************************* //

View File

@ -0,0 +1,19 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2403 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object turbulenceProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
simulationType laminar;
// ************************************************************************* //

View File

@ -0,0 +1,81 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2403 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
scale 0.001;
vertices
(
( 0 0 0)
( 300 0 0)
( 300 3 0)
( 0 3 0)
( 0 0 3)
( 300 0 3)
( 300 3 3)
( 0 3 3)
);
blocks
(
hex (0 1 2 3 4 5 6 7) (300 300 1) simpleGrading (1 1 1)
);
boundary
(
inlet
{
type patch;
faces
(
(0 4 7 3)
);
}
outlet
{
type patch;
faces
(
(2 6 5 1)
);
}
upperWall
{
type wall;
faces
(
(3 7 6 2)
);
}
lowerWall
{
type wall;
faces
(
(1 5 4 0)
);
}
frontAndBack
{
type empty;
faces
(
(0 3 2 1)
(4 5 6 7)
);
}
);
// ************************************************************************* //

View File

@ -0,0 +1,47 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2403 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application simpleFoam;
startFrom startTime;
startTime 0;
stopAt endTime;
endTime 500;
deltaT 1;
writeControl timeStep;
writeInterval 10;
purgeWrite 0;
writeFormat ascii;
writePrecision 6;
writeCompression off;
timeFormat general;
timePrecision 6;
runTimeModifiable false;
// ************************************************************************* //

View File

@ -0,0 +1,26 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2403 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 2;
method hierarchical;
coeffs
{
n (2 1 1);
}
// ************************************************************************* //

View File

@ -0,0 +1,61 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2403 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
default steadyState;
}
gradSchemes
{
default Gauss linear;
}
divSchemes
{
default none;
div(phi,U) bounded Gauss linearUpwind grad(U);
turbulence bounded Gauss limitedLinear 1;
div(phi,k) $turbulence;
div(phi,epsilon) $turbulence;
div(phi,omega) $turbulence;
div((nuEff*dev2(T(grad(U))))) Gauss linear;
}
laplacianSchemes
{
default Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
wallDist
{
method meshWave;
}
// ************************************************************************* //

View File

@ -0,0 +1,59 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2403 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
p
{
solver ${SOLVER};
preconditioner DIC;
nDirections 100;
tolerance 1e-06;
relTol 0.1;
}
"(U|k|epsilon|omega)"
{
solver smoothSolver;
smoother symGaussSeidel;
tolerance 1e-05;
relTol 0.1;
}
}
SIMPLE
{
nNonOrthogonalCorrectors 0;
consistent yes;
residualControl
{
p 1e-2;
U 1e-3;
"(k|epsilon|omega)" 1e-3;
}
}
relaxationFactors
{
equations
{
U 0.9;
".*" 0.9;
}
}
// ************************************************************************* //