228 for (size_type row = row_begin; row < row_end; ++row)
230 long int cursor = Ap[row];
231 for (size_type block = 0; block < matrix.n_block_cols(); ++block)
234 while ((cursor < Ap[row + 1] - 1) &&
235 (Ai[cursor] < Ai[cursor + 1]))
239 if (cursor == Ap[row + 1] - 1)
244 long int element = cursor;
245 while ((element < Ap[row + 1] - 1) &&
246 (Ai[element] > Ai[element + 1]))
248 std::swap(Ai[element], Ai[element + 1]);
250 std::swap(Ax[element], Ax[element + 1]);
251 if (numbers::NumberTraits<number>::is_complex == true)
252 std::swap(Az[element], Az[element + 1]);
259 parallel_grainsize(matrix));
272 using number =
typename Matrix::value_type;
298 Ai.resize(matrix.n_nonzero_elements());
299 Ax.resize(matrix.n_nonzero_elements());
301 Az.resize(matrix.n_nonzero_elements());
306 Ap[row] =
Ap[row - 1] + matrix.get_row_length(row - 1);
316 for (size_type row = row_begin; row < row_end; ++row)
318 long int index = Ap[row];
319 for (typename Matrix::const_iterator p = matrix.begin(row);
320 p != matrix.end(row);
324 Ai[index] = p->column();
325 Ax[index] = std::real(p->value());
326 if (numbers::NumberTraits<number>::is_complex == true)
327 Az[index] = std::imag(p->value());
332 Assert(index == Ap[row + 1], ExcInternalError());
335 parallel_grainsize(matrix));
344 status = umfpack_dl_symbolic(N,
349 &symbolic_decomposition,
353 status = umfpack_zl_symbolic(N,
359 &symbolic_decomposition,
363 ExcUMFPACKError(
"umfpack_dl_symbolic", status));
366 status = umfpack_dl_numeric(Ap.data(),
369 symbolic_decomposition,
370 &numeric_decomposition,
374 status = umfpack_zl_numeric(Ap.data(),
378 symbolic_decomposition,
379 &numeric_decomposition,
384 umfpack_dl_free_symbolic(&symbolic_decomposition);
385 if (status == UMFPACK_WARNING_singular_matrix)
392 "UMFPACK reports that the matrix is singular, "
393 "but that the factorization was successful anyway. "
394 "You can try and see whether you can still "
395 "solve a linear system with such a factorization "
396 "by catching and ignoring this exception, "
397 "though in practice this will typically not "
402 ExcUMFPACKError(
"umfpack_dl_numeric", status));
451# ifdef DEAL_II_WITH_COMPLEX_VALUES
481 for (
unsigned int i = 0; i < rhs_and_solution.size(); ++i)
483 rhs_re(i) = std::real(rhs_and_solution(i));
484 rhs_im(i) = std::imag(rhs_and_solution(i));
499 const int status = umfpack_zl_solve(
transpose ? UMFPACK_A : UMFPACK_Aat,
515 for (
unsigned int i = 0; i < rhs_and_solution.size(); ++i)
516 rhs_and_solution(i) = {solution_re(i), solution_im(i)};
531 for (
unsigned int i = 0; i < rhs.
size(); ++i)
532 rhs_real_or_imag(i) = std::real(rhs(i));
536 rhs_and_solution = rhs_real_or_imag;
541 for (
unsigned int i = 0; i < rhs.
size(); ++i)
542 rhs_real_or_imag(i) = std::imag(rhs(i));
546 for (
unsigned int i = 0; i < rhs.
size(); ++i)
547 rhs_and_solution(i).imag(rhs_real_or_imag(i));
552 (void)rhs_and_solution;
556 "This function can't be called if deal.II has been configured "
557 "with DEAL_II_WITH_COMPLEX_VALUES=FALSE."));
949 if constexpr (std::is_same_v<Matrix, SparseMatrix<double>>)
956 nnz = matrix.n_actually_nonzero_elements();
959 a = std::make_unique<double[]>(
nnz);
964 irn = std::make_unique<MUMPS_INT[]>(
nnz);
965 jcn = std::make_unique<MUMPS_INT[]>(
nnz);
973 for (
size_type row = 0; row < matrix.m(); ++row)
975 for (
typename Matrix::const_iterator ptr = matrix.begin(row);
976 ptr != matrix.end(row);
978 if (
std::abs(ptr->value()) > 0.0 && ptr->column() >= row)
980 a[n_non_zero_elements] = ptr->value();
981 irn[n_non_zero_elements] = row + 1;
982 jcn[n_non_zero_elements] = ptr->column() + 1;
984 ++n_non_zero_elements;
990 for (
size_type row = 0; row < matrix.m(); ++row)
992 for (
typename Matrix::const_iterator ptr = matrix.begin(row);
993 ptr != matrix.end(row);
997 a[n_non_zero_elements] = ptr->value();
998 irn[n_non_zero_elements] = row + 1;
999 jcn[n_non_zero_elements] = ptr->column() + 1;
1000 ++n_non_zero_elements;
1005 id.nnz = n_non_zero_elements;
1011 else if constexpr (std::is_same_v<Matrix, TrilinosWrappers::SparseMatrix> ||
1012 std::is_same_v<Matrix, PETScWrappers::MPI::SparseMatrix>)
1016 matrix.get_mpi_communicator(),
1019 ExcMessage(
"The matrix communicator must match the MUMPS "
1024 id.nnz = matrix.n_nonzero_elements();
1032 if constexpr (std::is_same_v<Matrix, TrilinosWrappers::SparseMatrix>)
1034 const auto &trilinos_matrix = matrix.trilinos_matrix();
1035 local_non_zeros = trilinos_matrix.NumMyNonzeros();
1037 else if constexpr (std::is_same_v<Matrix,
1040# ifdef DEAL_II_WITH_PETSC
1045 MatGetInfo(petsc_matrix, MAT_LOCAL, &info);
1046 local_non_zeros = (
size_type)info.nz_used;
1053 irn = std::make_unique<MUMPS_INT[]>(local_non_zeros);
1054 jcn = std::make_unique<MUMPS_INT[]>(local_non_zeros);
1055 a = std::make_unique<double[]>(local_non_zeros);
1060 if constexpr (std::is_same_v<Matrix,
1063# ifdef DEAL_II_WITH_PETSC
1068 PetscInt rstart, rend;
1069 MatGetOwnershipRange(petsc_matrix, &rstart, &rend);
1070 for (PetscInt i = rstart; i < rend; i++)
1073 const PetscInt *cols;
1074 const PetscScalar *values;
1075 MatGetRow(petsc_matrix, i, &n_cols, &cols, &values);
1077 for (PetscInt j = 0; j < n_cols; j++)
1081 irn[n_non_zero_local] = i + 1;
1082 jcn[n_non_zero_local] = cols[j] + 1;
1083 a[n_non_zero_local] = values[j];
1089 MatRestoreRow(petsc_matrix, i, &n_cols, &cols, &values);
1100 else if constexpr (std::is_same_v<Matrix,
1103 const auto &trilinos_matrix = matrix.trilinos_matrix();
1104 for (
int local_row = 0; local_row < trilinos_matrix.NumMyRows();
1110 int ierr = trilinos_matrix.ExtractMyRowView(local_row,
1118 "Error extracting global row view from Trilinos matrix. Error code " +
1119 std::to_string(ierr) +
"."));
1121 int global_row = trilinos_matrix.GRID(local_row);
1123 for (
int j = 0; j < num_entries; ++j)
1125 if (trilinos_matrix.GCID(local_cols[j]) >= global_row)
1127 irn[n_non_zero_local] = global_row + 1;
1128 jcn[n_non_zero_local] =
1129 trilinos_matrix.GCID(local_cols[j]) + 1;
1130 a[n_non_zero_local] = values[j];
1138 irhs_loc[local_row] = global_row + 1;
1150 if constexpr (std::is_same_v<Matrix,
1153# ifdef DEAL_II_WITH_PETSC
1158 PetscInt rstart, rend;
1159 MatGetOwnershipRange(petsc_matrix, &rstart, &rend);
1160 for (PetscInt i = rstart; i < rend; i++)
1163 const PetscInt *cols;
1164 const PetscScalar *values;
1165 MatGetRow(petsc_matrix, i, &n_cols, &cols, &values);
1167 for (PetscInt j = 0; j < n_cols; j++)
1169 irn[n_non_zero_local] = i + 1;
1170 jcn[n_non_zero_local] = cols[j] + 1;
1171 a[n_non_zero_local] = values[j];
1176 MatRestoreRow(petsc_matrix, i, &n_cols, &cols, &values);
1187 else if constexpr (std::is_same_v<Matrix,
1190 const auto &trilinos_matrix = matrix.trilinos_matrix();
1191 for (
int local_row = 0; local_row < trilinos_matrix.NumMyRows();
1197 int ierr = trilinos_matrix.ExtractMyRowView(local_row,
1205 "Error extracting global row view from Trilinos matrix. Error code " +
1206 std::to_string(ierr) +
"."));
1208 int global_row = trilinos_matrix.GRID(local_row);
1210 for (
int j = 0; j < num_entries; ++j)
1212 irn[n_non_zero_local] = global_row + 1;
1213 jcn[n_non_zero_local] =
1214 trilinos_matrix.GCID(local_cols[j]) + 1;
1215 a[n_non_zero_local] = values[j];
1222 irhs_loc[local_row] = global_row + 1;
1233 id.nnz_loc = n_non_zero_local;
1234 id.irn_loc =
irn.get();
1235 id.jcn_loc =
jcn.get();