nonBlockingGaussSeidelSmoother.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-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 
30 #include "PrecisionAdaptor.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36  defineTypeNameAndDebug(nonBlockingGaussSeidelSmoother, 0);
37 
38  lduMatrix::smoother::
39  addsymMatrixConstructorToTable<nonBlockingGaussSeidelSmoother>
41 
42  lduMatrix::smoother::
43  addasymMatrixConstructorToTable<nonBlockingGaussSeidelSmoother>
45 }
46 
47 
48 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
49 
51 (
52  const word& fieldName,
53  const lduMatrix& matrix,
54  const FieldField<Field, scalar>& interfaceBouCoeffs,
55  const FieldField<Field, scalar>& interfaceIntCoeffs,
56  const lduInterfaceFieldPtrsList& interfaces
57 )
58 :
60  (
61  fieldName,
62  matrix,
63  interfaceBouCoeffs,
64  interfaceIntCoeffs,
65  interfaces
66  )
67 {
68  // Check that all interface addressing is sorted to be after the
69  // non-interface addressing.
70 
71  const label nCells = matrix.diag().size();
72 
73  blockStart_ = nCells;
74 
75  labelList startCelli(interfaceBouCoeffs.size(), -1);
76  forAll(interfaces, patchi)
77  {
78  if (interfaces.set(patchi))
79  {
80  const labelUList& faceCells = matrix_.lduAddr().patchAddr(patchi);
81 
82  blockStart_ = min(blockStart_, min(faceCells));
83  }
84  }
85 
86  if (debug)
87  {
88  Pout<< "nonBlockingGaussSeidelSmoother :"
89  << " Starting block on cell " << blockStart_
90  << " out of " << nCells << endl;
91  }
92 }
93 
94 
95 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
96 
98 (
99  const word& fieldName_,
101  const lduMatrix& matrix_,
102  const label blockStart,
103  const solveScalarField& source,
104  const FieldField<Field, scalar>& interfaceBouCoeffs_,
105  const lduInterfaceFieldPtrsList& interfaces_,
106  const direction cmpt,
107  const label nSweeps
108 )
109 {
110  solveScalar* __restrict__ psiPtr = psi.begin();
111 
112  const label nCells = psi.size();
113 
114  solveScalarField bPrime(nCells);
115  solveScalar* __restrict__ bPrimePtr = bPrime.begin();
116 
117  const scalar* const __restrict__ diagPtr = matrix_.diag().begin();
118  const scalar* const __restrict__ upperPtr =
119  matrix_.upper().begin();
120  const scalar* const __restrict__ lowerPtr =
121  matrix_.lower().begin();
122 
123  const label* const __restrict__ uPtr =
124  matrix_.lduAddr().upperAddr().begin();
125 
126  const label* const __restrict__ ownStartPtr =
127  matrix_.lduAddr().ownerStartAddr().begin();
128 
129  // Parallel boundary initialisation. The parallel boundary is treated
130  // as an effective jacobi interface in the boundary.
131  // Note: there is a change of sign in the coupled
132  // interface update. The reason for this is that the
133  // internal coefficients are all located at the l.h.s. of
134  // the matrix whereas the "implicit" coefficients on the
135  // coupled boundaries are all created as if the
136  // coefficient contribution is of a source-kind (i.e. they
137  // have a sign as if they are on the r.h.s. of the matrix.
138  // To compensate for this, it is necessary to turn the
139  // sign of the contribution.
140 
141  for (label sweep=0; sweep<nSweeps; sweep++)
142  {
143  bPrime = source;
144 
145  matrix_.initMatrixInterfaces
146  (
147  false,
148  interfaceBouCoeffs_,
149  interfaces_,
150  psi,
151  bPrime,
152  cmpt
153  );
154 
155  solveScalar curPsi;
156  label fStart;
157  label fEnd = ownStartPtr[0];
158 
159  for (label celli=0; celli<blockStart; celli++)
160  {
161  // Start and end of this row
162  fStart = fEnd;
163  fEnd = ownStartPtr[celli + 1];
164 
165  // Get the accumulated neighbour side
166  curPsi = bPrimePtr[celli];
167 
168  // Accumulate the owner product side
169  for (label curFace=fStart; curFace<fEnd; curFace++)
170  {
171  curPsi -= upperPtr[curFace]*psiPtr[uPtr[curFace]];
172  }
173 
174  // Finish current psi
175  curPsi /= diagPtr[celli];
176 
177  // Distribute the neighbour side using current psi
178  for (label curFace=fStart; curFace<fEnd; curFace++)
179  {
180  bPrimePtr[uPtr[curFace]] -= lowerPtr[curFace]*curPsi;
181  }
182 
183  psiPtr[celli] = curPsi;
184  }
185 
186  matrix_.updateMatrixInterfaces
187  (
188  false,
189  interfaceBouCoeffs_,
190  interfaces_,
191  psi,
192  bPrime,
193  cmpt
194  );
195 
196  // Update rest of the cells
197  for (label celli=blockStart; celli < nCells; celli++)
198  {
199  // Start and end of this row
200  fStart = fEnd;
201  fEnd = ownStartPtr[celli + 1];
202 
203  // Get the accumulated neighbour side
204  curPsi = bPrimePtr[celli];
205 
206  // Accumulate the owner product side
207  for (label curFace=fStart; curFace<fEnd; curFace++)
208  {
209  curPsi -= upperPtr[curFace]*psiPtr[uPtr[curFace]];
210  }
211 
212  // Finish current psi
213  curPsi /= diagPtr[celli];
214 
215  // Distribute the neighbour side using current psi
216  for (label curFace=fStart; curFace<fEnd; curFace++)
217  {
218  bPrimePtr[uPtr[curFace]] -= lowerPtr[curFace]*curPsi;
219  }
220 
221  psiPtr[celli] = curPsi;
222  }
223  }
224 }
225 
226 
228 (
230  const solveScalarField& source,
231  const direction cmpt,
232  const label nSweeps
233 ) const
234 {
235  smooth
236  (
237  fieldName_,
238  psi,
239  matrix_,
240  blockStart_,
241  source,
242  interfaceBouCoeffs_,
243  interfaces_,
244  cmpt,
245  nSweeps
246  );
247 }
248 
249 
251 (
253  const scalarField& source,
254  const direction cmpt,
255  const label nSweeps
256 ) const
257 {
258  scalarSmooth
259  (
260  psi,
262  cmpt,
263  nSweeps
264  );
265 }
266 
267 
268 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::lduMatrix::lduAddr
const lduAddressing & lduAddr() const
Return the LDU addressing.
Definition: lduMatrix.H:572
Foam::addnonBlockingGaussSeidelSmootherSymMatrixConstructorToTable_
lduMatrix::smoother::addsymMatrixConstructorToTable< nonBlockingGaussSeidelSmoother > addnonBlockingGaussSeidelSmootherSymMatrixConstructorToTable_
Definition: nonBlockingGaussSeidelSmoother.C:40
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
Foam::nonBlockingGaussSeidelSmoother::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: nonBlockingGaussSeidelSmoother.C:228
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
Foam::nonBlockingGaussSeidelSmoother::nonBlockingGaussSeidelSmoother
nonBlockingGaussSeidelSmoother(const word &fieldName, const lduMatrix &matrix, const FieldField< Field, scalar > &interfaceBouCoeffs, const FieldField< Field, scalar > &interfaceIntCoeffs, const lduInterfaceFieldPtrsList &interfaces)
Construct from components.
Definition: nonBlockingGaussSeidelSmoother.C:51
Foam::UPtrList::set
const T * set(const label i) const
Return const pointer to element (if set) or nullptr.
Definition: UPtrListI.H:176
PrecisionAdaptor.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::Pout
prefixOSstream Pout
An Ostream wrapper for parallel output to std::cout.
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::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
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::List< label >
Foam::UList< label >
Foam::ConstPrecisionAdaptor
A const Field wrapper with possible data conversion.
Definition: PrecisionAdaptor.H:50
Foam::direction
uint8_t direction
Definition: direction.H:47
Foam::lduAddressing::patchAddr
virtual const labelUList & patchAddr(const label patchNo) const =0
Return patch to internal addressing given patch number.
Foam::addnonBlockingGaussSeidelSmootherAsymMatrixConstructorToTable_
lduMatrix::smoother::addasymMatrixConstructorToTable< nonBlockingGaussSeidelSmoother > addnonBlockingGaussSeidelSmootherAsymMatrixConstructorToTable_
Definition: nonBlockingGaussSeidelSmoother.C:44
psi
const volScalarField & psi
Definition: createFieldRefs.H:1
Foam::nonBlockingGaussSeidelSmoother::smooth
static void smooth(const word &fieldName, solveScalarField &psi, const lduMatrix &matrix, const label blockStart, 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: nonBlockingGaussSeidelSmoother.C:98
Foam::lduMatrix::lower
scalarField & lower()
Definition: lduMatrix.C:174
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::faceCells
Smooth ATC in cells next to a set of patches supplied by type.
Definition: faceCells.H:56
Foam::fvc::sweep
void sweep(volScalarField &field, const volScalarField &alpha, const label nLayers, const scalar alphaDiff=0.2)
Definition: fvcSmooth.C:224
nonBlockingGaussSeidelSmoother.H
Foam::fvc::smooth
void smooth(volScalarField &field, const scalar coeff)
Definition: fvcSmooth.C:37