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-2019 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
29#include "LduMatrix.H"
30
31// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32
33namespace Foam
34{
35
36template<class Type, class LUType>
38:
39 public LduInterfaceField<Type>::Amultiplier
40{
41 const Field<LUType>& A_;
42
43public:
44
46 :
47 A_(A)
48 {}
49
50 virtual ~Amultiplier() = default;
51
52 virtual void addAmul(Field<Type>& Apsi, const Field<Type>& psi) const
53 {
54 Apsi += A_*psi;
55 }
56};
57
58}
59
60
61// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
62
63template<class Type, class DType, class LUType>
65(
66 Field<Type>& Apsi,
67 const tmp<Field<Type>>& tpsi
68) const
69{
70 Type* __restrict__ ApsiPtr = Apsi.begin();
71
72 const Field<Type>& psi = tpsi();
73 const Type* const __restrict__ psiPtr = psi.begin();
74
75 const DType* const __restrict__ diagPtr = diag().begin();
76
77 const label* const __restrict__ uPtr = lduAddr().upperAddr().begin();
78 const label* const __restrict__ lPtr = lduAddr().lowerAddr().begin();
79
80 const LUType* const __restrict__ upperPtr = upper().begin();
81 const LUType* const __restrict__ lowerPtr = lower().begin();
82
83 // Initialise the update of interfaced interfaces
84 initMatrixInterfaces
85 (
86 true,
87 interfacesUpper_,
88 psi,
89 Apsi
90 );
91
92 const label nCells = diag().size();
93 for (label cell=0; cell<nCells; cell++)
94 {
95 ApsiPtr[cell] = dot(diagPtr[cell], psiPtr[cell]);
96 }
97
98
99 const label nFaces = upper().size();
100 for (label face=0; face<nFaces; face++)
101 {
102 ApsiPtr[uPtr[face]] += dot(lowerPtr[face], psiPtr[lPtr[face]]);
103 ApsiPtr[lPtr[face]] += dot(upperPtr[face], psiPtr[uPtr[face]]);
104 }
105
106 // Update interface interfaces
107 updateMatrixInterfaces
108 (
109 true,
110 interfacesUpper_,
111 psi,
112 Apsi
113 );
114
115 tpsi.clear();
116}
117
118
119template<class Type, class DType, class LUType>
121(
122 Field<Type>& Tpsi,
123 const tmp<Field<Type>>& tpsi
124) const
125{
126 Type* __restrict__ TpsiPtr = Tpsi.begin();
127
128 const Field<Type>& psi = tpsi();
129 const Type* const __restrict__ psiPtr = psi.begin();
130
131 const DType* const __restrict__ diagPtr = diag().begin();
132
133 const label* const __restrict__ uPtr = lduAddr().upperAddr().begin();
134 const label* const __restrict__ lPtr = lduAddr().lowerAddr().begin();
135
136 const LUType* const __restrict__ lowerPtr = lower().begin();
137 const LUType* const __restrict__ upperPtr = upper().begin();
138
139 // Initialise the update of interfaced interfaces
140 initMatrixInterfaces
141 (
142 true,
143 interfacesLower_,
144 psi,
145 Tpsi
146 );
147
148 const label nCells = diag().size();
149 for (label cell=0; cell<nCells; cell++)
150 {
151 TpsiPtr[cell] = dot(diagPtr[cell], psiPtr[cell]);
152 }
153
154 const label nFaces = upper().size();
155 for (label face=0; face<nFaces; face++)
156 {
157 TpsiPtr[uPtr[face]] += dot(upperPtr[face], psiPtr[lPtr[face]]);
158 TpsiPtr[lPtr[face]] += dot(lowerPtr[face], psiPtr[uPtr[face]]);
159 }
160
161 // Update interface interfaces
162 updateMatrixInterfaces
163 (
164 true,
165 interfacesLower_,
166 psi,
167 Tpsi
168 );
169
170 tpsi.clear();
171}
172
173
174template<class Type, class DType, class LUType>
176(
177 Field<Type>& sumA
178) const
179{
180 Type* __restrict__ sumAPtr = sumA.begin();
181
182 const DType* __restrict__ diagPtr = diag().begin();
183
184 const label* __restrict__ uPtr = lduAddr().upperAddr().begin();
185 const label* __restrict__ lPtr = lduAddr().lowerAddr().begin();
186
187 const LUType* __restrict__ lowerPtr = lower().begin();
188 const LUType* __restrict__ upperPtr = upper().begin();
189
190 const label nCells = diag().size();
191 const label nFaces = upper().size();
192
193 for (label cell=0; cell<nCells; cell++)
194 {
195 sumAPtr[cell] = dot(diagPtr[cell], pTraits<Type>::one);
196 }
197
198 for (label face=0; face<nFaces; face++)
199 {
200 sumAPtr[uPtr[face]] += dot(lowerPtr[face], pTraits<Type>::one);
201 sumAPtr[lPtr[face]] += dot(upperPtr[face], pTraits<Type>::one);
202 }
203
204 // Add the interface internal coefficients to diagonal
205 // and the interface boundary coefficients to the sum-off-diagonal
206 forAll(interfaces_, patchi)
207 {
208 if (interfaces_.set(patchi))
209 {
210 const labelUList& pa = lduAddr().patchAddr(patchi);
211 const Field<LUType>& pCoeffs = interfacesUpper_[patchi];
212
213 forAll(pa, face)
214 {
215 sumAPtr[pa[face]] -= dot(pCoeffs[face], pTraits<Type>::one);
216 }
217 }
218 }
219}
220
221
222template<class Type, class DType, class LUType>
224(
225 Field<Type>& rA,
226 const Field<Type>& psi
227) const
228{
229 Type* __restrict__ rAPtr = rA.begin();
230
231 const Type* const __restrict__ psiPtr = psi.begin();
232 const DType* const __restrict__ diagPtr = diag().begin();
233 const Type* const __restrict__ sourcePtr = source().begin();
234
235 const label* const __restrict__ uPtr = lduAddr().upperAddr().begin();
236 const label* const __restrict__ lPtr = lduAddr().lowerAddr().begin();
237
238 const LUType* const __restrict__ upperPtr = upper().begin();
239 const LUType* const __restrict__ lowerPtr = lower().begin();
240
241 // Parallel boundary initialisation.
242 // Note: there is a change of sign in the coupled
243 // interface update to add the contibution to the r.h.s.
244
245 // Initialise the update of interfaced interfaces
246 initMatrixInterfaces
247 (
248 false, // negate interface contributions
249 interfacesUpper_,
250 psi,
251 rA
252 );
253
254 const label nCells = diag().size();
255 for (label cell=0; cell<nCells; cell++)
256 {
257 rAPtr[cell] = sourcePtr[cell] - dot(diagPtr[cell], psiPtr[cell]);
258 }
259
260
261 const label nFaces = upper().size();
262 for (label face=0; face<nFaces; face++)
263 {
264 rAPtr[uPtr[face]] -= dot(lowerPtr[face], psiPtr[lPtr[face]]);
265 rAPtr[lPtr[face]] -= dot(upperPtr[face], psiPtr[uPtr[face]]);
266 }
267
268 // Update interface interfaces
269 updateMatrixInterfaces
270 (
271 false,
272 interfacesUpper_,
273 psi,
274 rA
275 );
276}
277
278
279template<class Type, class DType, class LUType>
281(
282 const Field<Type>& psi
283) const
284{
285 tmp<Field<Type>> trA(new Field<Type>(psi.size()));
286 residual(trA.ref(), psi);
287 return trA;
288}
289
290
291// ************************************************************************* //
static const Foam::dimensionedScalar A("", Foam::dimPressure, 611.21)
Amultiplier(const Field< LUType > &A)
virtual void addAmul(Field< Type > &Apsi, const Field< Type > &psi) const
virtual ~Amultiplier()=default
Generic templated field type.
Definition: Field.H:82
An abstract base class for implicitly-coupled interface fields e.g. processor and cyclic patch fields...
void Amul(Field< Type > &, const tmp< Field< Type > > &) const
Matrix multiplication.
void sumA(Field< Type > &) const
Sum the coefficients on each row of the matrix.
void Tmul(Field< Type > &, const tmp< Field< Type > > &) const
Matrix transpose multiplication.
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:329
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:57
tmp< Field< Type > > residual() const
Return the matrix residual.
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:62
A class for managing temporary objects.
Definition: tmp.H:65
T & ref() const
Definition: tmpI.H:227
const volScalarField & psi
const labelList nFaces(UPstream::listGatherValues< label >(aMesh.nFaces()))
Namespace for OpenFOAM.
void dot(FieldField< Field1, typename innerProduct< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333