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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "SmoothSolver.H"
30 
31 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
32 
33 template<class Type, class DType, class LUType>
35 (
36  const word& fieldName,
37  const LduMatrix<Type, DType, LUType>& matrix,
38  const dictionary& solverDict
39 )
40 :
41  LduMatrix<Type, DType, LUType>::solver
42  (
43  fieldName,
44  matrix,
45  solverDict
46  ),
47  nSweeps_(1)
48 {
50 }
51 
52 
53 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
54 
55 template<class Type, class DType, class LUType>
57 {
59  this->controlDict_.readIfPresent("nSweeps", nSweeps_);
60 }
61 
62 
63 template<class Type, class DType, class LUType>
66 {
67  // --- Setup class containing solver performance data
68  SolverPerformance<Type> solverPerf
69  (
70  typeName,
71  this->fieldName_
72  );
73 
74  label nIter = 0;
75 
76  // If the nSweeps_ is negative do a fixed number of sweeps
77  if (nSweeps_ < 0)
78  {
81  (
82  this->fieldName_,
83  this->matrix_,
84  this->controlDict_
85  );
86 
87  smootherPtr->smooth(psi, -nSweeps_);
88 
89  nIter -= nSweeps_;
90  }
91  else
92  {
93  Type normFactor = Zero;
94 
95  {
96  Field<Type> Apsi(psi.size());
97  Field<Type> temp(psi.size());
98 
99  // Calculate A.psi
100  this->matrix_.Amul(Apsi, psi);
101 
102  // Calculate normalisation factor
103  normFactor = this->normFactor(psi, Apsi, temp);
104 
105  // Calculate residual magnitude
106  solverPerf.initialResidual() = cmptDivide
107  (
108  gSumCmptMag(this->matrix_.source() - Apsi),
109  normFactor
110  );
111  solverPerf.finalResidual() = solverPerf.initialResidual();
112  }
113 
114  if ((this->log_ >= 2) || (LduMatrix<Type, DType, LUType>::debug >= 2))
115  {
116  Info<< " Normalisation factor = " << normFactor << endl;
117  }
118 
119 
120  // Check convergence, solve if not converged
121  if
122  (
123  this->minIter_ > 0
124  || !solverPerf.checkConvergence
125  (
126  this->tolerance_,
127  this->relTol_,
128  this->log_
129  )
130  )
131  {
132  autoPtr<typename LduMatrix<Type, DType, LUType>::smoother>
134  (
135  this->fieldName_,
136  this->matrix_,
137  this->controlDict_
138  );
139 
140  // Smoothing loop
141  do
142  {
143  smootherPtr->smooth
144  (
145  psi,
146  nSweeps_
147  );
148 
149  // Calculate the residual to check convergence
150  solverPerf.finalResidual() = cmptDivide
151  (
152  gSumCmptMag(this->matrix_.residual(psi)),
153  normFactor
154  );
155  } while
156  (
157  (
158  (nIter += nSweeps_) < this->maxIter_
159  && !solverPerf.checkConvergence
160  (
161  this->tolerance_,
162  this->relTol_,
163  this->log_
164  )
165  )
166  || nIter < this->minIter_
167  );
168  }
169  }
170 
171  solverPerf.nIterations() =
172  pTraits<typename pTraits<Type>::labelType>::one*nIter;
173 
174  return solverPerf;
175 }
176 
177 
178 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
Base solver class.
Definition: solver.H:45
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
virtual SolverPerformance< Type > solve(Field< Type > &psi) const
Solve the matrix with this solver.
Definition: SmoothSolver.C:58
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
static autoPtr< smoother > New(const word &fieldName, const LduMatrix< Type, DType, LUType > &matrix, const dictionary &smootherDict)
Return a new smoother.
Type gSumCmptMag(const UList< Type > &f, const label comm)
dimensioned< Type > cmptDivide(const dimensioned< Type > &, const dimensioned< Type > &)
Generic templated field type.
Definition: Field.H:62
A class for handling words, derived from Foam::string.
Definition: word.H:63
SolverPerformance is the class returned by the LduMatrix solver containing performance statistics...
virtual void readControls()
Read the control parameters from the controlDict_.
Definition: SmoothSolver.C:49
SmoothSolver(const word &fieldName, const LduMatrix< Type, DType, LUType > &matrix, const dictionary &solverDict)
Construct from matrix components and solver data dictionary.
Definition: SmoothSolver.C:28
int debug
Static debugging option.
LduMatrix is a general matrix class in which the coefficients are stored as three arrays...
Definition: LduMatrix.H:68
messageStream Info
Information stream (stdout output on master, null elsewhere)
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
const volScalarField & psi
virtual void readControls()
Read the control parameters from controlDict_.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127