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 Bi-Conjugate Gradient solver
28 Hrvoje Jasak, Wikki Ltd. All rights reserved.
30 \*---------------------------------------------------------------------------*/
32 #include "coupledBicgSolver.H"
33 #include "addToRunTimeSelectionTable.H"
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 defineTypeNameAndDebug(coupledBicgSolver, 0);
41 coupledLduSolver::addasymMatrixConstructorToTable<coupledBicgSolver>
42 addBicgSolverAsymMatrixConstructorToTable_;
46 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
48 //- Construct from matrix
49 Foam::coupledBicgSolver::coupledBicgSolver
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::coupledBicgSolver::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 // Calculate residual
116 // Optimised looping. HJ, 19/Jan/2009
119 const scalarField& curB = b[rowI];
120 const scalarField& curWA = wA[rowI];
121 scalarField& curRA = rA[rowI];
125 curRA[i] = curB[i] - curWA[i];
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, wApT;
139 FieldField<Field, scalar> pA(x.size());
140 FieldField<Field, scalar> pT(x.size());
142 FieldField<Field, scalar> wT(x.size());
143 FieldField<Field, scalar> rT = rA;
147 pA.set(rowI, new scalarField(x[rowI].size(), 0));
148 pT.set(rowI, new scalarField(x[rowI].size(), 0));
150 wT.set(rowI, new scalarField(x[rowI].size(), 0));
158 // Execute preconditioning
159 preconPtr_->precondition(wA, rA, cmpt);
161 // Using standard preconditioning on the transpose
162 // Not sure this is correct, but the other one does not work
164 // preconPtr_->preconditionT(wT, rT, cmpt);
165 preconPtr_->precondition(wT, rT, cmpt);
167 // Update search directions
168 rho = gSumProd(wA, rT);
174 scalarField& curPA = pA[rowI];
175 const scalarField& curWA = wA[rowI];
179 curPA[i] = curWA[i] + beta*curPA[i];
185 scalarField& curPT = pT[rowI];
186 const scalarField& curWT = wT[rowI];
190 curPT[i] = curWT[i] + beta*curPT[i];
194 // Update preconditioned residual
195 matrix_.Amul(wA, pA, bouCoeffs_, interfaces_, cmpt);
196 matrix_.Amul(wT, pT, bouCoeffs_, interfaces_, cmpt);
198 wApT = gSumProd(wA, pT);
201 // Check for singularity
202 if (solverPerf.checkSingularity(mag(wApT)/normFactor))
207 // Update solution and residual
212 scalarField& curX = x[rowI];
213 const scalarField& curPA = pA[rowI];
217 curX[i] += alpha*curPA[i];
223 scalarField& curRA = rA[rowI];
224 const scalarField& curWA = wA[rowI];
228 curRA[i] -= alpha*curWA[i];
234 scalarField& curRT = rT[rowI];
235 const scalarField& curWT = wT[rowI];
239 curRT[i] -= alpha*curWT[i];
243 solverPerf.finalResidual() = gSumMag(rA)/normFactor;
244 solverPerf.nIterations()++;
245 } while (!stop(solverPerf));
252 // ************************************************************************* //