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