15#ifndef B2PARDISO_SOLVER_H_
16#define B2PARDISO_SOLVER_H_
18#include "/opt/intel/composerxe/mkl/include/mkl_pardiso.h"
19#include "/opt/intel/composerxe/mkl/include/mkl_types.h"
20#include "b2sparse_solver.H"
30namespace b2000 {
namespace b2linalg {
33class PARDISO_LDLt_seq_sparse_direct_solver :
public LDLt_sparse_solver<T> {
35 PARDISO_LDLt_seq_sparse_direct_solver(
bool definit_positive =
false) {
40 size_t s,
size_t nnz,
const size_t* colind,
const size_t* rowind,
const T* value,
41 const int connectivity,
const Dictionary& dictionary) {}
43 void update_value() {}
46 size_t s,
size_t nrhs,
const T* b,
size_t ldb, T* x,
size_t ldx,
47 char left_or_right =
' ') {
53class PARDISO_LDLt_seq_extension_sparse_direct_solver :
public LDLt_extension_sparse_solver<T> {
55 PARDISO_LDLt_seq_extension_sparse_direct_solver(
bool definit_positive =
false) {
60 size_t s,
size_t nnz,
const size_t* colind,
const size_t* rowind,
const T* value,
61 size_t s_ext,
const int connectivity,
const Dictionary& dictionary) {}
63 void update_value() {}
66 size_t s,
size_t nrhs,
const T* b,
size_t ldb, T* x,
size_t ldx,
const T* ma = 0,
67 const T* mb = 0,
const T* mc = 0,
char left_or_right =
' ') {
73class PARDISO_LU_seq_sparse_direct_solver :
public LU_sparse_solver<T> {
75 PARDISO_LU_seq_sparse_direct_solver() {
80 size_t s,
size_t nnz,
const size_t* colind,
const size_t* rowind,
const T* value,
81 const int connectivity,
const Dictionary& dictionary) {}
83 void update_value() {}
86 size_t s,
size_t nrhs,
const T* b,
size_t ldb, T* x,
size_t ldx,
87 char left_or_right =
' ') {
93class PARDISO_LU_seq_extension_sparse_direct_solver :
public LU_extension_sparse_solver<T> {
95 PARDISO_LU_seq_extension_sparse_direct_solver() {
100 size_t s,
size_t nnz,
const size_t* colind,
const size_t* rowind,
const T* value,
101 size_t s_ext,
const int connectivity,
const Dictionary& dictionary) {}
103 void update_value() {}
106 size_t s,
size_t nrhs,
const T* b,
size_t ldb, T* x,
size_t ldx,
const T* ma = 0,
107 const T* mb = 0,
const T* mc = 0,
char left_or_right =
' ') {
113inline void decode_pardiso_param(
const Dictionary& d, T* iparam) {
114 std::string icntl = d.get_string(
"PARDISO_IPARAM",
"");
116 std::istringstream iss(icntl);
120 if (iss >> k && iss >> c && iss >> v) {
121 if (c !=
':' || (k <= 0 && k > 64)) {
122 Exception() <<
"Cannot parse the PARDISO_IPARAM analysis directive " << icntl
127 Exception() <<
"Cannot parse the PARDISO_IPARAM analysis directive " << icntl
133 Exception() <<
"Cannot parse the PARDISO_IPARAM analysis directive " << icntl
141inline std::string decode_pardiso_error_message(T error) {
144 return "input inconsistent";
146 return "not enough memory";
148 return "reordering problem";
150 return "zero pivot, numerical factorization or iterative refinement problem";
152 return "unclassified (internal) error";
154 return "reordering failed (matrix types 11 and 13 only)";
156 return "diagonal matrix is singular";
158 return "32-bit integer overflow problem";
160 return "not enough memory for OOC";
162 return "problems with opening OOC temporary files";
164 return "read/write problems with the OOC data file";
168 return "Unknown error code";
172class PARDISO_LDLt_seq_sparse_direct_solver<double> :
public LDLt_sparse_solver<double> {
174 PARDISO_LDLt_seq_sparse_direct_solver(
bool definit_positive =
false)
175 : updated_value(false), n(0), colptr(0), row(0), avals(0) {
176 std::fill_n(pt, 64, (
void*)(0));
177 mtype = definit_positive ? 2 : -2;
179 int imtype = definit_positive ? 2 : -2;
181 pardisoinit(pt, &imtype, iiparm);
182 std::copy(iiparm, iiparm + 64, iparm);
184 pardisoinit(pt, &mtype, iparm);
186 logging::Logger logger =
191 ~PARDISO_LDLt_seq_sparse_direct_solver() {
193 long long int maxfct = 1;
194 long long int mnum = 1;
195 long long int phase = -1;
197 long long int nrhs = 1;
201 pt, &maxfct, &mnum, &mtype, &phase, &n, &ddum, colptr, row, &idum, &nrhs, iparm,
202 &msglvl, &ddum, &ddum, &error);
212 pt, &maxfct, &mnum, &mtype, &phase, &n, &ddum, &colptr[0], &row[0], &idum, &nrhs,
213 iparm, &msglvl, &ddum, &ddum, &error);
216 Exception() <<
"The PARDISO solver return error " <<
error <<
", "
217 << decode_pardiso_error_message(error) <<
THROW;
222 size_t s,
size_t nnz,
const size_t* colind,
const size_t* rowind,
const double* value,
223 const int connectivity,
const Dictionary& dictionary) {
224 if (s == 0) {
return; }
225 decode_pardiso_param(dictionary, iparm);
228 avals =
const_cast<double*
>(value);
231 colptr =
reinterpret_cast<long long int*
>(
const_cast<size_t*
>(colind));
232 row =
reinterpret_cast<long long int*
>(
const_cast<size_t*
>(rowind));
233 long long int maxfct = 1;
234 long long int mnum = 1;
235 long long int phase = 12;
237 long long int nrhs = 0;
241 pt, &maxfct, &mnum, &mtype, &phase, &n, avals, colptr, row, &idum, &nrhs, iparm,
242 &msglvl, &ddum, &ddum, &error);
244 colptr.resize(s + 1);
247 size_t ptr_in = colind[0];
250 for (
size_t j = 1; j <= s; ++j) {
251 colptr[j] = colind[j] + 1;
252 const size_t ptr_end = colind[j];
253 for (; ptr_in != ptr_end; ++ptr_in, ++ptr_out) {
254 row[ptr_out] = rowind[ptr_in] + 1;
267 pt, &maxfct, &mnum, &mtype, &phase, &n, avals, &colptr[0], &row[0], &idum, &nrhs,
268 iparm, &msglvl, &ddum, &ddum, &error);
271 Exception() <<
"The PARDISO solver return error " <<
error <<
", "
272 << decode_pardiso_error_message(error) <<
THROW;
274 updated_value =
false;
277 void update_value() { updated_value =
true; }
280 size_t s,
size_t nrhs,
const double* b,
size_t ldb,
double* x,
size_t ldx,
281 char left_or_right =
' ') {
282 if (s == 0) {
return; }
284 long long int maxfct = 1;
285 long long int mnum = 1;
286 long long int phase = updated_value ? 23 : 33;
287 long long int inrhs = nrhs;
291 pt, &maxfct, &mnum, &mtype, &phase, &n, avals, colptr, row, &idum, &inrhs, iparm,
292 &msglvl,
const_cast<double*
>(b), x, &error);
296 int phase = updated_value ? 23 : 33;
301 pt, &maxfct, &mnum, &mtype, &phase, &n, avals, &colptr[0], &row[0], &idum, &inrhs,
302 iparm, &msglvl,
const_cast<double*
>(b), x, &error);
305 Exception() <<
"The PARDISO solver return error " <<
error <<
", "
306 << decode_pardiso_error_message(error) <<
THROW;
308 updated_value =
false;
316 long long int* colptr;
319 long long int msglvl;
320 long long int iparm[64];
323 std::vector<int> colptr;
324 std::vector<int> row;
333class PARDISO_LDLt_seq_extension_sparse_direct_solver<double>
334 :
public LDLt_extension_sparse_solver<double>,
335 public PARDISO_LDLt_seq_sparse_direct_solver<double> {
337 PARDISO_LDLt_seq_extension_sparse_direct_solver(
bool definit_positive =
false)
338 : PARDISO_LDLt_seq_sparse_direct_solver<double>(definit_positive), div(0) {}
341 size_t size_,
size_t nnz_,
const size_t* colind_,
const size_t* rowind_,
342 const double* value_,
size_t size_ext_,
const int connectivity,
343 const Dictionary& dictionary) {
346 PARDISO_LDLt_seq_sparse_direct_solver<double>::init(
347 size_, nnz_, colind_, rowind_, value_, connectivity, dictionary);
348 m_ab.resize(size_ * 2);
351 void update_value() { PARDISO_LDLt_seq_sparse_direct_solver<double>::update_value(); }
354 size_t s,
size_t nrhs,
const double* b,
size_t ldb,
double* x,
size_t ldx,
355 const double* ma_ = 0,
const double* mb_ = 0,
const double* mc_ = 0,
356 char left_or_right =
' ') {
358 std::copy(ma_, ma_ + s - 1, &m_ab[0]);
359 std::copy(mb_, mb_ + s - 1, &m_ab[s - 1]);
360 PARDISO_LDLt_seq_sparse_direct_solver<double>::resolve(
361 s - 1, 2, &m_ab[0], s - 1, &m_ab[0], s - 1);
362 div = 1 / (*mc_ - blas::dot(s - 1, ma_, 1, &m_ab[s - 1], 1));
365 for (
size_t i = 0; i != nrhs; ++i) {
366 const double x2 = x[ldx * i + s - 1] =
367 div * (b[ldb * i + s - 1] - blas::dot(s - 1, b + ldb * i, 1, &m_ab[s - 1], 1));
368 PARDISO_LDLt_seq_sparse_direct_solver<double>::resolve(
369 s - 1, 1, b + ldb * i, ldb, x + ldx * i, ldx);
370 blas::axpy(s - 1, -x2, &m_ab[0], 1, x + ldx * i, 1);
375 std::vector<double> m_ab;
380class PARDISO_LU_seq_sparse_direct_solver<double> :
public LU_sparse_solver<double> {
382 PARDISO_LU_seq_sparse_direct_solver()
383 : updated_value(false), n(0), colptr(0), row(0), avals(0) {
384 std::fill_n(pt, 64, (
void*)(0));
388 pardisoinit(pt, &mtype, iiparm);
389 std::copy(iiparm, iiparm + 64, iparm);
391 pardisoinit(pt, &mtype, iparm);
393 logging::Logger logger =
398 ~PARDISO_LU_seq_sparse_direct_solver() {
400 long long int maxfct = 1;
401 long long int mnum = 1;
402 long long int mtype = 11;
403 long long int phase = -1;
405 long long int nrhs = 1;
409 pt, &maxfct, &mnum, &mtype, &phase, &n, &ddum, colptr, row, &idum, &nrhs, iparm,
410 &msglvl, &ddum, &ddum, &error);
421 pt, &maxfct, &mnum, &mtype, &phase, &n, &ddum, &colptr[0], &row[0], &idum, &nrhs,
422 iparm, &msglvl, &ddum, &ddum, &error);
425 Exception() <<
"The PARDISO solver return error " <<
error <<
", "
426 << decode_pardiso_error_message(error) <<
THROW;
431 size_t s,
size_t nnz,
const size_t* colind,
const size_t* rowind,
const double* value,
432 const int connectivity,
const Dictionary& dictionary) {
433 if (s == 0) {
return; }
434 decode_pardiso_param(dictionary, iparm);
437 avals =
const_cast<double*
>(value);
440 colptr =
reinterpret_cast<long long int*
>(
const_cast<size_t*
>(colind));
441 row =
reinterpret_cast<long long int*
>(
const_cast<size_t*
>(rowind));
442 long long int maxfct = 1;
443 long long int mnum = 1;
444 long long int mtype = 11;
445 long long int phase = 12;
447 long long int nrhs = 0;
451 pt, &maxfct, &mnum, &mtype, &phase, &n, avals, colptr, row, &idum, &nrhs, iparm,
452 &msglvl, &ddum, &ddum, &error);
454 colptr.resize(s + 1);
457 size_t ptr_in = colind[0];
460 for (
size_t j = 1; j <= s; ++j) {
461 colptr[j] = colind[j] + 1;
462 const size_t ptr_end = colind[j];
463 for (; ptr_in != ptr_end; ++ptr_in, ++ptr_out) {
464 row[ptr_out] = rowind[ptr_in] + 1;
478 pt, &maxfct, &mnum, &mtype, &phase, &n, avals, &colptr[0], &row[0], &idum, &nrhs,
479 iparm, &msglvl, &ddum, &ddum, &error);
482 Exception() <<
"The PARDISO solver return error " <<
error <<
", "
483 << decode_pardiso_error_message(error) <<
THROW;
485 updated_value =
false;
488 void update_value() { updated_value =
true; }
491 size_t s,
size_t nrhs,
const double* b,
size_t ldb,
double* x,
size_t ldx,
492 char left_or_right =
' ') {
493 if (s == 0) {
return; }
495 long long int maxfct = 1;
496 long long int mnum = 1;
497 long long int mtype = 11;
498 long long int phase = updated_value ? 23 : 33;
499 long long int inrhs = nrhs;
503 pt, &maxfct, &mnum, &mtype, &phase, &n, avals, colptr, row, &idum, &inrhs, iparm,
504 &msglvl,
const_cast<double*
>(b), x, &error);
509 int phase = updated_value ? 23 : 33;
514 pt, &maxfct, &mnum, &mtype, &phase, &n, avals, &colptr[0], &row[0], &idum, &inrhs,
515 iparm, &msglvl,
const_cast<double*
>(b), x, &error);
518 Exception() <<
"The PARDISO solver return error " <<
error <<
", "
519 << decode_pardiso_error_message(error) <<
THROW;
521 updated_value =
false;
529 long long int* colptr;
531 long long int msglvl;
532 long long int iparm[64];
535 std::vector<int> colptr;
536 std::vector<int> row;
544class PARDISO_LU_seq_extension_sparse_direct_solver<double>
545 :
public LU_extension_sparse_solver<double>,
546 public PARDISO_LU_seq_sparse_direct_solver<double> {
549 size_t size_,
size_t nnz_,
const size_t* colind_,
const size_t* rowind_,
550 const double* value_,
size_t size_ext_,
const int connectivity,
551 const Dictionary& dictionary) {
554 PARDISO_LU_seq_sparse_direct_solver<double>::init(
555 size_, nnz_, colind_, rowind_, value_, connectivity, dictionary);
556 m_ab.resize(size_ * 2);
559 void update_value() { PARDISO_LU_seq_sparse_direct_solver<double>::update_value(); }
562 size_t s,
size_t nrhs,
const double* b,
size_t ldb,
double* x,
size_t ldx,
563 const double* ma_ = 0,
const double* mb_ = 0,
const double* mc_ = 0,
564 char left_or_right =
' ') {
566 std::copy(ma_, ma_ + s - 1, &m_ab[0]);
567 std::copy(mb_, mb_ + s - 1, &m_ab[s - 1]);
568 PARDISO_LU_seq_sparse_direct_solver<double>::resolve(
569 s - 1, 2, &m_ab[0], s - 1, &m_ab[0], s - 1);
570 div = 1 / (*mc_ - blas::dot(s - 1, ma_, 1, &m_ab[s - 1], 1));
573 for (
size_t i = 0; i != nrhs; ++i) {
574 const double x2 = x[ldx * i + s - 1] =
575 div * (b[ldb * i + s - 1] - blas::dot(s - 1, b + ldb * i, 1, &m_ab[s - 1], 1));
576 PARDISO_LU_seq_sparse_direct_solver<double>::resolve(
577 s - 1, 1, b + ldb * i, s - 1, x + ldx * i, s - 1);
578 blas::axpy(s - 1, -x2, &m_ab[0], 1, x + ldx * i, 1);
583 std::vector<double> m_ab;
#define THROW
Definition b2exception.H:198
Logger & get_logger(const std::string &logger_name="")
Definition b2logging.H:829
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32
GenericException< UnimplementedError_name > UnimplementedError
Definition b2exception.H:314