https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MatrixTools.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#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
20namespace MatrixTools
21{
22void
23inverse(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
48void
49inverse(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}
Provides a way for users to bail out of the current solve.
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
std::string stringify(const T &t)
conversion to string
Definition Conversion.h:64