initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / OpenFOAM / matrices / lduMatrix / solvers / smoothSolver / smoothSolver.C
blob22cad31b4385e91310a1f16e97d61f117ed587b3
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
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 \*---------------------------------------------------------------------------*/
27 #include "smoothSolver.H"
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 namespace Foam
33     defineTypeNameAndDebug(smoothSolver, 0);
35     lduMatrix::solver::addsymMatrixConstructorToTable<smoothSolver>
36         addsmoothSolverSymMatrixConstructorToTable_;
38     lduMatrix::solver::addasymMatrixConstructorToTable<smoothSolver>
39         addsmoothSolverAsymMatrixConstructorToTable_;
43 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
45 Foam::smoothSolver::smoothSolver
47     const word& fieldName,
48     const lduMatrix& matrix,
49     const FieldField<Field, scalar>& interfaceBouCoeffs,
50     const FieldField<Field, scalar>& interfaceIntCoeffs,
51     const lduInterfaceFieldPtrsList& interfaces,
52     const dictionary& solverControls
55     lduMatrix::solver
56     (
57         fieldName,
58         matrix,
59         interfaceBouCoeffs,
60         interfaceIntCoeffs,
61         interfaces,
62         solverControls
63     )
65     readControls();
69 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
71 void Foam::smoothSolver::readControls()
73     lduMatrix::solver::readControls();
74     nSweeps_ = controlDict_.lookupOrDefault<label>("nSweeps", 1);
78 Foam::lduMatrix::solverPerformance Foam::smoothSolver::solve
80     scalarField& psi,
81     const scalarField& source,
82     const direction cmpt
83 ) const
85     // Setup class containing solver performance data
86     lduMatrix::solverPerformance solverPerf(typeName, fieldName_);
88     // If the nSweeps_ is negative do a fixed number of sweeps
89     if (nSweeps_ < 0)
90     {
91         autoPtr<lduMatrix::smoother> smootherPtr = lduMatrix::smoother::New
92         (
93             fieldName_,
94             matrix_,
95             interfaceBouCoeffs_,
96             interfaceIntCoeffs_,
97             interfaces_,
98             controlDict_
99         );
101         smootherPtr->smooth
102         (
103             psi,
104             source,
105             cmpt,
106             -nSweeps_
107         );
109         solverPerf.nIterations() -= nSweeps_;
110     }
111     else
112     {
113         scalar normFactor = 0;
115         {
116             scalarField Apsi(psi.size());
117             scalarField temp(psi.size());
119             // Calculate A.psi
120             matrix_.Amul(Apsi, psi, interfaceBouCoeffs_, interfaces_, cmpt);
122             // Calculate normalisation factor
123             normFactor = this->normFactor(psi, source, Apsi, temp);
125             // Calculate residual magnitude
126             solverPerf.initialResidual() = gSumMag(source - Apsi)/normFactor;
127             solverPerf.finalResidual() = solverPerf.initialResidual();
128         }
130         if (lduMatrix::debug >= 2)
131         {
132             Info<< "   Normalisation factor = " << normFactor << endl;
133         }
136         // Check convergence, solve if not converged
137         if (!solverPerf.checkConvergence(tolerance_, relTol_))
138         {
139             autoPtr<lduMatrix::smoother> smootherPtr = lduMatrix::smoother::New
140             (
141                 fieldName_,
142                 matrix_,
143                 interfaceBouCoeffs_,
144                 interfaceIntCoeffs_,
145                 interfaces_,
146                 controlDict_
147             );
149             // Smoothing loop
150             do
151             {
152                 smootherPtr->smooth
153                 (
154                     psi,
155                     source,
156                     cmpt,
157                     nSweeps_
158                 );
160                 // Calculate the residual to check convergence
161                 solverPerf.finalResidual() = gSumMag
162                 (
163                     matrix_.residual
164                     (
165                         psi,
166                         source,
167                         interfaceBouCoeffs_,
168                         interfaces_,
169                         cmpt
170                     )
171                 )/normFactor;
172             } while
173             (
174                 (solverPerf.nIterations() += nSweeps_) < maxIter_
175              && !(solverPerf.checkConvergence(tolerance_, relTol_))
176             );
177         }
178     }
180     return solverPerf;
184 // ************************************************************************* //