19#ifdef DEAL_II_WITH_SCALAPACK
23# include <deal.II/base/mpi.templates.h>
25# include <deal.II/lac/scalapack.templates.h>
27# ifdef DEAL_II_WITH_HDF5
36# ifdef DEAL_II_WITH_HDF5
38template <
typename number>
80template <
typename NumberType>
84 const std::shared_ptr<const Utilities::MPI::ProcessGrid> &
process_grid,
91 , first_process_column(0)
105template <
typename NumberType>
108 const std::shared_ptr<const Utilities::MPI::ProcessGrid> &
process_grid,
121template <
typename NumberType>
124 const std::shared_ptr<const Utilities::MPI::ProcessGrid> &
process_grid,
130 , first_process_column(0)
132 , submatrix_column(1)
134# ifndef DEAL_II_WITH_HDF5
142 "This function is only available when deal.II is configured with HDF5"));
145 const unsigned int this_mpi_process(
151 if (this_mpi_process == 0)
215template <
typename NumberType>
220 const std::shared_ptr<const Utilities::MPI::ProcessGrid> &
process_grid,
227 ExcMessage(
"Column block size has to be positive."));
231 "Row block size can not be greater than the number of rows of the matrix"));
235 "Column block size can not be greater than the number of columns of the matrix"));
245 if (grid->mpi_process_is_active)
248 n_local_rows =
numroc_(&n_rows,
250 &(grid->this_process_row),
252 &(grid->n_process_rows));
253 n_local_columns =
numroc_(&n_columns,
255 &(grid->this_process_column),
256 &first_process_column,
257 &(grid->n_process_columns));
270 &first_process_column,
271 &(grid->blacs_context),
282 n_local_columns = -1;
283 std::fill(std::begin(descriptor), std::end(descriptor), -1);
289template <
typename NumberType>
293 const std::shared_ptr<const Utilities::MPI::ProcessGrid> &
process_grid,
302template <
typename NumberType>
312template <
typename NumberType>
321template <
typename NumberType>
330template <
typename NumberType>
340 Assert(n_columns ==
int(matrix.n()),
343 if (grid->mpi_process_is_active)
345 for (
int i = 0; i < n_local_rows; ++i)
347 const int glob_i = global_row(i);
348 for (
int j = 0;
j < n_local_columns; ++
j)
350 const int glob_j = global_column(
j);
361template <
typename NumberType>
364 const unsigned int rank)
366 if (n_rows * n_columns == 0)
369 const unsigned int this_mpi_process(
374 ExcMessage(
"All processes have to call routine with identical rank"));
376 ExcMessage(
"All processes have to call routine with identical rank"));
380 if (this_mpi_process == rank)
393 const std::vector<int>
ranks(n, rank);
411 const char *order =
"Col";
461 if (this->grid->mpi_process_is_active)
465 this->values.size() > 0 ? this->values.data() :
nullptr;
481 &(
this->grid->blacs_context));
496template <
typename NumberType>
500 Assert(n_local_rows >= 0 &&
loc_row <
static_cast<unsigned int>(n_local_rows),
505 &(grid->this_process_row),
507 &(grid->n_process_rows)) -
513template <
typename NumberType>
517 Assert(n_local_columns >= 0 &&
518 loc_column <
static_cast<unsigned int>(n_local_columns),
523 &(grid->this_process_column),
524 &first_process_column,
525 &(grid->n_process_columns)) -
531template <
typename NumberType>
534 const unsigned int rank)
const
536 if (n_rows * n_columns == 0)
539 const unsigned int this_mpi_process(
544 ExcMessage(
"All processes have to call routine with identical rank"));
546 ExcMessage(
"All processes have to call routine with identical rank"));
549 if (this_mpi_process == rank)
564 const std::vector<int>
ranks(n, rank);
582 const char *order =
"Col";
635 if (this->grid->mpi_process_is_active)
639 this->values.size() > 0 ? this->values.data() :
nullptr;
652 &(
this->grid->blacs_context));
665template <
typename NumberType>
674 Assert(n_columns ==
int(matrix.n()),
678 if (grid->mpi_process_is_active)
680 for (
int i = 0; i < n_local_rows; ++i)
682 const int glob_i = global_row(i);
683 for (
int j = 0;
j < n_local_columns; ++
j)
685 const int glob_j = global_column(
j);
698 for (
unsigned int i = 0; i < matrix.n(); ++i)
699 for (
unsigned int j = i + 1;
j < matrix.m(); ++
j)
702 for (
unsigned int i = 0; i < matrix.n(); ++i)
703 for (
unsigned int j = 0;
j < i; ++
j)
710 for (
unsigned int i = 0; i < matrix.n(); ++i)
711 for (
unsigned int j = i + 1;
j < matrix.m(); ++
j)
712 matrix(i,
j) = matrix(
j, i);
713 else if (uplo ==
'U')
714 for (
unsigned int i = 0; i < matrix.n(); ++i)
715 for (
unsigned int j = 0;
j < i; ++
j)
716 matrix(i,
j) = matrix(
j, i);
722template <
typename NumberType>
726 const std::pair<unsigned int, unsigned int> &
offset_A,
727 const std::pair<unsigned int, unsigned int> &
offset_B,
728 const std::pair<unsigned int, unsigned int> &
submatrix_size)
const
746 B.grid->mpi_communicator,
750 ExcMessage(
"Matrix A and B must have a common MPI Communicator"));
759 const char *order =
"Col";
811 if (this->values.size() != 0)
814 for (
unsigned int i = 0; i <
desc_A.
size(); ++i)
815 desc_A[i] = this->descriptor[i];
822 if (
B.values.
size() != 0)
825 for (
unsigned int i = 0; i <
desc_B.
size(); ++i)
851template <
typename NumberType>
859 if (this->grid->mpi_process_is_active)
861 this->descriptor[0] == 1,
863 "Copying of ScaLAPACK matrices only implemented for dense matrices"));
864 if (
dest.grid->mpi_process_is_active)
866 dest.descriptor[0] == 1,
868 "Copying of ScaLAPACK matrices only implemented for dense matrices"));
876 if ((this->grid !=
dest.grid) || (row_block_size !=
dest.row_block_size) ||
877 (column_block_size !=
dest.column_block_size))
918 const char *order =
"Col";
930 if (this->grid->mpi_process_is_active && (
this->values.
size() > 0))
934 "source: process is active but local matrix empty"));
937 if (
dest.grid->mpi_process_is_active && (
dest.values.
size() > 0))
942 "destination: process is active but local matrix empty"));
953 &
dest.submatrix_column,
970 if (this->grid->mpi_process_is_active)
971 dest.values = this->values;
974 dest.property = property;
979template <
typename NumberType>
989template <
typename NumberType>
992 const NumberType
alpha,
993 const NumberType
beta,
1000 Assert(column_block_size ==
B.row_block_size,
1002 Assert(row_block_size ==
B.column_block_size,
1008 Assert(n_columns ==
B.n_columns,
1010 Assert(column_block_size ==
B.column_block_size,
1012 Assert(row_block_size ==
B.row_block_size,
1016 ExcMessage(
"The matrices A and B need to have the same process grid"));
1018 if (this->grid->mpi_process_is_active)
1022 (this->values.size() > 0) ? this->values.data() :
nullptr;
1023 const NumberType *
B_loc =
1024 (
B.values.
size() > 0) ?
B.values.
data() :
nullptr;
1032 &
B.submatrix_column,
1045template <
typename NumberType>
1050 add(
B, 1, a,
false);
1055template <
typename NumberType>
1065template <
typename NumberType>
1075 ExcMessage(
"The matrices A and B need to have the same process grid"));
1077 ExcMessage(
"The matrices B and C need to have the same process grid"));
1083 Assert(this->n_columns ==
B.n_rows,
1085 Assert(this->n_rows == C.n_rows,
1087 Assert(
B.n_columns == C.n_columns,
1089 Assert(this->row_block_size == C.row_block_size,
1091 Assert(this->column_block_size ==
B.row_block_size,
1093 Assert(
B.column_block_size == C.column_block_size,
1098 Assert(this->n_rows ==
B.n_rows,
1100 Assert(this->n_columns == C.n_rows,
1102 Assert(
B.n_columns == C.n_columns,
1104 Assert(this->column_block_size == C.row_block_size,
1106 Assert(this->row_block_size ==
B.row_block_size,
1108 Assert(
B.column_block_size == C.column_block_size,
1113 Assert(this->n_columns ==
B.n_columns,
1115 Assert(this->n_rows == C.n_rows,
1117 Assert(
B.n_rows == C.n_columns,
1119 Assert(this->row_block_size == C.row_block_size,
1121 Assert(this->column_block_size ==
B.column_block_size,
1123 B.column_block_size));
1124 Assert(
B.row_block_size == C.column_block_size,
1129 Assert(this->n_rows ==
B.n_columns,
1131 Assert(this->n_columns == C.n_rows,
1133 Assert(
B.n_rows == C.n_columns,
1135 Assert(this->column_block_size == C.row_block_size,
1137 Assert(this->row_block_size ==
B.column_block_size,
1139 Assert(
B.row_block_size == C.column_block_size,
1143 if (this->grid->mpi_process_is_active)
1148 const NumberType *
A_loc =
1149 (this->values.size() > 0) ? this->values.data() :
nullptr;
1150 const NumberType *
B_loc =
1151 (
B.values.
size() > 0) ?
B.values.
data() :
nullptr;
1152 NumberType *
C_loc = (C.values.
size() > 0) ? C.values.
data() :
nullptr;
1154 int n = C.n_columns;
1164 &(this->submatrix_row),
1165 &(this->submatrix_column),
1169 &
B.submatrix_column,
1174 &C.submatrix_column,
1182template <
typename NumberType>
1189 mult(1.,
B, 1., C,
false,
false);
1191 mult(1.,
B, 0, C,
false,
false);
1196template <
typename NumberType>
1203 mult(1.,
B, 1., C,
true,
false);
1205 mult(1.,
B, 0, C,
true,
false);
1210template <
typename NumberType>
1217 mult(1.,
B, 1., C,
false,
true);
1219 mult(1.,
B, 0, C,
false,
true);
1224template <
typename NumberType>
1231 mult(1.,
B, 1., C,
true,
true);
1233 mult(1.,
B, 0, C,
true,
true);
1238template <
typename NumberType>
1245 "Cholesky factorization can be applied to symmetric matrices only."));
1248 "Matrix has to be in Matrix state before calling this function."));
1250 if (grid->mpi_process_is_active)
1253 NumberType *
A_loc = this->values.data();
1271template <
typename NumberType>
1277 "Matrix has to be in Matrix state before calling this function."));
1279 if (grid->mpi_process_is_active)
1282 NumberType *
A_loc = this->values.data();
1286 &(grid->this_process_row),
1288 &(grid->n_process_rows));
1291 &(grid->this_process_row),
1293 &(grid->n_process_rows));
1294 ipiv.resize(
mp + row_block_size);
1312template <
typename NumberType>
1330 if (grid->mpi_process_is_active)
1334 const char diag =
'N';
1336 NumberType *
A_loc = this->values.data();
1359 compute_cholesky_factorization();
1361 compute_lu_factorization();
1363 if (grid->mpi_process_is_active)
1366 NumberType *
A_loc = this->values.data();
1401 lwork =
static_cast<int>(work[0]);
1428template <
typename NumberType>
1429std::vector<NumberType>
1431 const std::pair<unsigned int, unsigned int> &
index_limits,
1438 std::pair<unsigned int, unsigned int> idx =
1443 if (idx.first == 0 && idx.second ==
static_cast<unsigned int>(n_rows - 1))
1451template <
typename NumberType>
1452std::vector<NumberType>
1462 std::pair<unsigned int, unsigned int> indices =
1471template <
typename NumberType>
1472std::vector<NumberType>
1480 "Matrix has to be in Matrix state before calling this function."));
1482 ExcMessage(
"Matrix has to be symmetric for this operation."));
1484 std::lock_guard<std::mutex> lock(mutex);
1499 "Prescribing both the index and value range for the eigenvalues is ambiguous"));
1503 std::unique_ptr<ScaLAPACKMatrix<NumberType>>
eigenvectors =
1505 std::make_unique<ScaLAPACKMatrix<NumberType>>(n_rows,
1508 std::make_unique<ScaLAPACKMatrix<NumberType>>(
1509 grid->n_process_rows, grid->n_process_columns, grid, 1, 1);
1516 std::vector<NumberType>
ev(n_rows);
1518 if (grid->mpi_process_is_active)
1529 NumberType vl = NumberType(),
vu = NumberType();
1535 NumberType
abstol = NumberType();
1542 NumberType
orfac = 0;
1544 std::vector<int>
ifail;
1557 std::vector<NumberType>
gap(n_local_rows * n_local_columns);
1586 NumberType *
A_loc = this->values.data();
1632 ifail.resize(n_rows);
1633 iclustr.resize(2 * grid->n_process_rows * grid->n_process_columns);
1634 gap.resize(grid->n_process_rows * grid->n_process_columns);
1667 lwork =
static_cast<int>(work[0]);
1741 grid->send_to_inactive(&m, 1);
1746 if (!grid->mpi_process_is_active)
1771template <
typename NumberType>
1772std::vector<NumberType>
1774 const std::pair<unsigned int, unsigned int> &
index_limits,
1781 const std::pair<unsigned int, unsigned int> idx =
1786 if (idx.first == 0 && idx.second ==
static_cast<unsigned int>(n_rows - 1))
1794template <
typename NumberType>
1795std::vector<NumberType>
1803 const std::pair<unsigned int, unsigned int> indices =
1812template <
typename NumberType>
1813std::vector<NumberType>
1821 "Matrix has to be in Matrix state before calling this function."));
1823 ExcMessage(
"Matrix has to be symmetric for this operation."));
1825 std::lock_guard<std::mutex> lock(mutex);
1840 "Prescribing both the index and value range for the eigenvalues is ambiguous"));
1844 std::unique_ptr<ScaLAPACKMatrix<NumberType>>
eigenvectors =
1846 std::make_unique<ScaLAPACKMatrix<NumberType>>(n_rows,
1849 std::make_unique<ScaLAPACKMatrix<NumberType>>(
1850 grid->n_process_rows, grid->n_process_columns, grid, 1, 1);
1856 std::vector<NumberType>
ev(n_rows);
1863 if (grid->mpi_process_is_active)
1874 NumberType vl = NumberType(),
vu = NumberType();
1901 NumberType *
A_loc = this->values.data();
1941 lwork =
static_cast<int>(work[0]);
1977 "psyevr failed to compute all eigenvectors for the selected eigenvalues"));
1992 grid->send_to_inactive(&m, 1);
1997 if (!grid->mpi_process_is_active)
2022template <
typename NumberType>
2023std::vector<NumberType>
2029 "Matrix has to be in Matrix state before calling this function."));
2030 Assert(row_block_size == column_block_size,
2039 Assert(U->n_rows == U->n_columns,
2041 Assert(row_block_size == U->row_block_size,
2043 Assert(column_block_size == U->column_block_size,
2045 Assert(grid->blacs_context == U->grid->blacs_context,
2054 Assert(row_block_size ==
VT->row_block_size,
2056 Assert(column_block_size ==
VT->column_block_size,
2058 Assert(grid->blacs_context ==
VT->grid->blacs_context,
2060 VT->grid->blacs_context));
2062 std::lock_guard<std::mutex> lock(mutex);
2064 std::vector<NumberType>
sv(
std::min(n_rows, n_columns));
2066 if (grid->mpi_process_is_active)
2070 NumberType *
A_loc = this->values.data();
2092 &U->submatrix_column,
2096 &
VT->submatrix_column,
2103 lwork =
static_cast<int>(work[0]);
2117 &U->submatrix_column,
2121 &
VT->submatrix_column,
2142template <
typename NumberType>
2148 ExcMessage(
"The matrices A and B need to have the same process grid"));
2151 "Matrix has to be in Matrix state before calling this function."));
2154 "Matrix B has to be in Matrix state before calling this function."));
2167 Assert(row_block_size == column_block_size,
2169 "Use identical block sizes for rows and columns of matrix A"));
2170 Assert(
B.row_block_size ==
B.column_block_size,
2172 "Use identical block sizes for rows and columns of matrix B"));
2173 Assert(row_block_size ==
B.row_block_size,
2175 "Use identical block-cyclic distribution for matrices A and B"));
2177 std::lock_guard<std::mutex> lock(mutex);
2179 if (grid->mpi_process_is_active)
2182 NumberType *
A_loc = this->values.data();
2202 &
B.submatrix_column,
2209 lwork =
static_cast<int>(work[0]);
2222 &
B.submatrix_column,
2234template <
typename NumberType>
2240 "Matrix has to be in Matrix state before calling this function."));
2241 Assert(row_block_size == column_block_size,
2243 "Use identical block sizes for rows and columns of matrix A"));
2247 "input parameter ratio has to be larger than zero and smaller than 1"));
2261 std::vector<NumberType>
sv = this->compute_SVD(&U, &
VT);
2269 unsigned int n_sv = 1;
2273 for (
unsigned int i = 1; i <
sv.
size(); ++i)
2299 std::make_pair(0, 0),
2300 std::make_pair(0, 0),
2301 std::make_pair(n_rows,
n_sv));
2303 std::make_pair(0, 0),
2304 std::make_pair(0, 0),
2305 std::make_pair(
n_sv, n_columns));
2314 VT_R.mult(1,
U_R, 0, *
this,
true,
true);
2321template <
typename NumberType>
2324 const NumberType
a_norm)
const
2328 "Matrix has to be in Cholesky state before calling this function."));
2329 std::lock_guard<std::mutex> lock(mutex);
2330 NumberType
rcond = 0.;
2332 if (grid->mpi_process_is_active)
2334 int liwork = n_local_rows;
2338 const NumberType *
A_loc = this->values.data();
2358 lwork =
static_cast<int>(std::ceil(work[0]));
2377 grid->send_to_inactive(&
rcond);
2383template <
typename NumberType>
2387 const char type(
'O');
2390 return norm_symmetric(type);
2392 return norm_general(type);
2397template <
typename NumberType>
2401 const char type(
'I');
2404 return norm_symmetric(type);
2406 return norm_general(type);
2411template <
typename NumberType>
2415 const char type(
'F');
2418 return norm_symmetric(type);
2420 return norm_general(type);
2425template <
typename NumberType>
2431 ExcMessage(
"norms can be called in matrix state only."));
2432 std::lock_guard<std::mutex> lock(mutex);
2433 NumberType
res = 0.;
2435 if (grid->mpi_process_is_active)
2439 &(grid->this_process_row),
2441 &(grid->n_process_rows));
2444 &(grid->this_process_column),
2445 &first_process_column,
2446 &(grid->n_process_columns));
2449 &(grid->this_process_row),
2451 &(grid->n_process_rows));
2454 &(grid->this_process_column),
2456 &(grid->n_process_columns));
2462 if (type ==
'O' || type ==
'1')
2464 else if (type ==
'I')
2468 const NumberType *
A_loc = this->values.begin();
2478 grid->send_to_inactive(&
res);
2484template <
typename NumberType>
2490 ExcMessage(
"norms can be called in matrix state only."));
2492 ExcMessage(
"Matrix has to be symmetric for this operation."));
2493 std::lock_guard<std::mutex> lock(mutex);
2494 NumberType
res = 0.;
2496 if (grid->mpi_process_is_active)
2501 ilcm_(&(grid->n_process_rows), &(grid->n_process_columns));
2502 const int v2 =
lcm / (grid->n_process_rows);
2506 &(grid->this_process_row),
2508 &(grid->n_process_rows));
2511 &(grid->this_process_column),
2512 &first_process_column,
2513 &(grid->n_process_columns));
2516 &(grid->this_process_row),
2518 &(grid->n_process_rows));
2521 &(grid->this_process_column),
2523 &(grid->n_process_columns));
2526 const int ldw = (n_local_rows == n_local_columns) ?
2531 (type ==
'M' || type ==
'F' || type ==
'E') ? 0 : 2 *
Nq0 +
Np0 +
ldw;
2533 const NumberType *
A_loc = this->values.begin();
2543 grid->send_to_inactive(&
res);
2549# ifdef DEAL_II_WITH_HDF5
2616template <
typename NumberType>
2620 const std::pair<unsigned int, unsigned int> &chunk_size)
const
2622# ifndef DEAL_II_WITH_HDF5
2628 std::pair<unsigned int, unsigned int>
chunks_size_ = chunk_size;
2638 ExcMessage(
"The row chunk size must be larger than 0."));
2641 ExcMessage(
"The column chunk size must be larger than 0."));
2644# ifdef H5_HAVE_PARALLEL
2658template <
typename NumberType>
2662 const std::pair<unsigned int, unsigned int> &chunk_size)
const
2664# ifndef DEAL_II_WITH_HDF5
2680 std::make_shared<Utilities::MPI::ProcessGrid>(this->grid->mpi_communicator,
2684 const int MB = n_rows,
NB = n_columns;
2690 if (tmp.grid->mpi_process_is_active)
2712 dims[0] = n_columns;
2815template <
typename NumberType>
2819 const std::pair<unsigned int, unsigned int> &chunk_size)
const
2821# ifndef DEAL_II_WITH_HDF5
2827 const unsigned int n_mpi_processes(
2838 std::make_shared<Utilities::MPI::ProcessGrid>(this->grid->mpi_communicator,
2842 const int MB = n_rows;
2855 const int NB =
std::max(
static_cast<int>(std::ceil(
2856 static_cast<double>(n_columns) / n_mpi_processes)),
2863 NumberType *
data = (tmp.values.
size() > 0) ? tmp.values.
data() :
nullptr;
2883 dims[0] = tmp.n_columns;
2884 dims[1] = tmp.n_rows;
2914 tmp.grid->mpi_communicator);
2922 tmp.grid->mpi_communicator);
2925 const unsigned int my_rank(
2932 count[0] = tmp.n_local_columns;
2933 count[1] = tmp.n_rows;
2936 hsize_t offset[2] = {0};
2937 for (
unsigned int i = 0; i < my_rank; ++i)
2952 if (tmp.values.
size() > 0)
2975 if (tmp.grid->this_mpi_process == 0)
3051template <
typename NumberType>
3055# ifndef DEAL_II_WITH_HDF5
3059# ifdef H5_HAVE_PARALLEL
3072template <
typename NumberType>
3076# ifndef DEAL_II_WITH_HDF5
3088 std::make_shared<Utilities::MPI::ProcessGrid>(this->grid->mpi_communicator,
3092 const int MB = n_rows,
NB = n_columns;
3100 if (tmp.grid->mpi_process_is_active)
3120 "The data type of the matrix to be read does not match the archive"));
3131 static_cast<int>(
dims[0]) == n_columns,
3133 "The number of columns of the matrix does not match the content of the archive"));
3135 static_cast<int>(
dims[1]) == n_rows,
3137 "The number of rows of the matrix does not match the content of the archive"));
3192 state_int =
static_cast<int>(tmp.state);
3235 tmp.grid->send_to_inactive(&
state_int, 1);
3250template <
typename NumberType>
3254# ifndef DEAL_II_WITH_HDF5
3258# ifndef H5_HAVE_PARALLEL
3262 const unsigned int n_mpi_processes(
3272 std::make_shared<Utilities::MPI::ProcessGrid>(this->grid->mpi_communicator,
3276 const int MB = n_rows;
3278 const int NB =
std::max(
static_cast<int>(std::ceil(
3279 static_cast<double>(n_columns) / n_mpi_processes)),
3285 NumberType *
data = (tmp.values.
size() > 0) ? tmp.values.
data() :
nullptr;
3314 "The data type of the matrix to be read does not match the archive"));
3327 static_cast<int>(
dims[0]) == n_columns,
3329 "The number of columns of the matrix does not match the content of the archive"));
3331 static_cast<int>(
dims[1]) == n_rows,
3333 "The number of rows of the matrix does not match the content of the archive"));
3344 tmp.grid->mpi_communicator);
3352 tmp.grid->mpi_communicator);
3355 const unsigned int my_rank(
3362 count[0] = tmp.n_local_columns;
3363 count[1] = tmp.n_local_rows;
3365 hsize_t offset[2] = {0};
3366 for (
unsigned int i = 0; i < my_rank; ++i)
3464 template <
typename NumberType>
3472 for (
unsigned int i = 0; i < matrix.local_n(); ++i)
3474 const NumberType s = factors[matrix.global_column(i)];
3476 for (
unsigned int j = 0;
j < matrix.local_m(); ++
j)
3477 matrix.local_el(
j, i) *= s;
3481 template <
typename NumberType>
3489 for (
unsigned int i = 0; i <
matrix.local_m(); ++i)
3491 const NumberType s = factors[
matrix.global_row(i)];
3493 for (
unsigned int j = 0;
j <
matrix.local_n(); ++
j)
3503template <
typename NumberType>
3504template <
class InputVector>
3508 if (this->grid->mpi_process_is_active)
3514template <
typename NumberType>
3515template <
class InputVector>
3519 if (this->grid->mpi_process_is_active)
3526# include "scalapack.inst"
ArrayView< typename std::remove_reference< typename std::iterator_traits< Iterator >::reference >::type, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
value_type * data() const noexcept
void reinit(value_type *starting_element, const std::size_t n_elements)
std::vector< NumberType > compute_SVD(ScaLAPACKMatrix< NumberType > *U=nullptr, ScaLAPACKMatrix< NumberType > *VT=nullptr)
std::vector< NumberType > eigenpairs_symmetric_by_value(const std::pair< NumberType, NumberType > &value_limits, const bool compute_eigenvectors)
NumberType frobenius_norm() const
unsigned int pseudoinverse(const NumberType ratio)
std::vector< NumberType > eigenpairs_symmetric_by_value_MRRR(const std::pair< NumberType, NumberType > &value_limits, const bool compute_eigenvectors)
void copy_from(const LAPACKFullMatrix< NumberType > &matrix, const unsigned int rank)
void save_parallel(const std::string &filename, const std::pair< unsigned int, unsigned int > &chunk_size) const
void least_squares(ScaLAPACKMatrix< NumberType > &B, const bool transpose=false)
ScaLAPACKMatrix< NumberType > & operator=(const FullMatrix< NumberType > &)
void Tadd(const NumberType b, const ScaLAPACKMatrix< NumberType > &B)
void mTmult(ScaLAPACKMatrix< NumberType > &C, const ScaLAPACKMatrix< NumberType > &B, const bool adding=false) const
void add(const ScaLAPACKMatrix< NumberType > &B, const NumberType a=0., const NumberType b=1., const bool transpose_B=false)
LAPACKSupport::State get_state() const
LAPACKSupport::Property get_property() const
void Tmmult(ScaLAPACKMatrix< NumberType > &C, const ScaLAPACKMatrix< NumberType > &B, const bool adding=false) const
std::vector< NumberType > eigenpairs_symmetric_MRRR(const bool compute_eigenvectors, const std::pair< unsigned int, unsigned int > &index_limits=std::make_pair(numbers::invalid_unsigned_int, numbers::invalid_unsigned_int), const std::pair< NumberType, NumberType > &value_limits=std::make_pair(std::numeric_limits< NumberType >::quiet_NaN(), std::numeric_limits< NumberType >::quiet_NaN()))
void scale_rows(const InputVector &factors)
ScaLAPACKMatrix(const size_type n_rows, const size_type n_columns, const std::shared_ptr< const Utilities::MPI::ProcessGrid > &process_grid, const size_type row_block_size=32, const size_type column_block_size=32, const LAPACKSupport::Property property=LAPACKSupport::Property::general)
void load(const std::string &filename)
void mmult(ScaLAPACKMatrix< NumberType > &C, const ScaLAPACKMatrix< NumberType > &B, const bool adding=false) const
std::vector< NumberType > eigenpairs_symmetric(const bool compute_eigenvectors, const std::pair< unsigned int, unsigned int > &index_limits=std::make_pair(numbers::invalid_unsigned_int, numbers::invalid_unsigned_int), const std::pair< NumberType, NumberType > &value_limits=std::make_pair(std::numeric_limits< NumberType >::quiet_NaN(), std::numeric_limits< NumberType >::quiet_NaN()))
void save_serial(const std::string &filename, const std::pair< unsigned int, unsigned int > &chunk_size) const
NumberType norm_general(const char type) const
void save(const std::string &filename, const std::pair< unsigned int, unsigned int > &chunk_size=std::make_pair(numbers::invalid_unsigned_int, numbers::invalid_unsigned_int)) const
void load_parallel(const std::string &filename)
NumberType l1_norm() const
void compute_lu_factorization()
NumberType norm_symmetric(const char type) const
void mult(const NumberType b, const ScaLAPACKMatrix< NumberType > &B, const NumberType c, ScaLAPACKMatrix< NumberType > &C, const bool transpose_A=false, const bool transpose_B=false) const
void set_property(const LAPACKSupport::Property property)
void reinit(const size_type n_rows, const size_type n_columns, const std::shared_ptr< const Utilities::MPI::ProcessGrid > &process_grid, const size_type row_block_size=32, const size_type column_block_size=32, const LAPACKSupport::Property property=LAPACKSupport::Property::general)
void load_serial(const std::string &filename)
std::vector< NumberType > eigenpairs_symmetric_by_index_MRRR(const std::pair< unsigned int, unsigned int > &index_limits, const bool compute_eigenvectors)
NumberType reciprocal_condition_number(const NumberType a_norm) const
void TmTmult(ScaLAPACKMatrix< NumberType > &C, const ScaLAPACKMatrix< NumberType > &B, const bool adding=false) const
std::vector< NumberType > eigenpairs_symmetric_by_index(const std::pair< unsigned int, unsigned int > &index_limits, const bool compute_eigenvectors)
unsigned int global_column(const unsigned int loc_column) const
void copy_to(FullMatrix< NumberType > &matrix) const
unsigned int global_row(const unsigned int loc_row) const
void compute_cholesky_factorization()
void copy_transposed(const ScaLAPACKMatrix< NumberType > &B)
NumberType linfty_norm() const
void scale_columns(const InputVector &factors)
void reinit(const size_type size1, const size_type size2, const bool omit_default_initialization=false)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcIO()
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcErrorCode(std::string arg1, types::blas_int arg2)
#define Assert(cond, exc)
#define AssertIsFinite(number)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcNeedsHDF5()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
@ cholesky
Contents is a Cholesky decomposition.
@ lu
Contents is an LU decomposition.
@ matrix
Contents is actually a matrix.
@ unusable
Contents is something useless.
@ inverse_matrix
Contents is the inverse of a matrix.
@ svd
Matrix contains singular value decomposition,.
@ inverse_svd
Matrix is the inverse of a singular value decomposition.
@ eigenvalues
Eigenvalue vector is filled.
@ symmetric
Matrix is symmetric.
@ hessenberg
Matrix is in upper Hessenberg form.
@ diagonal
Matrix is diagonal.
@ upper_triangular
Matrix is upper triangular.
@ lower_triangular
Matrix is lower triangular.
@ general
No special properties.
T sum(const T &t, const MPI_Comm mpi_communicator)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
T max(const T &t, const MPI_Comm mpi_communicator)
T min(const T &t, const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
const MPI_Datatype mpi_type_id_for_type
void free_communicator(MPI_Comm mpi_communicator)
static const unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
hid_t hdf5_type_id(const number *)
std::array< std::pair< Number, Tensor< 1, dim, Number > >, std::integral_constant< int, dim >::value > eigenvectors(const SymmetricTensor< 2, dim, Number > &T, const SymmetricTensorEigenvectorMethod method=SymmetricTensorEigenvectorMethod::ql_implicit_shifts)