LduMatrixOperations.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) 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
33template<class Type, class DType, class LUType>
35{
36 const Field<LUType>& Lower = const_cast<const LduMatrix&>(*this).lower();
37 const Field<LUType>& Upper = const_cast<const LduMatrix&>(*this).upper();
38 Field<DType>& Diag = diag();
39
40 const labelUList& l = lduAddr().lowerAddr();
41 const labelUList& u = lduAddr().upperAddr();
42
43 for (label face=0; face<l.size(); face++)
44 {
45 Diag[l[face]] += Lower[face];
46 Diag[u[face]] += Upper[face];
47 }
48}
49
50
51template<class Type, class DType, class LUType>
53{
54 const Field<LUType>& Lower = const_cast<const LduMatrix&>(*this).lower();
55 const Field<LUType>& Upper = const_cast<const LduMatrix&>(*this).upper();
56 Field<DType>& Diag = diag();
57
58 const labelUList& l = lduAddr().lowerAddr();
59 const labelUList& u = lduAddr().upperAddr();
60
61 for (label face=0; face<l.size(); face++)
62 {
63 Diag[l[face]] -= Lower[face];
64 Diag[u[face]] -= Upper[face];
65 }
66}
67
68
69template<class Type, class DType, class LUType>
71(
72 Field<LUType>& sumOff
73) const
74{
75 const Field<LUType>& Lower = const_cast<const LduMatrix&>(*this).lower();
76 const Field<LUType>& Upper = const_cast<const LduMatrix&>(*this).upper();
77
78 const labelUList& l = lduAddr().lowerAddr();
79 const labelUList& u = lduAddr().upperAddr();
80
81 for (label face = 0; face < l.size(); face++)
82 {
83 sumOff[u[face]] += cmptMag(Lower[face]);
84 sumOff[l[face]] += cmptMag(Upper[face]);
85 }
86}
87
88
89template<class Type, class DType, class LUType>
92{
93 tmp<Field<Type>> tHpsi
94 (
95 new Field<Type>(lduAddr().size(), Zero)
96 );
97
98 if (lowerPtr_ || upperPtr_)
99 {
100 Field<Type> & Hpsi = tHpsi();
101
102 Type* __restrict__ HpsiPtr = Hpsi.begin();
103
104 const Type* __restrict__ psiPtr = psi.begin();
105
106 const label* __restrict__ uPtr = lduAddr().upperAddr().begin();
107 const label* __restrict__ lPtr = lduAddr().lowerAddr().begin();
108
109 const LUType* __restrict__ lowerPtr = lower().begin();
110 const LUType* __restrict__ upperPtr = upper().begin();
111
112 const label nFaces = upper().size();
113
114 for (label face=0; face<nFaces; face++)
115 {
116 HpsiPtr[uPtr[face]] -= lowerPtr[face]*psiPtr[lPtr[face]];
117 HpsiPtr[lPtr[face]] -= upperPtr[face]*psiPtr[uPtr[face]];
118 }
119 }
120
121 return tHpsi;
122}
123
124template<class Type, class DType, class LUType>
127{
128 tmp<Field<Type>> tHpsi(H(tpsi()));
129 tpsi.clear();
130 return tHpsi;
131}
132
133
134template<class Type, class DType, class LUType>
137{
138 const Field<LUType>& Lower = const_cast<const LduMatrix&>(*this).lower();
139 const Field<LUType>& Upper = const_cast<const LduMatrix&>(*this).upper();
140
141 // Take references to addressing
142 const labelUList& l = lduAddr().lowerAddr();
143 const labelUList& u = lduAddr().upperAddr();
144
145 tmp<Field<Type>> tfaceHpsi(new Field<Type> (Lower.size()));
146 Field<Type> & faceHpsi = tfaceHpsi();
147
148 for (label face=0; face<l.size(); face++)
149 {
150 faceHpsi[face] = Upper[face]*psi[u[face]] - Lower[face]*psi[l[face]];
151 }
152
153 return tfaceHpsi;
154}
155
156
157template<class Type, class DType, class LUType>
160{
161 tmp<Field<Type>> tfaceHpsi(faceH(tpsi()));
162 tpsi.clear();
163 return tfaceHpsi;
164}
165
166
167// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
168
169template<class Type, class DType, class LUType>
171{
172 if (this == &A)
173 {
174 return; // Self-assignment is a no-op
175 }
176
177 if (A.diagPtr_)
178 {
179 diag() = A.diag();
180 }
181
182 if (A.upperPtr_)
183 {
184 upper() = A.upper();
185 }
186 else if (upperPtr_)
187 {
188 delete upperPtr_;
189 upperPtr_ = nullptr;
190 }
191
192 if (A.lowerPtr_)
193 {
194 lower() = A.lower();
195 }
196 else if (lowerPtr_)
197 {
198 delete lowerPtr_;
199 lowerPtr_ = nullptr;
200 }
201
202 if (A.sourcePtr_)
203 {
204 source() = A.source();
205 }
206
207 interfacesUpper_ = A.interfacesUpper_;
208 interfacesLower_ = A.interfacesLower_;
209}
210
211
212template<class Type, class DType, class LUType>
214{
215 if (diagPtr_)
216 {
217 diagPtr_->negate();
218 }
219
220 if (upperPtr_)
221 {
222 upperPtr_->negate();
223 }
224
225 if (lowerPtr_)
226 {
227 lowerPtr_->negate();
228 }
229
230 if (sourcePtr_)
231 {
232 sourcePtr_->negate();
233 }
234
235 negate(interfacesUpper_);
236 negate(interfacesLower_);
237}
238
239
240template<class Type, class DType, class LUType>
242{
243 if (A.diagPtr_)
244 {
245 diag() += A.diag();
246 }
247
248 if (A.sourcePtr_)
249 {
250 source() += A.source();
251 }
252
253 if (symmetric() && A.symmetric())
254 {
255 upper() += A.upper();
256 }
257 else if (symmetric() && A.asymmetric())
258 {
259 if (upperPtr_)
260 {
261 lower();
262 }
263 else
264 {
265 upper();
266 }
267
268 upper() += A.upper();
269 lower() += A.lower();
270 }
271 else if (asymmetric() && A.symmetric())
272 {
273 if (A.upperPtr_)
274 {
275 lower() += A.upper();
276 upper() += A.upper();
277 }
278 else
279 {
280 lower() += A.lower();
281 upper() += A.lower();
282 }
283
284 }
285 else if (asymmetric() && A.asymmetric())
286 {
287 lower() += A.lower();
288 upper() += A.upper();
289 }
290 else if (diagonal())
291 {
292 if (A.upperPtr_)
293 {
294 upper() = A.upper();
295 }
296
297 if (A.lowerPtr_)
298 {
299 lower() = A.lower();
300 }
301 }
302 else if (A.diagonal())
303 {
304 }
305 else
306 {
308 << "Unknown matrix type combination"
309 << abort(FatalError);
310 }
311
312 interfacesUpper_ += A.interfacesUpper_;
313 interfacesLower_ += A.interfacesLower_;
314}
315
316
317template<class Type, class DType, class LUType>
319{
320 if (A.diagPtr_)
321 {
322 diag() -= A.diag();
323 }
324
325 if (A.sourcePtr_)
326 {
327 source() -= A.source();
328 }
329
330 if (symmetric() && A.symmetric())
331 {
332 upper() -= A.upper();
333 }
334 else if (symmetric() && A.asymmetric())
335 {
336 if (upperPtr_)
337 {
338 lower();
339 }
340 else
341 {
342 upper();
343 }
344
345 upper() -= A.upper();
346 lower() -= A.lower();
347 }
348 else if (asymmetric() && A.symmetric())
349 {
350 if (A.upperPtr_)
351 {
352 lower() -= A.upper();
353 upper() -= A.upper();
354 }
355 else
356 {
357 lower() -= A.lower();
358 upper() -= A.lower();
359 }
360
361 }
362 else if (asymmetric() && A.asymmetric())
363 {
364 lower() -= A.lower();
365 upper() -= A.upper();
366 }
367 else if (diagonal())
368 {
369 if (A.upperPtr_)
370 {
371 upper() = -A.upper();
372 }
373
374 if (A.lowerPtr_)
375 {
376 lower() = -A.lower();
377 }
378 }
379 else if (A.diagonal())
380 {
381 }
382 else
383 {
385 << "Unknown matrix type combination"
386 << abort(FatalError);
387 }
388
389 interfacesUpper_ -= A.interfacesUpper_;
390 interfacesLower_ -= A.interfacesLower_;
391}
392
393
394template<class Type, class DType, class LUType>
396(
397 const scalarField& sf
398)
399{
400 if (diagPtr_)
401 {
402 *diagPtr_ *= sf;
403 }
404
405 if (sourcePtr_)
406 {
407 *sourcePtr_ *= sf;
408 }
409
410 // Non-uniform scaling causes a symmetric matrix
411 // to become asymmetric
412 if (symmetric() || asymmetric())
413 {
414 Field<LUType>& upper = this->upper();
415 Field<LUType>& lower = this->lower();
416
417 const labelUList& l = lduAddr().lowerAddr();
418 const labelUList& u = lduAddr().upperAddr();
419
420 for (label face=0; face<upper.size(); face++)
421 {
422 upper[face] *= sf[l[face]];
423 }
424
425 for (label face=0; face<lower.size(); face++)
426 {
427 lower[face] *= sf[u[face]];
428 }
429 }
430
432 << "Scaling a matrix by scalarField is not currently supported\n"
433 "because scaling interfacesUpper_ and interfacesLower_ "
434 "require special transfers"
435 << abort(FatalError);
436
437 //interfacesUpper_ *= ;
438 //interfacesLower_ *= sf;
439}
440
441
442template<class Type, class DType, class LUType>
444{
445 if (diagPtr_)
446 {
447 *diagPtr_ *= s;
448 }
449
450 if (sourcePtr_)
451 {
452 *sourcePtr_ *= s;
453 }
454
455 if (upperPtr_)
456 {
457 *upperPtr_ *= s;
458 }
459
460 if (lowerPtr_)
461 {
462 *lowerPtr_ *= s;
463 }
464
465 interfacesUpper_ *= s;
466 interfacesLower_ *= s;
467}
468
469
470// ************************************************************************* //
static const Foam::dimensionedScalar A("", Foam::dimPressure, 611.21)
Generic templated field type.
Definition: Field.H:82
LduMatrix is a general matrix class in which the coefficients are stored as three arrays,...
Definition: LduMatrix.H:88
Field< LUType > & upper()
Definition: LduMatrix.C:204
void operator+=(const LduMatrix< Type, DType, LUType > &)
void operator=(const LduMatrix< Type, DType, LUType > &)
void operator*=(const scalarField &)
void sumMagOffDiag(Field< LUType > &sumOff) const
tmp< Field< Type > > faceH(const Field< Type > &) const
void operator-=(const LduMatrix< Type, DType, LUType > &)
Field< LUType > & lower()
Definition: LduMatrix.C:227
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:329
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
tmp< GeometricField< Type, faPatchField, areaMesh > > H() const
Return the H operation source.
Definition: faMatrix.C:633
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
A class for managing temporary objects.
Definition: tmp.H:65
const volScalarField & psi
volScalarField H(IOobject("H", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), mesh, dimensionedScalar(dimLength, Zero))
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
const labelList nFaces(UPstream::listGatherValues< label >(aMesh.nFaces()))
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
void negate(FieldField< Field, Type > &res, const FieldField< Field, Type > &f)
errorManip< error > abort(error &err)
Definition: errorManip.H:144
error FatalError
void cmptMag(FieldField< Field, Type > &cf, const FieldField< Field, Type > &f)
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)