Loading...
Searching...
No Matches
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-------------------------------------------------------------------------------
11License
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
30
31// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
32
33template<class Type, class DType, class LUType>
35(
36 const word& fieldName,
38)
39:
40 LduMatrix<Type, DType, LUType>::smoother
41 (
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
60template<class Type, class DType, class LUType>
62(
63 const word& fieldName_,
64 Field<Type>& psi,
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
154template<class Type, class DType, class LUType>
156(
158 const label nSweeps
159) const
160{
161 smooth(this->fieldName_, psi, this->matrix_, rD_, nSweeps);
162}
163
164
165// ************************************************************************* //
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Definition Field.H:172
smoother(const word &fieldName, const LduMatrix< Type, DType, LUType > &matrix)
Construct for given field name and matrix.
const LduMatrix< Type, DType, LUType > & matrix() const noexcept
Definition LduMatrix.H:423
const LduMatrix< Type, DType, LUType > & matrix_
Definition LduMatrix.H:341
const word & fieldName() const noexcept
Definition LduMatrix.H:418
LduMatrix is a general matrix class in which the coefficients are stored as three arrays,...
Definition LduMatrix.H:84
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.
TGaussSeidelSmoother(const word &fieldName, const LduMatrix< Type, DType, LUType > &matrix)
Construct from components.
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition UListI.H:410
static label nRequests() noexcept
Number of outstanding requests (on the internal list of requests).
A class for handling words, derived from Foam::string.
Definition word.H:66
const volScalarField & psi
void smooth(volScalarField &field, const scalar coeff)
Definition fvcSmooth.C:37
void dot(FieldField< Field1, typename innerProduct< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)