16 #ifndef dealii_trilinos_sparse_matrix_h 17 # define dealii_trilinos_sparse_matrix_h 22 # ifdef DEAL_II_WITH_TRILINOS 36 # include <Epetra_Comm.h> 37 # include <Epetra_CrsGraph.h> 38 # include <Epetra_Export.h> 39 # include <Epetra_FECrsMatrix.h> 40 # include <Epetra_Map.h> 41 # include <Epetra_MultiVector.h> 42 # include <Epetra_Operator.h> 46 # include <type_traits> 48 # ifdef DEAL_II_WITH_MPI 49 # include <Epetra_MpiComm.h> 52 # include <Epetra_SerialComm.h> 59 template <
typename MatrixType>
62 template <
typename number>
74 template <
bool Constness>
99 <<
"You tried to access row " << arg1
100 <<
" of a distributed sparsity pattern, " 101 <<
" but only rows " << arg2 <<
" through " << arg3
102 <<
" are stored locally and can be accessed.");
203 template <
bool Constess>
242 template <
bool Other>
339 friend class Reference;
356 template <
bool Constness>
380 template <
bool Other>
424 operator<(const Iterator<Constness> &)
const;
438 <<
"Attempt to access element " << arg2 <<
" of row " 439 << arg1 <<
" which doesn't have that many elements.");
447 template <
bool Other>
528 <<
"You tried to access row " << arg1
529 <<
" of a non-contiguous locally owned row set." 530 <<
" The row " << arg1
531 <<
" is not stored locally and can't be accessed.");
546 static const bool zero_addition_can_be_elided =
true;
582 const unsigned int n_max_entries_per_row);
593 const std::vector<unsigned int> &n_entries_per_row);
637 template <
typename SparsityPatternType>
639 reinit(
const SparsityPatternType &sparsity_pattern);
687 template <
typename number>
689 reinit(const ::SparseMatrix<number> &dealii_sparse_matrix,
690 const double drop_tolerance = 1
e-13,
691 const bool copy_values =
true,
692 const ::SparsityPattern * use_this_sparsity =
nullptr);
700 reinit(
const Epetra_CrsMatrix &input_matrix,
const bool copy_values =
true);
720 const MPI_Comm & communicator = MPI_COMM_WORLD,
721 const unsigned int n_max_entries_per_row = 0);
731 const MPI_Comm & communicator,
732 const std::vector<unsigned int> &n_entries_per_row);
749 const IndexSet &col_parallel_partitioning,
750 const MPI_Comm &communicator = MPI_COMM_WORLD,
751 const size_type n_max_entries_per_row = 0);
768 const IndexSet & col_parallel_partitioning,
769 const MPI_Comm & communicator,
770 const std::vector<unsigned int> &n_entries_per_row);
792 template <
typename SparsityPatternType>
795 const SparsityPatternType &sparsity_pattern,
796 const MPI_Comm & communicator = MPI_COMM_WORLD,
797 const bool exchange_data =
false);
811 template <
typename SparsityPatternType>
812 typename std::enable_if<
813 !std::is_same<SparsityPatternType,
816 const IndexSet & col_parallel_partitioning,
817 const SparsityPatternType &sparsity_pattern,
818 const MPI_Comm & communicator = MPI_COMM_WORLD,
819 const bool exchange_data =
false);
837 template <
typename number>
840 const ::SparseMatrix<number> &dealii_sparse_matrix,
841 const MPI_Comm & communicator = MPI_COMM_WORLD,
842 const double drop_tolerance = 1
e-13,
843 const bool copy_values =
true,
844 const ::SparsityPattern * use_this_sparsity =
nullptr);
859 template <
typename number>
862 const IndexSet & col_parallel_partitioning,
863 const ::SparseMatrix<number> &dealii_sparse_matrix,
864 const MPI_Comm & communicator = MPI_COMM_WORLD,
865 const double drop_tolerance = 1
e-13,
866 const bool copy_values =
true,
867 const ::SparsityPattern * use_this_sparsity =
nullptr);
905 std::pair<size_type, size_type>
913 in_local_range(
const size_type index)
const;
920 n_nonzero_elements()
const;
935 is_compressed()
const;
949 get_mpi_communicator()
const;
967 operator=(
const double d);
1066 set(
const std::vector<size_type> & indices,
1068 const bool elide_zero_values =
false);
1076 set(
const std::vector<size_type> & row_indices,
1077 const std::vector<size_type> & col_indices,
1079 const bool elide_zero_values =
false);
1110 const std::vector<size_type> & col_indices,
1111 const std::vector<TrilinosScalar> &values,
1112 const bool elide_zero_values =
false);
1141 template <
typename Number>
1146 const Number * values,
1147 const bool elide_zero_values =
false);
1180 add(
const std::vector<size_type> & indices,
1182 const bool elide_zero_values =
true);
1190 add(
const std::vector<size_type> & row_indices,
1191 const std::vector<size_type> & col_indices,
1193 const bool elide_zero_values =
true);
1210 const std::vector<size_type> & col_indices,
1211 const std::vector<TrilinosScalar> &values,
1212 const bool elide_zero_values =
true);
1232 const bool elide_zero_values =
true,
1233 const bool col_indices_are_sorted =
false);
1313 clear_rows(
const std::vector<size_type> &rows,
1409 template <
typename VectorType>
1410 typename std::enable_if<std::is_same<
typename VectorType::value_type,
1420 template <
typename VectorType>
1421 typename std::enable_if<!std::is_same<
typename VectorType::value_type,
1439 template <
typename VectorType>
1440 typename std::enable_if<std::is_same<
typename VectorType::value_type,
1450 template <
typename VectorType>
1451 typename std::enable_if<!std::is_same<
typename VectorType::value_type,
1464 template <
typename VectorType>
1478 template <
typename VectorType>
1622 frobenius_norm()
const;
1634 const Epetra_CrsMatrix &
1635 trilinos_matrix()
const;
1641 const Epetra_CrsGraph &
1642 trilinos_sparsity_pattern()
const;
1656 locally_owned_domain_indices()
const;
1664 locally_owned_range_indices()
const;
1790 print(std::ostream &out,
1791 const bool write_extended_trilinos_info =
false)
const;
1804 <<
"An error with error number " << arg1
1805 <<
" occurred while calling a Trilinos function");
1813 <<
"The entry with index <" << arg1 <<
',' << arg2
1814 <<
"> does not exist.");
1820 "You are attempting an operation on two matrices that " 1821 "are the same object, but the operation requires that the " 1822 "two objects are in fact different.");
1837 <<
"You tried to access element (" << arg1 <<
"/" << arg2
1839 <<
" of a distributed matrix, but only rows " << arg3
1840 <<
" through " << arg4
1841 <<
" are stored locally and can be accessed.");
1849 <<
"You tried to access element (" << arg1 <<
"/" << arg2
1851 <<
" of a sparse matrix, but it appears to not" 1852 <<
" exist in the Trilinos sparsity pattern.");
1940 const Epetra_MultiVector &src,
1941 const Epetra_MultiVector &dst,
1944 if (transpose ==
false)
1946 Assert(src.Map().SameAs(mtrx.DomainMap()) ==
true,
1948 "Column map of matrix does not fit with vector map!"));
1949 Assert(dst.Map().SameAs(mtrx.RangeMap()) ==
true,
1950 ExcMessage(
"Row map of matrix does not fit with vector map!"));
1954 Assert(src.Map().SameAs(mtrx.RangeMap()) ==
true,
1956 "Column map of matrix does not fit with vector map!"));
1957 Assert(dst.Map().SameAs(mtrx.DomainMap()) ==
true,
1958 ExcMessage(
"Row map of matrix does not fit with vector map!"));
1967 const Epetra_MultiVector &src,
1968 const Epetra_MultiVector &dst,
1971 if (transpose ==
false)
1973 Assert(src.Map().SameAs(op.OperatorDomainMap()) ==
true,
1975 "Column map of operator does not fit with vector map!"));
1976 Assert(dst.Map().SameAs(op.OperatorRangeMap()) ==
true,
1978 "Row map of operator does not fit with vector map!"));
1982 Assert(src.Map().SameAs(op.OperatorRangeMap()) ==
true,
1984 "Column map of operator does not fit with vector map!"));
1985 Assert(dst.Map().SameAs(op.OperatorDomainMap()) ==
true,
1987 "Row map of operator does not fit with vector map!"));
1994 namespace LinearOperatorImplementation
2092 identity_payload()
const;
2098 null_payload()
const;
2104 transpose_payload()
const;
2122 template <
typename Solver,
typename Preconditioner>
2123 typename std::enable_if<
2128 inverse_payload(
Solver &,
const Preconditioner &)
const;
2147 template <
typename Solver,
typename Preconditioner>
2148 typename std::enable_if<
2150 std::is_base_of<TrilinosWrappers::PreconditionBase,
2153 inverse_payload(
Solver &,
const Preconditioner &)
const;
2168 locally_owned_domain_indices()
const;
2176 locally_owned_range_indices()
const;
2182 get_mpi_communicator()
const;
2200 std::function<void(VectorType &, const VectorType &)>
vmult;
2209 std::function<void(VectorType &, const VectorType &)>
Tvmult;
2219 std::function<void(VectorType &, const VectorType &)>
inv_vmult;
2229 std::function<void(VectorType &, const VectorType &)>
inv_Tvmult;
2245 UseTranspose()
const override;
2263 SetUseTranspose(
bool UseTranspose)
override;
2312 virtual const char *
2313 Label()
const override;
2322 virtual const Epetra_Comm &
2323 Comm()
const override;
2332 virtual const Epetra_Map &
2333 OperatorDomainMap()
const override;
2343 virtual const Epetra_Map &
2344 OperatorRangeMap()
const override;
2358 # ifdef DEAL_II_WITH_MPI 2361 Epetra_SerialComm communicator;
2385 HasNormInf()
const override;
2395 NormInf()
const override;
2431 visit_present_row();
2436 AccessorBase::row()
const 2444 AccessorBase::column()
const 2447 return (*colnum_cache)[a_index];
2452 AccessorBase::index()
const 2462 :
AccessorBase(const_cast<SparseMatrix *>(matrix), row, index)
2466 template <
bool Other>
2476 return (*value_cache)[a_index];
2480 inline Accessor<false>::Reference::Reference(
const Accessor<false> &acc)
2481 : accessor(const_cast<
Accessor<false> &>(acc))
2485 inline Accessor<false>::Reference::operator
TrilinosScalar()
const 2487 return (*accessor.value_cache)[accessor.a_index];
2490 inline const Accessor<false>::Reference &
2491 Accessor<false>::Reference::operator=(
const TrilinosScalar n)
const 2493 (*accessor.value_cache)[accessor.a_index] = n;
2494 accessor.matrix->set(accessor.row(),
2501 inline const Accessor<false>::Reference &
2502 Accessor<false>::Reference::operator+=(
const TrilinosScalar n)
const 2504 (*accessor.value_cache)[accessor.a_index] += n;
2505 accessor.matrix->set(accessor.row(),
2512 inline const Accessor<false>::Reference &
2513 Accessor<false>::Reference::operator-=(
const TrilinosScalar n)
const 2515 (*accessor.value_cache)[accessor.a_index] -= n;
2516 accessor.matrix->set(accessor.row(),
2523 inline const Accessor<false>::Reference &
2524 Accessor<false>::Reference::operator*=(
const TrilinosScalar n)
const 2526 (*accessor.value_cache)[accessor.a_index] *= n;
2527 accessor.matrix->set(accessor.row(),
2534 inline const Accessor<false>::Reference &
2535 Accessor<false>::Reference::operator/=(
const TrilinosScalar n)
const 2537 (*accessor.value_cache)[accessor.a_index] /= n;
2538 accessor.matrix->set(accessor.row(),
2552 inline Accessor<false>::Reference
2561 template <
bool Constness>
2565 : accessor(matrix, row, index)
2569 template <
bool Constness>
2570 template <
bool Other>
2572 : accessor(other.accessor)
2576 template <
bool Constness>
2577 inline Iterator<Constness> &
2588 if (accessor.a_index >= accessor.colnum_cache->size())
2590 accessor.a_index = 0;
2593 while ((accessor.a_row < accessor.matrix->m()) &&
2594 ((accessor.matrix->in_local_range(accessor.a_row) ==
false) ||
2595 (accessor.matrix->row_length(accessor.a_row) == 0)))
2598 accessor.visit_present_row();
2604 template <
bool Constness>
2605 inline Iterator<Constness>
2608 const Iterator<Constness> old_state = *
this;
2615 template <
bool Constness>
2623 template <
bool Constness>
2624 inline const Accessor<Constness> *Iterator<Constness>::operator->()
const 2631 template <
bool Constness>
2635 return (accessor.a_row == other.accessor.a_row &&
2636 accessor.a_index == other.accessor.a_index);
2641 template <
bool Constness>
2645 return !(*
this == other);
2650 template <
bool Constness>
2654 return (accessor.row() < other.accessor.row() ||
2655 (accessor.row() == other.accessor.row() &&
2656 accessor.index() < other.accessor.index()));
2660 template <
bool Constness>
2664 return (other < *
this);
2682 return const_iterator(
this, m(), 0);
2691 if (in_local_range(r) && (row_length(r) > 0))
2692 return const_iterator(
this, r, 0);
2708 if (in_local_range(i) && (row_length(i) > 0))
2709 return const_iterator(
this, i, 0);
2729 return iterator(
this, m(), 0);
2738 if (in_local_range(r) && (row_length(r) > 0))
2739 return iterator(
this, r, 0);
2755 if (in_local_range(i) && (row_length(i) > 0))
2756 return iterator(
this, i, 0);
2769 # ifndef DEAL_II_WITH_64BIT_INDICES 2770 begin =
matrix->RowMap().MinMyGID();
2771 end =
matrix->RowMap().MaxMyGID() + 1;
2773 begin =
matrix->RowMap().MinMyGID64();
2774 end =
matrix->RowMap().MaxMyGID64() + 1;
2777 return ((index >= static_cast<size_type>(begin)) &&
2778 (index < static_cast<size_type>(end)));
2796 SparseMatrix::set<TrilinosScalar>(
const size_type row,
2800 const bool elide_zero_values);
2804 template <
typename Number>
2809 const Number * values,
2810 const bool elide_zero_values)
2812 std::vector<TrilinosScalar> trilinos_values(n_cols);
2813 std::copy(values, values + n_cols, trilinos_values.begin());
2815 row, n_cols, col_indices, trilinos_values.data(), elide_zero_values);
2827 set(i, 1, &j, &
value,
false);
2835 const bool elide_zero_values)
2837 Assert(indices.size() == values.
m(),
2841 for (
size_type i = 0; i < indices.size(); ++i)
2866 if (last_action == Insert)
2869 ierr =
matrix->GlobalAssemble(*column_space_map,
2882 add(i, 1, &j, &value,
false);
2892 # ifndef DEAL_II_WITH_64BIT_INDICES 2893 return matrix->NumGlobalRows();
2895 return matrix->NumGlobalRows64();
2916 return matrix->NumMyRows();
2921 inline std::pair<SparseMatrix::size_type, SparseMatrix::size_type>
2925 # ifndef DEAL_II_WITH_64BIT_INDICES 2926 begin =
matrix->RowMap().MinMyGID();
2927 end =
matrix->RowMap().MaxMyGID() + 1;
2929 begin =
matrix->RowMap().MinMyGID64();
2930 end =
matrix->RowMap().MaxMyGID64() + 1;
2933 return std::make_pair(begin, end);
2941 # ifndef DEAL_II_WITH_64BIT_INDICES 2942 return matrix->NumGlobalNonzeros();
2944 return matrix->NumGlobalNonzeros64();
2950 template <
typename SparsityPatternType>
2953 const SparsityPatternType &sparsity_pattern,
2955 const bool exchange_data)
2957 reinit(parallel_partitioning,
2958 parallel_partitioning,
2966 template <
typename number>
2969 const ::SparseMatrix<number> &sparse_matrix,
2971 const double drop_tolerance,
2972 const bool copy_values,
2973 const ::SparsityPattern * use_this_sparsity)
2977 reinit(parallel_partitioning,
2978 parallel_partitioning,
2987 inline const Epetra_CrsMatrix &
2990 return static_cast<const Epetra_CrsMatrix &
>(*matrix);
2995 inline const Epetra_CrsGraph &
3036 namespace LinearOperatorImplementation
3038 template <
typename Solver,
typename Preconditioner>
3039 typename std::enable_if<
3046 const Preconditioner &preconditioner)
const 3048 const auto &payload = *
this;
3054 return_op.inv_vmult = [payload, &solver, &preconditioner](
3059 Assert(&tril_src != &tril_dst,
3064 !payload.UseTranspose());
3065 solver.solve(payload, tril_dst, tril_src, preconditioner);
3068 return_op.inv_Tvmult = [payload, &solver, &preconditioner](
3073 Assert(&tril_src != &tril_dst,
3078 payload.UseTranspose());
3081 solver.solve(payload, tril_dst, tril_src, preconditioner);
3087 if (return_op.UseTranspose() ==
true)
3088 std::swap(return_op.inv_vmult, return_op.inv_Tvmult);
3093 template <
typename Solver,
typename Preconditioner>
3094 typename std::enable_if<
3096 std::is_base_of<TrilinosWrappers::PreconditionBase,
3106 ExcMessage(
"Payload inv_vmult disabled because of " 3107 "incompatible solver/preconditioner choice."));
3113 ExcMessage(
"Payload inv_vmult disabled because of " 3114 "incompatible solver/preconditioner choice."));
3124 SparseMatrix::set<TrilinosScalar>(
const size_type row,
3128 const bool elide_zero_values);
3137 # endif // DEAL_II_WITH_TRILINOS
static ::ExceptionBase & ExcTrilinosError(int arg1)
const_iterator end() const
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
#define DeclException2(Exception2, type1, type2, outsequence)
Contents is actually a matrix.
static ::ExceptionBase & ExcSourceEqualsDestination()
TrilinosPayload operator*(const TrilinosPayload &first_op, const TrilinosPayload &second_op)
types::global_dof_index size_type
static ::ExceptionBase & ExcBeyondEndOfMatrix()
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Epetra_MultiVector VectorType
std::function< void(VectorType &, const VectorType &)> inv_Tvmult
bool operator!=(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
Epetra_CombineMode last_action
bool is_compressed() const
#define AssertIndexRange(index, range)
std::function< void(VectorType &, const VectorType &)> Tvmult
TrilinosPayload operator+(const TrilinosPayload &first_op, const TrilinosPayload &second_op)
bool operator<(const SynchronousIterators< Iterators > &a, const SynchronousIterators< Iterators > &b)
static ::ExceptionBase & ExcAccessToNonlocalRow(std::size_t arg1, std::size_t arg2, std::size_t arg3)
#define AssertThrow(cond, exc)
bool operator==(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
SymmetricTensor< 2, dim, Number > C(const Tensor< 2, dim, Number > &F)
Epetra_Map make_trilinos_map(const MPI_Comm &communicator=MPI_COMM_WORLD, const bool overlapping=false) const
std::shared_ptr< std::vector< size_type > > colnum_cache
std::unique_ptr< Epetra_FECrsMatrix > matrix
::types::global_dof_index size_type
bool in_local_range(const size_type index) const
static ::ExceptionBase & ExcMessage(std::string arg1)
std::string compress(const std::string &input)
#define DeclException1(Exception1, type1, outsequence)
void add(const size_type i, const size_type j, const TrilinosScalar value)
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
std::unique_ptr< Epetra_Export > nonlocal_matrix_exporter
#define DeclExceptionMsg(Exception, defaulttext)
Epetra_MpiComm communicator
Number linfty_norm(const Tensor< 2, dim, Number > &t)
#define DeclException0(Exception0)
typename Accessor< Constness >::MatrixType MatrixType
MatrixTableIterators::AccessorBase< TransposeTable< T >, Constness, MatrixTableIterators::Storage::column_major > AccessorBase
#define DEAL_II_NAMESPACE_CLOSE
std::function< void(VectorType &, const VectorType &)> inv_vmult
VectorType::value_type * end(VectorType &V)
SynchronousIterators< Iterators > operator++(SynchronousIterators< Iterators > &a)
std::enable_if< std::is_base_of< TrilinosWrappers::SolverBase, Solver >::value &&std::is_base_of< TrilinosWrappers::PreconditionBase, Preconditioner >::value, TrilinosPayload >::type inverse_payload(Solver &, const Preconditioner &) const
Expression operator>(const Expression &lhs, const Expression &rhs)
const Epetra_CrsMatrix & trilinos_matrix() const
AccessorBase(SparseMatrix *matrix, const size_type row, const size_type index)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SparseMatrix< double > SparseMatrix
MatrixTableIterators::Accessor< TransposeTable< T >, Constness, MatrixTableIterators::Storage::column_major > Accessor
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
IndexSet locally_owned_range_indices() const
size_type n_nonzero_elements() const
static ::ExceptionBase & ExcIteratorPastEnd()
const_iterator begin() const
static ::ExceptionBase & ExcNotQuadratic()
TrilinosWrappers::types::int_type n_global_elements(const Epetra_BlockMap &map)
Accessor< Constness > accessor
unsigned int global_dof_index
MatrixTableIterators::Iterator< TransposeTable< T >, Constness, MatrixTableIterators::Storage::column_major > Iterator
void swap(MemorySpaceData< Number, MemorySpace > &, MemorySpaceData< Number, MemorySpace > &)
void reinit(const SparsityPatternType &sparsity_pattern)
#define DEAL_II_NAMESPACE_OPEN
VectorType::value_type * begin(VectorType &V)
std::function< void(VectorType &, const VectorType &)> vmult
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Number l1_norm(const Tensor< 2, dim, Number > &t)
std::pair< size_type, size_type > local_range() const
IndexSet locally_owned_domain_indices() const
const Epetra_CrsGraph & trilinos_sparsity_pattern() const
#define DeclException3(Exception3, type1, type2, type3, outsequence)
std::unique_ptr< Epetra_Map > column_space_map
std::unique_ptr< Epetra_CrsMatrix > nonlocal_matrix
void set(const size_type i, const size_type j, const TrilinosScalar value)
void check_vector_map_equality(const Epetra_Operator &op, const Epetra_MultiVector &src, const Epetra_MultiVector &dst, const bool transpose)
void copy(const T *begin, const T *end, U *dest)
#define AssertIsFinite(number)
unsigned int local_size() const
::types::global_dof_index size_type
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
void check_vector_map_equality(const Epetra_CrsMatrix &mtrx, const Epetra_MultiVector &src, const Epetra_MultiVector &dst, const bool transpose)
static ::ExceptionBase & ExcInternalError()
std::shared_ptr< std::vector< TrilinosScalar > > value_cache