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/utilities.h> 22 # include <deal.II/base/mpi.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
58 ((TrilinosWrappers::types::int_type)this->
a_row,
61 (TrilinosWrappers::types::int_type *)&(*
colnum_cache)[0]);
83 column_space_map = std_cxx14::make_unique<Epetra_Map> (TrilinosWrappers::types::int_type(0),
84 TrilinosWrappers::types::int_type(0),
86 graph = std_cxx14::make_unique<Epetra_FECrsGraph>(View,
90 graph->FillComplete();
97 reinit (input_map, input_map, n_entries_per_row);
103 const std::vector<size_type> &n_entries_per_row)
105 reinit (input_map, input_map, n_entries_per_row);
111 const Epetra_Map &input_col_map,
114 reinit (input_row_map, input_col_map, n_entries_per_row);
120 const Epetra_Map &input_col_map,
121 const std::vector<size_type> &n_entries_per_row)
123 reinit (input_row_map, input_col_map, n_entries_per_row);
132 reinit (m, n, n_entries_per_row);
139 const std::vector<size_type> &n_entries_per_row)
141 reinit (m, n, n_entries_per_row);
149 column_space_map(std::move(other.column_space_map)),
150 graph(std::move(other.graph)),
151 nonlocal_graph(std::move(other.nonlocal_graph))
163 graph (new Epetra_FECrsGraph(View,
168 (void)input_sparsity;
170 ExcMessage (
"Copy constructor only works for empty sparsity patterns."));
176 const MPI_Comm &communicator,
179 reinit (parallel_partitioning, parallel_partitioning, communicator,
186 const MPI_Comm &communicator,
187 const std::vector<size_type> &n_entries_per_row)
189 reinit (parallel_partitioning, parallel_partitioning, communicator,
196 const IndexSet &col_parallel_partitioning,
197 const MPI_Comm &communicator,
200 reinit (row_parallel_partitioning, col_parallel_partitioning,
201 communicator, n_entries_per_row);
208 const IndexSet &col_parallel_partitioning,
209 const MPI_Comm &communicator,
210 const std::vector<size_type> &n_entries_per_row)
212 reinit (row_parallel_partitioning, col_parallel_partitioning,
213 communicator, n_entries_per_row);
220 const IndexSet &col_parallel_partitioning,
222 const MPI_Comm &communicator,
225 reinit (row_parallel_partitioning, col_parallel_partitioning,
226 writable_rows, communicator, n_max_entries_per_row);
236 reinit (complete_index_set(m), complete_index_set(n), MPI_COMM_SELF,
245 const std::vector<size_type> &n_entries_per_row)
247 reinit (complete_index_set(m), complete_index_set(n), MPI_COMM_SELF,
258 reinit_sp (
const Epetra_Map &row_map,
259 const Epetra_Map &col_map,
260 const size_type n_entries_per_row,
261 std::unique_ptr<Epetra_Map> &column_space_map,
262 std::unique_ptr<Epetra_FECrsGraph> &graph,
263 std::unique_ptr<Epetra_CrsGraph> &nonlocal_graph)
265 Assert(row_map.IsOneToOne(),
266 ExcMessage(
"Row map must be 1-to-1, i.e., no overlap between " 267 "the maps of different processors."));
268 Assert(col_map.IsOneToOne(),
269 ExcMessage(
"Column map must be 1-to-1, i.e., no overlap between " 270 "the maps of different processors."));
272 nonlocal_graph.reset();
274 column_space_map = std_cxx14::make_unique<Epetra_Map >(col_map);
284 if (row_map.Comm().NumProc() > 1)
285 graph = std_cxx14::make_unique<Epetra_FECrsGraph>
286 (Copy, row_map, n_entries_per_row,
false 294 graph = std_cxx14::make_unique<Epetra_FECrsGraph>
295 (Copy, row_map, col_map, n_entries_per_row,
false);
301 reinit_sp (
const Epetra_Map &row_map,
302 const Epetra_Map &col_map,
303 const std::vector<size_type> &n_entries_per_row,
304 std::unique_ptr<Epetra_Map> &column_space_map,
305 std::unique_ptr<Epetra_FECrsGraph> &graph,
306 std::unique_ptr<Epetra_CrsGraph> &nonlocal_graph)
308 Assert(row_map.IsOneToOne(),
309 ExcMessage(
"Row map must be 1-to-1, i.e., no overlap between " 310 "the maps of different processors."));
311 Assert(col_map.IsOneToOne(),
312 ExcMessage(
"Column map must be 1-to-1, i.e., no overlap between " 313 "the maps of different processors."));
316 nonlocal_graph.reset();
321 column_space_map = std_cxx14::make_unique<Epetra_Map >(col_map);
324 for (
unsigned int i=0; i<local_entries_per_row.size(); ++i)
327 if (row_map.Comm().NumProc() > 1)
328 graph = std_cxx14::make_unique<Epetra_FECrsGraph>
329 (Copy, row_map, local_entries_per_row.data(),
false 337 graph = std_cxx14::make_unique<Epetra_FECrsGraph>
338 (Copy, row_map, col_map, local_entries_per_row.data(),
false);
343 template <
typename SparsityPatternType>
345 reinit_sp (
const Epetra_Map &row_map,
346 const Epetra_Map &col_map,
347 const SparsityPatternType &sp,
348 const bool exchange_data,
349 std::unique_ptr<Epetra_Map> &column_space_map,
350 std::unique_ptr<Epetra_FECrsGraph> &graph,
351 std::unique_ptr<Epetra_CrsGraph> &nonlocal_graph)
353 nonlocal_graph.reset ();
361 column_space_map = std_cxx14::make_unique<Epetra_Map >(col_map);
363 Assert (row_map.LinearMap() ==
true,
364 ExcMessage (
"This function only works if the row map is contiguous."));
368 std::vector<int> n_entries_per_row(last_row - first_row);
372 for (size_type row=first_row; row<last_row; ++row)
373 n_entries_per_row[row-first_row] = static_cast<int>(sp.row_length(row));
375 if (row_map.Comm().NumProc() > 1)
376 graph = std_cxx14::make_unique<Epetra_FECrsGraph>(Copy, row_map,
377 n_entries_per_row.data(),
380 graph = std_cxx14::make_unique<Epetra_FECrsGraph>(Copy, row_map, col_map,
381 n_entries_per_row.data(),
387 std::vector<TrilinosWrappers::types::int_type> row_indices;
391 if (exchange_data==
false)
392 for (size_type row=first_row; row<last_row; ++row)
394 const TrilinosWrappers::types::int_type row_length = sp.row_length(row);
398 row_indices.resize (row_length, -1);
400 typename SparsityPatternType::iterator p = sp.begin(row);
403 for (
int col=0; col<row_length; )
405 row_indices[col++] = p->column();
406 if (col < row_length)
410 graph->Epetra_CrsGraph::InsertGlobalIndices (row, row_length,
414 for (size_type row=0; row<sp.n_rows(); ++row)
416 const TrilinosWrappers::types::int_type row_length = sp.row_length(row);
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->InsertGlobalIndices (1,
433 reinterpret_cast<TrilinosWrappers::types::int_type *>(&row),
434 row_length, row_indices.data());
438 graph->GlobalAssemble (*column_space_map,
439 static_cast<const Epetra_Map &>(graph->RangeMap()),
443 ierr = graph->OptimizeStorage ();
453 reinit_sp (input_map, input_map, n_entries_per_row,
461 const Epetra_Map &input_col_map,
464 reinit_sp (input_row_map, input_col_map, n_entries_per_row,
472 const std::vector<size_type> &n_entries_per_row)
474 reinit_sp (input_map, input_map, n_entries_per_row,
482 const Epetra_Map &input_col_map,
483 const std::vector<size_type> &n_entries_per_row)
485 reinit_sp (input_row_map, input_col_map, n_entries_per_row,
493 const MPI_Comm &communicator,
498 reinit_sp (map, map, n_entries_per_row,
505 const MPI_Comm &communicator,
506 const std::vector<size_type> &n_entries_per_row)
510 reinit_sp (map, map, n_entries_per_row,
517 const IndexSet &col_parallel_partitioning,
518 const MPI_Comm &communicator,
525 reinit_sp (row_map, col_map, n_entries_per_row,
533 const IndexSet &col_parallel_partitioning,
534 const MPI_Comm &communicator,
535 const std::vector<size_type> &n_entries_per_row)
541 reinit_sp (row_map, col_map, n_entries_per_row,
549 const IndexSet &col_parallel_partitioning,
551 const MPI_Comm &communicator,
558 reinit_sp (row_map, col_map, n_entries_per_row,
561 IndexSet nonlocal_partitioner = writable_rows;
565 IndexSet tmp = writable_rows & row_parallel_partitioning;
566 Assert (tmp == row_parallel_partitioning,
567 ExcMessage(
"The set of writable rows passed to this method does not " 568 "contain the locally owned rows, which is not allowed."));
571 nonlocal_partitioner.
subtract_set(row_parallel_partitioning);
574 Epetra_Map nonlocal_map =
576 nonlocal_graph = std_cxx14::make_unique<Epetra_CrsGraph>(Copy, nonlocal_map, 0);
584 template <
typename SparsityPatternType>
587 const IndexSet &col_parallel_partitioning,
588 const SparsityPatternType &nontrilinos_sparsity_pattern,
589 const MPI_Comm &communicator,
590 const bool exchange_data)
596 reinit_sp (row_map, col_map, nontrilinos_sparsity_pattern, exchange_data,
602 template <
typename SparsityPatternType>
605 const SparsityPatternType &nontrilinos_sparsity_pattern,
606 const MPI_Comm &communicator,
607 const bool exchange_data)
611 reinit_sp (map, map, nontrilinos_sparsity_pattern, exchange_data,
617 template <
typename SparsityPatternType>
620 const SparsityPatternType &sp,
621 const bool exchange_data)
623 reinit_sp (input_map, input_map, sp, exchange_data,
629 template <
typename SparsityPatternType>
632 const Epetra_Map &input_col_map,
633 const SparsityPatternType &sp,
634 const bool exchange_data)
636 reinit_sp (input_row_map, input_col_map, sp, exchange_data,
657 graph = std_cxx14::make_unique<Epetra_FECrsGraph>(*sp.
graph);
667 template <
typename SparsityPatternType>
671 const Epetra_Map rows (TrilinosWrappers::types::int_type(sp.n_rows()), 0,
673 const Epetra_Map columns (TrilinosWrappers::types::int_type(sp.n_cols()), 0,
676 reinit_sp (rows, columns, sp,
false,
688 column_space_map = std_cxx14::make_unique<Epetra_Map >(TrilinosWrappers::types::int_type(0),
689 TrilinosWrappers::types::int_type(0),
693 graph->FillComplete();
711 TrilinosWrappers::types::int_type row =
nonlocal_graph->RowMap().MyGID(
712 static_cast<TrilinosWrappers::types::int_type> (0));
719 static_cast<const Epetra_Map &>(
graph->RangeMap()));
726 static_cast<const Epetra_Map &>(
graph->RangeMap()));
730 static_cast<const Epetra_Map &>(
graph->RangeMap()),
735 ierr =
graph->OptimizeStorage ();
747 int trilinos_i =
graph->LRID(static_cast<TrilinosWrappers::types::int_type>(i)),
748 trilinos_j =
graph->LCID(static_cast<TrilinosWrappers::types::int_type>(j));
756 if (trilinos_i == -1)
765 if (
graph->Filled() ==
false)
767 int nnz_present =
graph->NumGlobalIndices(i);
769 TrilinosWrappers::types::int_type *col_indices;
777 int ierr =
graph->ExtractGlobalRowView(
778 static_cast<TrilinosWrappers::types::int_type>(trilinos_i),
779 nnz_extracted, col_indices);
782 Assert (nnz_present == nnz_extracted,
786 TrilinosWrappers::types::int_type *el_find =
787 std::find(col_indices, col_indices + nnz_present, trilinos_j);
789 TrilinosWrappers::types::int_type local_col_index =
790 (TrilinosWrappers::types::int_type)(el_find - col_indices);
792 if (local_col_index == nnz_present)
799 int nnz_present =
graph->NumGlobalIndices(
800 static_cast<TrilinosWrappers::types::int_type>(i));
807 int ierr =
graph->ExtractMyRowView(trilinos_i,
808 nnz_extracted, col_indices);
812 Assert (nnz_present == nnz_extracted,
816 int *el_find = std::find(col_indices, col_indices + nnz_present,
817 static_cast<int>(trilinos_j));
819 int local_col_index = (int)(el_find - col_indices);
821 if (local_col_index == nnz_present)
835 TrilinosWrappers::types::int_type global_b=0;
840 graph->ExtractMyRowView(i, num_entries, indices);
841 for (
unsigned int j=0; j<(
unsigned int)num_entries; ++j)
843 if (static_cast<size_type>(std::abs(static_cast<TrilinosWrappers::types::int_type>(i-indices[j]))) > local_b)
844 local_b = std::abs(static_cast<TrilinosWrappers::types::int_type>(i-indices[j]));
847 graph->Comm().MaxAll((TrilinosWrappers::types::int_type *)&local_b, &global_b, 1);
865 TrilinosWrappers::types::int_type
n_cols;
866 if (
graph->Filled() ==
true)
886 std::pair<SparsityPattern::size_type, SparsityPattern::size_type>
911 int nnz =
graph->MaxNumIndices();
913 return static_cast<unsigned int>(nnz);
925 TrilinosWrappers::types::int_type ncols = -1;
926 TrilinosWrappers::types::int_type local_row =
927 graph->LRID(static_cast<TrilinosWrappers::types::int_type>(row));
933 ncols =
graph->NumMyIndices (local_row);
943 return static_cast<const Epetra_Map &
>(
graph->DomainMap());
951 return static_cast<const Epetra_Map &
>(
graph->RangeMap());
959 return static_cast<const Epetra_Map &
>(
graph->RowMap());
967 return static_cast<const Epetra_Map &
>(
graph->ColMap());
975 return graph->RangeMap().Comm();
984 #ifdef DEAL_II_WITH_MPI 986 const Epetra_MpiComm *mpi_comm
987 =
dynamic_cast<const Epetra_MpiComm *
>(&
graph->RangeMap().Comm());
989 return mpi_comm->Comm();
992 return MPI_COMM_SELF;
1013 const bool write_extended_trilinos_info)
const 1015 if (write_extended_trilinos_info)
1022 for (
int i=0; i<
graph->NumMyRows(); ++i)
1024 graph->ExtractMyRowView (i, num_entries, indices);
1025 for (
int j=0; j<num_entries; ++j)
1045 graph->ExtractMyRowView (row, num_entries, indices);
1049 const ::types::global_dof_index num_entries_ = num_entries;
1082 const ::SparsityPattern &,
1086 const ::DynamicSparsityPattern &,
1092 const ::SparsityPattern &,
1097 const ::DynamicSparsityPattern &,
1103 const ::SparsityPattern &,
1108 const ::DynamicSparsityPattern &,
1116 const ::SparsityPattern &,
1122 const ::DynamicSparsityPattern &,
1128 DEAL_II_NAMESPACE_CLOSE
1130 #endif // DEAL_II_WITH_TRILINOS static ::ExceptionBase & ExcTrilinosError(int arg1)
types::global_dof_index size_type
const Epetra_Map & domain_partitioner() const
unsigned int local_size() const
#define AssertDimension(dim1, dim2)
::types::global_dof_index size_type
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)
unsigned int global_dof_index
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)
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)
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
static ::ExceptionBase & ExcInternalError()