Loading...
Searching...
No Matches
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-------------------------------------------------------------------------------
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
33template<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
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
80 (
81 true,
82 interfacesUpper_,
83 psi,
84 Apsi,
85 startRequest
86 );
87
88 tpsi.clear();
89}
90
91
92template<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 );
145
146 tpsi.clear();
147}
148
149
150template<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);
193 }
194 }
195}
196
197
198template<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
258template<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// ************************************************************************* //
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Definition Field.H:172
void Amul(Field< Type > &, const tmp< Field< Type > > &) const
Matrix multiplication.
const Field< LUType > & upper() const
Definition LduMatrix.C:178
void sumA(Field< Type > &) const
Sum the coefficients on each row of the matrix.
const lduAddressing & lduAddr() const
Return the LDU addressing.
Definition LduMatrix.H:616
const Field< Type > & source() const
Definition LduMatrix.C:267
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.
const Field< DType > & diag() const
Definition LduMatrix.C:151
void residual(Field< Type > &rA, const Field< Type > &psi) const
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 Tmul(Field< Type > &, const tmp< Field< Type > > &) const
Matrix transpose multiplication.
const Field< LUType > & lower() const
Definition LduMatrix.C:223
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 cell is defined as a list of faces with extra functionality.
Definition cell.H:56
A face is a list of labels corresponding to mesh vertices.
Definition face.H:71
A traits class, which is primarily used for primitives and vector-space.
Definition pTraits.H:64
A class for managing temporary objects.
Definition tmp.H:75
const volScalarField & psi
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
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.
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 > &)
UList< label > labelUList
A UList of labels.
Definition UList.H:75
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299