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 Bi-Conjugate Gradient solver with run-time selectable
30 Hrvoje Jasak, Wikki Ltd. All rights reserved.
32 \*---------------------------------------------------------------------------*/
34 #include "bicgSolver.H"
36 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 defineTypeNameAndDebug(bicgSolver, 0);
42 lduSolver::addasymMatrixConstructorToTable<bicgSolver>
43 addbicgSolverAsymMatrixConstructorToTable_;
47 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
49 //- Construct from matrix and solver data stream
50 Foam::bicgSolver::bicgSolver
52 const word& fieldName,
53 const lduMatrix& matrix,
54 const FieldField<Field, scalar>& coupleBouCoeffs,
55 const FieldField<Field, scalar>& coupleIntCoeffs,
56 const lduInterfaceFieldPtrsList& interfaces,
57 const dictionary& dict
71 lduPreconditioner::New
83 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
85 Foam::lduSolverPerformance Foam::bicgSolver::solve
92 // Prepare solver performance
93 lduSolverPerformance solverPerf(typeName, fieldName());
95 scalarField wA(x.size());
96 scalarField rA(x.size());
98 // Calculate initial residual
99 matrix_.Amul(wA, x, coupleBouCoeffs_, interfaces_, cmpt);
101 scalar normFactor = this->normFactor(x, b, wA, rA, cmpt);
103 if (lduMatrix::debug >= 2)
105 Info<< " Normalisation factor = " << normFactor << endl;
108 // Calculate residual
111 rA[i] = b[i] - wA[i];
114 solverPerf.initialResidual() = gSumMag(rA)/normFactor;
115 solverPerf.finalResidual() = solverPerf.initialResidual();
117 if (!stop(solverPerf))
119 scalar rho = matrix_.great_;
122 scalar alpha, beta, wApT;
124 scalarField pA(x.size(), 0);
125 scalarField pT(x.size(), 0);
127 // Calculate transpose residual
128 scalarField wT(x.size());
135 // Execute preconditioning
136 preconPtr_->precondition(wA, rA, cmpt);
137 preconPtr_->preconditionT(wT, rT, cmpt);
139 // Update search directions
140 rho = gSumProd(wA, rT);
146 pA[i] = wA[i] + beta*pA[i];
151 pT[i] = wT[i] + beta*pT[i];
154 // Update preconditioned residual
155 matrix_.Amul(wA, pA, coupleBouCoeffs_, interfaces_, cmpt);
156 matrix_.Amul(wT, pT, coupleIntCoeffs_, interfaces_, cmpt);
158 wApT = gSumProd(wA, pT);
161 // Check for singularity
162 if (solverPerf.checkSingularity(mag(wApT)/normFactor))
167 // Update solution and residual
177 rA[i] -= alpha*wA[i];
182 rT[i] -= alpha*wT[i];
185 solverPerf.finalResidual() = gSumMag(rA)/normFactor;
186 solverPerf.nIterations()++;
187 } while (!stop(solverPerf));
194 // ************************************************************************* //