16 #include <deal.II/lac/trilinos_index_access.h> 17 #include <deal.II/lac/trilinos_sparsity_pattern.h> 19 #ifdef DEAL_II_WITH_TRILINOS 21 # include <deal.II/base/mpi.h> 22 # include <deal.II/base/utilities.h> 24 # include <deal.II/lac/dynamic_sparsity_pattern.h> 25 # include <deal.II/lac/sparsity_pattern.h> 26 # include <deal.II/lac/trilinos_index_access.h> 28 # include <Epetra_Export.h> 30 DEAL_II_NAMESPACE_OPEN
62 reinterpret_cast<TrilinosWrappers::types::int_type *
>(
65 AssertThrow(
static_cast<std::vector<size_type>::size_type
>(ncols) ==
87 std_cxx14::make_unique<Epetra_Map>(TrilinosWrappers::types::int_type(0),
88 TrilinosWrappers::types::int_type(0),
90 graph = std_cxx14::make_unique<Epetra_FECrsGraph>(View,
94 graph->FillComplete();
101 reinit(input_map, input_map, n_entries_per_row);
107 const Epetra_Map & input_map,
108 const std::vector<size_type> &n_entries_per_row)
110 reinit(input_map, input_map, n_entries_per_row);
116 const Epetra_Map &input_col_map,
119 reinit(input_row_map, input_col_map, n_entries_per_row);
125 const Epetra_Map & input_row_map,
126 const Epetra_Map & input_col_map,
127 const std::vector<size_type> &n_entries_per_row)
129 reinit(input_row_map, input_col_map, n_entries_per_row);
138 reinit(m, n, n_entries_per_row);
146 const std::vector<size_type> &n_entries_per_row)
148 reinit(m, n, n_entries_per_row);
155 , column_space_map(std::move(other.column_space_map))
156 , graph(std::move(other.graph))
157 , nonlocal_graph(std::move(other.nonlocal_graph))
170 new Epetra_FECrsGraph(View, *column_space_map, *column_space_map, 0))
172 (void)input_sparsity;
175 "Copy constructor only works for empty sparsity patterns."));
181 const MPI_Comm &communicator,
184 reinit(parallel_partitioning,
185 parallel_partitioning,
193 const IndexSet & parallel_partitioning,
194 const MPI_Comm & communicator,
195 const std::vector<size_type> &n_entries_per_row)
197 reinit(parallel_partitioning,
198 parallel_partitioning,
206 const IndexSet &col_parallel_partitioning,
207 const MPI_Comm &communicator,
210 reinit(row_parallel_partitioning,
211 col_parallel_partitioning,
219 const IndexSet & row_parallel_partitioning,
220 const IndexSet & col_parallel_partitioning,
221 const MPI_Comm & communicator,
222 const std::vector<size_type> &n_entries_per_row)
224 reinit(row_parallel_partitioning,
225 col_parallel_partitioning,
233 const IndexSet &col_parallel_partitioning,
235 const MPI_Comm &communicator,
238 reinit(row_parallel_partitioning,
239 col_parallel_partitioning,
242 n_max_entries_per_row);
252 reinit(complete_index_set(m),
253 complete_index_set(n),
263 const std::vector<size_type> &n_entries_per_row)
265 reinit(complete_index_set(m),
266 complete_index_set(n),
278 reinit_sp(
const Epetra_Map & row_map,
279 const Epetra_Map & col_map,
280 const size_type n_entries_per_row,
281 std::unique_ptr<Epetra_Map> & column_space_map,
282 std::unique_ptr<Epetra_FECrsGraph> &graph,
283 std::unique_ptr<Epetra_CrsGraph> & nonlocal_graph)
285 Assert(row_map.IsOneToOne(),
286 ExcMessage(
"Row map must be 1-to-1, i.e., no overlap between " 287 "the maps of different processors."));
288 Assert(col_map.IsOneToOne(),
289 ExcMessage(
"Column map must be 1-to-1, i.e., no overlap between " 290 "the maps of different processors."));
292 nonlocal_graph.reset();
294 column_space_map = std_cxx14::make_unique<Epetra_Map>(col_map);
304 if (row_map.Comm().NumProc() > 1)
305 graph = std_cxx14::make_unique<Epetra_FECrsGraph>(
306 Copy, row_map, n_entries_per_row,
false 314 graph = std_cxx14::make_unique<Epetra_FECrsGraph>(
315 Copy, row_map, col_map, n_entries_per_row,
false);
321 reinit_sp(
const Epetra_Map & row_map,
322 const Epetra_Map & col_map,
323 const std::vector<size_type> & n_entries_per_row,
324 std::unique_ptr<Epetra_Map> & column_space_map,
325 std::unique_ptr<Epetra_FECrsGraph> &graph,
326 std::unique_ptr<Epetra_CrsGraph> & nonlocal_graph)
328 Assert(row_map.IsOneToOne(),
329 ExcMessage(
"Row map must be 1-to-1, i.e., no overlap between " 330 "the maps of different processors."));
331 Assert(col_map.IsOneToOne(),
332 ExcMessage(
"Column map must be 1-to-1, i.e., no overlap between " 333 "the maps of different processors."));
336 nonlocal_graph.reset();
341 column_space_map = std_cxx14::make_unique<Epetra_Map>(col_map);
342 std::vector<int> local_entries_per_row(
345 for (
unsigned int i = 0; i < local_entries_per_row.size(); ++i)
346 local_entries_per_row[i] =
349 if (row_map.Comm().NumProc() > 1)
350 graph = std_cxx14::make_unique<Epetra_FECrsGraph>(
351 Copy, row_map, local_entries_per_row.data(),
false 359 graph = std_cxx14::make_unique<Epetra_FECrsGraph>(
360 Copy, row_map, col_map, local_entries_per_row.data(),
false);
365 template <
typename SparsityPatternType>
367 reinit_sp(
const Epetra_Map & row_map,
368 const Epetra_Map & col_map,
369 const SparsityPatternType & sp,
370 const bool exchange_data,
371 std::unique_ptr<Epetra_Map> & column_space_map,
372 std::unique_ptr<Epetra_FECrsGraph> &graph,
373 std::unique_ptr<Epetra_CrsGraph> & nonlocal_graph)
375 nonlocal_graph.reset();
383 column_space_map = std_cxx14::make_unique<Epetra_Map>(col_map);
385 Assert(row_map.LinearMap() ==
true,
387 "This function only works if the row map is contiguous."));
391 std::vector<int> n_entries_per_row(last_row - first_row);
395 for (size_type row = first_row; row < last_row; ++row)
396 n_entries_per_row[row - first_row] =
397 static_cast<int>(sp.row_length(row));
399 if (row_map.Comm().NumProc() > 1)
400 graph = std_cxx14::make_unique<Epetra_FECrsGraph>(
401 Copy, row_map, n_entries_per_row.data(),
false);
403 graph = std_cxx14::make_unique<Epetra_FECrsGraph>(
404 Copy, row_map, col_map, n_entries_per_row.data(),
false);
408 std::vector<TrilinosWrappers::types::int_type> row_indices;
412 if (exchange_data ==
false)
413 for (size_type row = first_row; row < last_row; ++row)
415 const TrilinosWrappers::types::int_type row_length =
420 row_indices.resize(row_length, -1);
422 typename SparsityPatternType::iterator p = sp.begin(row);
425 for (
int col = 0; col < row_length;)
427 row_indices[col++] = p->column();
428 if (col < row_length)
432 graph->Epetra_CrsGraph::InsertGlobalIndices(row,
437 for (size_type row = 0; row < sp.n_rows(); ++row)
439 const TrilinosWrappers::types::int_type row_length =
444 row_indices.resize(row_length, -1);
446 typename SparsityPatternType::iterator p = sp.begin(row);
449 for (
int col = 0; col < row_length;)
451 row_indices[col++] = p->column();
452 if (col < row_length)
456 const TrilinosWrappers::types::int_type trilinos_row = row;
457 graph->InsertGlobalIndices(1,
464 const auto &range_map =
465 static_cast<const Epetra_Map &
>(graph->RangeMap());
466 int ierr = graph->GlobalAssemble(*column_space_map, range_map,
true);
469 ierr = graph->OptimizeStorage();
491 const Epetra_Map &input_col_map,
494 reinit_sp(input_row_map,
506 const std::vector<size_type> &n_entries_per_row)
520 const Epetra_Map & input_col_map,
521 const std::vector<size_type> &n_entries_per_row)
523 reinit_sp(input_row_map,
535 const MPI_Comm &communicator,
548 const MPI_Comm & communicator,
549 const std::vector<size_type> &n_entries_per_row)
561 const IndexSet &col_parallel_partitioning,
562 const MPI_Comm &communicator,
581 const IndexSet &col_parallel_partitioning,
582 const MPI_Comm &communicator,
583 const std::vector<size_type> &n_entries_per_row)
601 const IndexSet &col_parallel_partitioning,
603 const MPI_Comm &communicator,
617 IndexSet nonlocal_partitioner = writable_rows;
619 row_parallel_partitioning.
size());
622 IndexSet tmp = writable_rows & row_parallel_partitioning;
623 Assert(tmp == row_parallel_partitioning,
625 "The set of writable rows passed to this method does not " 626 "contain the locally owned rows, which is not allowed."));
629 nonlocal_partitioner.
subtract_set(row_parallel_partitioning);
632 Epetra_Map nonlocal_map =
635 std_cxx14::make_unique<Epetra_CrsGraph>(Copy, nonlocal_map, 0);
643 template <
typename SparsityPatternType>
646 const IndexSet & row_parallel_partitioning,
647 const IndexSet & col_parallel_partitioning,
648 const SparsityPatternType &nontrilinos_sparsity_pattern,
649 const MPI_Comm & communicator,
650 const bool exchange_data)
658 nontrilinos_sparsity_pattern,
667 template <
typename SparsityPatternType>
670 const IndexSet & parallel_partitioning,
671 const SparsityPatternType &nontrilinos_sparsity_pattern,
672 const MPI_Comm & communicator,
673 const bool exchange_data)
679 nontrilinos_sparsity_pattern,
688 template <
typename SparsityPatternType>
691 const SparsityPatternType &sp,
692 const bool exchange_data)
705 template <
typename SparsityPatternType>
708 const Epetra_Map & input_col_map,
709 const SparsityPatternType &sp,
710 const bool exchange_data)
712 reinit_sp(input_row_map,
737 graph = std_cxx14::make_unique<Epetra_FECrsGraph>(*sp.
graph);
748 template <
typename SparsityPatternType>
752 const Epetra_Map rows(TrilinosWrappers::types::int_type(sp.n_rows()),
755 const Epetra_Map columns(TrilinosWrappers::types::int_type(sp.n_cols()),
772 std_cxx14::make_unique<Epetra_Map>(TrilinosWrappers::types::int_type(0),
773 TrilinosWrappers::types::int_type(0),
775 graph = std_cxx14::make_unique<Epetra_FECrsGraph>(View,
779 graph->FillComplete();
798 TrilinosWrappers::types::int_type row =
800 TrilinosWrappers::types::int_type column = 0;
833 const auto &range_map =
834 static_cast<const Epetra_Map &
>(
graph->RangeMap());
839 ierr =
graph->OptimizeStorage();
848 return graph->RowMap().LID(
849 static_cast<TrilinosWrappers::types::int_type>(i)) != -1;
866 graph->LRID(static_cast<TrilinosWrappers::types::int_type>(i)),
868 graph->LCID(static_cast<TrilinosWrappers::types::int_type>(j));
873 if (
graph->Filled() ==
false)
875 int nnz_present =
graph->NumGlobalIndices(i);
877 TrilinosWrappers::types::int_type *col_indices;
885 int ierr =
graph->ExtractGlobalRowView(trilinos_i,
890 Assert(nnz_present == nnz_extracted,
894 const std::ptrdiff_t local_col_index =
895 std::find(col_indices, col_indices + nnz_present, trilinos_j) -
898 if (local_col_index == nnz_present)
905 int nnz_present =
graph->NumGlobalIndices(i);
913 graph->ExtractMyRowView(trilinos_i, nnz_extracted, col_indices);
917 Assert(nnz_present == nnz_extracted,
921 const std::ptrdiff_t local_col_index =
922 std::find(col_indices, col_indices + nnz_present, trilinos_j) -
925 if (local_col_index == nnz_present)
939 TrilinosWrappers::types::int_type global_b = 0;
940 for (
int i = 0; i < static_cast<int>(
local_size()); ++i)
944 graph->ExtractMyRowView(i, num_entries, indices);
945 for (
unsigned int j = 0; j < static_cast<unsigned int>(num_entries);
948 if (static_cast<size_type>(std::abs(i - indices[j])) > local_b)
949 local_b = std::abs(i - indices[j]);
952 graph->Comm().MaxAll(reinterpret_cast<TrilinosWrappers::types::int_type *>(
973 TrilinosWrappers::types::int_type
n_cols;
974 if (
graph->Filled() ==
true)
994 std::pair<SparsityPattern::size_type, SparsityPattern::size_type>
1019 int nnz =
graph->MaxNumIndices();
1021 return static_cast<unsigned int>(nnz);
1033 TrilinosWrappers::types::int_type local_row =
1034 graph->LRID(static_cast<TrilinosWrappers::types::int_type>(row));
1039 return graph->NumMyIndices(local_row);
1050 const auto &domain_map =
1051 static_cast<const Epetra_Map &
>(
graph->DomainMap());
1061 const auto &range_map =
1062 static_cast<const Epetra_Map &
>(
graph->RangeMap());
1072 const auto &row_map =
1073 static_cast<const Epetra_Map &
>(
graph->RowMap());
1083 const auto &col_map =
1084 static_cast<const Epetra_Map &
>(
graph->ColMap());
1093 return graph->RangeMap().Comm();
1101 # ifdef DEAL_II_WITH_MPI 1103 const Epetra_MpiComm *mpi_comm =
1104 dynamic_cast<const Epetra_MpiComm *
>(&
graph->RangeMap().Comm());
1106 return mpi_comm->Comm();
1109 return MPI_COMM_SELF;
1129 const bool write_extended_trilinos_info)
const 1131 if (write_extended_trilinos_info)
1138 for (
int i = 0; i <
graph->NumMyRows(); ++i)
1140 graph->ExtractMyRowView(i, num_entries, indices);
1141 for (
int j = 0; j < num_entries; ++j)
1145 <<
") " << std::endl;
1162 graph->ExtractMyRowView(row, num_entries, indices);
1166 const ::types::global_dof_index num_entries_ = num_entries;
1173 out << static_cast<int>(
1176 << -
static_cast<int>(
1203 const ::SparsityPattern &,
1207 const ::DynamicSparsityPattern &,
1213 const ::SparsityPattern &,
1218 const ::DynamicSparsityPattern &,
1224 const ::SparsityPattern &,
1229 const ::DynamicSparsityPattern &,
1237 const ::SparsityPattern &,
1243 const ::DynamicSparsityPattern &,
1249 DEAL_II_NAMESPACE_CLOSE
1251 #endif // DEAL_II_WITH_TRILINOS static ::ExceptionBase & ExcTrilinosError(int arg1)
const Epetra_Map & domain_partitioner() const
unsigned int local_size() const
#define AssertDimension(dim1, dim2)
void print(std::ostream &out, const bool write_extended_trilinos_info=false) const
std::shared_ptr< const std::vector< size_type > > colnum_cache
static ::ExceptionBase & ExcIO()
size_type row_length(const size_type row) const
const Epetra_Map & row_partitioner() const
size_type n_nonzero_elements() const
TrilinosWrappers::types::int_type min_my_gid(const Epetra_BlockMap &map)
const Epetra_Map & col_partitioner() const
#define AssertThrow(cond, exc)
const Epetra_Comm & comm_self()
std::unique_ptr< Epetra_CrsGraph > nonlocal_graph
const_iterator begin() const
Epetra_Map make_trilinos_map(const MPI_Comm &communicator=MPI_COMM_WORLD, const bool overlapping=false) const
bool exists(const size_type i, const size_type j) const
static ::ExceptionBase & ExcTrilinosError(int arg1)
SparsityPattern * sparsity_pattern
static ::ExceptionBase & ExcMessage(std::string arg1)
TrilinosWrappers::types::int_type n_global_rows(const Epetra_CrsGraph &graph)
::types::global_dof_index size_type
MPI_Comm get_mpi_communicator() const
std::unique_ptr< Epetra_Map > column_space_map
void subtract_set(const IndexSet &other)
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
TrilinosWrappers::types::int_type n_global_cols(const Epetra_CrsGraph &graph)
size_type bandwidth() const
std::size_t memory_consumption() const
void print_gnuplot(std::ostream &out) const
const_iterator end() const
TrilinosWrappers::types::int_type n_global_entries(const Epetra_CrsGraph &graph)
bool is_compressed() const
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
unsigned int max_entries_per_row() const
TrilinosWrappers::types::int_type n_global_elements(const Epetra_BlockMap &map)
unsigned int global_dof_index
SparsityPattern & operator=(const SparsityPattern &input_sparsity_pattern)
void copy_from(const SparsityPattern &input_sparsity_pattern)
TrilinosWrappers::types::int_type max_my_gid(const Epetra_BlockMap &map)
const Epetra_Comm & trilinos_communicator() const
static ::ExceptionBase & ExcNotImplemented()
TrilinosWrappers::types::int_type global_index(const Epetra_BlockMap &map, const ::types::global_dof_index i)
void reinit(const size_type m, const size_type n, const size_type n_entries_per_row=0)
const Epetra_Map & range_partitioner() const
size_type n_elements() const
std::pair< size_type, size_type > local_range() const
std::unique_ptr< Epetra_FECrsGraph > graph
::types::global_dof_index size_type
static ::ExceptionBase & ExcInternalError()
bool row_is_stored_locally(const size_type i) const