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 Stabilised Bi-Conjugate Gradient solver
28 Hrvoje Jasak, Wikki Ltd. All rights reserved.
30 \*---------------------------------------------------------------------------*/
32 #include "coupledBicgStabSolver.H"
33 #include "addToRunTimeSelectionTable.H"
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 defineTypeNameAndDebug(coupledBicgStabSolver, 0);
41 coupledLduSolver::addsymMatrixConstructorToTable<coupledBicgStabSolver>
42 addBicgStabSolverSymMatrixConstructorToTable_;
43 coupledLduSolver::addasymMatrixConstructorToTable<coupledBicgStabSolver>
44 addBicgStabSolverAsymMatrixConstructorToTable_;
48 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
50 //- Construct from matrix
51 Foam::coupledBicgStabSolver::coupledBicgStabSolver
53 const word& fieldName,
54 const coupledLduMatrix& matrix,
55 const PtrList<FieldField<Field, scalar> >& bouCoeffs,
56 const PtrList<FieldField<Field, scalar> >& intCoeffs,
57 const lduInterfaceFieldPtrsListList& interfaces,
58 const dictionary& solverData
61 coupledIterativeSolver
84 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
86 Foam::coupledSolverPerformance Foam::coupledBicgStabSolver::solve
88 FieldField<Field, scalar>& x,
89 const FieldField<Field, scalar>& b,
93 // Prepare solver performance
94 coupledSolverPerformance solverPerf(typeName, fieldName());
96 FieldField<Field, scalar> p(x.size());
97 FieldField<Field, scalar> r(x.size());
101 p.set(rowI, new scalarField(x[rowI].size(), 0));
102 r.set(rowI, new scalarField(x[rowI].size(), 0));
106 // Calculate initial residual
107 matrix_.Amul(p, x, bouCoeffs_, interfaces_, cmpt);
109 // Use r as scratch space when calculating the normalisation factor
110 scalar normFactor = this->normFactor(x, b, p, r, cmpt);
112 if (coupledLduMatrix::debug >= 2)
114 Info<< " Normalisation factor = " << normFactor << endl;
117 // Calculate residual
120 const scalarField& curB = b[rowI];
121 const scalarField& curP = p[rowI];
122 scalarField& curR = r[rowI];
126 curR[i] = curB[i] - curP[i];
130 solverPerf.initialResidual() = gSumMag(r)/normFactor;
131 solverPerf.finalResidual() = solverPerf.initialResidual();
133 if (!solverPerf.checkConvergence(tolerance_, relTolerance_))
135 scalar rho = matrix_[0].great_;
139 scalar omega = matrix_[0].great_;
143 FieldField<Field, scalar> ph(x.size());
144 FieldField<Field, scalar> v(x.size());
145 FieldField<Field, scalar> s(x.size());
146 FieldField<Field, scalar> sh(x.size());
147 FieldField<Field, scalar> t(x.size());
151 ph.set(rowI, new scalarField(x[rowI].size(), 0));
152 v.set(rowI, new scalarField(x[rowI].size(), 0));
153 s.set(rowI, new scalarField(x[rowI].size(), 0));
154 sh.set(rowI, new scalarField(x[rowI].size(), 0));
155 t.set(rowI, new scalarField(x[rowI].size(), 0));
158 // Calculate transpose residual
159 FieldField<Field, scalar> rw(r);
165 // Update search directions
166 rho = gSumProd(rw, r);
168 beta = rho/rhoOld*(alpha/omega);
170 // Restart if breakdown occurs
174 rho = gSumProd(rw, r);
183 scalarField& curP = p[rowI];
184 const scalarField& curR = r[rowI];
185 const scalarField& curV = v[rowI];
189 curP[i] = curR[i] + beta*curP[i] - beta*omega*curV[i];
193 // Execute preconditioning
194 preconPtr_->precondition(ph, p, cmpt);
195 matrix_.Amul(v, ph, bouCoeffs_, interfaces_, cmpt);
196 alpha = rho/gSumProd(rw, v);
200 scalarField& curS = s[rowI];
201 const scalarField& curR = r[rowI];
202 const scalarField& curV = v[rowI];
206 curS[i] = curR[i] - alpha*curV[i];
210 // Execute preconditioning
211 // Bug fix, Alexander Monakov, 11/Jul/2012
212 preconPtr_->precondition(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 // ************************************************************************* //