LduMatrixATmul.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 "LduMatrix.H"
30 
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 
33 template<class Type, class DType, class LUType>
35 (
36  Field<Type>& Apsi,
37  const tmp<Field<Type>>& tpsi
38 ) const
39 {
40  Type* __restrict__ ApsiPtr = Apsi.begin();
41 
42  const Field<Type>& psi = tpsi();
43  const Type* const __restrict__ psiPtr = psi.begin();
44 
45  const DType* const __restrict__ diagPtr = diag().begin();
46 
47  const label* const __restrict__ uPtr = lduAddr().upperAddr().begin();
48  const label* const __restrict__ lPtr = lduAddr().lowerAddr().begin();
49 
50  const LUType* const __restrict__ upperPtr = upper().begin();
51  const LUType* const __restrict__ lowerPtr = lower().begin();
52 
53  const label startRequest = UPstream::nRequests();
54 
55  // Initialise the update of interfaced interfaces
56  initMatrixInterfaces
57  (
58  true,
59  interfacesUpper_,
60  psi,
61  Apsi
62  );
63 
64  const label nCells = diag().size();
65  for (label cell=0; cell<nCells; cell++)
66  {
67  ApsiPtr[cell] = dot(diagPtr[cell], psiPtr[cell]);
68  }
69 
70 
71  const label nFaces = upper().size();
72  for (label face=0; face<nFaces; face++)
73  {
74  ApsiPtr[uPtr[face]] += dot(lowerPtr[face], psiPtr[lPtr[face]]);
75  ApsiPtr[lPtr[face]] += dot(upperPtr[face], psiPtr[uPtr[face]]);
76  }
77 
78  // Update interface interfaces
79  updateMatrixInterfaces
80  (
81  true,
82  interfacesUpper_,
83  psi,
84  Apsi,
85  startRequest
86  );
87 
88  tpsi.clear();
89 }
90 
91 
92 template<class Type, class DType, class LUType>
94 (
95  Field<Type>& Tpsi,
96  const tmp<Field<Type>>& tpsi
97 ) const
98 {
99  Type* __restrict__ TpsiPtr = Tpsi.begin();
100 
101  const Field<Type>& psi = tpsi();
102  const Type* const __restrict__ psiPtr = psi.begin();
103 
104  const DType* const __restrict__ diagPtr = diag().begin();
105 
106  const label* const __restrict__ uPtr = lduAddr().upperAddr().begin();
107  const label* const __restrict__ lPtr = lduAddr().lowerAddr().begin();
108 
109  const LUType* const __restrict__ lowerPtr = lower().begin();
110  const LUType* const __restrict__ upperPtr = upper().begin();
111 
112  const label startRequest = UPstream::nRequests();
113 
114  // Initialise the update of interfaced interfaces
115  initMatrixInterfaces
116  (
117  true,
118  interfacesLower_,
119  psi,
120  Tpsi
121  );
122 
123  const label nCells = diag().size();
124  for (label cell=0; cell<nCells; cell++)
125  {
126  TpsiPtr[cell] = dot(diagPtr[cell], psiPtr[cell]);
127  }
128 
129  const label nFaces = upper().size();
130  for (label face=0; face<nFaces; face++)
131  {
132  TpsiPtr[uPtr[face]] += dot(upperPtr[face], psiPtr[lPtr[face]]);
133  TpsiPtr[lPtr[face]] += dot(lowerPtr[face], psiPtr[uPtr[face]]);
134  }
135 
136  // Update interface interfaces
137  updateMatrixInterfaces
138  (
139  true,
140  interfacesLower_,
141  psi,
142  Tpsi,
143  startRequest
144  );
146  tpsi.clear();
147 }
148 
149 
150 template<class Type, class DType, class LUType>
152 (
153  Field<Type>& sumA
154 ) const
155 {
156  Type* __restrict__ sumAPtr = sumA.begin();
157 
158  const DType* __restrict__ diagPtr = diag().begin();
159 
160  const label* __restrict__ uPtr = lduAddr().upperAddr().begin();
161  const label* __restrict__ lPtr = lduAddr().lowerAddr().begin();
162 
163  const LUType* __restrict__ lowerPtr = lower().begin();
164  const LUType* __restrict__ upperPtr = upper().begin();
165 
166  const label nCells = diag().size();
167  const label nFaces = upper().size();
168 
169  for (label cell=0; cell<nCells; cell++)
170  {
171  sumAPtr[cell] = dot(diagPtr[cell], pTraits<Type>::one);
172  }
173 
174  for (label face=0; face<nFaces; face++)
175  {
176  sumAPtr[uPtr[face]] += dot(lowerPtr[face], pTraits<Type>::one);
177  sumAPtr[lPtr[face]] += dot(upperPtr[face], pTraits<Type>::one);
178  }
179 
180  // Add the interface internal coefficients to diagonal
181  // and the interface boundary coefficients to the sum-off-diagonal
182  forAll(interfaces_, patchi)
183  {
184  if (interfaces_.set(patchi))
185  {
186  const labelUList& pa = lduAddr().patchAddr(patchi);
187  const Field<LUType>& pCoeffs = interfacesUpper_[patchi];
188 
189  forAll(pa, face)
190  {
191  sumAPtr[pa[face]] -= dot(pCoeffs[face], pTraits<Type>::one);
192  }
193  }
194  }
195 }
196 
197 
198 template<class Type, class DType, class LUType>
200 (
201  Field<Type>& rA,
202  const Field<Type>& psi
203 ) const
204 {
205  Type* __restrict__ rAPtr = rA.begin();
206 
207  const Type* const __restrict__ psiPtr = psi.begin();
208  const DType* const __restrict__ diagPtr = diag().begin();
209  const Type* const __restrict__ sourcePtr = source().begin();
210 
211  const label* const __restrict__ uPtr = lduAddr().upperAddr().begin();
212  const label* const __restrict__ lPtr = lduAddr().lowerAddr().begin();
213 
214  const LUType* const __restrict__ upperPtr = upper().begin();
215  const LUType* const __restrict__ lowerPtr = lower().begin();
216 
217  // Parallel boundary initialisation.
218  // Note: there is a change of sign in the coupled
219  // interface update to add the contibution to the r.h.s.
220 
221  const label startRequest = UPstream::nRequests();
222 
223  // Initialise the update of interfaced interfaces
224  initMatrixInterfaces
225  (
226  false, // negate interface contributions
227  interfacesUpper_,
228  psi,
229  rA
230  );
231 
232  const label nCells = diag().size();
233  for (label cell=0; cell<nCells; cell++)
234  {
235  rAPtr[cell] = sourcePtr[cell] - dot(diagPtr[cell], psiPtr[cell]);
236  }
237 
238 
239  const label nFaces = upper().size();
240  for (label face=0; face<nFaces; face++)
241  {
242  rAPtr[uPtr[face]] -= dot(lowerPtr[face], psiPtr[lPtr[face]]);
243  rAPtr[lPtr[face]] -= dot(upperPtr[face], psiPtr[uPtr[face]]);
244  }
245 
246  // Update interface interfaces
247  updateMatrixInterfaces
248  (
249  false,
250  interfacesUpper_,
251  psi,
252  rA,
253  startRequest
254  );
255 }
256 
257 
258 template<class Type, class DType, class LUType>
260 (
261  const Field<Type>& psi
262 ) const
263 {
264  auto trA = tmp<Field<Type>>::New(psi.size());
265  residual(trA.ref(), psi);
266  return trA;
267 }
268 
269 
270 // ************************************************************************* //
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:68
A traits class, which is primarily used for primitives and vector-space.
Definition: pTraits.H:75
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
Definition: stringOps.C:1187
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
void sumA(Field< Type > &) const
Sum the coefficients on each row of the matrix.
void dot(FieldField< Field1, typename innerProduct< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
void Amul(Field< Type > &, const tmp< Field< Type >> &) const
Matrix multiplication.
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
Generic templated field type.
Definition: Field.H:62
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:391
void residual(Field< Type > &rA, const Field< Type > &psi) const
void Tmul(Field< Type > &, const tmp< Field< Type >> &) const
Matrix transpose multiplication.
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
Definition: stringOps.C:1171
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:53
const volScalarField & psi
A class for managing temporary objects.
Definition: HashPtrTable.H:50