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 Stabilised Bi-Conjugate Gradient solver
29 Hrvoje Jasak, Wikki Ltd. All rights reserved.
31 \*---------------------------------------------------------------------------*/
33 #include "coupledBicgStabSolver.H"
34 #include "addToRunTimeSelectionTable.H"
36 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 defineTypeNameAndDebug(coupledBicgStabSolver, 0);
42 coupledLduSolver::addsymMatrixConstructorToTable<coupledBicgStabSolver>
43 addBicgStabSolverSymMatrixConstructorToTable_;
44 coupledLduSolver::addasymMatrixConstructorToTable<coupledBicgStabSolver>
45 addBicgStabSolverAsymMatrixConstructorToTable_;
49 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
51 //- Construct from matrix
52 Foam::coupledBicgStabSolver::coupledBicgStabSolver
54 const word& fieldName,
55 const coupledLduMatrix& matrix,
56 const PtrList<FieldField<Field, scalar> >& bouCoeffs,
57 const PtrList<FieldField<Field, scalar> >& intCoeffs,
58 const lduInterfaceFieldPtrsListList& interfaces,
59 const dictionary& solverData
62 coupledIterativeSolver
79 dict().subDict("preconditioner")
85 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
87 Foam::coupledSolverPerformance Foam::coupledBicgStabSolver::solve
89 FieldField<Field, scalar>& x,
90 const FieldField<Field, scalar>& b,
94 // Prepare solver performance
95 coupledSolverPerformance solverPerf(typeName, fieldName());
97 FieldField<Field, scalar> p(x.size());
98 FieldField<Field, scalar> r(x.size());
102 p.set(rowI, new scalarField(x[rowI].size(), 0));
103 r.set(rowI, new scalarField(x[rowI].size(), 0));
107 // Calculate initial residual
108 matrix_.Amul(p, x, bouCoeffs_, interfaces_, cmpt);
110 // Use r as scratch space when calculating the normalisation factor
111 scalar normFactor = this->normFactor(x, b, p, r, cmpt);
113 if (coupledLduMatrix::debug >= 2)
115 Info<< " Normalisation factor = " << normFactor << endl;
118 // Calculate residual
121 const scalarField& curB = b[rowI];
122 const scalarField& curP = p[rowI];
123 scalarField& curR = r[rowI];
127 curR[i] = curB[i] - curP[i];
131 solverPerf.initialResidual() = gSumMag(r)/normFactor;
132 solverPerf.finalResidual() = solverPerf.initialResidual();
134 if (!solverPerf.checkConvergence(tolerance_, relTolerance_))
136 scalar rho = matrix_[0].great_;
140 scalar omega = matrix_[0].great_;
144 FieldField<Field, scalar> ph(x.size());
145 FieldField<Field, scalar> v(x.size());
146 FieldField<Field, scalar> s(x.size());
147 FieldField<Field, scalar> sh(x.size());
148 FieldField<Field, scalar> t(x.size());
152 ph.set(rowI, new scalarField(x[rowI].size(), 0));
153 v.set(rowI, new scalarField(x[rowI].size(), 0));
154 s.set(rowI, new scalarField(x[rowI].size(), 0));
155 sh.set(rowI, new scalarField(x[rowI].size(), 0));
156 t.set(rowI, new scalarField(x[rowI].size(), 0));
159 // Calculate transpose residual
160 FieldField<Field, scalar> rw(r);
166 // Update search directions
167 rho = gSumProd(rw, r);
169 beta = rho/rhoOld*(alpha/omega);
171 // Restart if breakdown occurs
175 rho = gSumProd(rw, r);
184 scalarField& curP = p[rowI];
185 const scalarField& curR = r[rowI];
186 const scalarField& curV = v[rowI];
190 curP[i] = curR[i] + beta*curP[i] - beta*omega*curV[i];
194 // Execute preconditioning
195 preconPtr_->precondition(ph, p, cmpt);
196 matrix_.Amul(v, ph, bouCoeffs_, interfaces_, cmpt);
197 alpha = rho/gSumProd(rw, v);
201 scalarField& curS = s[rowI];
202 const scalarField& curR = r[rowI];
203 const scalarField& curV = v[rowI];
207 curS[i] = curR[i] - alpha*curV[i];
211 // Execute preconditioning transpose
212 preconPtr_->preconditionT(sh, s, cmpt);
213 matrix_.Amul(t, sh, bouCoeffs_, interfaces_, cmpt);
214 omega = gSumProd(t, s)/gSumProd(t, t);
216 // Update solution and residual
219 scalarField& curX = x[rowI];
220 const scalarField& curPh = ph[rowI];
221 const scalarField& curSh = sh[rowI];
225 curX[i] = curX[i] + alpha*curPh[i] + omega*curSh[i];
231 scalarField& curR = r[rowI];
232 const scalarField& curS = s[rowI];
233 const scalarField& curT = t[rowI];
237 curR[i] = curS[i] - omega*curT[i];
241 solverPerf.finalResidual() = gSumMag(r)/normFactor;
242 solverPerf.nIterations()++;
243 } while (!stop(solverPerf));
250 // ************************************************************************* //