16#ifdef DEAL_II_WITH_TRILINOS
28# include <boost/container/small_vector.hpp>
31# ifdef DEAL_II_TRILINOS_WITH_EPETRAEXT
32# include <EpetraExt_MatrixMatrix.h>
34# include <Epetra_Export.h>
35# include <Teuchos_RCP.hpp>
36# include <ml_epetra_utils.h>
37# include <ml_struct.h>
47#ifdef DEAL_II_WITH_TRILINOS
53 template <
typename VectorType>
54 typename VectorType::value_type *
60 template <
typename VectorType>
61 const typename VectorType::value_type *
67 template <
typename VectorType>
68 typename VectorType::value_type *
74 template <
typename VectorType>
75 const typename VectorType::value_type *
76 end(
const VectorType &V)
85 return V.trilinos_vector()[0];
92 return V.trilinos_vector()[0];
99 return V.trilinos_vector()[0] + V.trilinos_vector().MyLength();
106 return V.trilinos_vector()[0] + V.trilinos_vector().MyLength();
137 value_cache = std::make_shared<std::vector<TrilinosScalar>>(colnums);
138 colnum_cache = std::make_shared<std::vector<size_type>>(colnums);
178 : column_space_map(new Epetra_Map(0, 0,
Utilities::Trilinos::comm_self()))
180 new Epetra_FECrsMatrix(View, *column_space_map, *column_space_map, 0))
191 const unsigned int n_max_entries_per_row)
206 matrix(new Epetra_FECrsMatrix(
212 n_max_entries_per_row,
222 const std::vector<unsigned int> &n_entries_per_row)
227 , matrix(new Epetra_FECrsMatrix(
233 reinterpret_cast<
int *>(
234 const_cast<unsigned
int *>(n_entries_per_row.
data())),
244 const unsigned int n_max_entries_per_row)
245 : column_space_map(new Epetra_Map(
246 parallel_partitioning.make_trilinos_map(communicator, false)))
247 , matrix(new Epetra_FECrsMatrix(Copy,
249 n_max_entries_per_row,
265 :
SparseMatrix(parallel_partitioning, MPI_COMM_WORLD, 0)
272 const std::vector<unsigned int> &n_entries_per_row)
273 : column_space_map(new Epetra_Map(
274 parallel_partitioning.make_trilinos_map(communicator, false)))
275 , matrix(new Epetra_FECrsMatrix(Copy,
277 reinterpret_cast<
int *>(
278 const_cast<unsigned
int *>(
279 n_entries_per_row.
data())),
288 const IndexSet &col_parallel_partitioning,
291 : column_space_map(new Epetra_Map(
292 col_parallel_partitioning.make_trilinos_map(communicator, false)))
293 , matrix(new Epetra_FECrsMatrix(
295 row_parallel_partitioning.make_trilinos_map(communicator, false),
296 n_max_entries_per_row,
305 const IndexSet &col_parallel_partitioning,
308 col_parallel_partitioning,
316 const IndexSet &col_parallel_partitioning)
318 col_parallel_partitioning,
326 const IndexSet &col_parallel_partitioning,
328 const std::vector<unsigned int> &n_entries_per_row)
329 : column_space_map(new Epetra_Map(
330 col_parallel_partitioning.make_trilinos_map(communicator, false)))
331 , matrix(new Epetra_FECrsMatrix(
333 row_parallel_partitioning.make_trilinos_map(communicator, false),
334 reinterpret_cast<
int *>(
335 const_cast<unsigned
int *>(n_entries_per_row.
data())),
344 : column_space_map(new Epetra_Map(sparsity_pattern.domain_partitioner()))
346 new Epetra_FECrsMatrix(Copy,
347 sparsity_pattern.trilinos_sparsity_pattern(),
354 "The Trilinos sparsity pattern has not been compressed."));
361 : column_space_map(std::move(other.column_space_map))
362 , matrix(std::move(other.matrix))
363 , nonlocal_matrix(std::move(other.nonlocal_matrix))
364 , nonlocal_matrix_exporter(std::move(other.nonlocal_matrix_exporter))
365 , last_action(other.last_action)
366 , compressed(other.compressed)
368 other.last_action = Zero;
369 other.compressed =
false;
386 bool needs_deep_copy =
391 if (!needs_deep_copy)
398 const int row_local =
matrix->RowMap().LID(
402 int n_entries, rhs_n_entries;
404 int *index_ptr, *rhs_index_ptr;
405 int ierr = rhs.
matrix->ExtractMyRowView(row_local,
411 ierr =
matrix->ExtractMyRowView(row_local,
417 if (n_entries != rhs_n_entries ||
418 std::memcmp(
static_cast<void *
>(index_ptr),
419 static_cast<void *
>(rhs_index_ptr),
420 sizeof(
int) * n_entries) != 0)
422 needs_deep_copy =
true;
426 for (
int i = 0; i < n_entries; ++i)
427 value_ptr[i] = rhs_value_ptr[i];
437 matrix = std::make_unique<Epetra_FECrsMatrix>(*rhs.
matrix);
444 std::make_unique<Epetra_CrsMatrix>(Copy, rhs.
nonlocal_matrix->Graph());
451 template <
typename SparsityPatternType>
453 reinit_matrix(
const IndexSet &row_parallel_partitioning,
454 const IndexSet &column_parallel_partitioning,
455 const SparsityPatternType &sparsity_pattern,
456 const bool exchange_data,
458 std::unique_ptr<Epetra_Map> &column_space_map,
459 std::unique_ptr<Epetra_FECrsMatrix> &matrix,
460 std::unique_ptr<Epetra_CrsMatrix> &nonlocal_matrix,
461 std::unique_ptr<Epetra_Export> &nonlocal_matrix_exporter)
465 nonlocal_matrix.reset();
466 nonlocal_matrix_exporter.reset();
468 column_space_map = std::make_unique<Epetra_Map>(
471 if (column_space_map->Comm().MyPID() == 0)
474 row_parallel_partitioning.
size());
476 column_parallel_partitioning.
size());
479 Epetra_Map row_space_map =
489 trilinos_sparsity.
reinit(row_parallel_partitioning,
490 column_parallel_partitioning,
494 matrix = std::make_unique<Epetra_FECrsMatrix>(
495 Copy, trilinos_sparsity.trilinos_sparsity_pattern(),
false);
505 std::vector<int> n_entries_per_row(last_row - first_row);
508 n_entries_per_row[row - first_row] = sparsity_pattern.row_length(row);
524 std::unique_ptr<Epetra_CrsGraph> graph;
525 if (row_space_map.Comm().NumProc() > 1)
526 graph = std::make_unique<Epetra_CrsGraph>(Copy,
528 n_entries_per_row.data(),
531 graph = std::make_unique<Epetra_CrsGraph>(Copy,
534 n_entries_per_row.data(),
542 std::vector<TrilinosWrappers::types::int_type> row_indices;
546 const int row_length = sparsity_pattern.row_length(row);
550 row_indices.resize(row_length, -1);
552 typename SparsityPatternType::iterator p =
553 sparsity_pattern.begin(row);
555 p != sparsity_pattern.end(row);
557 row_indices[col] = p->column();
559 graph->Epetra_CrsGraph::InsertGlobalIndices(row,
568 graph->FillComplete(*column_space_map, row_space_map);
569 graph->OptimizeStorage();
576 matrix = std::make_unique<Epetra_FECrsMatrix>(Copy, *graph,
false);
588 class Epetra_CrsGraphMod :
public Epetra_CrsGraph
591 Epetra_CrsGraphMod(
const Epetra_Map &row_map,
592 const int *n_entries_per_row)
593 : Epetra_CrsGraph(Copy, row_map, n_entries_per_row, true)
597 SetIndicesAreGlobal()
599 this->Epetra_CrsGraph::SetIndicesAreGlobal(
true);
609 reinit_matrix(
const IndexSet &row_parallel_partitioning,
610 const IndexSet &column_parallel_partitioning,
612 const bool exchange_data,
614 std::unique_ptr<Epetra_Map> &column_space_map,
615 std::unique_ptr<Epetra_FECrsMatrix> &matrix,
616 std::unique_ptr<Epetra_CrsMatrix> &nonlocal_matrix,
617 std::unique_ptr<Epetra_Export> &nonlocal_matrix_exporter)
620 nonlocal_matrix.reset();
621 nonlocal_matrix_exporter.reset();
623 column_space_map = std::make_unique<Epetra_Map>(
627 row_parallel_partitioning.
size());
629 column_parallel_partitioning.
size());
631 Epetra_Map row_space_map =
636 if (relevant_rows.size() == 0)
638 relevant_rows.set_size(
640 relevant_rows.add_range(
643 relevant_rows.compress();
644 Assert(relevant_rows.n_elements() >=
645 static_cast<unsigned int>(row_space_map.NumMyElements()),
647 "Locally relevant rows of sparsity pattern must contain "
648 "all locally owned rows"));
653 const bool have_ghost_rows = [&]() {
654 const std::vector<::types::global_dof_index> indices =
655 relevant_rows.get_index_vector();
656 Epetra_Map relevant_map(
664 row_space_map.Comm());
665 return !relevant_map.SameAs(row_space_map);
668 std::vector<TrilinosWrappers::types::int_type> ghost_rows;
669 std::vector<int> n_entries_per_row(row_space_map.NumMyElements());
670 std::vector<int> n_entries_per_ghost_row;
673 for (
const auto global_row : relevant_rows)
675 if (row_space_map.MyGID(
677 n_entries_per_row[own++] =
679 else if (sparsity_pattern.
row_length(global_row) > 0)
681 ghost_rows.push_back(global_row);
682 n_entries_per_ghost_row.push_back(
688 Epetra_Map off_processor_map(-1,
690 (ghost_rows.size() > 0) ?
691 (ghost_rows.data()) :
694 row_space_map.Comm());
696 std::unique_ptr<Epetra_CrsGraph> graph;
697 std::unique_ptr<Epetra_CrsGraphMod> nonlocal_graph;
698 if (row_space_map.Comm().NumProc() > 1)
701 std::make_unique<Epetra_CrsGraph>(Copy,
703 (n_entries_per_row.size() > 0) ?
704 (n_entries_per_row.data()) :
706 exchange_data ? false : true);
707 if (have_ghost_rows ==
true)
708 nonlocal_graph = std::make_unique<Epetra_CrsGraphMod>(
709 off_processor_map, n_entries_per_ghost_row.data());
713 std::make_unique<Epetra_CrsGraph>(Copy,
716 (n_entries_per_row.size() > 0) ?
717 (n_entries_per_row.data()) :
722 std::vector<TrilinosWrappers::types::int_type> row_indices;
724 for (
const auto global_row : relevant_rows)
726 const int row_length = sparsity_pattern.
row_length(global_row);
730 row_indices.resize(row_length, -1);
731 for (
int col = 0; col < row_length; ++col)
732 row_indices[col] = sparsity_pattern.
column_number(global_row, col);
734 if (row_space_map.MyGID(
736 graph->InsertGlobalIndices(global_row,
742 nonlocal_graph->InsertGlobalIndices(global_row,
749 if (nonlocal_graph.get() !=
nullptr)
755 nonlocal_graph->SetIndicesAreGlobal();
756 Assert(nonlocal_graph->IndicesAreGlobal() ==
true,
758 nonlocal_graph->FillComplete(*column_space_map, row_space_map);
759 nonlocal_graph->OptimizeStorage();
764 Epetra_Export exporter(nonlocal_graph->RowMap(), row_space_map);
765 int ierr = graph->Export(*nonlocal_graph, exporter, Add);
770 std::make_unique<Epetra_CrsMatrix>(Copy, *nonlocal_graph);
773 graph->FillComplete(*column_space_map, row_space_map);
774 graph->OptimizeStorage();
779 matrix = std::make_unique<Epetra_FECrsMatrix>(Copy, *graph,
false);
785 template <
typename SparsityPatternType>
802 template <
typename SparsityPatternType>
804 !std::is_same_v<SparsityPatternType, ::SparseMatrix<double>>>
806 const IndexSet &col_parallel_partitioning,
807 const SparsityPatternType &sparsity_pattern,
809 const bool exchange_data)
811 reinit_matrix(row_parallel_partitioning,
812 col_parallel_partitioning,
838 matrix = std::make_unique<Epetra_FECrsMatrix>(
843 std::make_unique<Epetra_CrsMatrix>(Copy,
857 if (
this == &sparse_matrix)
861 std::make_unique<Epetra_Map>(sparse_matrix.
trilinos_matrix().DomainMap());
864 matrix = std::make_unique<Epetra_FECrsMatrix>(
879 template <
typename number>
882 const IndexSet &row_parallel_partitioning,
883 const IndexSet &col_parallel_partitioning,
884 const ::SparseMatrix<number> &dealii_sparse_matrix,
886 const double drop_tolerance,
887 const bool copy_values,
888 const ::SparsityPattern *use_this_sparsity)
890 if (copy_values ==
false)
894 if (use_this_sparsity ==
nullptr)
895 reinit(row_parallel_partitioning,
896 col_parallel_partitioning,
897 dealii_sparse_matrix.get_sparsity_pattern(),
901 reinit(row_parallel_partitioning,
902 col_parallel_partitioning,
909 const size_type n_rows = dealii_sparse_matrix.m();
914 const ::SparsityPattern &sparsity_pattern =
915 (use_this_sparsity !=
nullptr) ?
917 dealii_sparse_matrix.get_sparsity_pattern();
919 if (
matrix.get() ==
nullptr ||
m() != n_rows ||
922 reinit(row_parallel_partitioning,
923 col_parallel_partitioning,
935 std::vector<size_type> row_indices(maximum_row_length);
936 std::vector<TrilinosScalar> values(maximum_row_length);
938 for (
size_type row = 0; row < n_rows; ++row)
940 if (row_parallel_partitioning.
is_element(row) ==
true)
943 sparsity_pattern.begin(row);
944 typename ::SparseMatrix<number>::const_iterator it =
945 dealii_sparse_matrix.begin(row);
947 if (sparsity_pattern.n_rows() == sparsity_pattern.n_cols())
951 if (std::fabs(it->value()) > drop_tolerance)
953 values[col] = it->value();
954 row_indices[col++] = it->column();
960 while (it != dealii_sparse_matrix.end(row) &&
961 select_index != sparsity_pattern.end(row))
963 while (select_index->column() < it->column() &&
964 select_index != sparsity_pattern.end(row))
966 while (it->column() < select_index->column() &&
967 it != dealii_sparse_matrix.end(row))
970 if (it == dealii_sparse_matrix.end(row))
972 if (std::fabs(it->value()) > drop_tolerance)
974 values[col] = it->value();
975 row_indices[col++] = it->column();
982 reinterpret_cast<size_type *
>(row_indices.data()),
991 template <
typename number>
994 const ::SparseMatrix<number> &dealii_sparse_matrix,
995 const double drop_tolerance,
996 const bool copy_values,
997 const ::SparsityPattern *use_this_sparsity)
1001 dealii_sparse_matrix,
1012 const bool copy_values)
1014 Assert(input_matrix.Filled() ==
true,
1015 ExcMessage(
"Input CrsMatrix has not called FillComplete()!"));
1019 const Epetra_CrsGraph *graph = &input_matrix.Graph();
1024 matrix = std::make_unique<Epetra_FECrsMatrix>(Copy, *graph,
false);
1028 if (copy_values ==
true)
1034 const size_type my_nonzeros = input_matrix.NumMyNonzeros();
1035 std::memcpy(values, in_values, my_nonzeros *
sizeof(
TrilinosScalar));
1059 "compress() can only be called with VectorOperation add, insert, or unknown"));
1066 ExcMessage(
"Operation and argument to compress() do not match"));
1092 ierr =
matrix->OptimizeStorage();
1137 matrix->ExtractMyRowView(local_row, num_entries, values, col_indices);
1141 const std::ptrdiff_t diag_index =
1142 std::find(col_indices, col_indices + num_entries, local_row) -
1146 if (diag_index != j || new_diag_value == 0)
1149 if (diag_index != num_entries)
1150 values[diag_index] = new_diag_value;
1160 for (
const auto row : rows)
1183 if (trilinos_i == -1)
1198 int nnz_present =
matrix->NumMyEntries(trilinos_i);
1207 int ierr =
matrix->ExtractMyRowView(trilinos_i,
1213 Assert(nnz_present == nnz_extracted,
1219 const std::ptrdiff_t local_col_index =
1220 std::find(col_indices, col_indices + nnz_present, trilinos_j) -
1231 if (local_col_index == nnz_present)
1236 value = values[local_col_index];
1262 if ((trilinos_i == -1) || (trilinos_j == -1))
1273 int nnz_present =
matrix->NumMyEntries(trilinos_i);
1281 int ierr =
matrix->ExtractMyRowView(trilinos_i,
1287 Assert(nnz_present == nnz_extracted,
1293 const std::ptrdiff_t local_col_index =
1294 std::find(col_indices, col_indices + nnz_present, trilinos_j) -
1304 if (local_col_index == nnz_present)
1307 value = values[local_col_index];
1356 int ierr =
matrix->NumMyRowEntries(local_row, ncols);
1360 return static_cast<unsigned int>(ncols);
1367 const std::vector<size_type> &col_indices,
1369 const bool elide_zero_values)
1371 Assert(row_indices.size() == values.m(),
1373 Assert(col_indices.size() == values.n(),
1376 for (
size_type i = 0; i < row_indices.size(); ++i)
1388 const std::vector<size_type> &col_indices,
1389 const std::vector<TrilinosScalar> &values,
1390 const bool elide_zero_values)
1392 Assert(col_indices.size() == values.size(),
1406 SparseMatrix::set<TrilinosScalar>(
const size_type row,
1410 const bool elide_zero_values)
1430 boost::container::small_vector<TrilinosScalar, 200> local_value_array(
1431 elide_zero_values ? n_cols : 0);
1432 boost::container::small_vector<TrilinosWrappers::types::int_type, 200>
1433 local_index_array(elide_zero_values ? n_cols : 0);
1438 if (elide_zero_values ==
false)
1443 col_value_ptr = values;
1450 col_index_ptr = local_index_array.data();
1451 col_value_ptr = local_value_array.data();
1456 const double value = values[j];
1460 local_index_array[n_columns] = col_indices[j];
1461 local_value_array[n_columns] = value;
1478 if (
matrix->RowMap().MyGID(
1481 if (
matrix->Filled() ==
false)
1483 ierr =
matrix->Epetra_CrsMatrix::InsertGlobalValues(
1484 row,
static_cast<int>(n_columns), col_value_ptr, col_index_ptr);
1493 ierr =
matrix->Epetra_CrsMatrix::ReplaceGlobalValues(row,
1508 if (
matrix->Filled() ==
false)
1510 ierr =
matrix->InsertGlobalValues(1,
1515 Epetra_FECrsMatrix::ROW_MAJOR);
1520 ierr =
matrix->ReplaceGlobalValues(1,
1525 Epetra_FECrsMatrix::ROW_MAJOR);
1542 const bool elide_zero_values)
1544 Assert(indices.size() == values.m(),
1548 for (
size_type i = 0; i < indices.size(); ++i)
1560 const std::vector<size_type> &col_indices,
1562 const bool elide_zero_values)
1564 Assert(row_indices.size() == values.m(),
1566 Assert(col_indices.size() == values.n(),
1569 for (
size_type i = 0; i < row_indices.size(); ++i)
1581 const std::vector<size_type> &col_indices,
1582 const std::vector<TrilinosScalar> &values,
1583 const bool elide_zero_values)
1585 Assert(col_indices.size() == values.size(),
1602 const bool elide_zero_values,
1627 boost::container::small_vector<TrilinosScalar, 100> local_value_array(
1629 boost::container::small_vector<TrilinosWrappers::types::int_type, 100>
1630 local_index_array(n_cols);
1635 if (elide_zero_values ==
false)
1640 col_value_ptr = values;
1652 col_index_ptr = local_index_array.data();
1653 col_value_ptr = local_value_array.data();
1658 const double value = values[j];
1663 local_index_array[n_columns] = col_indices[j];
1664 local_value_array[n_columns] = value;
1680 if (
matrix->RowMap().MyGID(
1683 ierr =
matrix->Epetra_CrsMatrix::SumIntoGlobalValues(row,
1697 ExcMessage(
"Attempted to write into off-processor matrix row "
1698 "that has not be specified as being writable upon "
1716 ierr =
matrix->SumIntoGlobalValues(1,
1721 Epetra_FECrsMatrix::ROW_MAJOR);
1729 std::cout <<
"------------------------------------------"
1731 std::cout <<
"Got error " << ierr <<
" in row " << row
1732 <<
" of proc " <<
matrix->RowMap().Comm().MyPID()
1733 <<
" when trying to add the columns:" << std::endl;
1735 std::cout << col_index_ptr[i] <<
" ";
1736 std::cout << std::endl << std::endl;
1737 std::cout <<
"Matrix row "
1738 << (
matrix->RowMap().MyGID(
1743 <<
" has the following indices:" << std::endl;
1744 std::vector<TrilinosWrappers::types::int_type> indices;
1745 const Epetra_CrsGraph *graph =
1753 indices.resize(graph->NumGlobalIndices(row));
1755 graph->ExtractGlobalRowCopy(row,
1762 std::cout << indices[i] <<
" ";
1763 std::cout << std::endl << std::endl;
1784 const int ierr =
matrix->PutScalar(0.0);
1806 ExcMessage(
"Can only add matrices with same distribution of rows"));
1808 ExcMessage(
"Addition of matrices only allowed if matrices are "
1809 "filled, i.e., compress() has been called"));
1811 const bool same_col_map =
matrix->ColMap().SameAs(rhs.
matrix->ColMap());
1815 const int row_local =
matrix->RowMap().LID(
1823 int n_entries, rhs_n_entries;
1825 int *index_ptr, *rhs_index_ptr;
1826 int ierr = rhs.
matrix->ExtractMyRowView(row_local,
1833 matrix->ExtractMyRowView(row_local, n_entries, value_ptr, index_ptr);
1835 bool expensive_checks = (n_entries != rhs_n_entries || !same_col_map);
1836 if (!expensive_checks)
1840 expensive_checks = std::memcmp(
static_cast<void *
>(index_ptr),
1841 static_cast<void *
>(rhs_index_ptr),
1842 sizeof(
int) * n_entries) != 0;
1843 if (!expensive_checks)
1844 for (
int i = 0; i < n_entries; ++i)
1845 value_ptr[i] += rhs_value_ptr[i] * factor;
1851 if (expensive_checks)
1853 for (
int i = 0; i < rhs_n_entries; ++i)
1855 if (rhs_value_ptr[i] == 0.)
1859 int local_col =
matrix->ColMap().LID(rhs_global_col);
1861 index_ptr + n_entries,
1863 Assert(local_index != index_ptr + n_entries &&
1864 *local_index == local_col,
1866 "Adding the entries from the other matrix "
1867 "failed, because the sparsity pattern "
1868 "of that matrix includes more elements than the "
1869 "calling matrix, which is not allowed."));
1870 value_ptr[local_index - index_ptr] += factor * rhs_value_ptr[i];
1888 if (!
matrix->UseTranspose())
1890 ierr =
matrix->SetUseTranspose(
true);
1895 ierr =
matrix->SetUseTranspose(
false);
1905 const int ierr =
matrix->Scale(a);
1920 const int ierr =
matrix->Scale(factor);
1932 return matrix->NormOne();
1941 return matrix->NormInf();
1950 return matrix->NormFrobenius();
1957 namespace SparseMatrixImplementation
1959 template <
typename VectorType>
1972 ExcMessage(
"The column partitioning of a matrix does not match "
1973 "the partitioning of a vector you are trying to "
1974 "multiply it with. Are you multiplying the "
1975 "matrix with a vector that has ghost elements?"));
1977 ExcMessage(
"The row partitioning of a matrix does not match "
1978 "the partitioning of a vector you are trying to "
1979 "put the result of a matrix-vector product in. "
1980 "Are you trying to put the product of the "
1981 "matrix with a vector into a vector that has "
1982 "ghost elements?"));
1988 template <
typename VectorType>
1992 if constexpr (std::is_same_v<
typename VectorType::value_type,
2008 Epetra_MultiVector tril_dst(
2010 Epetra_MultiVector tril_src(View,
2017 const int ierr =
matrix->Multiply(
false, tril_src, tril_dst);
2028 template <
typename VectorType>
2032 if constexpr (std::is_same_v<
typename VectorType::value_type,
2048 Epetra_MultiVector tril_dst(
2050 Epetra_MultiVector tril_src(View,
2056 const int ierr =
matrix->Multiply(
true, tril_src, tril_dst);
2067 template <
typename VectorType>
2075 VectorType tmp_vector;
2076 tmp_vector.reinit(dst,
true);
2077 vmult(tmp_vector, src);
2083 template <
typename VectorType>
2091 VectorType tmp_vector;
2092 tmp_vector.reinit(dst,
true);
2106 temp_vector.
reinit(v,
true);
2108 vmult(temp_vector, v);
2109 return temp_vector * v;
2123 temp_vector.
reinit(v,
true);
2125 vmult(temp_vector, v);
2126 return u * temp_vector;
2138 const bool transpose_left)
2140 const bool use_vector = (V.size() == inputright.
m() ? true :
false);
2141 if (transpose_left ==
false)
2143 Assert(inputleft.
n() == inputright.
m(),
2147 ExcMessage(
"Parallel partitioning of A and B does not fit."));
2151 Assert(inputleft.
m() == inputright.
m(),
2155 ExcMessage(
"Parallel partitioning of A and B does not fit."));
2166 Teuchos::RCP<Epetra_CrsMatrix> mod_B;
2169 mod_B = Teuchos::rcp(
const_cast<Epetra_CrsMatrix *
>(
2175 mod_B = Teuchos::rcp(
2181 ExcMessage(
"Parallel distribution of matrix B and vector V "
2182 "does not match."));
2185 for (
int i = 0; i < local_N; ++i)
2188 double *new_data, *B_data;
2189 mod_B->ExtractMyRowView(i, N_entries, new_data);
2193 double value = V.trilinos_vector()[0][i];
2195 new_data[j] = value * B_data[j];
2207# ifdef DEAL_II_TRILINOS_WITH_EPETRAEXT
2212 const_cast<Epetra_CrsMatrix &
>(
2213 tmp_result.trilinos_matrix()));
2216 ExcMessage(
"This function requires that the Trilinos "
2217 "installation found while running the deal.II "
2218 "CMake scripts contains the optional Trilinos "
2219 "package 'EpetraExt'. However, this optional "
2220 "part of Trilinos was not found."));
2222 result.
reinit(tmp_result.trilinos_matrix());
2260 const bool print_detailed_trilinos_information)
const
2262 if (print_detailed_trilinos_information ==
true)
2270 for (
int i = 0; i <
matrix->NumMyRows(); ++i)
2273 matrix->ExtractMyRowView(i, num_entries, values, indices);
2280 <<
") " << values[j] << std::endl;
2293 sizeof(*this) +
sizeof(*matrix) +
sizeof(*
matrix->Graph().DataPtr());
2296 matrix->NumMyNonzeros() +
2305 const Epetra_MpiComm *mpi_comm =
2306 dynamic_cast<const Epetra_MpiComm *
>(&
matrix->RangeMap().Comm());
2308 return mpi_comm->Comm();
2317 namespace LinearOperatorImplementation
2322 : use_transpose(false)
2323 , communicator(MPI_COMM_SELF)
2324 , domain_map(
IndexSet().make_trilinos_map(communicator.Comm()))
2325 , range_map(
IndexSet().make_trilinos_map(communicator.Comm()))
2329 ExcMessage(
"Uninitialized TrilinosPayload::vmult called "
2330 "(Default constructor)"));
2335 ExcMessage(
"Uninitialized TrilinosPayload::Tvmult called "
2336 "(Default constructor)"));
2341 ExcMessage(
"Uninitialized TrilinosPayload::inv_vmult called "
2342 "(Default constructor)"));
2347 ExcMessage(
"Uninitialized TrilinosPayload::inv_Tvmult called "
2348 "(Default constructor)"));
2358 matrix.trilinos_matrix()),
2360 matrix_exemplar.trilinos_matrix().UseTranspose(),
2361 matrix_exemplar.get_mpi_communicator(),
2362 matrix_exemplar.locally_owned_domain_indices(),
2363 matrix_exemplar.locally_owned_range_indices())
2373 matrix.trilinos_matrix()),
2375 payload_exemplar.UseTranspose(),
2376 payload_exemplar.get_mpi_communicator(),
2377 payload_exemplar.locally_owned_domain_indices(),
2378 payload_exemplar.locally_owned_range_indices())
2388 matrix_exemplar.trilinos_matrix().UseTranspose(),
2389 matrix_exemplar.get_mpi_communicator(),
2390 matrix_exemplar.locally_owned_domain_indices(),
2391 matrix_exemplar.locally_owned_range_indices())
2400 preconditioner.trilinos_operator(),
2402 preconditioner_exemplar.trilinos_operator().UseTranspose(),
2403 preconditioner_exemplar.get_mpi_communicator(),
2404 preconditioner_exemplar.locally_owned_domain_indices(),
2405 preconditioner_exemplar.locally_owned_range_indices())
2415 payload_exemplar.UseTranspose(),
2416 payload_exemplar.get_mpi_communicator(),
2417 payload_exemplar.locally_owned_domain_indices(),
2418 payload_exemplar.locally_owned_range_indices())
2424 : vmult(payload.vmult)
2425 , Tvmult(payload.Tvmult)
2426 , inv_vmult(payload.inv_vmult)
2427 , inv_Tvmult(payload.inv_Tvmult)
2428 , use_transpose(payload.use_transpose)
2429 , communicator(payload.communicator)
2430 , domain_map(payload.domain_map)
2431 , range_map(payload.range_map)
2440 : use_transpose(false)
2443 communicator(first_op.communicator)
2444 , domain_map(second_op.domain_map)
2445 , range_map(first_op.range_map)
2456 tril_dst = tril_src;
2460 tril_dst = tril_src;
2464 tril_dst = tril_src;
2468 tril_dst = tril_src;
2482 const int ierr = tril_dst.PutScalar(0.0);
2488 const int ierr = tril_dst.PutScalar(0.0);
2495 ExcMessage(
"Cannot compute inverse of null operator"));
2497 const int ierr = tril_dst.PutScalar(0.0);
2504 ExcMessage(
"Cannot compute inverse of null operator"));
2506 const int ierr = tril_dst.PutScalar(0.0);
2606 return "TrilinosPayload";
2664 "Operators are set to work on incompatible IndexSets."));
2668 "Operators are set to work on incompatible IndexSets."));
2673 return_op.
vmult = [first_op, second_op](Range &tril_dst,
2674 const Domain &tril_src) {
2682 i->reinit(
IndexSet(first_op_init_map),
2687 const size_type i_local_size = i->end() - i->begin();
2691 Intermediate tril_int(View,
2699 second_op.
Apply(tril_src, tril_int);
2700 first_op.
Apply(tril_src, tril_dst);
2701 const int ierr = tril_dst.Update(1.0, tril_int, 1.0);
2705 return_op.
Tvmult = [first_op, second_op](Domain &tril_dst,
2706 const Range &tril_src) {
2721 i->reinit(
IndexSet(first_op_init_map),
2726 const size_type i_local_size = i->end() - i->begin();
2730 Intermediate tril_int(View,
2738 second_op.
Apply(tril_src, tril_int);
2739 first_op.
Apply(tril_src, tril_dst);
2740 const int ierr = tril_dst.Update(1.0, tril_int, 1.0);
2748 return_op.
inv_vmult = [first_op, second_op](Domain &tril_dst,
2749 const Range &tril_src) {
2757 i->reinit(
IndexSet(first_op_init_map),
2762 const size_type i_local_size = i->end() - i->begin();
2766 Intermediate tril_int(View,
2776 const int ierr = tril_dst.Update(1.0, tril_int, 1.0);
2780 return_op.
inv_Tvmult = [first_op, second_op](Range &tril_dst,
2781 const Domain &tril_src) {
2796 i->reinit(
IndexSet(first_op_init_map),
2801 const size_type i_local_size = i->end() - i->begin();
2805 Intermediate tril_int(View,
2815 const int ierr = tril_dst.Update(1.0, tril_int, 1.0);
2840 "Operators are set to work on incompatible IndexSets."));
2845 return_op.
vmult = [first_op, second_op](Range &tril_dst,
2846 const Domain &tril_src) {
2854 i->reinit(
IndexSet(first_op_init_map),
2859 const size_type i_local_size = i->end() - i->begin();
2863 Intermediate tril_int(View,
2871 second_op.
Apply(tril_src, tril_int);
2872 first_op.
Apply(tril_int, tril_dst);
2875 return_op.
Tvmult = [first_op, second_op](Domain &tril_dst,
2876 const Range &tril_src) {
2891 i->reinit(
IndexSet(first_op_init_map),
2896 const size_type i_local_size = i->end() - i->begin();
2900 Intermediate tril_int(View,
2907 first_op.
Apply(tril_src, tril_int);
2908 second_op.
Apply(tril_int, tril_dst);
2915 return_op.
inv_vmult = [first_op, second_op](Domain &tril_dst,
2916 const Range &tril_src) {
2924 i->reinit(
IndexSet(first_op_init_map),
2929 const size_type i_local_size = i->end() - i->begin();
2933 Intermediate tril_int(View,
2945 return_op.
inv_Tvmult = [first_op, second_op](Range &tril_dst,
2946 const Domain &tril_src) {
2961 i->reinit(
IndexSet(first_op_init_map),
2966 const size_type i_local_size = i->end() - i->begin();
2970 Intermediate tril_int(View,
2998# include "lac/trilinos_sparse_matrix.inst"
3013 const ::SparsityPattern &,
3029 const ::Vector<double> &)
const;
3034 const ::LinearAlgebra::distributed::Vector<double, MemorySpace::Host>
3040 const ::LinearAlgebra::distributed::Vector<float, MemorySpace::Host>
3046 const ::LinearAlgebra::EpetraWrappers::Vector &)
const;
3053 const ::Vector<double> &)
const;
3058 const ::LinearAlgebra::distributed::Vector<double, MemorySpace::Host>
3064 const ::LinearAlgebra::EpetraWrappers::Vector &)
const;
3071 const ::Vector<double> &)
const;
3076 const ::LinearAlgebra::distributed::Vector<double, MemorySpace::Host>
3082 const ::LinearAlgebra::EpetraWrappers::Vector &)
const;
3089 const ::Vector<double> &)
const;
3094 const ::LinearAlgebra::distributed::Vector<double, MemorySpace::Host>
3100 const ::LinearAlgebra::distributed::Vector<float, MemorySpace::Host>
3106 const ::LinearAlgebra::EpetraWrappers::Vector &)
const;
* * reference operator*() const
const IndexSet & row_index_set() const
size_type row_length(const size_type row) const
size_type column_number(const size_type row, const size_type index) const
bool is_element(const size_type index) const
Epetra_Map make_trilinos_map(const MPI_Comm communicator=MPI_COMM_WORLD, const bool overlapping=false) const
void reinit(const size_type m, const size_type n, const ArrayView< const unsigned int > &row_lengths)
void reinit(const Vector &v, const bool omit_zeroing_entries=false)
const Epetra_BlockMap & trilinos_partitioner() const
size_type size() const override
std::shared_ptr< std::vector< TrilinosScalar > > value_cache
std::shared_ptr< std::vector< size_type > > colnum_cache
void set(const size_type i, const size_type j, const TrilinosScalar value)
std::unique_ptr< Epetra_Map > column_space_map
MPI_Comm get_mpi_communicator() const
SparseMatrix & operator*=(const TrilinosScalar factor)
void mmult(SparseMatrix &C, const SparseMatrix &B, const MPI::Vector &V=MPI::Vector()) const
std::unique_ptr< Epetra_Export > nonlocal_matrix_exporter
TrilinosScalar l1_norm() const
void compress(VectorOperation::values operation)
std::unique_ptr< Epetra_FECrsMatrix > matrix
void vmult(VectorType &dst, const VectorType &src) const
TrilinosScalar linfty_norm() const
const Epetra_CrsMatrix & trilinos_matrix() const
size_type memory_consumption() const
TrilinosScalar matrix_norm_square(const MPI::Vector &v) const
Epetra_CombineMode last_action
IndexSet locally_owned_range_indices() const
void print(std::ostream &out, const bool write_extended_trilinos_info=false) const
void Tmmult(SparseMatrix &C, const SparseMatrix &B, const MPI::Vector &V=MPI::Vector()) const
void clear_row(const size_type row, const TrilinosScalar new_diag_value=0)
void clear_rows(const ArrayView< const size_type > &rows, const TrilinosScalar new_diag_value=0)
void reinit(const SparsityPatternType &sparsity_pattern)
void vmult_add(VectorType &dst, const VectorType &src) const
SparseMatrix & operator=(const SparseMatrix &)=delete
SparseMatrix & operator/=(const TrilinosScalar factor)
void Tvmult_add(VectorType &dst, const VectorType &src) const
TrilinosScalar el(const size_type i, const size_type j) const
IndexSet locally_owned_domain_indices() const
bool in_local_range(const size_type index) const
void copy_from(const SparseMatrix &source)
unsigned int row_length(const size_type row) const
TrilinosScalar frobenius_norm() const
void Tvmult(VectorType &dst, const VectorType &src) const
std::uint64_t n_nonzero_elements() const
const Epetra_CrsGraph & trilinos_sparsity_pattern() const
TrilinosScalar diag_element(const size_type i) const
void add(const size_type i, const size_type j, const TrilinosScalar value)
unsigned int local_size() const
TrilinosScalar operator()(const size_type i, const size_type j) const
TrilinosScalar matrix_scalar_product(const MPI::Vector &u, const MPI::Vector &v) const
std::pair< size_type, size_type > local_range() const
std::unique_ptr< Epetra_CrsMatrix > nonlocal_matrix
std::unique_ptr< Epetra_CrsGraph > nonlocal_graph
const Epetra_Map & domain_partitioner() const
const Epetra_FECrsGraph & trilinos_sparsity_pattern() const
::types::global_dof_index size_type
Epetra_MpiComm communicator
std::function< void(VectorType &, const VectorType &)> inv_Tvmult
virtual int SetUseTranspose(bool UseTranspose) override
virtual bool UseTranspose() const override
virtual const Epetra_Map & OperatorDomainMap() const override
IndexSet locally_owned_range_indices() const
TrilinosPayload transpose_payload() const
Epetra_MultiVector VectorType
MPI_Comm get_mpi_communicator() const
virtual int ApplyInverse(const VectorType &Y, VectorType &X) const override
std::function< void(VectorType &, const VectorType &)> Tvmult
virtual int Apply(const VectorType &X, VectorType &Y) const override
std::function< void(VectorType &, const VectorType &)> vmult
virtual const Epetra_Map & OperatorRangeMap() const override
std::function< void(VectorType &, const VectorType &)> inv_vmult
virtual const char * Label() const override
IndexSet locally_owned_domain_indices() const
virtual const Epetra_Comm & Comm() const override
virtual bool HasNormInf() const override
TrilinosPayload identity_payload() const
virtual double NormInf() const override
TrilinosPayload null_payload() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcIO()
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcScalarAssignmentOnlyForZeroValue()
static ::ExceptionBase & ExcInvalidIndex(size_type arg1, size_type arg2)
#define Assert(cond, exc)
static ::ExceptionBase & ExcAccessToNonPresentElement(size_type arg1, size_type arg2)
#define AssertIsFinite(number)
static ::ExceptionBase & ExcAccessToNonlocalRow(std::size_t arg1)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDivideByZero()
static ::ExceptionBase & ExcSourceEqualsDestination()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcNotQuadratic()
static ::ExceptionBase & ExcMatrixNotCompressed()
static ::ExceptionBase & ExcTrilinosError(int arg1)
static ::ExceptionBase & ExcAccessToNonLocalElement(size_type arg1, size_type arg2, size_type arg3, size_type arg4)
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcTrilinosError(int arg1)
#define AssertThrow(cond, exc)
IndexSet complete_index_set(const IndexSet::size_type N)
std::vector< index_type > data
@ matrix
Contents is actually a matrix.
* * * * std::vector< Number > ThermoPlasticMaterial< dim, ViscoplasticYieldLaw, Number >::get_state_parameters const
TrilinosPayload operator+(const TrilinosPayload &first_op, const TrilinosPayload &second_op)
void check_vector_map_equality(const Epetra_CrsMatrix &, const VectorType &, const VectorType &)
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
void perform_mmult(const SparseMatrix &inputleft, const SparseMatrix &inputright, SparseMatrix &result, const MPI::Vector &V, const bool transpose_left)
TrilinosWrappers::types::int_type min_my_gid(const Epetra_BlockMap &map)
TrilinosWrappers::types::int64_type n_global_elements(const Epetra_BlockMap &map)
TrilinosWrappers::types::int_type global_column_index(const Epetra_CrsMatrix &matrix, const ::types::global_dof_index i)
TrilinosWrappers::types::int_type max_my_gid(const Epetra_BlockMap &map)
TrilinosWrappers::types::int_type global_row_index(const Epetra_CrsMatrix &matrix, const ::types::global_dof_index i)
TrilinosWrappers::types::int_type n_global_cols(const Epetra_CrsGraph &graph)
const Epetra_Comm & comm_self()
Iterator lower_bound(Iterator first, Iterator last, const T &val)