38 #if defined(GMM_USES_MUMPS) 
   40 #ifndef GMM_MUMPS_INTERFACE_H 
   41 #define GMM_MUMPS_INTERFACE_H 
   69 #define ICNTL(I) icntl[(I)-1] 
   70 #define INFO(I) info[(I)-1] 
   71 #define INFOG(I) infog[(I)-1] 
   72 #define RINFOG(I) rinfog[(I)-1] 
   74   template <
typename T> 
struct ij_sparse_matrix {
 
   80     template <
typename L> 
void store(
const L& l, 
size_type i) {
 
   81        typename linalg_traits<L>::const_iterator it = vect_const_begin(l),
 
   82          ite = vect_const_end(l);
 
   83        for (; it != ite; ++it) {
 
   84          int ir = (int)i + 1, jc = (
int)it.index() + 1;
 
   85          if (*it != T(0) && (!sym || ir >= jc))
 
   86          { irn.push_back(ir); jcn.push_back(jc); a.push_back(*it); }
 
   90     template <
typename L> 
void build_from(
const L& l, row_major) {
 
   91       for (
size_type i = 0; i < mat_nrows(l); ++i)
 
   92         store(mat_const_row(l, i), i);
 
   95     template <
typename L> 
void build_from(
const L& l, col_major) {
 
   96       for (
size_type i = 0; i < mat_ncols(l); ++i)
 
   97         store(mat_const_col(l, i), i);
 
  101     template <
typename L> ij_sparse_matrix(
const L& A, 
bool sym_) {
 
  104       irn.reserve(nz); jcn.reserve(nz); a.reserve(nz);
 
  105       build_from(A,  
typename principal_orientation_type<
typename 
  106                  linalg_traits<L>::sub_orientation>::potype());
 
  114   template <
typename T> 
struct mumps_interf {};
 
  116   template <> 
struct mumps_interf<float> {
 
  117     typedef SMUMPS_STRUC_C  MUMPS_STRUC_C;
 
  118     typedef float value_type;
 
  120     static void mumps_c(MUMPS_STRUC_C &
id) { smumps_c(&
id); }
 
  123   template <> 
struct mumps_interf<double> {
 
  124     typedef DMUMPS_STRUC_C  MUMPS_STRUC_C;
 
  125     typedef double value_type;
 
  126     static void mumps_c(MUMPS_STRUC_C &
id) { dmumps_c(&
id); }
 
  129   template <> 
struct mumps_interf<std::complex<float> > {
 
  130     typedef CMUMPS_STRUC_C  MUMPS_STRUC_C;
 
  131     typedef mumps_complex value_type;
 
  132     static void mumps_c(MUMPS_STRUC_C &
id) { cmumps_c(&
id); }
 
  135   template <> 
struct mumps_interf<std::complex<double> > {
 
  136     typedef ZMUMPS_STRUC_C  MUMPS_STRUC_C;
 
  137     typedef mumps_double_complex value_type;
 
  138     static void mumps_c(MUMPS_STRUC_C &
id) { zmumps_c(&
id); }
 
  142   template <
typename MUMPS_STRUCT>
 
  143   static inline bool mumps_error_check(MUMPS_STRUCT &
id) {
 
  144     if (
id.INFO(1) < 0) {
 
  145       switch (
id.INFO(1)) {
 
  147           GMM_ASSERT1(
false, 
"Solve with MUMPS failed: NZ = " << 
id.INFO(2)
 
  148                       << 
" is out of range");
 
  151           GMM_WARNING1(
"Solve with MUMPS failed: matrix is singular");
 
  154           GMM_ASSERT1(
false, 
"Solve with MUMPS failed: error " 
  155                       << 
id.INFO(1) << 
", increase ICNTL(14)");
 
  158           GMM_ASSERT1(
false, 
"Solve with MUMPS failed: not enough memory");
 
  161           GMM_ASSERT1(
false, 
"Solve with MUMPS failed with error " 
  173   template <
typename MAT, 
typename VECTX, 
typename VECTB>
 
  174   bool MUMPS_solve(
const MAT &A, 
const VECTX &X_, 
const VECTB &B,
 
  175                    bool sym = 
false, 
bool distributed = 
false) {
 
  176     VECTX &X = 
const_cast<VECTX &
>(X_);
 
  178     typedef typename linalg_traits<MAT>::value_type T;
 
  179     typedef typename mumps_interf<T>::value_type MUMPS_T;
 
  180     GMM_ASSERT2(gmm::mat_nrows(A) == gmm::mat_ncols(A), 
"Non-square matrix");
 
  182     std::vector<T> rhs(gmm::vect_size(B)); 
gmm::copy(B, rhs);
 
  184     ij_sparse_matrix<T> AA(A, sym);
 
  186     const int JOB_INIT = -1;
 
  187     const int JOB_END = -2;
 
  188     const int USE_COMM_WORLD = -987654;
 
  190     typename mumps_interf<T>::MUMPS_STRUC_C id;
 
  194     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
 
  199     id.sym = sym ? 2 : 0;
 
  200     id.comm_fortran = USE_COMM_WORLD;
 
  201     mumps_interf<T>::mumps_c(
id);
 
  203     if (rank == 0 || distributed) {
 
  204       id.n = int(gmm::mat_nrows(A));
 
  206         id.nz_loc = int(AA.irn.size());
 
  207         id.irn_loc = &(AA.irn[0]);
 
  208         id.jcn_loc = &(AA.jcn[0]);
 
  209         id.a_loc = (MUMPS_T*)(&(AA.a[0]));
 
  211         id.nz = int(AA.irn.size());
 
  212         id.irn = &(AA.irn[0]);
 
  213         id.jcn = &(AA.jcn[0]);
 
  214         id.a = (MUMPS_T*)(&(AA.a[0]));
 
  217         id.rhs = (MUMPS_T*)(&(rhs[0]));
 
  240     mumps_interf<T>::mumps_c(
id);
 
  241     bool ok = mumps_error_check(
id);
 
  244     mumps_interf<T>::mumps_c(
id);
 
  247     MPI_Bcast(&(rhs[0]),
id.n,gmm::mpi_type(T()),0,MPI_COMM_WORLD);
 
  261   template <
typename MAT, 
typename VECTX, 
typename VECTB>
 
  262   bool MUMPS_distributed_matrix_solve(
const MAT &A, 
const VECTX &X_,
 
  263                                       const VECTB &B, 
bool sym = 
false) {
 
  264     return MUMPS_solve(A, X_, B, sym, 
true);
 
  270   inline T real_or_complex(std::complex<T> a) { 
return a.real(); }
 
  272   inline T real_or_complex(T &a) { 
return a; }
 
  278   template <typename MAT, typename T = typename linalg_traits<MAT>::value_type>
 
  279   T MUMPS_determinant(
const MAT &A, 
int &exponent,
 
  280                       bool sym = 
false, 
bool distributed = 
false) {
 
  282     typedef typename mumps_interf<T>::value_type MUMPS_T;
 
  283     typedef typename number_traits<T>::magnitude_type R;
 
  284     GMM_ASSERT2(gmm::mat_nrows(A) == gmm::mat_ncols(A), 
"Non-square matrix");
 
  286     ij_sparse_matrix<T> AA(A, sym);
 
  288     const int JOB_INIT = -1;
 
  289     const int JOB_END = -2;
 
  290     const int USE_COMM_WORLD = -987654;
 
  292     typename mumps_interf<T>::MUMPS_STRUC_C id;
 
  296     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
 
  301     id.sym = sym ? 2 : 0;
 
  302     id.comm_fortran = USE_COMM_WORLD;
 
  303     mumps_interf<T>::mumps_c(
id);
 
  305     if (rank == 0 || distributed) {
 
  306       id.n = int(gmm::mat_nrows(A));
 
  308         id.nz_loc = int(AA.irn.size());
 
  309         id.irn_loc = &(AA.irn[0]);
 
  310         id.jcn_loc = &(AA.jcn[0]);
 
  311         id.a_loc = (MUMPS_T*)(&(AA.a[0]));
 
  313         id.nz = int(AA.irn.size());
 
  314         id.irn = &(AA.irn[0]);
 
  315         id.jcn = &(AA.jcn[0]);
 
  316         id.a = (MUMPS_T*)(&(AA.a[0]));
 
  337     mumps_interf<T>::mumps_c(
id);
 
  338     mumps_error_check(
id);
 
  340     T det = real_or_complex(std::complex<R>(
id.RINFOG(12),
id.RINFOG(13)));
 
  341     exponent = 
id.INFOG(34);
 
  344     mumps_interf<T>::mumps_c(
id);
 
size_type nnz(const L &l)
count the number of non-zero entries of a vector or matrix.
void copy(const L1 &l1, L2 &l2)
*/
Include the base gmm files.
size_t size_type
used as the common size type in the library