FreeFOAM The Cross-Platform CFD Toolkit
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) 1991-2010 OpenCFD Ltd.
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 <OpenFOAM/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 (register 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>
62 Foam::Matrix<Form, Type>::Matrix(const label n, const label m)
63 :
64  n_(n),
65  m_(m),
66  v_(NULL)
67 {
68  if (n_ < 0 || m_ < 0)
69  {
70  FatalErrorIn("Matrix<Form, Type>::Matrix(const label n, const label m)")
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  (
90  "Matrix<Form, Type>::Matrix(const label n, const label m, const T&)"
91  ) << "bad n, m " << n_ << ", " << m_
92  << abort(FatalError);
93  }
94 
95  allocate();
96 
97  if (v_)
98  {
99  Type* v = v_[0];
100 
101  label nm = n_*m_;
102 
103  for (register label i=0; i<nm; i++)
104  {
105  v[i] = a;
106  }
107  }
108 }
109 
110 
111 template<class Form, class Type>
113 :
114  n_(a.n_),
115  m_(a.m_),
116  v_(NULL)
117 {
118  if (a.v_)
119  {
120  allocate();
121  Type* v = v_[0];
122  const Type* av = a.v_[0];
123 
124  label nm = n_*m_;
125  for (register label i=0; i<nm; i++)
126  {
127  v[i] = av[i];
128  }
129  }
130 }
131 
132 
133 template<class Form, class Type>
135 {
136  if (v_)
137  {
138  delete[] (v_[0]);
139  delete[] v_;
140  }
141  n_ = 0;
142  m_ = 0;
143  v_ = NULL;
144 }
145 
146 
147 template<class Form, class Type>
149 {
150  clear();
151 
152  n_ = a.n_;
153  a.n_ = 0;
154 
155  m_ = a.m_;
156  a.m_ = 0;
157 
158  v_ = a.v_;
159  a.v_ = NULL;
160 }
161 
162 
163 template<class Form, class Type>
165 {
166  const Matrix<Form, Type>& A = *this;
167  Form At(m(), n());
168 
169  for (register label i=0; i<n(); i++)
170  {
171  for (register label j=0; j<m(); j++)
172  {
173  At[j][i] = A[i][j];
174  }
175  }
176 
177  return At;
178 }
179 
180 
181 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
182 
183 template<class Form, class Type>
185 {
186  if (v_)
187  {
188  Type* v = v_[0];
189 
190  label nm = n_*m_;
191  for (register label i=0; i<nm; i++)
192  {
193  v[i] = t;
194  }
195  }
196 }
197 
198 
199 // Assignment operator. Takes linear time.
200 template<class Form, class Type>
202 {
203  if (this == &a)
204  {
205  FatalErrorIn("Matrix<Form, Type>::operator=(const Matrix<Form, Type>&)")
206  << "attempted assignment to self"
207  << abort(FatalError);
208  }
209 
210  if (n_ != a.n_ || m_ != a.m_)
211  {
212  clear();
213  n_ = a.n_;
214  m_ = a.m_;
215  allocate();
216  }
217 
218  if (v_)
219  {
220  Type* v = v_[0];
221  const Type* av = a.v_[0];
222 
223  label nm = n_*m_;
224  for (register label i=0; i<nm; i++)
225  {
226  v[i] = av[i];
227  }
228  }
229 }
230 
231 
232 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
233 
234 template<class Form, class Type>
235 const Type& Foam::max(const Matrix<Form, Type>& a)
236 {
237  label nm = a.n()*a.m();
238 
239  if (nm)
240  {
241  label curMaxI = 0;
242  const Type* v = a[0];
243 
244  for (register label i=1; i<nm; i++)
245  {
246  if (v[i] > v[curMaxI])
247  {
248  curMaxI = i;
249  }
250  }
251 
252  return v[curMaxI];
253  }
254  else
255  {
256  FatalErrorIn("max(const Matrix<Form, Type>&)")
257  << "matrix is empty"
258  << abort(FatalError);
259 
260  // Return in error to keep compiler happy
261  return a[0][0];
262  }
263 }
264 
265 
266 template<class Form, class Type>
267 const Type& Foam::min(const Matrix<Form, Type>& a)
268 {
269  label nm = a.n()*a.m();
270 
271  if (nm)
272  {
273  label curMinI = 0;
274  const Type* v = a[0];
275 
276  for (register label i=1; i<nm; i++)
277  {
278  if (v[i] < v[curMinI])
279  {
280  curMinI = i;
281  }
282  }
283 
284  return v[curMinI];
285  }
286  else
287  {
288  FatalErrorIn("min(const Matrix<Form, Type>&)")
289  << "matrix is empty"
290  << abort(FatalError);
291 
292  // Return in error to keep compiler happy
293  return a[0][0];
294  }
295 }
296 
297 
298 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
299 
300 template<class Form, class Type>
302 {
303  Form na(a.n(), a.m());
304 
305  if (a.n() && a.m())
306  {
307  Type* nav = na[0];
308  const Type* av = a[0];
309 
310  label nm = a.n()*a.m();
311  for (register label i=0; i<nm; i++)
312  {
313  nav[i] = -av[i];
314  }
315  }
316 
317  return na;
318 }
319 
320 
321 template<class Form, class Type>
323 {
324  if (a.n() != b.n())
325  {
327  (
328  "Matrix<Form, Type>::operator+(const Matrix<Form, Type>&, const Matrix<Form, Type>&)"
329  ) << "attempted add matrices with different number of rows: "
330  << a.n() << ", " << b.n()
331  << abort(FatalError);
332  }
333 
334  if (a.m() != b.m())
335  {
337  (
338  "Matrix<Form, Type>::operator+(const Matrix<Form, Type>&, const Matrix<Form, Type>&)"
339  ) << "attempted add matrices with different number of columns: "
340  << a.m() << ", " << b.m()
341  << abort(FatalError);
342  }
343 
344  Form ab(a.n(), a.m());
345 
346  Type* abv = ab[0];
347  const Type* av = a[0];
348  const Type* bv = b[0];
349 
350  label nm = a.n()*a.m();
351  for (register label i=0; i<nm; i++)
352  {
353  abv[i] = av[i] + bv[i];
354  }
355 
356  return ab;
357 }
358 
359 
360 template<class Form, class Type>
362 {
363  if (a.n() != b.n())
364  {
366  (
367  "Matrix<Form, Type>::operator-(const Matrix<Form, Type>&, const Matrix<Form, Type>&)"
368  ) << "attempted add matrices with different number of rows: "
369  << a.n() << ", " << b.n()
370  << abort(FatalError);
371  }
372 
373  if (a.m() != b.m())
374  {
376  (
377  "Matrix<Form, Type>::operator-(const Matrix<Form, Type>&, const Matrix<Form, Type>&)"
378  ) << "attempted add matrices with different number of columns: "
379  << a.m() << ", " << b.m()
380  << abort(FatalError);
381  }
382 
383  Form ab(a.n(), a.m());
384 
385  Type* abv = ab[0];
386  const Type* av = a[0];
387  const Type* bv = b[0];
388 
389  label nm = a.n()*a.m();
390  for (register label i=0; i<nm; i++)
391  {
392  abv[i] = av[i] - bv[i];
393  }
394 
395  return ab;
396 }
397 
398 
399 template<class Form, class Type>
400 Form Foam::operator*(const scalar s, const Matrix<Form, Type>& a)
401 {
402  Form sa(a.n(), a.m());
403 
404  if (a.n() && a.m())
405  {
406  Type* sav = sa[0];
407  const Type* av = a[0];
408 
409  label nm = a.n()*a.m();
410  for (register label i=0; i<nm; i++)
411  {
412  sav[i] = s*av[i];
413  }
414  }
415 
416  return sa;
417 }
418 
419 
420 // * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
421 
422 #include <OpenFOAM/MatrixIO.C>
423 
424 // ************************ vim: set sw=4 sts=4 et: ************************ //