16 #include <deal.II/lac/trilinos_sparsity_pattern.h> 18 #ifdef DEAL_II_WITH_TRILINOS 20 # include <deal.II/base/utilities.h> 21 # include <deal.II/base/mpi.h> 22 # include <deal.II/lac/sparsity_pattern.h> 23 # include <deal.II/lac/dynamic_sparsity_pattern.h> 25 DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
26 # include <Epetra_Export.h> 27 DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
29 DEAL_II_NAMESPACE_OPEN
39 #ifndef DEAL_II_WITH_64BIT_INDICES 40 int n_global_elements (
const Epetra_BlockMap &map)
42 return map.NumGlobalElements();
45 int min_my_gid(
const Epetra_BlockMap &map)
47 return map.MinMyGID();
50 int max_my_gid(
const Epetra_BlockMap &map)
52 return map.MaxMyGID();
55 int n_global_rows(
const Epetra_CrsGraph &graph)
57 return graph.NumGlobalRows();
60 int n_global_cols(
const Epetra_CrsGraph &graph)
62 return graph.NumGlobalCols();
65 int n_global_entries(
const Epetra_CrsGraph &graph)
67 return graph.NumGlobalEntries();
70 int local_to_global_index(
const Epetra_BlockMap &map,
int i)
75 long long int n_global_elements (
const Epetra_BlockMap &map)
77 return map.NumGlobalElements64();
80 long long int min_my_gid(
const Epetra_BlockMap &map)
82 return map.MinMyGID64();
85 long long int max_my_gid(
const Epetra_BlockMap &map)
87 return map.MaxMyGID64();
90 long long int n_global_rows(
const Epetra_CrsGraph &graph)
92 return graph.NumGlobalRows64();
95 long long int n_global_cols(
const Epetra_CrsGraph &graph)
97 return graph.NumGlobalCols64();
100 long long int n_global_entries(
const Epetra_CrsGraph &graph)
102 return graph.NumGlobalEntries64();
105 long long int local_to_global_index(
const Epetra_BlockMap &map,
int i)
137 ((TrilinosWrappers::types::int_type)this->
a_row,
140 (TrilinosWrappers::types::int_type *)&(*
colnum_cache)[0]);
162 column_space_map.reset(
new Epetra_Map (TrilinosWrappers::types::int_type(0),
163 TrilinosWrappers::types::int_type(0),
165 graph.reset (
new Epetra_FECrsGraph(View,
169 graph->FillComplete();
176 reinit (input_map, input_map, n_entries_per_row);
182 const std::vector<size_type> &n_entries_per_row)
184 reinit (input_map, input_map, n_entries_per_row);
190 const Epetra_Map &input_col_map,
193 reinit (input_row_map, input_col_map, n_entries_per_row);
199 const Epetra_Map &input_col_map,
200 const std::vector<size_type> &n_entries_per_row)
202 reinit (input_row_map, input_col_map, n_entries_per_row);
211 reinit (m, n, n_entries_per_row);
218 const std::vector<size_type> &n_entries_per_row)
220 reinit (m, n, n_entries_per_row);
232 graph (new Epetra_FECrsGraph(View,
237 (void)input_sparsity;
239 ExcMessage (
"Copy constructor only works for empty sparsity patterns."));
245 const MPI_Comm &communicator,
248 reinit (parallel_partitioning, parallel_partitioning, communicator,
255 const MPI_Comm &communicator,
256 const std::vector<size_type> &n_entries_per_row)
258 reinit (parallel_partitioning, parallel_partitioning, communicator,
265 const IndexSet &col_parallel_partitioning,
266 const MPI_Comm &communicator,
269 reinit (row_parallel_partitioning, col_parallel_partitioning,
270 communicator, n_entries_per_row);
277 const IndexSet &col_parallel_partitioning,
278 const MPI_Comm &communicator,
279 const std::vector<size_type> &n_entries_per_row)
281 reinit (row_parallel_partitioning, col_parallel_partitioning,
282 communicator, n_entries_per_row);
289 const IndexSet &col_parallel_partitioning,
291 const MPI_Comm &communicator,
294 reinit (row_parallel_partitioning, col_parallel_partitioning,
295 writable_rows, communicator, n_max_entries_per_row);
310 reinit (complete_index_set(m), complete_index_set(n), MPI_COMM_SELF,
319 const std::vector<size_type> &n_entries_per_row)
321 reinit (complete_index_set(m), complete_index_set(n), MPI_COMM_SELF,
332 reinit_sp (
const Epetra_Map &row_map,
333 const Epetra_Map &col_map,
334 const size_type n_entries_per_row,
335 std_cxx11::shared_ptr<Epetra_Map> &column_space_map,
336 std_cxx11::shared_ptr<Epetra_FECrsGraph> &graph,
337 std_cxx11::shared_ptr<Epetra_CrsGraph> &nonlocal_graph)
339 Assert(row_map.IsOneToOne(),
340 ExcMessage(
"Row map must be 1-to-1, i.e., no overlap between " 341 "the maps of different processors."));
342 Assert(col_map.IsOneToOne(),
343 ExcMessage(
"Column map must be 1-to-1, i.e., no overlap between " 344 "the maps of different processors."));
346 nonlocal_graph.reset();
348 column_space_map.reset (
new Epetra_Map (col_map));
358 if (row_map.Comm().NumProc() > 1)
359 graph.reset (
new Epetra_FECrsGraph(Copy, row_map,
360 n_entries_per_row,
false 370 graph.reset (
new Epetra_FECrsGraph(Copy, row_map, col_map,
371 n_entries_per_row,
false));
377 reinit_sp (
const Epetra_Map &row_map,
378 const Epetra_Map &col_map,
379 const std::vector<size_type> &n_entries_per_row,
380 std_cxx11::shared_ptr<Epetra_Map> &column_space_map,
381 std_cxx11::shared_ptr<Epetra_FECrsGraph> &graph,
382 std_cxx11::shared_ptr<Epetra_CrsGraph> &nonlocal_graph)
384 Assert(row_map.IsOneToOne(),
385 ExcMessage(
"Row map must be 1-to-1, i.e., no overlap between " 386 "the maps of different processors."));
387 Assert(col_map.IsOneToOne(),
388 ExcMessage(
"Column map must be 1-to-1, i.e., no overlap between " 389 "the maps of different processors."));
392 nonlocal_graph.reset();
395 static_cast<size_type
>(n_global_elements(row_map)));
397 column_space_map.reset (
new Epetra_Map (col_map));
398 std::vector<int> local_entries_per_row(max_my_gid(row_map)-
399 min_my_gid(row_map));
400 for (
unsigned int i=0; i<local_entries_per_row.size(); ++i)
401 local_entries_per_row[i] = n_entries_per_row[min_my_gid(row_map)+i];
403 if (row_map.Comm().NumProc() > 1)
404 graph.reset(
new Epetra_FECrsGraph(Copy, row_map,
405 &local_entries_per_row[0],
416 graph.reset(
new Epetra_FECrsGraph(Copy, row_map, col_map,
417 &local_entries_per_row[0],
423 template <
typename SparsityPatternType>
425 reinit_sp (
const Epetra_Map &row_map,
426 const Epetra_Map &col_map,
427 const SparsityPatternType &sp,
428 const bool exchange_data,
429 std_cxx11::shared_ptr<Epetra_Map> &column_space_map,
430 std_cxx11::shared_ptr<Epetra_FECrsGraph> &graph,
431 std_cxx11::shared_ptr<Epetra_CrsGraph> &nonlocal_graph)
433 nonlocal_graph.reset ();
437 static_cast<size_type>(n_global_elements(row_map)));
439 static_cast<size_type>(n_global_elements(col_map)));
441 column_space_map.reset (
new Epetra_Map (col_map));
443 Assert (row_map.LinearMap() ==
true,
444 ExcMessage (
"This function only works if the row map is contiguous."));
446 const size_type first_row = min_my_gid(row_map),
447 last_row = max_my_gid(row_map)+1;
448 std::vector<int> n_entries_per_row(last_row - first_row);
452 for (size_type row=first_row; row<last_row; ++row)
453 n_entries_per_row[row-first_row] = static_cast<int>(sp.row_length(row));
455 if (row_map.Comm().NumProc() > 1)
456 graph.reset(
new Epetra_FECrsGraph(Copy, row_map,
457 &n_entries_per_row[0],
460 graph.reset (
new Epetra_FECrsGraph(Copy, row_map, col_map,
461 &n_entries_per_row[0],
465 static_cast<size_type>(n_global_rows(*graph)));
467 std::vector<TrilinosWrappers::types::int_type> row_indices;
471 if (exchange_data==
false)
472 for (size_type row=first_row; row<last_row; ++row)
474 const TrilinosWrappers::types::int_type row_length = sp.row_length(row);
478 row_indices.resize (row_length, -1);
480 typename SparsityPatternType::iterator p = sp.begin(row);
483 for (
int col=0; col<row_length; )
485 row_indices[col++] = p->column();
486 if (col < row_length)
490 graph->Epetra_CrsGraph::InsertGlobalIndices (row, row_length,
494 for (size_type row=0; row<sp.n_rows(); ++row)
496 const TrilinosWrappers::types::int_type row_length = sp.row_length(row);
500 row_indices.resize (row_length, -1);
502 typename SparsityPatternType::iterator p = sp.begin(row);
505 for (
int col=0; col<row_length; )
507 row_indices[col++] = p->column();
508 if (col < row_length)
512 graph->InsertGlobalIndices (1,
513 reinterpret_cast<TrilinosWrappers::types::int_type *>(&row),
514 row_length, &row_indices[0]);
518 graph->GlobalAssemble (*column_space_map,
519 static_cast<const Epetra_Map &>(graph->RangeMap()),
523 ierr = graph->OptimizeStorage ();
533 reinit_sp (input_map, input_map, n_entries_per_row,
541 const Epetra_Map &input_col_map,
544 reinit_sp (input_row_map, input_col_map, n_entries_per_row,
552 const std::vector<size_type> &n_entries_per_row)
554 reinit_sp (input_map, input_map, n_entries_per_row,
562 const Epetra_Map &input_col_map,
563 const std::vector<size_type> &n_entries_per_row)
565 reinit_sp (input_row_map, input_col_map, n_entries_per_row,
573 const MPI_Comm &communicator,
578 reinit_sp (map, map, n_entries_per_row,
585 const MPI_Comm &communicator,
586 const std::vector<size_type> &n_entries_per_row)
590 reinit_sp (map, map, n_entries_per_row,
597 const IndexSet &col_parallel_partitioning,
598 const MPI_Comm &communicator,
605 reinit_sp (row_map, col_map, n_entries_per_row,
613 const IndexSet &col_parallel_partitioning,
614 const MPI_Comm &communicator,
615 const std::vector<size_type> &n_entries_per_row)
621 reinit_sp (row_map, col_map, n_entries_per_row,
629 const IndexSet &col_parallel_partitioning,
631 const MPI_Comm &communicator,
638 reinit_sp (row_map, col_map, n_entries_per_row,
641 IndexSet nonlocal_partitioner = writable_rows;
645 IndexSet tmp = writable_rows & row_parallel_partitioning;
646 Assert (tmp == row_parallel_partitioning,
647 ExcMessage(
"The set of writable rows passed to this method does not " 648 "contain the locally owned rows, which is not allowed."));
651 nonlocal_partitioner.
subtract_set(row_parallel_partitioning);
654 Epetra_Map nonlocal_map =
664 template<
typename SparsityPatternType>
667 const IndexSet &col_parallel_partitioning,
668 const SparsityPatternType &nontrilinos_sparsity_pattern,
669 const MPI_Comm &communicator,
670 const bool exchange_data)
676 reinit_sp (row_map, col_map, nontrilinos_sparsity_pattern, exchange_data,
682 template<
typename SparsityPatternType>
685 const SparsityPatternType &nontrilinos_sparsity_pattern,
686 const MPI_Comm &communicator,
687 const bool exchange_data)
691 reinit_sp (map, map, nontrilinos_sparsity_pattern, exchange_data,
697 template <
typename SparsityPatternType>
700 const SparsityPatternType &sp,
701 const bool exchange_data)
703 reinit_sp (input_map, input_map, sp, exchange_data,
709 template <
typename SparsityPatternType>
712 const Epetra_Map &input_col_map,
713 const SparsityPatternType &sp,
714 const bool exchange_data)
716 reinit_sp (input_row_map, input_col_map, sp, exchange_data,
733 template <
typename SparsityPatternType>
737 const Epetra_Map rows (TrilinosWrappers::types::int_type(sp.n_rows()), 0,
739 const Epetra_Map columns (TrilinosWrappers::types::int_type(sp.n_cols()), 0,
742 reinit_sp (rows, columns, sp,
false,
754 column_space_map.reset (
new Epetra_Map (TrilinosWrappers::types::int_type(0),
755 TrilinosWrappers::types::int_type(0),
759 graph->FillComplete();
777 TrilinosWrappers::types::int_type row =
nonlocal_graph->RowMap().MyGID(
778 static_cast<TrilinosWrappers::types::int_type> (0));
785 static_cast<const Epetra_Map &>(
graph->RangeMap()));
792 static_cast<const Epetra_Map &>(
graph->RangeMap()));
796 static_cast<const Epetra_Map &>(
graph->RangeMap()),
801 ierr =
graph->OptimizeStorage ();
813 int trilinos_i =
graph->LRID(static_cast<TrilinosWrappers::types::int_type>(i)),
814 trilinos_j =
graph->LCID(static_cast<TrilinosWrappers::types::int_type>(j));
822 if (trilinos_i == -1)
831 if (
graph->Filled() ==
false)
833 int nnz_present =
graph->NumGlobalIndices(i);
835 TrilinosWrappers::types::int_type *col_indices;
843 int ierr =
graph->ExtractGlobalRowView(
844 static_cast<TrilinosWrappers::types::int_type>(trilinos_i),
845 nnz_extracted, col_indices);
848 Assert (nnz_present == nnz_extracted,
852 TrilinosWrappers::types::int_type *el_find =
853 std::find(col_indices, col_indices + nnz_present, trilinos_j);
855 TrilinosWrappers::types::int_type local_col_index =
856 (TrilinosWrappers::types::int_type)(el_find - col_indices);
858 if (local_col_index == nnz_present)
865 int nnz_present =
graph->NumGlobalIndices(
866 static_cast<TrilinosWrappers::types::int_type>(i));
873 int ierr =
graph->ExtractMyRowView(trilinos_i,
874 nnz_extracted, col_indices);
878 Assert (nnz_present == nnz_extracted,
882 int *el_find = std::find(col_indices, col_indices + nnz_present,
883 static_cast<int>(trilinos_j));
885 int local_col_index = (int)(el_find - col_indices);
887 if (local_col_index == nnz_present)
901 TrilinosWrappers::types::int_type global_b=0;
906 graph->ExtractMyRowView(i, num_entries, indices);
907 for (
unsigned int j=0; j<(
unsigned int)num_entries; ++j)
909 if (static_cast<size_type>(std::abs(static_cast<TrilinosWrappers::types::int_type>(i-indices[j]))) > local_b)
910 local_b = std::abs(static_cast<TrilinosWrappers::types::int_type>(i-indices[j]));
913 graph->Comm().MaxAll((TrilinosWrappers::types::int_type *)&local_b, &global_b, 1);
922 const TrilinosWrappers::types::int_type
n_rows = n_global_rows(*
graph);
931 TrilinosWrappers::types::int_type
n_cols;
932 if (
graph->Filled() ==
true)
952 std::pair<SparsityPattern::size_type, SparsityPattern::size_type>
957 end = max_my_gid(
graph->RowMap())+1;
967 TrilinosWrappers::types::int_type nnz = n_global_entries(*
graph);
977 int nnz =
graph->MaxNumIndices();
979 return static_cast<unsigned int>(nnz);
991 TrilinosWrappers::types::int_type ncols = -1;
992 TrilinosWrappers::types::int_type local_row =
993 graph->LRID(static_cast<TrilinosWrappers::types::int_type>(row));
999 ncols =
graph->NumMyIndices (local_row);
1009 return static_cast<const Epetra_Map &
>(
graph->DomainMap());
1017 return static_cast<const Epetra_Map &
>(
graph->RangeMap());
1025 return static_cast<const Epetra_Map &
>(
graph->RowMap());
1033 return static_cast<const Epetra_Map &
>(
graph->ColMap());
1041 return graph->RangeMap().Comm();
1050 #ifdef DEAL_II_WITH_MPI 1052 const Epetra_MpiComm *mpi_comm
1053 =
dynamic_cast<const Epetra_MpiComm *
>(&
graph->RangeMap().Comm());
1055 return mpi_comm->Comm();
1058 return MPI_COMM_SELF;
1079 const bool write_extended_trilinos_info)
const 1081 if (write_extended_trilinos_info)
1088 for (
int i=0; i<
graph->NumMyRows(); ++i)
1090 graph->ExtractMyRowView (i, num_entries, indices);
1091 for (
int j=0; j<num_entries; ++j)
1092 out <<
"(" << local_to_global_index(
graph->RowMap(), i)
1093 <<
"," << local_to_global_index(
graph->ColMap(), indices[j]) <<
") " 1107 for (
unsigned int row=0; row<
local_size(); ++row)
1111 graph->ExtractMyRowView (row, num_entries, indices);
1113 for (
int j=0; j<num_entries; ++j)
1119 out << static_cast<int>(local_to_global_index(
graph->ColMap(), indices[j]))
1120 <<
" " << -
static_cast<int>(local_to_global_index(
graph->RowMap(), row)) << std::endl;
1145 const ::SparsityPattern &,
1149 const ::DynamicSparsityPattern &,
1155 const ::SparsityPattern &,
1160 const ::DynamicSparsityPattern &,
1166 const ::SparsityPattern &,
1171 const ::DynamicSparsityPattern &,
1179 const ::SparsityPattern &,
1185 const ::DynamicSparsityPattern &,
1191 DEAL_II_NAMESPACE_CLOSE
1193 #endif // DEAL_II_WITH_TRILINOS static ::ExceptionBase & ExcTrilinosError(int arg1)
types::global_dof_index size_type
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
static ::ExceptionBase & ExcIO()
size_type row_length(const size_type row) const
std_cxx11::shared_ptr< Epetra_FECrsGraph > graph
size_type n_nonzero_elements() const
std_cxx11::shared_ptr< Epetra_CrsGraph > nonlocal_graph
#define AssertThrow(cond, exc)
const Epetra_Comm & comm_self()
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
std_cxx11::shared_ptr< Epetra_Map > column_space_map
static ::ExceptionBase & ExcMessage(std::string arg1)
std_cxx11::shared_ptr< const std::vector< size_type > > colnum_cache
MPI_Comm get_mpi_communicator() const
void subtract_set(const IndexSet &other)
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void copy_from(const SparsityPattern &input_sparsity_pattern)
size_type bandwidth() const
std::size_t memory_consumption() const
const Epetra_Comm & trilinos_communicator() const 1
const Epetra_Map & domain_partitioner() const 1
void print_gnuplot(std::ostream &out) const
const_iterator end() const
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
unsigned int max_entries_per_row() const
const Epetra_Map & range_partitioner() const 1
SparsityPattern & operator=(const SparsityPattern &input_sparsity_pattern)
const Epetra_Map & col_partitioner() const 1
static ::ExceptionBase & ExcNotImplemented()
const Epetra_Map & row_partitioner() const 1
void reinit(const size_type m, const size_type n, const size_type n_entries_per_row=0)
size_type n_elements() const
virtual ~SparsityPattern()
std::pair< size_type, size_type > local_range() const
static ::ExceptionBase & ExcInternalError()