24 #if (LIBMESH_HAVE_PETSC) 27 # include <petscblaslapack.h> 34 #if (LIBMESH_HAVE_PETSC && LIBMESH_USE_REAL_NUMBERS) 48 result_size = other.
m() * this->n();
49 if (other.
n() == this->m())
52 libmesh_fallthrough();
55 result_size = other.
n() * this->m();
56 if (other.
m() == this->n())
59 libmesh_fallthrough();
60 case LEFT_MULTIPLY_TRANSPOSE:
62 result_size = other.
n() * this->n();
63 if (other.
m() == this->m())
66 libmesh_fallthrough();
67 case RIGHT_MULTIPLY_TRANSPOSE:
69 result_size = other.
m() * this->m();
70 if (other.
n() == this->n())
73 libmesh_fallthrough();
75 libmesh_error_msg(
"Unknown flag selected or matrices are incompatible for multiplication.");
79 const DenseMatrix<T> * const_that = cast_ptr<const DenseMatrix<T> *>(&other);
96 if (flag==RIGHT_MULTIPLY || flag==RIGHT_MULTIPLY_TRANSPOSE)
113 PetscBLASInt M =
static_cast<PetscBLASInt
>(
A->n() );
122 PetscBLASInt N =
static_cast<PetscBLASInt
>( B->
m() );
132 PetscBLASInt K =
static_cast<PetscBLASInt
>(
A->m() );
136 PetscBLASInt LDA =
static_cast<PetscBLASInt
>(
A->n() );
140 PetscBLASInt LDB =
static_cast<PetscBLASInt
>( B->
n() );
142 if (flag == LEFT_MULTIPLY_TRANSPOSE)
145 N =
static_cast<PetscBLASInt
>( B->
n() );
148 else if (flag == RIGHT_MULTIPLY_TRANSPOSE)
156 PetscBLASInt LDC = M;
167 std::vector<T> result (result_size);
170 BLASgemm_(transa, transb, &M, &N, &K, &alpha,
A->get_values().data(), &LDA, B->
get_values().data(), &LDB, &beta, result.data(), &LDC);
175 case LEFT_MULTIPLY: { this->_m = other.
m();
break; }
176 case RIGHT_MULTIPLY: { this->_n = other.
n();
break; }
177 case LEFT_MULTIPLY_TRANSPOSE: { this->_m = other.
n();
break; }
178 case RIGHT_MULTIPLY_TRANSPOSE: { this->_n = other.
m();
break; }
180 libmesh_error_msg(
"Unknown flag selected.");
184 this->_val.swap(result);
193 libmesh_error_msg(
"No PETSc-provided BLAS/LAPACK available!");
204 #if (LIBMESH_HAVE_PETSC && LIBMESH_USE_REAL_NUMBERS) 211 libmesh_assert_equal_to (this->_decomposition_type, NONE);
219 PetscBLASInt M = this->n();
224 PetscBLASInt N = this->m();
233 PetscBLASInt LDA = M;
239 this->_pivots.resize(
std::min(M,N) );
248 PetscBLASInt INFO = 0;
251 LAPACKgetrf_(&M, &N, this->_val.data(), &LDA, _pivots.data(), &INFO);
255 libmesh_error_msg(
"INFO=" << INFO <<
", Error during Lapack LU factorization!");
258 this->_decomposition_type = LU_BLAS_LAPACK;
266 libmesh_error_msg(
"No PETSc-provided BLAS/LAPACK available!");
302 std::vector<Real> sigma_val;
303 std::vector<Number> U_val;
304 std::vector<Number> VT_val;
306 _svd_helper(JOBU, JOBVT, sigma_val, U_val, VT_val);
309 sigma.
resize(cast_int<unsigned int>(sigma_val.size()));
311 sigma(i) = sigma_val[i];
351 std::vector<Real> sigma_val;
354 int min_MN = (M < N) ? M : N;
373 sigma.
resize(cast_int<unsigned int>(sigma_val.size()));
375 sigma(i) = sigma_val[i];
378 #if (LIBMESH_HAVE_PETSC) 383 std::vector<Real> & sigma_val,
384 std::vector<Number> & U_val,
385 std::vector<Number> & VT_val)
391 PetscBLASInt M = this->n();
396 PetscBLASInt N = this->m();
398 PetscBLASInt min_MN = (M < N) ? M : N;
399 PetscBLASInt max_MN = (M > N) ? M : N;
414 PetscBLASInt LDA = M;
418 sigma_val.resize( min_MN );
423 PetscBLASInt LDU = M;
432 U_val.resize( LDU*min_MN );
434 U_val.resize( LDU*M );
439 PetscBLASInt LDVT = N;
449 VT_val.resize( LDVT*N );
460 PetscBLASInt larger = (3*min_MN+max_MN > 5*min_MN) ? 3*min_MN+max_MN : 5*min_MN;
461 PetscBLASInt LWORK = (larger > 1) ? larger : 1;
471 std::vector<Number> WORK( LWORK );
480 PetscBLASInt INFO = 0;
483 #ifdef LIBMESH_USE_REAL_NUMBERS 485 LAPACKgesvd_(&JOBU, &JOBVT, &M, &N, _val.data(), &LDA, sigma_val.data(), U_val.data(),
486 &LDU, VT_val.data(), &LDVT, WORK.data(), &LWORK, &INFO);
491 std::vector<Number> val_copy(_val.size());
492 for (std::size_t i=0; i<_val.size(); i++)
493 val_copy[i] = _val[i];
495 std::vector<Real> RWORK(5 * min_MN);
496 LAPACKgesvd_(&JOBU, &JOBVT, &M, &N, val_copy.data(), &LDA, sigma_val.data(), U_val.data(),
497 &LDU, VT_val.data(), &LDVT, WORK.data(), &LWORK, RWORK.data(), &INFO);
502 libmesh_error_msg(
"INFO=" << INFO <<
", Error during Lapack SVD calculation!");
512 std::vector<Number> &,
513 std::vector<Number> &)
515 libmesh_error_msg(
"No PETSc-provided BLAS/LAPACK available!");
522 #if (LIBMESH_HAVE_PETSC && LIBMESH_USE_REAL_NUMBERS) 523 #if !PETSC_VERSION_LESS_THAN(3,1,0) 539 this->get_transpose(A_trans);
544 PetscBLASInt M = A_trans.
n();
549 PetscBLASInt N = A_trans.
m();
552 PetscBLASInt max_MN =
std::max(M,N);
553 PetscBLASInt min_MN =
std::min(M,N);
560 PetscBLASInt NRHS = 1;
568 std::vector<T> & A_trans_vals = A_trans.
get_values();
572 PetscBLASInt LDA = M;
594 PetscBLASInt LDB = x.
size();
599 std::vector<T> S(min_MN);
610 PetscBLASInt RANK = 0;
624 PetscBLASInt LWORK = (3*min_MN +
std::max(2*min_MN,
std::max(max_MN, NRHS))) * 3/2;
628 std::vector<T> WORK(LWORK);
636 PetscBLASInt INFO = 0;
651 LAPACKgelss_(&M, &N, &NRHS, A_trans_vals.data(), &LDA, B.data(), &LDB, S.data(), &RCOND, &RANK, WORK.data(), &LWORK, &INFO);
655 libmesh_error_msg(
"Error, argument " << -INFO <<
" to LAPACKgelss_ had an illegal value.");
657 libmesh_error_msg(
"The algorithm for computing the SVD failed to converge!");
683 libmesh_error_msg(
"svd_solve() requires PETSc >= 3.1!");
686 #endif // !PETSC_VERSION_LESS_THAN(3,1,0) 694 libmesh_not_implemented();
696 #endif // (LIBMESH_HAVE_PETSC && LIBMESH_USE_REAL_NUMBERS) 700 #if (LIBMESH_HAVE_PETSC && LIBMESH_USE_REAL_NUMBERS) 709 if (this->m() != this->n())
710 libmesh_error_msg(
"Can only compute eigen-decompositions for square matrices.");
745 char JOBVL = VL ?
'V' :
'N';
750 char JOBVR = VR ?
'V' :
'N';
754 PetscBLASInt N = this->m();
762 PetscBLASInt LDA = N;
789 PetscBLASInt LDVL = VL ? N : 1;
806 PetscBLASInt LDVR = VR ? N : 1;
820 PetscBLASInt LWORK = (VR || VL) ? 4*N : 3*N;
821 std::vector<T> WORK(LWORK);
830 PetscBLASInt INFO = 0;
833 std::vector<T> & lambda_real_val = lambda_real.
get_values();
834 std::vector<T> & lambda_imag_val = lambda_imag.
get_values();
837 T * VR_ptr =
nullptr;
844 T * VL_ptr =
nullptr;
857 lambda_real_val.data(),
858 lambda_imag_val.data(),
869 libmesh_error_msg(
"INFO=" << INFO <<
", Error during Lapack eigenvalue calculation!");
899 libmesh_error_msg(
"_evd_lapack is currently only available when LIBMESH_USE_REAL_NUMBERS is defined!");
908 #if (LIBMESH_HAVE_PETSC && LIBMESH_USE_REAL_NUMBERS) 923 PetscBLASInt N = this->m();
929 PetscBLASInt NRHS = 1;
937 PetscBLASInt LDA = N;
959 PetscBLASInt LDB = N;
964 PetscBLASInt INFO = 0;
967 LAPACKgetrs_(TRANS, &N, &NRHS, _val.data(), &LDA, _pivots.data(), x_vec.data(), &LDB, &INFO);
971 libmesh_error_msg(
"INFO=" << INFO <<
", Error during Lapack LU solve!");
988 libmesh_error_msg(
"No PETSc-provided BLAS/LAPACK available!");
997 #if (LIBMESH_HAVE_PETSC && LIBMESH_USE_REAL_NUMBERS) 1011 if ((dest.
size() != this->m()) || (arg.
size() != this->n()))
1012 libmesh_error_msg(
"Improper input argument sizes!");
1020 if ((dest.
size() != this->n()) || (arg.
size() != this->m()))
1021 libmesh_error_msg(
"Improper input argument sizes!");
1039 PetscBLASInt M = this->n();
1044 PetscBLASInt N = this->m();
1063 PetscBLASInt LDA = M;
1079 PetscBLASInt INCX = 1;
1099 PetscBLASInt INCY = 1;
1102 BLASgemv_(TRANS, &M, &N, &alpha, a.data(), &LDA, x.data(), &INCX, &beta, y.data(), &INCY);
1109 template<
typename T>
1116 libmesh_error_msg(
"No PETSc-provided BLAS/LAPACK available!");
1128 DenseVector<Real> &);
1131 DenseVector<Real> &,
1132 const DenseVector<Real> &,
1136 DenseMatrix<Number> &,
1137 DenseMatrix<Number> &);
1140 std::vector<Real> &,
1141 std::vector<Number> &,
1142 std::vector<Number> &);
1145 DenseVector<Real> &,
1146 DenseMatrix<Real> *,
1147 DenseMatrix<Real> *);
1149 #if !(LIBMESH_USE_REAL_NUMBERS) 1153 DenseVector<Number> &);
1156 DenseVector<Number> &,
1157 const DenseVector<Number> &,
1161 DenseMatrix<Number> &,
1162 DenseMatrix<Number> &);
1165 std::vector<Real> &,
1166 std::vector<Number> &,
1167 std::vector<Number> &);
1170 DenseVector<Number> &,
1171 DenseMatrix<Number> *,
1172 DenseMatrix<Number> *);
virtual unsigned int size() const override
void _lu_decompose_lapack()
void _evd_lapack(DenseVector< T > &lambda_real, DenseVector< T > &lambda_imag, DenseMatrix< T > *VL=nullptr, DenseMatrix< T > *VR=nullptr)
void resize(const unsigned int n)
std::vector< T > & get_values()
void _lu_back_substitute_lapack(const DenseVector< T > &b, DenseVector< T > &x)
void _svd_lapack(DenseVector< Real > &sigma)
long double max(long double a, double b)
void _svd_solve_lapack(const DenseVector< T > &rhs, DenseVector< T > &x, Real rcond) const
void _multiply_blas(const DenseMatrixBase< T > &other, _BLAS_Multiply_Flag flag)
void _svd_helper(char JOBU, char JOBVT, std::vector< Real > &sigma_val, std::vector< Number > &U_val, std::vector< Number > &VT_val)
std::vector< T > & get_values()
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static PetscErrorCode Mat * A
void swap(Iterator &lhs, Iterator &rhs)
void _matvec_blas(T alpha, T beta, DenseVector< T > &dest, const DenseVector< T > &arg, bool trans=false) const
void resize(const unsigned int new_m, const unsigned int new_n)
A matrix object used for finite element assembly and numerics.
long double min(long double a, double b)