1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 Preconditioned Conjugate Gradient solver
29 Hrvoje Jasak, Wikki Ltd. All rights reserved
31 \*---------------------------------------------------------------------------*/
33 #include "coupledCgSolver.H"
34 #include "addToRunTimeSelectionTable.H"
36 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 defineTypeNameAndDebug(coupledCgSolver, 0);
42 coupledLduSolver::addsymMatrixConstructorToTable<coupledCgSolver>
43 addCgSolverSymMatrixConstructorToTable_;
47 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
49 //- Construct from matrix
50 Foam::coupledCgSolver::coupledCgSolver
52 const word& fieldName,
53 const coupledLduMatrix& matrix,
54 const PtrList<FieldField<Field, scalar> >& bouCoeffs,
55 const PtrList<FieldField<Field, scalar> >& intCoeffs,
56 const lduInterfaceFieldPtrsListList& interfaces,
57 const dictionary& solverData
60 coupledIterativeSolver
77 dict().subDict("preconditioner")
83 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
85 Foam::coupledSolverPerformance Foam::coupledCgSolver::solve
87 FieldField<Field, scalar>& x,
88 const FieldField<Field, scalar>& b,
92 // Prepare solver performance
93 coupledSolverPerformance solverPerf(typeName, fieldName());
95 FieldField<Field, scalar> wA(x.size());
96 FieldField<Field, scalar> rA(x.size());
100 wA.set(rowI, new scalarField(x[rowI].size(), 0));
101 rA.set(rowI, new scalarField(x[rowI].size(), 0));
105 // Calculate initial residual
106 matrix_.Amul(wA, x, bouCoeffs_, interfaces_, cmpt);
108 // Use rA as scratch space when calculating the normalisation factor
109 scalar normFactor = this->normFactor(x, b, wA, rA, cmpt);
111 if (coupledLduMatrix::debug >= 2)
113 Info<< " Normalisation factor = " << normFactor << endl;
116 // Optimised looping. HJ, 19/Jan/2009
119 const scalarField& bi = b[i];
120 const scalarField& wAi = wA[i];
121 scalarField& rAi = rA[i];
125 rAi[j] = bi[j] - wAi[j];
129 solverPerf.initialResidual() = gSumMag(rA)/normFactor;
130 solverPerf.finalResidual() = solverPerf.initialResidual();
132 if (!solverPerf.checkConvergence(tolerance_, relTolerance_))
134 scalar rho = matrix_[0].great_;
137 scalar alpha, beta, wApA;
139 FieldField<Field, scalar> pA(x.size());
143 pA.set(rowI, new scalarField(x[rowI].size(), 0));
150 // Execute preconditioning
151 preconPtr_->precondition(wA, rA, cmpt);
153 // Update search directions
154 rho = gSumProd(wA, rA);
160 scalarField& curPA = pA[rowI];
161 const scalarField& curWA = wA[rowI];
165 curPA[i] = curWA[i] + beta*curPA[i];
169 // Update preconditioned residual
170 matrix_.Amul(wA, pA, bouCoeffs_, interfaces_, cmpt);
172 wApA = gSumProd(wA, pA);
175 // Check for singularity
176 if (solverPerf.checkSingularity(mag(wApA)/normFactor))
181 // Update solution and residual
186 scalarField& curX = x[rowI];
187 const scalarField& curPA = pA[rowI];
191 curX[i] += alpha*curPA[i];
197 scalarField& curRA = rA[rowI];
198 const scalarField& curWA = wA[rowI];
202 curRA[i] -= alpha*curWA[i];
206 solverPerf.finalResidual() = gSumMag(rA)/normFactor;
207 solverPerf.nIterations()++;
208 } while (!stop(solverPerf));
215 // ************************************************************************* //