1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
25 Preconditioned Conjugate Gradient solver
28 Hrvoje Jasak, Wikki Ltd. All rights reserved
30 \*---------------------------------------------------------------------------*/
32 #include "coupledCgSolver.H"
33 #include "addToRunTimeSelectionTable.H"
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 defineTypeNameAndDebug(coupledCgSolver, 0);
41 coupledLduSolver::addsymMatrixConstructorToTable<coupledCgSolver>
42 addCgSolverSymMatrixConstructorToTable_;
46 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
48 //- Construct from matrix
49 Foam::coupledCgSolver::coupledCgSolver
51 const word& fieldName,
52 const coupledLduMatrix& matrix,
53 const PtrList<FieldField<Field, scalar> >& bouCoeffs,
54 const PtrList<FieldField<Field, scalar> >& intCoeffs,
55 const lduInterfaceFieldPtrsListList& interfaces,
56 const dictionary& solverData
59 coupledIterativeSolver
82 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
84 Foam::coupledSolverPerformance Foam::coupledCgSolver::solve
86 FieldField<Field, scalar>& x,
87 const FieldField<Field, scalar>& b,
91 // Prepare solver performance
92 coupledSolverPerformance solverPerf(typeName, fieldName());
94 FieldField<Field, scalar> wA(x.size());
95 FieldField<Field, scalar> rA(x.size());
99 wA.set(rowI, new scalarField(x[rowI].size(), 0));
100 rA.set(rowI, new scalarField(x[rowI].size(), 0));
104 // Calculate initial residual
105 matrix_.Amul(wA, x, bouCoeffs_, interfaces_, cmpt);
107 // Use rA as scratch space when calculating the normalisation factor
108 scalar normFactor = this->normFactor(x, b, wA, rA, cmpt);
110 if (coupledLduMatrix::debug >= 2)
112 Info<< " Normalisation factor = " << normFactor << endl;
115 // Optimised looping. HJ, 19/Jan/2009
118 const scalarField& bi = b[i];
119 const scalarField& wAi = wA[i];
120 scalarField& rAi = rA[i];
124 rAi[j] = bi[j] - wAi[j];
128 solverPerf.initialResidual() = gSumMag(rA)/normFactor;
129 solverPerf.finalResidual() = solverPerf.initialResidual();
131 if (!solverPerf.checkConvergence(tolerance_, relTolerance_))
133 scalar rho = matrix_[0].great_;
136 scalar alpha, beta, wApA;
138 FieldField<Field, scalar> pA(x.size());
142 pA.set(rowI, new scalarField(x[rowI].size(), 0));
149 // Execute preconditioning
150 preconPtr_->precondition(wA, rA, cmpt);
152 // Update search directions
153 rho = gSumProd(wA, rA);
159 scalarField& curPA = pA[rowI];
160 const scalarField& curWA = wA[rowI];
164 curPA[i] = curWA[i] + beta*curPA[i];
168 // Update preconditioned residual
169 matrix_.Amul(wA, pA, bouCoeffs_, interfaces_, cmpt);
171 wApA = gSumProd(wA, pA);
174 // Check for singularity
175 if (solverPerf.checkSingularity(mag(wApA)/normFactor))
180 // Update solution and residual
185 scalarField& curX = x[rowI];
186 const scalarField& curPA = pA[rowI];
190 curX[i] += alpha*curPA[i];
196 scalarField& curRA = rA[rowI];
197 const scalarField& curWA = wA[rowI];
201 curRA[i] -= alpha*curWA[i];
205 solverPerf.finalResidual() = gSumMag(rA)/normFactor;
206 solverPerf.nIterations()++;
207 } while (!stop(solverPerf));
214 // ************************************************************************* //