MatrixSpaceI.H
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) 2016 OpenFOAM Foundation
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include <type_traits>
29 
30 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
31 
32 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
34 (
35  const Foam::zero
36 )
37 :
39 {}
40 
41 
42 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
43 template<class Form2, class Cmpt2>
45 (
47 )
48 :
49  MatrixSpace::vsType(vs)
50 {}
51 
52 
53 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
54 template
55 <
56  template<class, Foam::direction, Foam::direction> class Block2,
57  Foam::direction BRowStart,
58  Foam::direction BColStart
59 >
61 (
62  const Block2<Form, BRowStart, BColStart>& block
63 )
64 {
65  for (direction i=0; i<Mrows; ++i)
66  {
67  for (direction j=0; j<Ncols; ++j)
68  {
69  operator()(i, j) = block(i, j);
70  }
71  }
72 }
73 
74 
75 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
77 :
78  MatrixSpace::vsType(is)
79 {}
80 
81 
82 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
83 template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
86 ConstBlock(const msType& matrix)
87 :
88  matrix_(matrix)
89 {
90  static_assert
91  (
92  msType::mRows >= BRowStart + mRows,
93  "Rows in block > rows in matrix"
94  );
95  static_assert
96  (
97  msType::nCols >= BColStart + nCols,
98  "Columns in block > columns in matrix"
99  );
100 }
101 
102 
103 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
104 template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
107 Block(msType& matrix)
108 :
109  matrix_(matrix)
110 {
111  static_assert
112  (
113  msType::mRows >= BRowStart + mRows,
114  "Rows in block > rows in matrix"
115  );
116  static_assert
117  (
118  msType::nCols >= BColStart + nCols,
119  "Columns in block > columns in matrix"
120  );
121 }
122 
123 
124 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
125 
126 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
127 template<Foam::direction Row, Foam::direction Col>
129 const noexcept
130 {
131  static_assert(Row < Mrows && Col < Ncols, "Address outside matrix");
132  return this->v_[Row*Ncols + Col];
133 }
134 
135 
136 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
137 template<Foam::direction Row, Foam::direction Col>
139 noexcept
140 {
141  static_assert(Row < Mrows && Col < Ncols, "Address outside matrix");
142  return this->v_[Row*Ncols + Col];
143 }
144 
145 
146 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
149 {
150  static_assert(Mrows == Ncols, "Matrix is not square");
151  msType result(Zero);
152 
153  for (direction i=0; i<Ncols; ++i)
154  {
155  result(i, i) = 1;
156  }
158  return result;
159 }
160 
161 
162 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
165 {
166  typename typeOfTranspose<Cmpt, Form>::type result;
167 
168  for (direction i=0; i<Mrows; ++i)
169  {
170  for (direction j=0; j<Ncols; ++j)
171  {
172  result(j,i) = operator()(i, j);
173  }
174  }
175 
176  return result;
177 }
178 
179 
180 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
181 template
182 <
183  class SubTensor,
184  Foam::direction BRowStart,
185  Foam::direction BColStart
186 >
188  ConstBlock<SubTensor, BRowStart, BColStart>
190 {
191  return *this;
192 }
193 
194 
195 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
196 template
197 <
198  class SubTensor,
199  Foam::direction BRowStart,
200  Foam::direction BColStart
201 >
202 inline
204  Block<SubTensor, BRowStart, BColStart>
206 {
207  return *this;
208 }
209 
210 
211 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
212 
213 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
215 (
216  const direction& i,
217  const direction& j
218 ) const
219 {
220  #ifdef FULLDEBUG
221  if (i >= Mrows || j >= Ncols)
222  {
224  << "indices out of range"
225  << abort(FatalError);
226  }
227  #endif
229  return this->v_[i*Ncols + j];
230 }
231 
232 
233 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
235 (
236  const direction& i,
237  const direction& j
238 )
239 {
240  #ifdef FULLDEBUG
241  if (i >= Mrows || j >= Ncols)
242  {
244  << "indices out of range"
245  << abort(FatalError);
246  }
247  #endif
248 
249  return this->v_[i*Ncols + j];
250 }
252 
253 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
254 template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
255 inline SubTensor
258 operator()() const
259 {
260  return *this;
261 }
263 
264 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
265 template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
266 inline const Cmpt&
269 operator()(const direction i, const direction j) const
270 {
271  return matrix_(BRowStart + i, BColStart + j);
272 }
274 
275 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
276 template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
277 inline SubTensor
280 operator()() const
281 {
282  SubTensor st;
283 
284  for (direction i=0; i<SubTensor::mRows; ++i)
285  {
286  for (direction j=0; j<SubTensor::nCols; ++j)
287  {
288  st[i*SubTensor::nCols + j] = operator()(i, j);
289  }
290  }
291 
292  return st;
293 }
295 
296 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
297 template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
298 inline const Cmpt&
301 operator()(const direction i, const direction j) const
302 {
303  return matrix_(BRowStart + i, BColStart + j);
304 }
306 
307 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
308 template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
309 inline Cmpt&
312 operator()(const direction i, const direction j)
313 {
314  return matrix_(BRowStart + i, BColStart + j);
315 }
316 
317 
318 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
320 (
321  const Foam::zero
322 )
323 {
325 }
326 
327 
328 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
329 template<class Form2>
331 (
332  const MatrixSpace<Form, Cmpt, Ncols, Ncols>& matrix
333 )
334 {
335  *this = *this & matrix;
336 }
337 
338 
339 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
340 template
341 <
342  template<class, Foam::direction, Foam::direction> class Block2,
343  Foam::direction BRowStart,
344  Foam::direction BColStart
345 >
347 (
348  const Block2<Form, BRowStart, BColStart>& block
349 )
350 {
351  for (direction i = 0; i < Mrows; ++i)
352  {
353  for (direction j = 0; j < Ncols; ++j)
354  {
355  operator()(i, j) = block(i, j);
356  }
357  }
358 }
359 
360 
361 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
362 template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
363 template<class Form2>
364 inline void
367 operator=
368 (
370 )
371 {
372  for (direction i=0; i<mRows; ++i)
373  {
374  for (direction j=0; j<nCols; ++j)
375  {
376  operator()(i,j) = matrix(i,j);
377  }
378  }
379 }
380 
381 
382 template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
383 template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
384 template<class VSForm>
385 inline void
388 operator=
389 (
391 )
392 {
393  static_assert(nCols == 1, "Matrix must have a single column");
394 
395  for (direction i=0; i<SubTensor::mRows; ++i)
396  {
397  operator()(i,0) = v[i];
398  }
399 }
400 
401 
402 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
403 
404 namespace Foam
405 {
406 
407 // * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
408 
409 template<class Form, class Cmpt, direction Mrows, direction Ncols>
410 inline typename typeOfTranspose<Cmpt, Form>::type T
411 (
413 )
414 {
415  return matrix.T();
416 }
417 
418 
419 template<class Form, class Cmpt, direction Ncmpts>
420 inline typename typeOfTranspose<Cmpt, Form>::type T
421 (
422  const VectorSpace<Form, Cmpt, Ncmpts>& v
423 )
424 {
425  typename typeOfTranspose<Cmpt, Form>::type result;
426 
427  for (direction i=0; i<Ncmpts; ++i)
428  {
429  result[i] = v[i];
430  }
431 
432  return result;
433 }
434 
435 
436 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
437 
438 template
439 <
440  class Form1,
441  class Form2,
442  class Cmpt,
443  direction Mrows1,
444  direction Ncols1,
445  direction Mrows2,
446  direction Ncols2
447 >
448 inline typename typeOfInnerProduct<Cmpt, Form1, Form2>::type operator&
449 (
452 )
453 {
454  static_assert
455  (
456  Ncols1 == Mrows2,
457  "Number of columns in matrix 1 != number of rows in matrix 2"
458  );
459 
461 
462  for (direction i=0; i<Mrows1; ++i)
463  {
464  for (direction j=0; j<Ncols2; ++j)
465  {
466  for (direction k=0; k<Mrows2; k++)
467  {
468  result(i, j) += matrix1(i, k)*matrix2(k, j);
469  }
470  }
471  }
473  return result;
474 }
475 
476 
477 template<class Form, class VSForm, class Cmpt, direction Mrows, direction Ncols>
478 inline typename typeOfInnerProduct<Cmpt, Form, VSForm>::type operator&
479 (
480  const MatrixSpace<Form, Cmpt, Mrows, Ncols>& matrix,
481  const VectorSpace<VSForm, Cmpt, Ncols>& v
482 )
483 {
485 
486  for (direction i=0; i<Mrows; ++i)
487  {
488  for (direction j=0; j<Ncols; ++j)
489  {
490  result[i] += matrix(i, j)*v[j];
491  }
492  }
493 
494  return result;
495 }
496 
497 
498 template
499 <
500  class Form1,
501  class Form2,
502  class Cmpt,
503  direction Ncmpts1,
504  direction Ncmpts2
505 >
506 inline typename typeOfOuterProduct<Cmpt, Form1, Form2>::type operator*
507 (
510 )
511 {
513 
514  for (direction i=0; i<Ncmpts1; ++i)
515  {
516  for (direction j=0; j<Ncmpts2; ++j)
517  {
518  result(i, j) = v1[i]*v2[j];
519  }
520  }
521 
522  return result;
523 }
524 
525 
526 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
527 
528 } // End namespace Foam
529 
530 // ************************************************************************* //
Abstract template class to provide the form resulting from the outer-product of two forms...
Definition: products.H:55
Abstract template class to provide the form resulting from the inner-product of two forms...
Definition: products.H:47
type
Types of root.
Definition: Roots.H:52
uint8_t direction
Definition: direction.H:46
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:598
const Cmpt & operator()(const direction &i, const direction &j) const
(i, j) const element access operator
Definition: MatrixSpaceI.H:208
void operator=(const VectorSpace< Form, Cmpt, Ncmpts > &)
Definition: VectorSpaceI.H:331
static const direction nCols
Definition: MatrixSpace.H:172
Templated vector space.
Definition: VectorSpace.H:52
MatrixSpace< Form, Cmpt, Mrows, Ncols > msType
MatrixSpace type.
Definition: MatrixSpace.H:65
label k
Boltzmann constant.
typeOfTranspose< Cmpt, Form >::type T() const
Return the transpose of the matrix.
Definition: MatrixSpaceI.H:157
Templated matrix space.
Definition: MatrixSpace.H:54
static const direction mRows
Definition: MatrixSpace.H:113
static constexpr direction nCols
Definition: MatrixSpace.H:71
static constexpr direction mRows
Definition: MatrixSpace.H:70
static const direction mRows
Definition: MatrixSpace.H:171
static const direction nCols
Definition: MatrixSpace.H:114
errorManip< error > abort(error &err)
Definition: errorManip.H:139
Abstract template class to provide the transpose form of a form.
Definition: products.H:62
ConstBlock< SubTensor, BRowStart, BColStart > block() const
Return a const sub-block corresponding to the specified type.
Creates a single block of cells from point coordinates, numbers of cells in each direction and an exp...
Definition: block.H:54
const Cmpt & elmt() const noexcept
Fast const element access using compile-time addressing.
Definition: MatrixSpaceI.H:121
const direction noexcept
Definition: Scalar.H:258
Sub-block type.
Definition: MatrixSpace.H:162
friend Ostream & operator(Ostream &, const VectorSpace< Form, Cmpt, Ncmpts > &)
MatrixSpace()=default
Default construct.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
static msType identity()
An identity matrix for square matrix-spaces.
Definition: MatrixSpaceI.H:141
Cmpt v_[Ncmpts]
The components of this vector space.
Definition: VectorSpace.H:81
Namespace for OpenFOAM.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127