www.mooseframework.org
MatrixTools.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 #include "MatrixTools.h"
11 
12 // MOOSE includes
13 #include "Conversion.h"
14 #include "MooseError.h"
15 #include "MooseException.h"
16 
17 // PETSc includes
18 #include "petscblaslapack.h"
19 
20 namespace MatrixTools
21 {
22 void
23 inverse(const std::vector<std::vector<Real>> & m, std::vector<std::vector<Real>> & m_inv)
24 {
25  unsigned int n = m.size();
26 
27  // check the matrix m exists and is square
28  if (n == 0)
29  throw MooseException("Input matrix empty during matrix inversion.");
30  if (n != m_inv.size() || n != m[0].size() || n != m_inv[0].size())
31  throw MooseException("Input and output matrix are not same size square matrices.");
32 
33  // build the vectorial representation
34  std::vector<PetscScalar> A;
35  for (const auto & rowvec : m)
36  for (const auto & matrix_entry : rowvec)
37  A.push_back(matrix_entry);
38 
39  inverse(A, n);
40 
41  // build the inverse
42  unsigned int i = 0;
43  for (auto & rowvec : m_inv)
44  for (auto & inv_entry : rowvec)
45  inv_entry = A[i++];
46 }
47 
48 void
49 inverse(std::vector<PetscScalar> & A, unsigned int n)
50 {
51  mooseAssert(n >= 1, "MatrixTools::inverse - n (leading dimension) needs to be positive");
52  mooseAssert(n <= std::numeric_limits<unsigned int>::max(),
53  "MatrixTools::inverse - n (leading dimension) too large");
54 
55  std::vector<PetscBLASInt> ipiv(n);
56  std::vector<PetscScalar> buffer(n * 64);
57 
58  // Following does a LU decomposition of "square matrix A"
59  // upon return "A = P*L*U" if return_value == 0
60  // Here I use quotes because A is actually an array of length n^2, not a matrix of size n-by-n
61  PetscBLASInt return_value;
62  LAPACKgetrf_(reinterpret_cast<PetscBLASInt *>(&n),
63  reinterpret_cast<PetscBLASInt *>(&n),
64  &A[0],
65  reinterpret_cast<PetscBLASInt *>(&n),
66  &ipiv[0],
67  &return_value);
68 
69  if (return_value != 0)
70  throw MooseException(
71  return_value < 0
72  ? "Argument " + Moose::stringify(-return_value) +
73  " was invalid during LU factorization in MatrixTools::inverse."
74  : "Matrix on-diagonal entry " + Moose::stringify(return_value) +
75  " was exactly zero during LU factorization in MatrixTools::inverse.");
76 
77  // get the inverse of A
78  PetscBLASInt buffer_size = buffer.size();
79  LAPACKgetri_(reinterpret_cast<PetscBLASInt *>(&n),
80  &A[0],
81  reinterpret_cast<PetscBLASInt *>(&n),
82  &ipiv[0],
83  &buffer[0],
84  &buffer_size,
85  &return_value);
86 
87  if (return_value != 0)
88  throw MooseException(return_value < 0
89  ? "Argument " + Moose::stringify(-return_value) +
90  " was invalid during invert in MatrixTools::inverse."
91  : "Matrix on-diagonal entry " + Moose::stringify(return_value) +
92  " was exactly zero during invert in MatrixTools::inverse.");
93 }
94 }
void inverse(const std::vector< std::vector< Real >> &m, std::vector< std::vector< Real >> &m_inv)
Inverse the dense square matrix m using LAPACK routines.
Definition: MatrixTools.C:23
auto max(const L &left, const R &right)
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:62
Provides a way for users to bail out of the current solve.