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
27Description
28 lduMatrix member operations.
29
30\*---------------------------------------------------------------------------*/
31
32#include "lduMatrix.H"
33
34// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35
37{
38 const scalarField& Lower = const_cast<const lduMatrix&>(*this).lower();
39 const scalarField& Upper = const_cast<const lduMatrix&>(*this).upper();
40 scalarField& Diag = diag();
41
42 const labelUList& l = lduAddr().lowerAddr();
43 const labelUList& u = lduAddr().upperAddr();
44
45 for (label face=0; face<l.size(); face++)
46 {
47 Diag[l[face]] += Lower[face];
48 Diag[u[face]] += Upper[face];
49 }
50}
51
52
54{
55 const scalarField& Lower = const_cast<const lduMatrix&>(*this).lower();
56 const scalarField& Upper = const_cast<const lduMatrix&>(*this).upper();
57 scalarField& Diag = diag();
58
59 const labelUList& l = lduAddr().lowerAddr();
60 const labelUList& u = lduAddr().upperAddr();
61
62 for (label face=0; face<l.size(); face++)
63 {
64 Diag[l[face]] -= Lower[face];
65 Diag[u[face]] -= Upper[face];
66 }
67}
68
69
71(
72 scalarField& sumOff
73) const
74{
75 const scalarField& Lower = const_cast<const lduMatrix&>(*this).lower();
76 const scalarField& 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]] += mag(Lower[face]);
84 sumOff[l[face]] += mag(Upper[face]);
85 }
86}
87
88
89// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
90
92{
93 if (this == &A)
94 {
95 return; // Self-assignment is a no-op
96 }
97
98 if (A.lowerPtr_)
99 {
100 lower() = A.lower();
101 }
102 else if (lowerPtr_)
103 {
104 delete lowerPtr_;
105 lowerPtr_ = nullptr;
106 }
107
108 if (A.upperPtr_)
109 {
110 upper() = A.upper();
111 }
112 else if (upperPtr_)
113 {
114 delete upperPtr_;
115 upperPtr_ = nullptr;
116 }
117
118 if (A.diagPtr_)
119 {
120 diag() = A.diag();
121 }
122}
123
124
126{
127 if (lowerPtr_)
128 {
129 lowerPtr_->negate();
130 }
131
132 if (upperPtr_)
133 {
134 upperPtr_->negate();
135 }
136
137 if (diagPtr_)
138 {
139 diagPtr_->negate();
140 }
141}
142
143
145{
146 if (A.diagPtr_)
147 {
148 diag() += A.diag();
149 }
150
151 if (symmetric() && A.symmetric())
152 {
153 upper() += A.upper();
154 }
155 else if (symmetric() && A.asymmetric())
156 {
157 if (upperPtr_)
158 {
159 lower();
160 }
161 else
162 {
163 upper();
164 }
165
166 upper() += A.upper();
167 lower() += A.lower();
168 }
169 else if (asymmetric() && A.symmetric())
170 {
171 if (A.upperPtr_)
172 {
173 lower() += A.upper();
174 upper() += A.upper();
175 }
176 else
177 {
178 lower() += A.lower();
179 upper() += A.lower();
180 }
181
182 }
183 else if (asymmetric() && A.asymmetric())
184 {
185 lower() += A.lower();
186 upper() += A.upper();
187 }
188 else if (diagonal())
189 {
190 if (A.upperPtr_)
191 {
192 upper() = A.upper();
193 }
194
195 if (A.lowerPtr_)
196 {
197 lower() = A.lower();
198 }
199 }
200 else if (A.diagonal())
201 {
202 }
203 else
204 {
205 if (debug > 1)
206 {
208 << "Unknown matrix type combination" << nl
209 << " this :"
210 << " diagonal:" << diagonal()
211 << " symmetric:" << symmetric()
212 << " asymmetric:" << asymmetric() << nl
213 << " A :"
214 << " diagonal:" << A.diagonal()
215 << " symmetric:" << A.symmetric()
216 << " asymmetric:" << A.asymmetric()
217 << endl;
218 }
219 }
220}
221
222
224{
225 if (A.diagPtr_)
226 {
227 diag() -= A.diag();
228 }
229
230 if (symmetric() && A.symmetric())
231 {
232 upper() -= A.upper();
233 }
234 else if (symmetric() && A.asymmetric())
235 {
236 if (upperPtr_)
237 {
238 lower();
239 }
240 else
241 {
242 upper();
243 }
244
245 upper() -= A.upper();
246 lower() -= A.lower();
247 }
248 else if (asymmetric() && A.symmetric())
249 {
250 if (A.upperPtr_)
251 {
252 lower() -= A.upper();
253 upper() -= A.upper();
254 }
255 else
256 {
257 lower() -= A.lower();
258 upper() -= A.lower();
259 }
260
261 }
262 else if (asymmetric() && A.asymmetric())
263 {
264 lower() -= A.lower();
265 upper() -= A.upper();
266 }
267 else if (diagonal())
268 {
269 if (A.upperPtr_)
270 {
271 upper() = -A.upper();
272 }
273
274 if (A.lowerPtr_)
275 {
276 lower() = -A.lower();
277 }
278 }
279 else if (A.diagonal())
280 {
281 }
282 else
283 {
284 if (debug > 1)
285 {
287 << "Unknown matrix type combination" << nl
288 << " this :"
289 << " diagonal:" << diagonal()
290 << " symmetric:" << symmetric()
291 << " asymmetric:" << asymmetric() << nl
292 << " A :"
293 << " diagonal:" << A.diagonal()
294 << " symmetric:" << A.symmetric()
295 << " asymmetric:" << A.asymmetric()
296 << endl;
297 }
298 }
299}
300
301
303{
304 if (diagPtr_)
305 {
306 *diagPtr_ *= sf;
307 }
308
309 // Non-uniform scaling causes a symmetric matrix
310 // to become asymmetric
311 if (symmetric() || asymmetric())
312 {
313 scalarField& upper = this->upper();
314 scalarField& lower = this->lower();
315
316 const labelUList& l = lduAddr().lowerAddr();
317 const labelUList& u = lduAddr().upperAddr();
318
319 for (label face=0; face<upper.size(); face++)
320 {
321 upper[face] *= sf[l[face]];
322 }
323
324 for (label face=0; face<lower.size(); face++)
325 {
326 lower[face] *= sf[u[face]];
327 }
328 }
329}
330
331
333{
334 if (diagPtr_)
335 {
336 *diagPtr_ *= s;
337 }
338
339 if (upperPtr_)
340 {
341 *upperPtr_ *= s;
342 }
343
344 if (lowerPtr_)
345 {
346 *lowerPtr_ *= s;
347 }
348}
349
350
351// ************************************************************************* //
static const Foam::dimensionedScalar A("", Foam::dimPressure, 611.21)
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
virtual const labelUList & upperAddr() const =0
Return upper addressing.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
lduMatrix is a general matrix class in which the coefficients are stored as three arrays,...
Definition: lduMatrix.H:84
void operator=(const lduMatrix &)
scalarField & upper()
Definition: lduMatrix.C:203
const lduAddressing & lduAddr() const
Return the LDU addressing.
Definition: lduMatrix.H:578
scalarField & lower()
Definition: lduMatrix.C:174
void operator*=(const scalarField &)
scalarField & diag()
Definition: lduMatrix.C:192
void operator+=(const lduMatrix &)
void sumMagOffDiag(scalarField &sumOff) const
void operator-=(const lduMatrix &)
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))
#define WarningInFunction
Report a warning using Foam::Warning.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53