48#include "rheolef/config.h"
49#ifdef _RHEOLEF_HAVE_MUMPS
52#undef DEBUG_MUMPS_SCOTCH
53#ifdef DEBUG_MUMPS_SCOTCH
54#undef _RHEOLEF_HAVE_MUMPS_WITH_PTSCOTCH
65template<
class T,
class M>
71 size_type dia_nnz = 0;
73 for (size_type i = 0, n =
a.nrow(); i < n; i++) {
75 size_type j = (*p).first;
76 if (j >= i) dia_nnz++;
82template<
class T,
class M>
89#ifdef _RHEOLEF_HAVE_MPI
96 size_type first_i =
a.row_ownership().first_index();
97 size_type ext_nnz = 0;
99 for (size_type i = 0, n =
a.nrow(); i < n; i++) {
101 size_type dis_i = first_i + i;
102 size_type dis_j =
a.jext2dis_j ((*p).first);
103 if (dis_j >= dis_i) ext_nnz++;
109template<
class T,
class M>
112csr2mumps_struct_seq (
const csr<T,M>& a, vector<int>& row, vector<int>& col,
bool use_symmetry)
116 for (size_type i = 0, n =
a.nrow(), q = 0; i < n; i++) {
118 size_type j = (*p).first;
119 if (!use_symmetry || j >= i) {
127template<
class T,
class M>
130csr2mumps_values_seq (
const csr<T,M>& a, vector<T>& val,
bool use_symmetry)
134 for (size_type i = 0, n =
a.nrow(), q = 0; i < n; i++) {
136 size_type j = (*p).first;
137 if (!use_symmetry || j >= i) {
138 val[q] = (*p).second;
144#ifdef _RHEOLEF_HAVE_MPI
148csr2mumps_struct_dis (
const csr<T,sequential>& a, vector<int>& row, vector<int>& col,
bool use_symmetry,
bool)
155csr2mumps_struct_dis (
const csr<T,distributed>& a, vector<int>& row, vector<int>& col,
bool use_symmetry,
bool drop_ext_nnz)
160 size_type dis_nr =
a.dis_nrow();
161 size_type dis_nc =
a.dis_ncol();
162 size_type nc =
a.ncol();
163 size_type first_i =
a.row_ownership().first_index();
164 for (size_type i = 0, n =
a.nrow(), q = 0; i < n; i++) {
166 size_type j = (*p).first;
167 size_type dis_i = first_i + i;
168 size_type dis_j = first_i + j;
170 assert_macro (dis_i < dis_nr && dis_j < dis_nc,
"invalid matrix");
171 if (!use_symmetry || dis_j >= dis_i) {
177 if (drop_ext_nnz)
continue;
179 size_type dis_i = first_i + i;
180 size_type dis_j =
a.jext2dis_j ((*p).first);
181 assert_macro (dis_i < dis_nr && dis_j < dis_nc,
"invalid matrix");
182 if (!use_symmetry || dis_j >= dis_i) {
193csr2mumps_values_dis (
const csr<T,sequential>& a, vector<T>& val,
bool use_symmetry,
bool)
200csr2mumps_values_dis (
const csr<T,distributed>& a, vector<T>& val,
bool use_symmetry,
bool drop_ext_nnz)
203 std:fill (val.begin(), val.end(), std::numeric_limits<T>::max());
207 size_type first_i =
a.row_ownership().first_index();
210 for (size_type i = 0, n =
a.nrow(), q = 0; i < n; i++) {
212 size_type dis_i = first_i + i;
213 size_type dis_j = first_i + (*p).first;
214 if (!use_symmetry || dis_j >= dis_i) {
218 val[q] = (*p).second;
222 if (drop_ext_nnz)
continue;
224 size_type dis_i = first_i + i;
225 size_type dis_j =
a.jext2dis_j ((*p).first);
226 if (!use_symmetry || dis_j >= dis_i) {
230 val[q] = (*p).second;
236 T val_min = std::numeric_limits<T>::max(), val_max = 0;
237 for (
size_t q = 0; q < val.size(); q++) {
238 val_min = std::min (val_min, abs(val[q]));
239 val_max = std::max (val_max, abs(val[q]));
248template<
class T,
class M>
263template<
class T,
class M>
268 if (a.dis_nrow() <= 1) {
271 _a00 = (*(a.begin()[0])).second;
280 bool use_symmetry = a.is_symmetric();
281 bool use_definite_positive = a.is_definite_positive();
283#ifdef _RHEOLEF_HAVE_MPI
284 _mumps_par.comm_fortran = MPI_Comm_c2f (a.row_ownership().comm());
286 if (use_symmetry && !use_definite_positive) {
290 }
else if (use_symmetry && use_definite_positive) {
335#if defined(_RHEOLEF_HAVE_MUMPS_WITH_PTSCOTCH) || defined(_RHEOLEF_HAVE_MUMPS_WITH_SCOTCH)
337#elif defined(_RHEOLEF_HAVE_MUMPS_WITH_PARMETIS) || defined(_RHEOLEF_HAVE_MUMPS_WITH_METIS)
348#if defined(_RHEOLEF_HAVE_MUMPS_WITH_SCOTCH) || defined(_RHEOLEF_HAVE_MUMPS_WITH_METIS)
350#elif defined(_RHEOLEF_HAVE_MUMPS_WITH_PTSCOTCH) || defined(_RHEOLEF_HAVE_MUMPS_WITH_PARMETIS)
354#ifdef _RHEOLEF_HAVE_MUMPS_WITH_PTSCOTCH
356#elif _RHEOLEF_HAVE_MUMPS_WITH_PARMETIS
366 size_type dia_nnz = ((use_symmetry) ? nnz_dia_upper(a) : a.nnz());
367 size_type ext_nnz = ((use_symmetry) ? nnz_ext_upper(a) : a.ext_nnz());
370#ifdef _RHEOLEF_HAVE_MPI
371 _row.resize (dis_nnz);
372 _col.resize (dis_nnz);
379 _row.resize (dia_nnz);
380 _col.resize (dia_nnz);
381 csr2mumps_struct_seq (a,
_row,
_col, use_symmetry);
383#if (_RHEOLEF_MUMPS_VERSION_MAJOR >= 5)
393 if (a.dis_nrow() <= 1) {
396 _a00 = (*(a.begin()[0])).second;
404#ifdef _RHEOLEF_HAVE_MPI
405 _val.resize (dis_nnz);
410 _val.resize (dia_nnz);
411 csr2mumps_values_seq (a,
_val, use_symmetry);
415 bool finished =
false;
416 while (!finished &&
_mumps_par.icntl[14-1] <= 2000) {
431 "solver failed: mumps error infog(1)=" <<
_mumps_par.infog[1-1]
443template<
class T,
class M>
447 if (b.dis_size() <= 1) {
470 distributor host_ownership (b.dis_size(), comm, comm.rank() == 0 ? b.dis_size() : 0);
471 b_host.
resize (host_ownership);
472 size_type first_i = b.ownership().first_index();
473 for (
size_type i = 0, n = b.size(); i < n; i++) {
475 b_host.dis_entry(dis_i) = b[i];
477 b_host.dis_entry_assembly();
478 if (comm.rank() == 0) {
483 sol.resize (sol_size);
484 perm.resize (sol_size);
486 _mumps_par.sol_loc = (sol_size > 0) ? sol.begin().operator->() : &dummy;
487 _mumps_par.isol_loc = (sol_size > 0) ? perm.begin().operator->() : &idummy;
501 "solver failed: mumps error infog(1)="<<
_mumps_par.infog[1-1]
510 for (
size_t i = 0; i < sol_size; i++) {
513 x.dis_entry(dis_i) = sol[i];
515 x.dis_entry_assembly();
519template<
class T,
class M>
526template<
class T,
class M>
545#ifdef _RHEOLEF_HAVE_MPI
see the communicator page for the full documentation
see the csr page for the full documentation
see the distributor page for the full documentation
solver_abstract_rep(const solver_option &opt)
const solver_option & option() const
DMUMPS_STRUC_C _mumps_par
std::vector< MUMPS_INT > _col
std::vector< MUMPS_INT > _row
void update_values(const csr< T, M > &a)
base::size_type size_type
solver_mumps_rep(const csr< T, M > &a, const solver_option &opt=solver_option())
std::vector< double > _val
vec< T, M > trans_solve(const vec< T, M > &rhs) const
vec< T, M > solve(const vec< T, M > &rhs) const
see the solver_option page for the full documentation
see the vec page for the full documentation
void resize(const distributor &ownership, const T &init_val=std::numeric_limits< T >::max())
#define trace_macro(message)
#define assert_macro(ok_condition, message)
#define error_macro(message)
#define dis_warning_macro(message)
#define warning_macro(message)
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
This file is part of Rheolef.