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 -------------------------------------------------------------------------------
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  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 
51 template<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 
69 template<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 
89 template<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 
124 template<class Type, class DType, class LUType>
127 {
128  tmp<Field<Type>> tHpsi(H(tpsi()));
129  tpsi.clear();
130  return tHpsi;
131 }
132 
133 
134 template<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 
157 template<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 
169 template<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 
212 template<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 
240 template<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 
317 template<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 
394 template<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 
442 template<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 // ************************************************************************* //
Foam::LduMatrix::sumMagOffDiag
void sumMagOffDiag(Field< LUType > &sumOff) const
Definition: LduMatrixOperations.C:71
Foam::LduMatrix::operator=
void operator=(const LduMatrix< Type, DType, LUType > &)
Definition: LduMatrixOperations.C:170
s
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))
Definition: gmvOutputSpray.H:25
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::diag
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
Definition: pointPatchFieldFunctions.H:287
H
volScalarField H(IOobject("H", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), mesh, dimensionedScalar(dimLength, Zero))
Foam::LduMatrix
LduMatrix is a general matrix class in which the coefficients are stored as three arrays,...
Definition: LduMatrix.H:72
A
static const Foam::dimensionedScalar A("", Foam::dimPressure, 611.21)
Foam::LduMatrix::H
tmp< Field< Type > > H(const Field< Type > &) const
Definition: LduMatrixOperations.C:91
lduMatrix.H
Foam::LduMatrix::upper
Field< LUType > & upper()
Definition: LduMatrix.C:204
Foam::LduMatrix::operator-=
void operator-=(const LduMatrix< Type, DType, LUType > &)
Definition: LduMatrixOperations.C:318
Foam::cmptMag
void cmptMag(FieldField< Field, Type > &cf, const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:400
Foam::stringOps::lower
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
Definition: stringOps.C:1184
Foam::Field< LUType >
Foam::LduMatrix::negSumDiag
void negSumDiag()
Definition: LduMatrixOperations.C:52
Foam::LduMatrix::negate
void negate()
Definition: LduMatrixOperations.C:213
Foam::negate
void negate(FieldField< Field, Type > &res, const FieldField< Field, Type > &f)
Foam::LduMatrix::operator+=
void operator+=(const LduMatrix< Type, DType, LUType > &)
Definition: LduMatrixOperations.C:241
Foam::FatalError
error FatalError
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::LduMatrix::sumDiag
void sumDiag()
Definition: LduMatrixOperations.C:34
Foam::LduMatrix::operator*=
void operator*=(const scalarField &)
Definition: LduMatrixOperations.C:396
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::UList< label >
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Foam::stringOps::upper
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
Definition: stringOps.C:1200
psi
const volScalarField & psi
Definition: createFieldRefs.H:1
Foam::LduMatrix::faceH
tmp< Field< Type > > faceH(const Field< Type > &) const
Definition: LduMatrixOperations.C:136
Foam::LduMatrix::lower
Field< LUType > & lower()
Definition: LduMatrix.C:227