https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ColumnMajorMatrix.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10// MOOSE includes
11#include "ColumnMajorMatrix.h"
12
13#include "libmesh/petsc_macro.h"
14
15// PETSc includes
16#include <petscsys.h>
17#include <petscblaslapack.h>
18
19template <typename T>
20ColumnMajorMatrixTempl<T>::ColumnMajorMatrixTempl(unsigned int rows, unsigned int cols)
21 : _n_rows(rows), _n_cols(cols), _n_entries(rows * cols), _values(rows * cols, 0.0)
22{
23 _values.resize(rows * cols);
24}
25
26template <typename T>
28 : _n_rows(LIBMESH_DIM), _n_cols(LIBMESH_DIM), _n_entries(_n_cols * _n_cols)
29{
30 *this = rhs;
31}
32
33template <typename T>
35 : _n_rows(LIBMESH_DIM),
36 _n_cols(LIBMESH_DIM),
37 _n_entries(LIBMESH_DIM * LIBMESH_DIM),
38 _values(LIBMESH_DIM * LIBMESH_DIM)
39{
40 for (const auto j : make_range(Moose::dim))
41 for (const auto i : make_range(Moose::dim))
42 (*this)(i, j) = rhs(i, j);
43}
45template <typename T>
47 : _n_rows(LIBMESH_DIM), _n_cols(LIBMESH_DIM), _n_entries(_n_cols * _n_cols)
48{
49 *this = rhs;
50}
52template <typename T>
54 : _n_rows(LIBMESH_DIM), _n_cols(LIBMESH_DIM), _n_entries(_n_cols * _n_cols)
55{
56 *this = rhs;
57}
59template <typename T>
61 const TypeVector<T> & col2,
62 const TypeVector<T> & col3)
63 : _n_rows(LIBMESH_DIM),
64 _n_cols(LIBMESH_DIM),
65 _n_entries(LIBMESH_DIM * LIBMESH_DIM),
66 _values(LIBMESH_DIM * LIBMESH_DIM)
67{
68 unsigned int entry = 0;
69 for (const auto i : make_range(Moose::dim))
70 _values[entry++] = col1(i);
71
72 for (const auto i : make_range(Moose::dim))
73 _values[entry++] = col2(i);
74
75 for (const auto i : make_range(Moose::dim))
76 _values[entry++] = col3(i);
77}
78
79template <typename T>
82{
83 rhs.checkSquareness();
84
85 ColumnMajorMatrixTempl<T> ret_matrix(_n_rows * rhs._n_rows, _n_cols * rhs._n_cols);
86
87 for (unsigned int i = 0; i < _n_rows; i++)
88 for (unsigned int j = 0; j < _n_cols; j++)
89 for (unsigned int k = 0; k < rhs._n_rows; k++)
90 for (unsigned int l = 0; l < rhs._n_cols; l++)
91 ret_matrix(((i * _n_rows) + k), ((j * _n_cols) + l)) = (*this)(i, j) * rhs(k, l);
92
93 return ret_matrix;
94}
95
96template <typename T>
98ColumnMajorMatrixTempl<T>::operator=(const DenseMatrix<T> & rhs)
99{
100 if (_n_rows != rhs.m() || _n_cols != rhs.n())
101 mooseError("ColumnMajorMatrix and DenseMatrix should be of the same shape.");
102
103 _n_rows = rhs.m();
104 _n_cols = rhs.n();
105 _n_entries = rhs.m() * rhs.n();
106 _values.resize(rhs.m() * rhs.n());
107
108 for (unsigned int j = 0; j < _n_cols; ++j)
109 for (unsigned int i = 0; i < _n_rows; ++i)
110 (*this)(i, j) = rhs(i, j);
111
112 return *this;
113}
114
115template <typename T>
117ColumnMajorMatrixTempl<T>::operator=(const DenseVector<T> & rhs)
118{
119 if (_n_rows != rhs.size() || _n_cols != 1)
120 mooseError("ColumnMajorMatrix and DenseVector should be of the same shape.");
121
122 _n_rows = rhs.size();
123 _n_cols = 1;
124 _n_entries = rhs.size();
125 _values.resize(rhs.size());
126
127 for (unsigned int i = 0; i < _n_rows; ++i)
128 (*this)(i) = rhs(i);
130 return *this;
131}
132
133template <typename T>
134void
136 ColumnMajorMatrixTempl<T> & evec) const
137{
138 this->checkSquareness();
139
140 char jobz = 'V';
141 char uplo = 'U';
142 PetscBLASInt n = _n_rows;
143 PetscBLASInt return_value = 0;
144
145 eval._n_rows = _n_rows;
146 eval._n_cols = 1;
147 eval._n_entries = _n_rows;
148 eval._values.resize(_n_rows);
149
150 evec = *this;
151
152 T * eval_data = eval.rawData();
153 T * evec_data = evec.rawData();
154
155 PetscBLASInt buffer_size = n * 64;
156 std::vector<T> buffer(buffer_size);
157
158 LAPACKsyev_(&jobz, &uplo, &n, evec_data, &n, eval_data, &buffer[0], &buffer_size, &return_value);
159
160 if (return_value)
161 mooseError("error in lapack eigen solve");
162}
163
164template <>
165void
168{
169 mooseError("Eigen solves with AD types is not supported.");
170}
171
172template <typename T>
173void
175 ColumnMajorMatrixTempl<T> & eval_img,
176 ColumnMajorMatrixTempl<T> & evec_right,
177 ColumnMajorMatrixTempl<T> & evec_left) const
178{
179 this->checkSquareness();
180
182
183 char jobvl = 'V';
184 char jobvr = 'V';
185 PetscBLASInt n = _n_rows;
186 PetscBLASInt return_value = 0;
187
188 eval_real._n_rows = _n_rows;
189 eval_real._n_cols = 1;
190 eval_real._n_entries = _n_rows;
191 eval_real._values.resize(_n_rows);
193 eval_img._n_rows = _n_rows;
194 eval_img._n_cols = 1;
195 eval_img._n_entries = _n_rows;
196 eval_img._values.resize(_n_rows);
198 T * a_data = a.rawData();
199 T * eval_r = eval_real.rawData();
200 T * eval_i = eval_img.rawData();
201 T * evec_ri = evec_right.rawData();
202 T * evec_le = evec_left.rawData();
203
204 PetscBLASInt buffer_size = n * 64;
205 std::vector<T> buffer(buffer_size);
206
207 LAPACKgeev_(&jobvl,
208 &jobvr,
209 &n,
210 a_data,
211 &n,
212 eval_r,
213 eval_i,
214 evec_le,
215 &n,
216 evec_ri,
217 &n,
218 &buffer[0],
219 &buffer_size,
220 &return_value);
221
222 if (return_value)
223 mooseError("error in lapack eigen solve");
224}
225
226template <>
227void
235
236template <typename T>
237void
239{
240 using std::exp;
241 this->checkSquareness();
242
244 ColumnMajorMatrixTempl<T> evals_real(_n_rows, 1), evals_img(_n_rows, 1),
245 evals_real2(_n_rows, _n_cols);
246 ColumnMajorMatrixTempl<T> evec_right(_n_rows, _n_cols), evec_left(_n_rows, _n_cols);
247 ColumnMajorMatrixTempl<T> evec_right_inverse(_n_rows, _n_cols);
248
249 a.eigenNonsym(evals_real, evals_img, evec_right, evec_left);
250
251 for (unsigned int i = 0; i < _n_rows; i++)
252 evals_real2(i, i) = exp(evals_real(i, 0));
253
254 evec_right.inverse(evec_right_inverse);
255
256 z = evec_right * evals_real2 * evec_right_inverse;
257}
258
259template <typename T>
260void
262{
263 this->checkSquareness();
264 this->checkShapeEquality(invA);
265
266 PetscBLASInt n = _n_rows;
267 PetscBLASInt return_value = 0;
268
269 invA = *this;
270
271 std::vector<PetscBLASInt> ipiv(n);
272 T * invA_data = invA.rawData();
273
274 PetscBLASInt buffer_size = n * 64;
275 std::vector<T> buffer(buffer_size);
276
277 LAPACKgetrf_(&n, &n, invA_data, &n, &ipiv[0], &return_value);
278
279 LAPACKgetri_(&n, invA_data, &n, &ipiv[0], &buffer[0], &buffer_size, &return_value);
280
281 if (return_value)
282 mooseException("Error in LAPACK matrix-inverse calculation");
283}
284
285template <typename T>
286void
288{
289 if (_n_rows != _n_cols)
290 mooseError("ColumnMajorMatrix error: Unable to perform the operation on a non-square matrix.");
291}
292
293template <typename T>
294void
296{
297 if (_n_rows != rhs._n_rows || _n_cols != rhs._n_cols)
298 mooseError("ColumnMajorMatrix error: Unable to perform the operation on matrices of different "
299 "shapes.");
300}
301
302template <>
303void
305{
306 mooseError("Inverse solves with AD types is not supported for the ColumnMajorMatrix class.");
307}
308
309template <typename T>
312{
313 using std::abs;
314 ColumnMajorMatrixTempl<T> & s = (*this);
316 ColumnMajorMatrixTempl<T> ret_matrix(_n_rows, _n_cols);
317
318 for (unsigned int j = 0; j < _n_cols; j++)
319 for (unsigned int i = 0; i < _n_rows; i++)
320 ret_matrix(i, j) = abs(s(i, j));
321
322 return ret_matrix;
323}
324
325template <typename T>
326inline T
328{
329 using std::sqrt;
330 return sqrt(doubleContraction(*this));
331}
332
333template class ColumnMajorMatrixTempl<Real>;
334template class ColumnMajorMatrixTempl<ADReal>;
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
This class defines a Tensor that can change its shape.
void eigenNonsym(ColumnMajorMatrixTempl< T > &eval_real, ColumnMajorMatrixTempl< T > &eval_img, ColumnMajorMatrixTempl< T > &evec_right, ColumnMajorMatrixTempl< T > &eve_left) const
Returns eigen system solve for a non-symmetric real matrix.
void exp(ColumnMajorMatrixTempl< T > &z) const
Returns matrix that is the exponential of the matrix this was called on.
ColumnMajorMatrixTempl(const unsigned int rows=Moose::dim, const unsigned int cols=Moose::dim)
Constructor that sets an initial number of entries and shape.
ColumnMajorMatrixTempl< T > & operator=(const TypeTensor< T > &rhs)
Sets the values in this tensor to the values on the RHS.
void inverse(ColumnMajorMatrixTempl< T > &invA) const
Returns inverse of a general matrix.
T norm()
The Euclidean norm of the matrix.
void eigen(ColumnMajorMatrixTempl< T > &eval, ColumnMajorMatrixTempl< T > &evec) const
Returns eigen system solve for a symmetric real matrix.
void checkSquareness() const
Check if matrix is square.
ColumnMajorMatrixTempl< T > abs()
Returns a matrix that is the absolute value of the matrix this was called on.
ColumnMajorMatrixTempl< T > kronecker(const ColumnMajorMatrixTempl< T > &rhs) const
Kronecker Product.
T * rawData()
Returns a reference to the raw data pointer.
void checkShapeEquality(const ColumnMajorMatrixTempl< T > &rhs) const
Check if matrices are of same shape.
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition Moose.h:165