Matrix.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 | Copyright (C) 2011-2015 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "Matrix.H"
27 
28 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
29 
30 template<class Form, class Type>
32 {
33  if (n_ && m_)
34  {
35  v_ = new Type*[n_];
36  v_[0] = new Type[n_*m_];
37 
38  for (label i=1; i<n_; i++)
39  {
40  v_[i] = v_[i-1] + m_;
41  }
42  }
43 }
44 
45 
46 // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
47 
48 template<class Form, class Type>
50 {
51  if (v_)
52  {
53  delete[] (v_[0]);
54  delete[] v_;
55  }
56 }
57 
58 
59 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
60 
61 template<class Form, class Type>
63 :
64  n_(n),
65  m_(m),
66  v_(NULL)
67 {
68  if (n_ < 0 || m_ < 0)
69  {
71  << "bad n, m " << n_ << ", " << m_
72  << abort(FatalError);
73  }
74 
75  allocate();
76 }
77 
78 
79 template<class Form, class Type>
80 Foam::Matrix<Form, Type>::Matrix(const label n, const label m, const Type& a)
81 :
82  n_(n),
83  m_(m),
84  v_(NULL)
85 {
86  if (n_ < 0 || m_ < 0)
87  {
89  << "bad n, m " << n_ << ", " << m_
90  << abort(FatalError);
91  }
92 
93  allocate();
94 
95  if (v_)
96  {
97  Type* v = v_[0];
98 
99  label nm = n_*m_;
100 
101  for (label i=0; i<nm; i++)
102  {
103  v[i] = a;
104  }
105  }
106 }
107 
108 
109 template<class Form, class Type>
110 Foam::Matrix<Form, Type>::Matrix(const Matrix<Form, Type>& a)
111 :
112  n_(a.n_),
113  m_(a.m_),
114  v_(NULL)
115 {
116  if (a.v_)
117  {
118  allocate();
119  Type* v = v_[0];
120  const Type* av = a.v_[0];
121 
122  label nm = n_*m_;
123  for (label i=0; i<nm; i++)
124  {
125  v[i] = av[i];
126  }
127  }
128 }
129 
130 
131 template<class Form, class Type>
133 {
134  if (v_)
135  {
136  delete[] (v_[0]);
137  delete[] v_;
138  }
139  n_ = 0;
140  m_ = 0;
141  v_ = NULL;
142 }
143 
144 
145 template<class Form, class Type>
147 {
148  clear();
149 
150  n_ = a.n_;
151  a.n_ = 0;
152 
153  m_ = a.m_;
154  a.m_ = 0;
155 
156  v_ = a.v_;
157  a.v_ = NULL;
158 }
159 
160 
161 template<class Form, class Type>
163 {
164  const Matrix<Form, Type>& A = *this;
165  Form At(m(), n());
166 
167  for (label i=0; i<n(); i++)
168  {
169  for (label j=0; j<m(); j++)
170  {
171  At[j][i] = A[i][j];
172  }
173  }
174 
175  return At;
176 }
177 
178 
179 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
180 
181 template<class Form, class Type>
182 void Foam::Matrix<Form, Type>::operator=(const Type& t)
183 {
184  if (v_)
185  {
186  Type* v = v_[0];
187 
188  label nm = n_*m_;
189  for (label i=0; i<nm; i++)
190  {
191  v[i] = t;
192  }
193  }
194 }
195 
196 
197 // Assignment operator. Takes linear time.
198 template<class Form, class Type>
199 void Foam::Matrix<Form, Type>::operator=(const Matrix<Form, Type>& a)
200 {
201  if (this == &a)
202  {
204  << "attempted assignment to self"
205  << abort(FatalError);
206  }
207 
208  if (n_ != a.n_ || m_ != a.m_)
209  {
210  clear();
211  n_ = a.n_;
212  m_ = a.m_;
213  allocate();
214  }
215 
216  if (v_)
217  {
218  Type* v = v_[0];
219  const Type* av = a.v_[0];
220 
221  label nm = n_*m_;
222  for (label i=0; i<nm; i++)
223  {
224  v[i] = av[i];
225  }
226  }
227 }
228 
229 
230 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
231 
232 template<class Form, class Type>
233 const Type& Foam::max(const Matrix<Form, Type>& a)
234 {
235  label nm = a.n()*a.m();
236 
237  if (nm)
238  {
239  label curMaxI = 0;
240  const Type* v = a[0];
241 
242  for (label i=1; i<nm; i++)
243  {
244  if (v[i] > v[curMaxI])
245  {
246  curMaxI = i;
247  }
248  }
249 
250  return v[curMaxI];
251  }
252  else
253  {
255  << "matrix is empty"
256  << abort(FatalError);
257 
258  // Return in error to keep compiler happy
259  return a[0][0];
260  }
261 }
262 
263 
264 template<class Form, class Type>
265 const Type& Foam::min(const Matrix<Form, Type>& a)
266 {
267  label nm = a.n()*a.m();
268 
269  if (nm)
270  {
271  label curMinI = 0;
272  const Type* v = a[0];
273 
274  for (label i=1; i<nm; i++)
275  {
276  if (v[i] < v[curMinI])
277  {
278  curMinI = i;
279  }
280  }
281 
282  return v[curMinI];
283  }
284  else
285  {
287  << "matrix is empty"
288  << abort(FatalError);
289 
290  // Return in error to keep compiler happy
291  return a[0][0];
292  }
293 }
294 
295 
296 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
297 
298 template<class Form, class Type>
300 {
301  Form na(a.n(), a.m());
302 
303  if (a.n() && a.m())
304  {
305  Type* nav = na[0];
306  const Type* av = a[0];
307 
308  label nm = a.n()*a.m();
309  for (label i=0; i<nm; i++)
310  {
311  nav[i] = -av[i];
312  }
313  }
314 
315  return na;
316 }
317 
318 
319 template<class Form, class Type>
321 {
322  if (a.n() != b.n())
323  {
325  << "attempted add matrices with different number of rows: "
326  << a.n() << ", " << b.n()
327  << abort(FatalError);
328  }
329 
330  if (a.m() != b.m())
331  {
333  << "attempted add matrices with different number of columns: "
334  << a.m() << ", " << b.m()
335  << abort(FatalError);
336  }
337 
338  Form ab(a.n(), a.m());
339 
340  Type* abv = ab[0];
341  const Type* av = a[0];
342  const Type* bv = b[0];
343 
344  label nm = a.n()*a.m();
345  for (label i=0; i<nm; i++)
346  {
347  abv[i] = av[i] + bv[i];
348  }
349 
350  return ab;
351 }
352 
353 
354 template<class Form, class Type>
356 {
357  if (a.n() != b.n())
358  {
360  << "attempted add matrices with different number of rows: "
361  << a.n() << ", " << b.n()
362  << abort(FatalError);
363  }
364 
365  if (a.m() != b.m())
366  {
368  << "attempted add matrices with different number of columns: "
369  << a.m() << ", " << b.m()
370  << abort(FatalError);
371  }
372 
373  Form ab(a.n(), a.m());
374 
375  Type* abv = ab[0];
376  const Type* av = a[0];
377  const Type* bv = b[0];
378 
379  label nm = a.n()*a.m();
380  for (label i=0; i<nm; i++)
381  {
382  abv[i] = av[i] - bv[i];
383  }
384 
385  return ab;
386 }
387 
388 
389 template<class Form, class Type>
390 Form Foam::operator*(const scalar s, const Matrix<Form, Type>& a)
391 {
392  Form sa(a.n(), a.m());
393 
394  if (a.n() && a.m())
395  {
396  Type* sav = sa[0];
397  const Type* av = a[0];
398 
399  label nm = a.n()*a.m();
400  for (label i=0; i<nm; i++)
401  {
402  sav[i] = s*av[i];
403  }
404  }
405 
406  return sa;
407 }
408 
409 
410 template<class Form, class Type>
412 {
413  if (a.m() != b.n())
414  {
416  << "attempted to multiply incompatible matrices:" << nl
417  << "Matrix A : " << a.n() << " rows, " << a.m() << " columns" << nl
418  << "Matrix B : " << b.n() << " rows, " << b.m() << " columns" << nl
419  << "In order to multiply matrices, columns of A must equal "
420  << "rows of B"
421  << abort(FatalError);
422  }
423 
424  Form ab(a.n(), b.m(), scalar(0));
425 
426  for (label i = 0; i < ab.n(); i++)
427  {
428  for (label j = 0; j < ab.m(); j++)
429  {
430  for (label l = 0; l < b.n(); l++)
431  {
432  ab[i][j] += a[i][l]*b[l][j];
433  }
434  }
435  }
436 
437  return ab;
438 }
439 
440 
441 // * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
442 
443 #include "MatrixIO.C"
444 
445 // ************************************************************************* //
Foam::Matrix::m
label m() const
Return the number of columns.
Definition: MatrixI.H:63
clear
UEqn clear()
Matrix.H
Foam::Matrix::~Matrix
~Matrix()
Destructor.
Definition: Matrix.C:49
Foam::Matrix::allocate
void allocate()
Allocate the storage for the row-pointers and the data.
Definition: Matrix.C:31
Foam::Matrix::n
label n() const
Return the number of rows.
Definition: MatrixI.H:56
A
simpleMatrix< scalar > A(Nc)
Foam::Matrix
A templated 2D matrix of objects of <T>, where the n x m matrix dimensions are known and used for sub...
Definition: DiagonalMatrix.H:47
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::operator-
tmp< fvMatrix< Type > > operator-(const fvMatrix< Type > &)
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:28
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Matrix::operator=
void operator=(const Matrix< Form, Type > &)
Assignment operator. Takes linear time.
Foam::Matrix::clear
void clear()
Clear the Matrix, i.e. set sizes to zero.
Definition: Matrix.C:132
Foam::FatalError
error FatalError
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
s
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().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))
Foam::operator*
tmp< fvMatrix< Type > > operator*(const DimensionedField< scalar, volMesh > &, const fvMatrix< Type > &)
Foam::Matrix::T
Form T() const
Return the transpose of the matrix.
Definition: Matrix.C:162
Foam::max
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::Matrix::n_
label n_
Number of rows and columns in Matrix.
Definition: Matrix.H:78
Foam::Matrix::v_
Type **__restrict__ v_
Row pointers.
Definition: Matrix.H:81
Foam::Matrix::Matrix
Matrix()
Null constructor.
Definition: MatrixI.H:29
Foam::Matrix::m_
label m_
Definition: Matrix.H:78
Foam::min
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::operator+
tmp< fvMatrix< Type > > operator+(const fvMatrix< Type > &, const fvMatrix< Type > &)
MatrixIO.C
Foam::Matrix::transfer
void transfer(Matrix< Form, Type > &)
Transfer the contents of the argument Matrix into this Matrix.
Definition: Matrix.C:146