Loading...
Searching...
No Matches
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-------------------------------------------------------------------------------
10License
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
32template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
34(
36)
39{}
40
41
42template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
43template<class Form2, class Cmpt2>
45(
47)
48:
49 MatrixSpace::vsType(vs)
50{}
51
52
53template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
54template
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
75template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
77:
79{}
80
81
82template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
83template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
86ConstBlock(const msType& matrix)
87:
88 matrix_(matrix)
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
103template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
104template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
107Block(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 );
122
124// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
125
126template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
127template<Foam::direction Row, Foam::direction Col>
129const noexcept
130{
131 static_assert(Row < Mrows && Col < Ncols, "Address outside matrix");
132 return this->v_[Row*Ncols + Col];
133}
134
135
136template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
137template<Foam::direction Row, Foam::direction Col>
140{
141 static_assert(Row < Mrows && Col < Ncols, "Address outside matrix");
142 return this->v_[Row*Ncols + Col];
143}
144
145
146template<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
162template<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 }
176 return result;
177}
178
179
180template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
181template
183 class SubTensor,
184 Foam::direction BRowStart,
185 Foam::direction BColStart
186>
188 ConstBlock<SubTensor, BRowStart, BColStart>
190{
191 return *this;
192}
193
194
195template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
196template
197<
198 class SubTensor,
199 Foam::direction BRowStart,
200 Foam::direction BColStart
201>
202inline
206{
207 return *this;
208}
209
210
211// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
212
213template<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
228
229 return this->v_[i*Ncols + j];
230}
231
232
233template<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];
251
252
253template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
254template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
255inline SubTensor
258operator()() const
259{
260 return *this;
262
263
264template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
265template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
266inline const Cmpt&
269operator()(const direction i, const direction j) const
270{
271 return matrix_(BRowStart + i, BColStart + j);
273
274
275template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
276template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
277inline SubTensor
280operator()() 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;
294
295
296template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
297template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
298inline const Cmpt&
301operator()(const direction i, const direction j) const
302{
303 return matrix_(BRowStart + i, BColStart + j);
305
306
307template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
308template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
309inline Cmpt&
313{
314 return matrix_(BRowStart + i, BColStart + j);
315}
316
317
318template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
320(
322)
325}
326
327
328template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
329template<class Form2>
331(
334{
335 *this = *this & matrix;
336}
337
338
339template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
340template
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)
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}
360
361template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
362template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
363template<class Form2>
364inline void
366Block<SubTensor, BRowStart, BColStart>::
368(
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}
381
382template<class Form, class Cmpt, Foam::direction Mrows, Foam::direction Ncols>
383template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
384template<class VSForm>
385inline void
387Block<SubTensor, BRowStart, BColStart>::
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// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
404namespace Foam
405{
406
407// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
408
409template<class Form, class Cmpt, direction Mrows, direction Ncols>
411(
414{
415 return matrix.T();
416}
417
418
419template<class Form, class Cmpt, direction Ncmpts>
420inline 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
438template
439<
440 class Form1,
441 class Form2,
442 class Cmpt,
443 direction Mrows1,
444 direction Ncols1,
445 direction Mrows2,
446 direction Ncols2
447>
448inline 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 }
472
473 return result;
474}
475
476
477template<class Form, class VSForm, class Cmpt, direction Mrows, direction Ncols>
478inline typename typeOfInnerProduct<Cmpt, Form, VSForm>::type operator&
479(
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
498template
500 class Form1,
501 class Form2,
502 class Cmpt,
503 direction Ncmpts1,
504 direction Ncmpts2
505>
506inline 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// ************************************************************************* //
label k
tmp< GeometricField< Type, PatchField, GeoMesh > > T() const
Return transpose (only if it is a tensor field).
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition Istream.H:60
static const direction nCols
static const direction mRows
static const direction mRows
Templated matrix space.
Definition MatrixSpace.H:57
typeOfTranspose< Cmpt, Form >::type T() const
Return the transpose of the matrix.
static constexpr direction nCols
Definition MatrixSpace.H:71
MatrixSpace< Form, Cmpt, Mrows, Ncols > msType
MatrixSpace type.
Definition MatrixSpace.H:65
const Cmpt & elmt() const noexcept
Fast const element access using compile-time addressing.
static msType identity()
An identity matrix for square matrix-spaces.
const Cmpt & operator()(const direction i, const direction j) const
(i, j) const element access operator
static constexpr direction mRows
Definition MatrixSpace.H:70
ConstBlock< SubTensor, BRowStart, BColStart > block() const
Return a const sub-block corresponding to the specified type.
MatrixSpace()=default
Default construct.
Templated vector space.
Definition VectorSpace.H:75
void operator=(const VectorSpace< Form, Cmpt, Ncmpts > &)
VectorSpace< Form, Cmpt, Ncmpts > vsType
Definition VectorSpace.H:86
friend Ostream & operator(Ostream &, const VectorSpace< Form, Cmpt, Ncmpts > &)
Abstract template class to provide the form resulting from the inner-product of two forms.
Definition products.H:48
Abstract template class to provide the form resulting from the outer-product of two forms.
Definition products.H:56
Abstract template class to provide the transpose form of a form.
Definition products.H:63
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition zero.H:58
const volScalarField & T
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
Namespace for OpenFOAM.
errorManip< error > abort(error &err)
Definition errorManip.H:139
uint8_t direction
Definition direction.H:49
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
const direction noexcept
Definition scalarImpl.H:265
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...