Initial commit for version 2.0.x patch release
[OpenFOAM-2.0.x.git] / src / OpenFOAM / matrices / lduMatrix / solvers / smoothSolver / smoothSolver.C
bloba3d9a8f0763d365f1f7de3ba4c8852f0115d51c8
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2004-2010 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
13     the Free Software Foundation, either version 3 of the License, or
14     (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "smoothSolver.H"
28 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 namespace Foam
32     defineTypeNameAndDebug(smoothSolver, 0);
34     lduMatrix::solver::addsymMatrixConstructorToTable<smoothSolver>
35         addsmoothSolverSymMatrixConstructorToTable_;
37     lduMatrix::solver::addasymMatrixConstructorToTable<smoothSolver>
38         addsmoothSolverAsymMatrixConstructorToTable_;
42 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
44 Foam::smoothSolver::smoothSolver
46     const word& fieldName,
47     const lduMatrix& matrix,
48     const FieldField<Field, scalar>& interfaceBouCoeffs,
49     const FieldField<Field, scalar>& interfaceIntCoeffs,
50     const lduInterfaceFieldPtrsList& interfaces,
51     const dictionary& solverControls
54     lduMatrix::solver
55     (
56         fieldName,
57         matrix,
58         interfaceBouCoeffs,
59         interfaceIntCoeffs,
60         interfaces,
61         solverControls
62     )
64     readControls();
68 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
70 void Foam::smoothSolver::readControls()
72     lduMatrix::solver::readControls();
73     nSweeps_ = controlDict_.lookupOrDefault<label>("nSweeps", 1);
77 Foam::lduMatrix::solverPerformance Foam::smoothSolver::solve
79     scalarField& psi,
80     const scalarField& source,
81     const direction cmpt
82 ) const
84     // Setup class containing solver performance data
85     lduMatrix::solverPerformance solverPerf(typeName, fieldName_);
87     // If the nSweeps_ is negative do a fixed number of sweeps
88     if (nSweeps_ < 0)
89     {
90         autoPtr<lduMatrix::smoother> smootherPtr = lduMatrix::smoother::New
91         (
92             fieldName_,
93             matrix_,
94             interfaceBouCoeffs_,
95             interfaceIntCoeffs_,
96             interfaces_,
97             controlDict_
98         );
100         smootherPtr->smooth
101         (
102             psi,
103             source,
104             cmpt,
105             -nSweeps_
106         );
108         solverPerf.nIterations() -= nSweeps_;
109     }
110     else
111     {
112         scalar normFactor = 0;
114         {
115             scalarField Apsi(psi.size());
116             scalarField temp(psi.size());
118             // Calculate A.psi
119             matrix_.Amul(Apsi, psi, interfaceBouCoeffs_, interfaces_, cmpt);
121             // Calculate normalisation factor
122             normFactor = this->normFactor(psi, source, Apsi, temp);
124             // Calculate residual magnitude
125             solverPerf.initialResidual() = gSumMag(source - Apsi)/normFactor;
126             solverPerf.finalResidual() = solverPerf.initialResidual();
127         }
129         if (lduMatrix::debug >= 2)
130         {
131             Info<< "   Normalisation factor = " << normFactor << endl;
132         }
135         // Check convergence, solve if not converged
136         if (!solverPerf.checkConvergence(tolerance_, relTol_))
137         {
138             autoPtr<lduMatrix::smoother> smootherPtr = lduMatrix::smoother::New
139             (
140                 fieldName_,
141                 matrix_,
142                 interfaceBouCoeffs_,
143                 interfaceIntCoeffs_,
144                 interfaces_,
145                 controlDict_
146             );
148             // Smoothing loop
149             do
150             {
151                 smootherPtr->smooth
152                 (
153                     psi,
154                     source,
155                     cmpt,
156                     nSweeps_
157                 );
159                 // Calculate the residual to check convergence
160                 solverPerf.finalResidual() = gSumMag
161                 (
162                     matrix_.residual
163                     (
164                         psi,
165                         source,
166                         interfaceBouCoeffs_,
167                         interfaces_,
168                         cmpt
169                     )
170                 )/normFactor;
171             } while
172             (
173                 (solverPerf.nIterations() += nSweeps_) < maxIter_
174              && !(solverPerf.checkConvergence(tolerance_, relTol_))
175             );
176         }
177     }
179     return solverPerf;
183 // ************************************************************************* //