FreeFOAM The Cross-Platform CFD Toolkit
smoothSolver.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include <OpenFOAM/smoothSolver.H>
27 
28 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
29 
30 namespace Foam
31 {
32  defineTypeNameAndDebug(smoothSolver, 0);
33 
34  lduMatrix::solver::addsymMatrixConstructorToTable<smoothSolver>
36 
37  lduMatrix::solver::addasymMatrixConstructorToTable<smoothSolver>
39 }
40 
41 
42 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
43 
45 (
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
52 )
53 :
55  (
56  fieldName,
57  matrix,
58  interfaceBouCoeffs,
59  interfaceIntCoeffs,
60  interfaces,
61  solverControls
62  )
63 {
64  readControls();
65 }
66 
67 
68 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
69 
71 {
73  nSweeps_ = controlDict_.lookupOrDefault<label>("nSweeps", 1);
74 }
75 
76 
78 (
80  const scalarField& source,
81  const direction cmpt
82 ) const
83 {
84  // Setup class containing solver performance data
85  lduMatrix::solverPerformance solverPerf(typeName, fieldName_);
86 
87  // If the nSweeps_ is negative do a fixed number of sweeps
88  if (nSweeps_ < 0)
89  {
91  (
92  fieldName_,
93  matrix_,
94  interfaceBouCoeffs_,
95  interfaceIntCoeffs_,
96  interfaces_,
97  controlDict_
98  );
99 
100  smootherPtr->smooth
101  (
102  psi,
103  source,
104  cmpt,
105  -nSweeps_
106  );
107 
108  solverPerf.nIterations() -= nSweeps_;
109  }
110  else
111  {
112  scalar normFactor = 0;
113 
114  {
115  scalarField Apsi(psi.size());
116  scalarField temp(psi.size());
117 
118  // Calculate A.psi
119  matrix_.Amul(Apsi, psi, interfaceBouCoeffs_, interfaces_, cmpt);
120 
121  // Calculate normalisation factor
122  normFactor = this->normFactor(psi, source, Apsi, temp);
123 
124  // Calculate residual magnitude
125  solverPerf.initialResidual() = gSumMag(source - Apsi)/normFactor;
126  solverPerf.finalResidual() = solverPerf.initialResidual();
127  }
128 
129  if (lduMatrix::debug >= 2)
130  {
131  Info<< " Normalisation factor = " << normFactor << endl;
132  }
133 
134 
135  // Check convergence, solve if not converged
136  if (!solverPerf.checkConvergence(tolerance_, relTol_))
137  {
139  (
140  fieldName_,
141  matrix_,
142  interfaceBouCoeffs_,
143  interfaceIntCoeffs_,
144  interfaces_,
145  controlDict_
146  );
147 
148  // Smoothing loop
149  do
150  {
151  smootherPtr->smooth
152  (
153  psi,
154  source,
155  cmpt,
156  nSweeps_
157  );
158 
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  }
178 
179  return solverPerf;
180 }
181 
182 
183 // ************************ vim: set sw=4 sts=4 et: ************************ //