TGaussSeidelSmoother.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) 2017-2023 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 "TGaussSeidelSmoother.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 )
39 :
40  LduMatrix<Type, DType, LUType>::smoother
41  (
42  fieldName,
43  matrix
44  ),
45  rD_(matrix.diag().size())
46 {
47  const label nCells = matrix.diag().size();
48  const DType* const __restrict__ diagPtr = matrix.diag().begin();
49  DType* __restrict__ rDPtr = rD_.begin();
50 
51  for (label celli=0; celli<nCells; celli++)
52  {
53  rDPtr[celli] = inv(diagPtr[celli]);
54  }
55 }
56 
57 
58 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
59 
60 template<class Type, class DType, class LUType>
62 (
63  const word& fieldName_,
65  const LduMatrix<Type, DType, LUType>& matrix_,
66  const Field<DType>& rD_,
67  const label nSweeps
68 )
69 {
70  Type* __restrict__ psiPtr = psi.begin();
71 
72  const label nCells = psi.size();
73 
74  Field<Type> bPrime(nCells);
75  Type* __restrict__ bPrimePtr = bPrime.begin();
76 
77  const DType* const __restrict__ rDPtr = rD_.begin();
78 
79  const LUType* const __restrict__ upperPtr =
80  matrix_.upper().begin();
81 
82  const LUType* const __restrict__ lowerPtr =
83  matrix_.lower().begin();
84 
85  const label* const __restrict__ uPtr =
86  matrix_.lduAddr().upperAddr().begin();
87 
88  const label* const __restrict__ ownStartPtr =
89  matrix_.lduAddr().ownerStartAddr().begin();
90 
91 
92  // Parallel boundary initialisation. The parallel boundary is treated
93  // as an effective jacobi interface in the boundary.
94  // Note: there is a change of sign in the coupled
95  // interface update to add the contibution to the r.h.s.
96 
97  for (label sweep=0; sweep<nSweeps; sweep++)
98  {
99  bPrime = matrix_.source();
100 
101  const label startRequest = UPstream::nRequests();
102 
103  matrix_.initMatrixInterfaces
104  (
105  false,
106  matrix_.interfacesUpper(),
107  psi,
108  bPrime
109  );
110 
111  matrix_.updateMatrixInterfaces
112  (
113  false,
114  matrix_.interfacesUpper(),
115  psi,
116  bPrime,
117  startRequest
118  );
119 
120  Type curPsi;
121  label fStart;
122  label fEnd = ownStartPtr[0];
123 
124  for (label celli=0; celli<nCells; celli++)
125  {
126  // Start and end of this row
127  fStart = fEnd;
128  fEnd = ownStartPtr[celli + 1];
129 
130  // Get the accumulated neighbour side
131  curPsi = bPrimePtr[celli];
132 
133  // Accumulate the owner product side
134  for (label curFace=fStart; curFace<fEnd; curFace++)
135  {
136  curPsi -= dot(upperPtr[curFace], psiPtr[uPtr[curFace]]);
137  }
138 
139  // Finish current psi
140  curPsi = dot(rDPtr[celli], curPsi);
141 
142  // Distribute the neighbour side using current psi
143  for (label curFace=fStart; curFace<fEnd; curFace++)
144  {
145  bPrimePtr[uPtr[curFace]] -= dot(lowerPtr[curFace], curPsi);
146  }
147 
148  psiPtr[celli] = curPsi;
149  }
150  }
151 }
152 
153 
154 template<class Type, class DType, class LUType>
156 (
157  Field<Type>& psi,
158  const label nSweeps
159 ) const
160 {
161  smooth(this->fieldName_, psi, this->matrix_, rD_, nSweeps);
162 }
163 
164 
165 // ************************************************************************* //
void initMatrixInterfaces(const bool add, const FieldField< Field, LUType > &interfaceCoeffs, const Field< Type > &psiif, Field< Type > &result) const
Initialise the update of interfaced interfaces.
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
static void smooth(const word &fieldName, Field< Type > &psi, const LduMatrix< Type, DType, LUType > &matrix, const Field< DType > &rD, const label nSweeps)
Smooth for the given number of sweeps.
Field< Type > & source()
Definition: LduMatrix.C:243
static label nRequests() noexcept
Number of outstanding requests (on the internal list of requests)
const LduMatrix< Type, DType, LUType > & matrix() const noexcept
Definition: LduMatrix.H:411
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
Field< LUType > & lower()
Definition: LduMatrix.C:220
void dot(FieldField< Field1, typename innerProduct< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
void smooth(volScalarField &field, const scalar coeff)
Definition: fvcSmooth.C:37
TGaussSeidelSmoother(const word &fieldName, const LduMatrix< Type, DType, LUType > &matrix)
Construct from components.
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
void sweep(volScalarField &field, const volScalarField &alpha, const label nLayers, const scalar alphaDiff=0.2)
Definition: fvcSmooth.C:224
Generic templated field type.
Definition: Field.H:62
A class for handling words, derived from Foam::string.
Definition: word.H:63
virtual const labelUList & upperAddr() const =0
Return upper addressing.
Field< LUType > & upper()
Definition: LduMatrix.C:197
void updateMatrixInterfaces(const bool add, const FieldField< Field, LUType > &interfaceCoeffs, const Field< Type > &psiif, Field< Type > &result, const label startRequest) const
Update interfaced interfaces for matrix operations.
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:391
const lduAddressing & lduAddr() const
Return the LDU addressing.
Definition: LduMatrix.H:596
FieldField< Field, LUType > & interfacesUpper()
Definition: LduMatrix.H:633
LduMatrix is a general matrix class in which the coefficients are stored as three arrays...
Definition: LduMatrix.H:68
const volScalarField & psi
const labelUList & ownerStartAddr() const
Return owner start addressing.