https://mooseframework.inl.gov
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 
19 template <typename T>
20 ColumnMajorMatrixTempl<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 
26 template <typename T>
28  : _n_rows(LIBMESH_DIM), _n_cols(LIBMESH_DIM), _n_entries(_n_cols * _n_cols)
29 {
30  *this = rhs;
31 }
32 
33 template <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 }
44 
45 template <typename T>
47  : _n_rows(LIBMESH_DIM), _n_cols(LIBMESH_DIM), _n_entries(_n_cols * _n_cols)
48 {
49  *this = rhs;
50 }
51 
52 template <typename T>
54  : _n_rows(LIBMESH_DIM), _n_cols(LIBMESH_DIM), _n_entries(_n_cols * _n_cols)
55 {
56  *this = rhs;
57 }
58 
59 template <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 
79 template <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 
96 template <typename T>
98 ColumnMajorMatrixTempl<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 
115 template <typename T>
117 ColumnMajorMatrixTempl<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);
129 
130  return *this;
131 }
132 
133 template <typename T>
134 void
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 
164 template <>
165 void
168 {
169  mooseError("Eigen solves with AD types is not supported.");
170 }
171 
172 template <typename T>
173 void
175  ColumnMajorMatrixTempl<T> & eval_img,
176  ColumnMajorMatrixTempl<T> & evec_right,
177  ColumnMajorMatrixTempl<T> & evec_left) const
178 {
179  this->checkSquareness();
180 
181  ColumnMajorMatrixTempl<T> a(*this);
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);
192 
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);
197 
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 
226 template <>
227 void
232 {
233  mooseError("Eigen solves with AD types is not supported.");
234 }
235 
236 template <typename T>
237 void
239 {
240  this->checkSquareness();
241 
242  ColumnMajorMatrixTempl<T> a(*this);
243  ColumnMajorMatrixTempl<T> evals_real(_n_rows, 1), evals_img(_n_rows, 1),
244  evals_real2(_n_rows, _n_cols);
245  ColumnMajorMatrixTempl<T> evec_right(_n_rows, _n_cols), evec_left(_n_rows, _n_cols);
246  ColumnMajorMatrixTempl<T> evec_right_inverse(_n_rows, _n_cols);
247 
248  a.eigenNonsym(evals_real, evals_img, evec_right, evec_left);
249 
250  for (unsigned int i = 0; i < _n_rows; i++)
251  evals_real2(i, i) = std::exp(evals_real(i, 0));
252 
253  evec_right.inverse(evec_right_inverse);
254 
255  z = evec_right * evals_real2 * evec_right_inverse;
256 }
257 
258 template <typename T>
259 void
261 {
262  this->checkSquareness();
263  this->checkShapeEquality(invA);
264 
265  PetscBLASInt n = _n_rows;
266  PetscBLASInt return_value = 0;
267 
268  invA = *this;
269 
270  std::vector<PetscBLASInt> ipiv(n);
271  T * invA_data = invA.rawData();
272 
273  PetscBLASInt buffer_size = n * 64;
274  std::vector<T> buffer(buffer_size);
275 
276  LAPACKgetrf_(&n, &n, invA_data, &n, &ipiv[0], &return_value);
277 
278  LAPACKgetri_(&n, invA_data, &n, &ipiv[0], &buffer[0], &buffer_size, &return_value);
279 
280  if (return_value)
281  mooseException("Error in LAPACK matrix-inverse calculation");
282 }
283 
284 template <typename T>
285 void
287 {
288  if (_n_rows != _n_cols)
289  mooseError("ColumnMajorMatrix error: Unable to perform the operation on a non-square matrix.");
290 }
291 
292 template <typename T>
293 void
295 {
296  if (_n_rows != rhs._n_rows || _n_cols != rhs._n_cols)
297  mooseError("ColumnMajorMatrix error: Unable to perform the operation on matrices of different "
298  "shapes.");
299 }
300 
301 template <>
302 void
304 {
305  mooseError("Inverse solves with AD types is not supported for the ColumnMajorMatrix class.");
306 }
307 
308 template <typename T>
311 {
312  ColumnMajorMatrixTempl<T> & s = (*this);
313 
314  ColumnMajorMatrixTempl<T> ret_matrix(_n_rows, _n_cols);
315 
316  for (unsigned int j = 0; j < _n_cols; j++)
317  for (unsigned int i = 0; i < _n_rows; i++)
318  ret_matrix(i, j) = std::abs(s(i, j));
319 
320  return ret_matrix;
321 }
322 
323 template <typename T>
324 inline T
326 {
327  return std::sqrt(doubleContraction(*this));
328 }
329 
330 template class ColumnMajorMatrixTempl<Real>;
331 template class ColumnMajorMatrixTempl<ADReal>;
void inverse(ColumnMajorMatrixTempl< T > &invA) const
Returns inverse of a general matrix.
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
Definition: EigenADReal.h:42
This class defines a Tensor that can change its shape.
auto exp(const T &)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
ColumnMajorMatrixTempl< T > abs()
Returns a matrix that is the absolute value of the matrix this was called on.
T norm()
The Euclidean norm of the matrix.
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition: Moose.h:153
ColumnMajorMatrixTempl< T > kronecker(const ColumnMajorMatrixTempl< T > &rhs) const
Kronecker Product.
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.
T * rawData()
Returns a reference to the raw data pointer.
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 checkShapeEquality(const ColumnMajorMatrixTempl< T > &rhs) const
Check if matrices are of same shape.
ColumnMajorMatrixTempl(const unsigned int rows=Moose::dim, const unsigned int cols=Moose::dim)
Constructor that sets an initial number of entries and shape.
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
std::vector< T > _values
IntRange< T > make_range(T beg, T end)
ColumnMajorMatrixTempl< T > & operator=(const TypeTensor< T > &rhs)
Sets the values in this tensor to the values on the RHS.
void exp(ColumnMajorMatrixTempl< T > &z) const
Returns matrix that is the exponential of the matrix this was called on.