LduMatrix.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) 2024 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 #include "IOstreams.H"
31 
32 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
33 
34 template<class Type, class DType, class LUType>
36 :
37  lduMesh_(mesh)
38 {}
39 
40 
41 template<class Type, class DType, class LUType>
43 :
44  lduMesh_(A.lduMesh_)
45 {
46  if (A.diagPtr_)
47  {
48  diagPtr_ = std::make_unique<Field<DType>>(*(A.diagPtr_));
49  }
50 
51  if (A.upperPtr_)
52  {
53  upperPtr_ = std::make_unique<Field<LUType>>(*(A.upperPtr_));
54  }
55 
56  if (A.lowerPtr_)
57  {
58  lowerPtr_ = std::make_unique<Field<LUType>>(*(A.lowerPtr_));
59  }
60 
61  if (A.sourcePtr_)
62  {
63  sourcePtr_ = std::make_unique<Field<Type>>(*(A.sourcePtr_));
64  }
65 }
66 
67 
68 template<class Type, class DType, class LUType>
70 :
71  lduMesh_(A.lduMesh_),
72  diagPtr_(std::move(A.diagPtr_)),
73  lowerPtr_(std::move(A.lowerPtr_)),
74  upperPtr_(std::move(A.upperPtr_)),
75  sourcePtr_(std::move(A.sourcePtr_))
76 {
77  // Clear the old interfaces?
78 }
79 
80 
81 template<class Type, class DType, class LUType>
83 :
84  lduMesh_(A.lduMesh_)
85 {
86  if (reuse)
87  {
88  // Move assignment
89  diagPtr_ = std::move(A.diagPtr_);
90  upperPtr_ = std::move(A.upperPtr_);
91  lowerPtr_ = std::move(A.lowerPtr_);
92  sourcePtr_ = std::move(A.sourcePtr_);
93 
94  // Clear the old interfaces?
95  }
96  else
97  {
98  // Copy assignment
99  if (A.diagPtr_)
100  {
101  diagPtr_ = std::make_unique<Field<DType>>(*(A.diagPtr_));
102  }
103 
104  if (A.upperPtr_)
105  {
106  upperPtr_ = std::make_unique<Field<LUType>>(*(A.upperPtr_));
107  }
108 
109  if (A.lowerPtr_)
110  {
111  lowerPtr_ = std::make_unique<Field<LUType>>(*(A.lowerPtr_));
112  }
113 
114  if (A.sourcePtr_)
115  {
116  sourcePtr_ = std::make_unique<Field<Type>>(*(A.sourcePtr_));
117  }
118  }
119 }
120 
121 
122 template<class Type, class DType, class LUType>
124 (
125  const lduMesh& mesh,
126  Istream& is
127 )
128 :
129  lduMesh_(mesh),
130  diagPtr_(new Field<DType>(is)),
131  upperPtr_(new Field<LUType>(is)),
132  lowerPtr_(new Field<LUType>(is)),
133  sourcePtr_(new Field<Type>(is))
134 {}
135 
136 
137 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
138 
139 template<class Type, class DType, class LUType>
141 {
142  if (diagPtr_)
143  {
144  return
145  (
146  (!upperPtr_)
147  ? (!lowerPtr_ ? "diagonal" : "diagonal-lower")
148  : (!lowerPtr_ ? "symmetric" : "asymmetric")
149  );
150  }
152  // is empty (or just wrong)
153  return (!upperPtr_ && !lowerPtr_ ? "empty" : "ill-defined");
154 }
155 
156 
157 template<class Type, class DType, class LUType>
159 {
160  if (!diagPtr_)
161  {
163  << "diagPtr_ unallocated"
164  << abort(FatalError);
165  }
166 
167  return *diagPtr_;
168 }
169 
170 
171 template<class Type, class DType, class LUType>
173 {
174  if (!diagPtr_)
175  {
176  diagPtr_ =
177  std::make_unique<Field<DType>>(lduAddr().size(), Foam::zero{});
178  }
179 
180  return *diagPtr_;
181 }
182 
183 
184 template<class Type, class DType, class LUType>
186 {
187  if (upperPtr_)
188  {
189  return *upperPtr_;
190  }
191  else
192  {
193  if (!lowerPtr_)
194  {
196  << "lowerPtr_ and upperPtr_ unallocated"
197  << abort(FatalError);
198  }
200  return *lowerPtr_;
201  }
202 }
203 
204 
205 template<class Type, class DType, class LUType>
207 {
208  if (!upperPtr_)
209  {
210  if (lowerPtr_)
211  {
212  upperPtr_ = std::make_unique<Field<LUType>>(*lowerPtr_);
213  }
214  else
215  {
216  upperPtr_ =
217  std::make_unique<Field<LUType>>
218  (
219  lduAddr().lowerAddr().size(),
220  Foam::zero{}
221  );
222  }
223  }
224 
225  return *upperPtr_;
226 }
227 
228 
229 template<class Type, class DType, class LUType>
231 {
232  if (lowerPtr_)
233  {
234  return *lowerPtr_;
235  }
236  else
237  {
238  if (!upperPtr_)
239  {
241  << "lowerPtr_ and upperPtr_ unallocated"
242  << abort(FatalError);
243  }
245  return *upperPtr_;
246  }
247 }
248 
249 
250 template<class Type, class DType, class LUType>
252 {
253  if (!lowerPtr_)
254  {
255  if (upperPtr_)
256  {
257  lowerPtr_ = std::make_unique<Field<LUType>>(*upperPtr_);
258  }
259  else
260  {
261  lowerPtr_ = std::make_unique<Field<LUType>>
262  (
263  lduAddr().lowerAddr().size(),
264  Foam::zero{}
265  );
266  }
267  }
268 
269  return *lowerPtr_;
270 }
271 
272 
273 template<class Type, class DType, class LUType>
275 {
276  if (!sourcePtr_)
277  {
279  << "sourcePtr_ unallocated"
280  << abort(FatalError);
281  }
282 
283  return *sourcePtr_;
284 }
285 
286 
287 template<class Type, class DType, class LUType>
289 {
290  if (!sourcePtr_)
291  {
292  sourcePtr_ =
293  std::make_unique<Field<Type>>(lduAddr().size(), Foam::zero{});
294  }
295 
296  return *sourcePtr_;
297 }
298 
299 
300 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
301 
302 // template<class Type, class DType, class LUType>
303 // Foam::Ostream& Foam::operator<<
304 // (
305 // Ostream& os,
306 // const InfoProxy<Type, DType, LUType>& iproxy
307 // )
308 // {
309 // const auto& mat = *iproxy;
310 //
311 // ...
312 //
313 // os.check(FUNCTION_NAME);
314 // return os;
315 // }
316 
317 
318 template<class Type, class DType, class LUType>
319 Foam::Ostream& Foam::operator<<
320 (
321  Ostream& os,
322  const LduMatrix<Type, DType, LUType>& mat
323 )
324 {
325  if (mat.hasDiag())
326  {
327  os << "Diagonal = " << mat.diag() << nl << nl;
328  }
329 
330  if (mat.hasUpper())
331  {
332  os << "Upper triangle = " << mat.upper() << nl << nl;
333  }
334 
335  if (mat.hasLower())
336  {
337  os << "Lower triangle = " << mat.lower() << nl << nl;
338  }
339 
340  if (mat.hasSource())
341  {
342  os << "Source = " << mat.source() << nl << nl;
343  }
344 
346  return os;
347 }
348 
349 
350 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
351 
352 #include "LduMatrixOperations.C"
353 #include "LduMatrixATmul.C"
355 #include "LduMatrixPreconditioner.C"
356 #include "LduMatrixSmoother.C"
357 #include "LduMatrixSolver.C"
358 
359 // ************************************************************************* //
const Field< DType > & diag() const
Definition: LduMatrix.C:151
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:45
LduMatrix(const lduMesh &mesh)
Construct given an LDU addressed mesh.
Definition: LduMatrix.C:28
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Abstract base class for meshes which provide LDU addressing for the construction of lduMatrix and LDU...
Definition: lduMesh.H:53
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
dynamicFvMesh & mesh
Generic templated field type.
Definition: Field.H:62
A class for handling words, derived from Foam::string.
Definition: word.H:63
errorManip< error > abort(error &err)
Definition: errorManip.H:139
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
const Field< LUType > & upper() const
Definition: LduMatrix.C:178
const Field< LUType > & lower() const
Definition: LduMatrix.C:223
LduMatrix is a general matrix class in which the coefficients are stored as three arrays...
Definition: LduMatrix.H:68
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
static const Foam::dimensionedScalar A("", Foam::dimPressure, 611.21)
const Field< Type > & source() const
Definition: LduMatrix.C:267
word matrixTypeName() const
The matrix type (empty, diagonal, symmetric, ...)
Definition: LduMatrix.C:133