16#ifdef DEAL_II_WITH_TRILINOS
25# include <Epetra_Export.h>
35#ifdef DEAL_II_WITH_TRILINOS
71 AssertThrow(
static_cast<std::vector<size_type>::size_type
>(ncols) ==
96 graph = std::make_unique<Epetra_FECrsGraph>(View,
100 graph->FillComplete();
109 reinit(m, n, n_entries_per_row);
123 const std::vector<size_type> &n_entries_per_row)
125 reinit(m, n, n_entries_per_row);
132 , column_space_map(std::move(other.column_space_map))
133 , graph(std::move(other.graph))
134 , nonlocal_graph(std::move(other.nonlocal_graph))
147 new Epetra_FECrsGraph(View, *column_space_map, *column_space_map, 0))
151 "Copy constructor only works for empty sparsity patterns."));
160 reinit(parallel_partitioning,
161 parallel_partitioning,
182 const IndexSet ¶llel_partitioning,
184 const std::vector<size_type> &n_entries_per_row)
186 reinit(parallel_partitioning,
187 parallel_partitioning,
195 const IndexSet &col_parallel_partitioning,
199 reinit(row_parallel_partitioning,
200 col_parallel_partitioning,
208 const IndexSet &col_parallel_partitioning,
211 col_parallel_partitioning,
219 const IndexSet &col_parallel_partitioning)
221 col_parallel_partitioning,
229 const IndexSet &row_parallel_partitioning,
230 const IndexSet &col_parallel_partitioning,
232 const std::vector<size_type> &n_entries_per_row)
234 reinit(row_parallel_partitioning,
235 col_parallel_partitioning,
243 const IndexSet &col_parallel_partitioning,
247 col_parallel_partitioning,
256 const IndexSet &col_parallel_partitioning,
261 reinit(row_parallel_partitioning,
262 col_parallel_partitioning,
265 n_max_entries_per_row);
294 const std::vector<size_type> &n_entries_per_row)
309 reinit_sp(
const Epetra_Map &row_map,
310 const Epetra_Map &col_map,
311 const size_type n_entries_per_row,
312 std::unique_ptr<Epetra_Map> &column_space_map,
313 std::unique_ptr<Epetra_FECrsGraph> &graph,
314 std::unique_ptr<Epetra_CrsGraph> &nonlocal_graph)
316 Assert(row_map.IsOneToOne(),
317 ExcMessage(
"Row map must be 1-to-1, i.e., no overlap between "
318 "the maps of different processors."));
319 Assert(col_map.IsOneToOne(),
320 ExcMessage(
"Column map must be 1-to-1, i.e., no overlap between "
321 "the maps of different processors."));
323 nonlocal_graph.reset();
325 column_space_map = std::make_unique<Epetra_Map>(col_map);
329 auto max_local_elements =
333 std::uint64_t(n_entries_per_row);
335 static_cast<std::uint64_t
>(std::numeric_limits<int>::max()),
336 ExcMessage(
"The TrilinosWrappers use Epetra internally which "
337 "uses 'signed int' to represent local indices. "
338 "Therefore, only 2,147,483,647 nonzero matrix "
339 "entries can be stored on a single process, "
340 "but you are requesting more than that. "
341 "If possible, use more MPI processes."));
352 if (row_map.Comm().NumProc() > 1)
353 graph = std::make_unique<Epetra_FECrsGraph>(
354 Copy, row_map, n_entries_per_row,
false
362 graph = std::make_unique<Epetra_FECrsGraph>(
363 Copy, row_map, col_map, n_entries_per_row,
false);
369 reinit_sp(
const Epetra_Map &row_map,
370 const Epetra_Map &col_map,
371 const std::vector<size_type> &n_entries_per_row,
372 std::unique_ptr<Epetra_Map> &column_space_map,
373 std::unique_ptr<Epetra_FECrsGraph> &graph,
374 std::unique_ptr<Epetra_CrsGraph> &nonlocal_graph)
376 Assert(row_map.IsOneToOne(),
377 ExcMessage(
"Row map must be 1-to-1, i.e., no overlap between "
378 "the maps of different processors."));
379 Assert(col_map.IsOneToOne(),
380 ExcMessage(
"Column map must be 1-to-1, i.e., no overlap between "
381 "the maps of different processors."));
384 nonlocal_graph.reset();
389 column_space_map = std::make_unique<Epetra_Map>(col_map);
393 std::vector<int> local_entries_per_row(
396 for (
unsigned int i = 0; i < local_entries_per_row.size(); ++i)
397 local_entries_per_row[i] =
400 AssertThrow(std::accumulate(local_entries_per_row.begin(),
401 local_entries_per_row.end(),
403 static_cast<std::uint64_t
>(std::numeric_limits<int>::max()),
404 ExcMessage(
"The TrilinosWrappers use Epetra internally which "
405 "uses 'signed int' to represent local indices. "
406 "Therefore, only 2,147,483,647 nonzero matrix "
407 "entries can be stored on a single process, "
408 "but you are requesting more than that. "
409 "If possible, use more MPI processes."));
411 if (row_map.Comm().NumProc() > 1)
412 graph = std::make_unique<Epetra_FECrsGraph>(
413 Copy, row_map, local_entries_per_row.data(),
false
421 graph = std::make_unique<Epetra_FECrsGraph>(
422 Copy, row_map, col_map, local_entries_per_row.data(),
false);
427 template <
typename SparsityPatternType>
430 const Epetra_Map &col_map,
431 const SparsityPatternType &sp,
432 const bool exchange_data,
433 std::unique_ptr<Epetra_Map> &column_space_map,
434 std::unique_ptr<Epetra_FECrsGraph> &graph,
435 std::unique_ptr<Epetra_CrsGraph> &nonlocal_graph)
437 nonlocal_graph.reset();
445 column_space_map = std::make_unique<Epetra_Map>(col_map);
447 Assert(row_map.LinearMap() ==
true,
449 "This function only works if the row map is contiguous."));
453 std::vector<int> n_entries_per_row(last_row - first_row);
457 for (size_type row = first_row; row < last_row; ++row)
458 n_entries_per_row[row - first_row] =
459 static_cast<int>(sp.row_length(row));
461 AssertThrow(std::accumulate(n_entries_per_row.begin(),
462 n_entries_per_row.end(),
464 static_cast<std::uint64_t
>(std::numeric_limits<int>::max()),
465 ExcMessage(
"The TrilinosWrappers use Epetra internally which "
466 "uses 'signed int' to represent local indices. "
467 "Therefore, only 2,147,483,647 nonzero matrix "
468 "entries can be stored on a single process, "
469 "but you are requesting more than that. "
470 "If possible, use more MPI processes."));
472 if (row_map.Comm().NumProc() > 1)
473 graph = std::make_unique<Epetra_FECrsGraph>(Copy,
475 n_entries_per_row.data(),
478 graph = std::make_unique<Epetra_FECrsGraph>(
479 Copy, row_map, col_map, n_entries_per_row.data(),
false);
483 std::vector<TrilinosWrappers::types::int_type> row_indices;
485 for (size_type row = first_row; row < last_row; ++row)
492 row_indices.resize(row_length, -1);
494 typename SparsityPatternType::iterator p = sp.begin(row);
497 for (
int col = 0; col < row_length;)
499 row_indices[col++] = p->column();
500 if (col < row_length)
504 if (exchange_data ==
false)
505 graph->Epetra_CrsGraph::InsertGlobalIndices(row,
513 graph->InsertGlobalIndices(1,
521 const auto &range_map =
522 static_cast<const Epetra_Map &
>(graph->RangeMap());
523 int ierr = graph->GlobalAssemble(*column_space_map, range_map,
true);
526 ierr = graph->OptimizeStorage();
539 parallel_partitioning.
size());
552 reinit(parallel_partitioning, communicator, 0);
560 reinit(parallel_partitioning, MPI_COMM_WORLD, 0);
568 const std::vector<size_type> &n_entries_per_row)
571 parallel_partitioning.
size());
582 const IndexSet &col_parallel_partitioning,
587 col_parallel_partitioning.
size());
604 const IndexSet &col_parallel_partitioning,
607 reinit(row_parallel_partitioning,
608 col_parallel_partitioning,
617 const IndexSet &col_parallel_partitioning)
619 reinit(row_parallel_partitioning,
620 col_parallel_partitioning,
629 const IndexSet &col_parallel_partitioning,
631 const std::vector<size_type> &n_entries_per_row)
634 col_parallel_partitioning.
size());
651 const IndexSet &col_parallel_partitioning,
657 col_parallel_partitioning.
size());
669 IndexSet nonlocal_partitioner = writable_rows;
671 row_parallel_partitioning.
size());
675 IndexSet tmp = writable_rows & row_parallel_partitioning;
676 Assert(tmp == row_parallel_partitioning,
678 "The set of writable rows passed to this method does not "
679 "contain the locally owned rows, which is not allowed."));
682 nonlocal_partitioner.
subtract_set(row_parallel_partitioning);
685 Epetra_Map nonlocal_map =
688 std::make_unique<Epetra_CrsGraph>(Copy, nonlocal_map, 0);
698 const IndexSet &col_parallel_partitioning,
702 reinit(row_parallel_partitioning,
703 col_parallel_partitioning,
713 const IndexSet &col_parallel_partitioning,
716 reinit(row_parallel_partitioning,
717 col_parallel_partitioning,
725 template <
typename SparsityPatternType,
typename>
728 const IndexSet &row_parallel_partitioning,
729 const IndexSet &col_parallel_partitioning,
730 const SparsityPatternType &nontrilinos_sparsity_pattern,
732 const bool exchange_data)
735 col_parallel_partitioning.
size());
742 nontrilinos_sparsity_pattern,
751 template <
typename SparsityPatternType,
typename>
754 const IndexSet ¶llel_partitioning,
755 const SparsityPatternType &nontrilinos_sparsity_pattern,
757 const bool exchange_data)
760 parallel_partitioning.
size());
762 parallel_partitioning.
size());
764 parallel_partitioning.
size());
769 nontrilinos_sparsity_pattern,
792 graph = std::make_unique<Epetra_FECrsGraph>(*sp.
graph);
802 template <
typename SparsityPatternType>
831 graph = std::make_unique<Epetra_FECrsGraph>(View,
835 graph->FillComplete();
891 const auto &range_map =
892 static_cast<const Epetra_Map &
>(
graph->RangeMap());
899 ierr =
graph->OptimizeStorage();
901 catch (
const int error_code)
906 "The Epetra_CrsGraph::OptimizeStorage() function "
907 "has thrown an error with code " +
908 std::to_string(error_code) +
909 ". You will have to look up the exact meaning of this error "
910 "in the Trilinos source code, but oftentimes, this function "
911 "throwing an error indicates that you are trying to allocate "
912 "more than 2,147,483,647 nonzero entries in the sparsity "
913 "pattern on the local process; this will not work because "
914 "Epetra indexes entries with a simple 'signed int'."));
932 return graph->RowMap().LID(
957 if (
graph->Filled() ==
false)
959 int nnz_present =
graph->NumGlobalIndices(i);
969 int ierr =
graph->ExtractGlobalRowView(trilinos_i,
973 Assert(nnz_present == nnz_extracted,
977 const std::ptrdiff_t local_col_index =
978 std::find(col_indices, col_indices + nnz_present, trilinos_j) -
981 if (local_col_index == nnz_present)
988 int nnz_present =
graph->NumGlobalIndices(i);
996 graph->ExtractMyRowView(trilinos_i, nnz_extracted, col_indices);
999 Assert(nnz_present == nnz_extracted,
1003 const std::ptrdiff_t local_col_index =
1004 std::find(col_indices, col_indices + nnz_present, trilinos_j) -
1007 if (local_col_index == nnz_present)
1021 for (
int i = 0; i < static_cast<int>(
local_size()); ++i)
1025 graph->ExtractMyRowView(i, num_entries, indices);
1026 for (
unsigned int j = 0; j < static_cast<unsigned int>(num_entries);
1030 local_b =
std::abs(i - indices[j]);
1039 return static_cast<size_type>(global_b);
1047 return graph->NumMyRows();
1052 std::pair<SparsityPattern::size_type, SparsityPattern::size_type>
1074 return graph->MaxNumIndices();
1092 return graph->NumMyIndices(local_row);
1102 const bool indices_are_sorted)
1113 const auto &domain_map =
1114 static_cast<const Epetra_Map &
>(
graph->DomainMap());
1124 const auto &range_map =
1125 static_cast<const Epetra_Map &
>(
graph->RangeMap());
1134 const Epetra_MpiComm *mpi_comm =
1135 dynamic_cast<const Epetra_MpiComm *
>(&
graph->RangeMap().Comm());
1137 return mpi_comm->Comm();
1155 const bool write_extended_trilinos_info)
const
1157 if (write_extended_trilinos_info)
1164 for (
int i = 0; i <
graph->NumMyRows(); ++i)
1166 graph->ExtractMyRowView(i, num_entries, indices);
1167 for (
int j = 0; j < num_entries; ++j)
1171 <<
") " << std::endl;
1188 graph->ExtractMyRowView(row, num_entries, indices);
1192 const ::types::global_dof_index num_entries_ = num_entries;
1199 out <<
static_cast<int>(
1202 << -
static_cast<int>(
1229 const ::SparsityPattern &,
1234 const ::DynamicSparsityPattern &,
1242 const ::SparsityPattern &,
1248 const ::DynamicSparsityPattern &,
size_type n_elements() const
Epetra_Map make_trilinos_map(const MPI_Comm communicator=MPI_COMM_WORLD, const bool overlapping=false) const
void subtract_set(const IndexSet &other)
virtual void resize(const size_type rows, const size_type cols)
std::shared_ptr< const std::vector< size_type > > colnum_cache
SparsityPattern * sparsity_pattern
size_type row_length(const size_type row) const
std::unique_ptr< Epetra_FECrsGraph > graph
void print(std::ostream &out, const bool write_extended_trilinos_info=false) const
unsigned int max_entries_per_row() const
size_type bandwidth() const
void print_gnuplot(std::ostream &out) const
const_iterator end() const
MPI_Comm get_mpi_communicator() const
virtual void add_row_entries(const size_type &row, const ArrayView< const size_type > &columns, const bool indices_are_sorted=false) override
std::uint64_t n_nonzero_elements() const
std::unique_ptr< Epetra_CrsGraph > nonlocal_graph
bool exists(const size_type i, const size_type j) const
const Epetra_Map & domain_partitioner() const
std::pair< size_type, size_type > local_range() const
::types::global_dof_index size_type
void add_entries(const size_type row, ForwardIterator begin, ForwardIterator end, const bool indices_are_sorted=false)
bool is_compressed() const
void reinit(const size_type m, const size_type n, const size_type n_entries_per_row)
unsigned int local_size() const
void copy_from(const SparsityPattern &input_sparsity_pattern)
std::unique_ptr< Epetra_Map > column_space_map
const Epetra_Map & range_partitioner() const
const_iterator begin() const
bool in_local_range(const size_type index) const
std::size_t memory_consumption() const
SparsityPattern & operator=(const SparsityPattern &input_sparsity_pattern)
bool row_is_stored_locally(const size_type i) 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()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcTrilinosError(int arg1)
static ::ExceptionBase & ExcTrilinosError(int arg1)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
IndexSet complete_index_set(const IndexSet::size_type N)
types::global_dof_index size_type
void reinit_sp(const Teuchos::RCP< TpetraTypes::MapType< MemorySpace > > &row_map, const Teuchos::RCP< TpetraTypes::MapType< MemorySpace > > &col_map, const size_type< MemorySpace > n_entries_per_row, Teuchos::RCP< TpetraTypes::MapType< MemorySpace > > &column_space_map, Teuchos::RCP< TpetraTypes::GraphType< MemorySpace > > &graph, Teuchos::RCP< TpetraTypes::GraphType< MemorySpace > > &nonlocal_graph)
TrilinosWrappers::types::int_type global_index(const Epetra_BlockMap &map, const ::types::global_dof_index i)
TrilinosWrappers::types::int_type n_global_rows(const Epetra_CrsGraph &graph)
TrilinosWrappers::types::int_type min_my_gid(const Epetra_BlockMap &map)
TrilinosWrappers::types::int64_type n_global_entries(const Epetra_CrsGraph &graph)
TrilinosWrappers::types::int64_type n_global_elements(const Epetra_BlockMap &map)
TrilinosWrappers::types::int_type max_my_gid(const Epetra_BlockMap &map)
TrilinosWrappers::types::int_type n_global_cols(const Epetra_CrsGraph &graph)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
const Epetra_Comm & comm_self()
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)