Fix tutorials: coupled/conjugateHeatFoam/conjugateCavity: fix Allrun file
[OpenFOAM-1.6-ext.git] / src / coupledMatrix / coupledLduSolver / cgSolver / coupledCgSolver.C
blobac8275762f0c2435608558eef53b537db7ea55d5
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright held by original author
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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
25 Description
26     Preconditioned Conjugate Gradient solver
28 Author
29     Hrvoje Jasak, Wikki Ltd.  All rights reserved
31 \*---------------------------------------------------------------------------*/
33 #include "coupledCgSolver.H"
34 #include "addToRunTimeSelectionTable.H"
36 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
38 namespace Foam
40     defineTypeNameAndDebug(coupledCgSolver, 0);
42     coupledLduSolver::addsymMatrixConstructorToTable<coupledCgSolver>
43         addCgSolverSymMatrixConstructorToTable_;
47 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
49 //- Construct from matrix
50 Foam::coupledCgSolver::coupledCgSolver
52     const word& fieldName,
53     const coupledLduMatrix& matrix,
54     const PtrList<FieldField<Field, scalar> >& bouCoeffs,
55     const PtrList<FieldField<Field, scalar> >& intCoeffs,
56     const lduInterfaceFieldPtrsListList& interfaces,
57     const dictionary& solverData
60     coupledIterativeSolver
61     (
62         fieldName,
63         matrix,
64         bouCoeffs,
65         intCoeffs,
66         interfaces,
67         solverData
68     ),
69     preconPtr_
70     (
71         coupledLduPrecon::New
72         (
73             matrix,
74             bouCoeffs,
75             intCoeffs,
76             interfaces,
77             dict().subDict("preconditioner")
78         )
79     )
83 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
85 Foam::coupledSolverPerformance Foam::coupledCgSolver::solve
87     FieldField<Field, scalar>& x,
88     const FieldField<Field, scalar>& b,
89     const direction cmpt
90 ) const
92     // Prepare solver performance
93     coupledSolverPerformance solverPerf(typeName, fieldName());
95     FieldField<Field, scalar> wA(x.size());
96     FieldField<Field, scalar> rA(x.size());
98     forAll (x, rowI)
99     {
100         wA.set(rowI, new scalarField(x[rowI].size(), 0));
101         rA.set(rowI, new scalarField(x[rowI].size(), 0));
102     }
105     // Calculate initial residual
106     matrix_.Amul(wA, x, bouCoeffs_, interfaces_, cmpt);
108     // Use rA as scratch space when calculating the normalisation factor
109     scalar normFactor = this->normFactor(x, b, wA, rA, cmpt);
111     if (coupledLduMatrix::debug >= 2)
112     {
113         Info<< "   Normalisation factor = " << normFactor << endl;
114     }
116     // Optimised looping.  HJ, 19/Jan/2009
117     forAll (rA, i)
118     {
119         const scalarField& bi = b[i];
120         const scalarField& wAi = wA[i];
121         scalarField& rAi = rA[i];
123         forAll (rAi, j)
124         {
125             rAi[j] = bi[j] - wAi[j];
126         }
127     }
129     solverPerf.initialResidual() = gSumMag(rA)/normFactor;
130     solverPerf.finalResidual() = solverPerf.initialResidual();
132     if (!solverPerf.checkConvergence(tolerance_, relTolerance_))
133     {
134         scalar rho = matrix_[0].great_;
135         scalar rhoOld = rho;
137         scalar alpha, beta, wApA;
139         FieldField<Field, scalar> pA(x.size());
141         forAll (pA, rowI)
142         {
143             pA.set(rowI, new scalarField(x[rowI].size(), 0));
144         }
146         do
147         {
148             rhoOld = rho;
150             // Execute preconditioning
151             preconPtr_->precondition(wA, rA, cmpt);
153             // Update search directions
154             rho = gSumProd(wA, rA);
156             beta = rho/rhoOld;
158             forAll (pA, rowI)
159             {
160                 scalarField& curPA = pA[rowI];
161                 const scalarField& curWA = wA[rowI];
163                 forAll (curPA, i)
164                 {
165                     curPA[i] = curWA[i] + beta*curPA[i];
166                 }
167             }
169             // Update preconditioned residual
170             matrix_.Amul(wA, pA, bouCoeffs_, interfaces_, cmpt);
172             wApA = gSumProd(wA, pA);
175             // Check for singularity
176             if (solverPerf.checkSingularity(mag(wApA)/normFactor))
177             {
178                 break;
179             }
181             // Update solution and residual
182             alpha = rho/wApA;
184             forAll (x, rowI)
185             {
186                 scalarField& curX = x[rowI];
187                 const scalarField& curPA = pA[rowI];
189                 forAll (curX, i)
190                 {
191                     curX[i] += alpha*curPA[i];
192                 }
193             }
195             forAll (rA, rowI)
196             {
197                 scalarField& curRA = rA[rowI];
198                 const scalarField& curWA = wA[rowI];
200                 forAll (curRA, i)
201                 {
202                     curRA[i] -= alpha*curWA[i];
203                 }
204             }
206             solverPerf.finalResidual() = gSumMag(rA)/normFactor;
207             solverPerf.nIterations()++;
208         } while (!stop(solverPerf));
209     }
211     return solverPerf;
215 // ************************************************************************* //