symGaussSeidelSmoother.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) 2012-2015 OpenFOAM Foundation
9  Copyright (C) 2017-2019 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 "symGaussSeidelSmoother.H"
30 #include "PrecisionAdaptor.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36  defineTypeNameAndDebug(symGaussSeidelSmoother, 0);
37 
38  lduMatrix::smoother::addsymMatrixConstructorToTable<symGaussSeidelSmoother>
40 
41  lduMatrix::smoother::addasymMatrixConstructorToTable<symGaussSeidelSmoother>
43 }
44 
45 
46 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
47 
49 (
50  const word& fieldName,
51  const lduMatrix& matrix,
52  const FieldField<Field, scalar>& interfaceBouCoeffs,
53  const FieldField<Field, scalar>& interfaceIntCoeffs,
54  const lduInterfaceFieldPtrsList& interfaces
55 )
56 :
58  (
59  fieldName,
60  matrix,
61  interfaceBouCoeffs,
62  interfaceIntCoeffs,
63  interfaces
64  )
65 {}
66 
67 
68 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
69 
71 (
72  const word& fieldName_,
74  const lduMatrix& matrix_,
75  const solveScalarField& source,
76  const FieldField<Field, scalar>& interfaceBouCoeffs_,
77  const lduInterfaceFieldPtrsList& interfaces_,
78  const direction cmpt,
79  const label nSweeps
80 )
81 {
82  solveScalar* __restrict__ psiPtr = psi.begin();
83 
84  const label nCells = psi.size();
85 
86  solveScalarField bPrime(nCells);
87  solveScalar* __restrict__ bPrimePtr = bPrime.begin();
88 
89  const scalar* const __restrict__ diagPtr = matrix_.diag().begin();
90  const scalar* const __restrict__ upperPtr =
91  matrix_.upper().begin();
92  const scalar* const __restrict__ lowerPtr =
93  matrix_.lower().begin();
94 
95  const label* const __restrict__ uPtr =
96  matrix_.lduAddr().upperAddr().begin();
97 
98  const label* const __restrict__ ownStartPtr =
99  matrix_.lduAddr().ownerStartAddr().begin();
100 
101 
102  // Parallel boundary initialisation. The parallel boundary is treated
103  // as an effective jacobi interface in the boundary.
104  // Note: there is a change of sign in the coupled
105  // interface update. The reason for this is that the
106  // internal coefficients are all located at the l.h.s. of
107  // the matrix whereas the "implicit" coefficients on the
108  // coupled boundaries are all created as if the
109  // coefficient contribution is of a source-kind (i.e. they
110  // have a sign as if they are on the r.h.s. of the matrix.
111  // To compensate for this, it is necessary to turn the
112  // sign of the contribution.
113 
114  for (label sweep=0; sweep<nSweeps; sweep++)
115  {
116  bPrime = source;
117 
118  matrix_.initMatrixInterfaces
119  (
120  false,
121  interfaceBouCoeffs_,
122  interfaces_,
123  psi,
124  bPrime,
125  cmpt
126  );
127 
128  matrix_.updateMatrixInterfaces
129  (
130  false,
131  interfaceBouCoeffs_,
132  interfaces_,
133  psi,
134  bPrime,
135  cmpt
136  );
137 
138  solveScalar psii;
139  label fStart;
140  label fEnd = ownStartPtr[0];
141 
142  for (label celli=0; celli<nCells; celli++)
143  {
144  // Start and end of this row
145  fStart = fEnd;
146  fEnd = ownStartPtr[celli + 1];
147 
148  // Get the accumulated neighbour side
149  psii = bPrimePtr[celli];
150 
151  // Accumulate the owner product side
152  for (label facei=fStart; facei<fEnd; facei++)
153  {
154  psii -= upperPtr[facei]*psiPtr[uPtr[facei]];
155  }
156 
157  // Finish current psi
158  psii /= diagPtr[celli];
159 
160  // Distribute the neighbour side using current psi
161  for (label facei=fStart; facei<fEnd; facei++)
162  {
163  bPrimePtr[uPtr[facei]] -= lowerPtr[facei]*psii;
164  }
165 
166  psiPtr[celli] = psii;
167  }
168 
169  fStart = ownStartPtr[nCells];
170 
171  for (label celli=nCells-1; celli>=0; celli--)
172  {
173  // Start and end of this row
174  fEnd = fStart;
175  fStart = ownStartPtr[celli];
176 
177  // Get the accumulated neighbour side
178  psii = bPrimePtr[celli];
179 
180  // Accumulate the owner product side
181  for (label facei=fStart; facei<fEnd; facei++)
182  {
183  psii -= upperPtr[facei]*psiPtr[uPtr[facei]];
184  }
185 
186  // Finish psi for this cell
187  psii /= diagPtr[celli];
188 
189  // Distribute the neighbour side using psi for this cell
190  for (label facei=fStart; facei<fEnd; facei++)
191  {
192  bPrimePtr[uPtr[facei]] -= lowerPtr[facei]*psii;
193  }
194 
195  psiPtr[celli] = psii;
196  }
197  }
198 }
199 
200 
202 (
204  const solveScalarField& source,
205  const direction cmpt,
206  const label nSweeps
207 ) const
208 {
209  smooth
210  (
211  fieldName_,
212  psi,
213  matrix_,
214  source,
215  interfaceBouCoeffs_,
216  interfaces_,
217  cmpt,
218  nSweeps
219  );
220 }
221 
222 
224 (
226  const scalarField& source,
227  const direction cmpt,
228  const label nSweeps
229 ) const
230 {
231  scalarSmooth
232  (
233  psi,
235  cmpt,
236  nSweeps
237  );
238 }
239 
240 
241 // ************************************************************************* //
Foam::lduMatrix::lduAddr
const lduAddressing & lduAddr() const
Return the LDU addressing.
Definition: lduMatrix.H:572
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::FieldField
A field of fields is a PtrList of fields with reference counting.
Definition: FieldField.H:53
symGaussSeidelSmoother.H
Foam::lduMatrix::upper
scalarField & upper()
Definition: lduMatrix.C:203
Foam::lduMatrix
lduMatrix is a general matrix class in which the coefficients are stored as three arrays,...
Definition: lduMatrix.H:83
PrecisionAdaptor.H
Foam::symGaussSeidelSmoother::scalarSmooth
virtual void scalarSmooth(solveScalarField &psi, const solveScalarField &source, const direction cmpt, const label nSweeps) const
Smooth the solution for a given number of sweeps.
Definition: symGaussSeidelSmoother.C:202
Foam::lduAddressing::ownerStartAddr
const labelUList & ownerStartAddr() const
Return owner start addressing.
Definition: lduAddressing.C:199
Foam::lduAddressing::upperAddr
virtual const labelUList & upperAddr() const =0
Return upper addressing.
Foam::UList::begin
iterator begin()
Return an iterator to begin traversing the UList.
Definition: UListI.H:276
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::Field< solveScalar >
Foam::UPtrList< const lduInterfaceField >
Foam::lduMatrix::updateMatrixInterfaces
void updateMatrixInterfaces(const bool add, const FieldField< Field, scalar > &interfaceCoeffs, const lduInterfaceFieldPtrsList &interfaces, const solveScalarField &psiif, solveScalarField &result, const direction cmpt) const
Update interfaced interfaces for matrix operations.
Definition: lduMatrixUpdateMatrixInterfaces.C:103
Foam::lduMatrix::smoother
Abstract base-class for lduMatrix smoothers.
Definition: lduMatrix.H:285
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::lduMatrix::diag
scalarField & diag()
Definition: lduMatrix.C:192
Foam::lduMatrix::initMatrixInterfaces
void initMatrixInterfaces(const bool add, const FieldField< Field, scalar > &interfaceCoeffs, const lduInterfaceFieldPtrsList &interfaces, const solveScalarField &psiif, solveScalarField &result, const direction cmpt) const
Definition: lduMatrixUpdateMatrixInterfaces.C:34
Foam::symGaussSeidelSmoother::smooth
static void smooth(const word &fieldName, solveScalarField &psi, const lduMatrix &matrix, const solveScalarField &source, const FieldField< Field, scalar > &interfaceBouCoeffs, const lduInterfaceFieldPtrsList &interfaces, const direction cmpt, const label nSweeps)
Smooth for the given number of sweeps.
Definition: symGaussSeidelSmoother.C:71
Foam::ConstPrecisionAdaptor
A const Field wrapper with possible data conversion.
Definition: PrecisionAdaptor.H:50
Foam::direction
uint8_t direction
Definition: direction.H:47
Foam::symGaussSeidelSmoother::symGaussSeidelSmoother
symGaussSeidelSmoother(const word &fieldName, const lduMatrix &matrix, const FieldField< Field, scalar > &interfaceBouCoeffs, const FieldField< Field, scalar > &interfaceIntCoeffs, const lduInterfaceFieldPtrsList &interfaces)
Construct from components.
Definition: symGaussSeidelSmoother.C:49
Foam::addsymGaussSeidelSmootherAsymMatrixConstructorToTable_
lduMatrix::smoother::addasymMatrixConstructorToTable< symGaussSeidelSmoother > addsymGaussSeidelSmootherAsymMatrixConstructorToTable_
Definition: symGaussSeidelSmoother.C:42
psi
const volScalarField & psi
Definition: createFieldRefs.H:1
Foam::lduMatrix::lower
scalarField & lower()
Definition: lduMatrix.C:174
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::fvc::sweep
void sweep(volScalarField &field, const volScalarField &alpha, const label nLayers, const scalar alphaDiff=0.2)
Definition: fvcSmooth.C:224
Foam::addsymGaussSeidelSmootherSymMatrixConstructorToTable_
lduMatrix::smoother::addsymMatrixConstructorToTable< symGaussSeidelSmoother > addsymGaussSeidelSmootherSymMatrixConstructorToTable_
Definition: symGaussSeidelSmoother.C:39
Foam::fvc::smooth
void smooth(volScalarField &field, const scalar coeff)
Definition: fvcSmooth.C:37