Reference documentation for deal.II version 8.4.2
trilinos_sparsity_pattern.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2008 - 2015 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii__trilinos_sparsity_pattern_h
17 #define dealii__trilinos_sparsity_pattern_h
18 
19 
20 #include <deal.II/base/config.h>
21 
22 #ifdef DEAL_II_WITH_TRILINOS
23 
24 # include <deal.II/base/subscriptor.h>
25 # include <deal.II/base/index_set.h>
26 # include <deal.II/lac/exceptions.h>
27 
28 # include <vector>
29 # include <cmath>
30 # include <memory>
31 
32 # include <deal.II/base/std_cxx11/shared_ptr.h>
33 
34 DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
35 # include <Epetra_FECrsGraph.h>
36 # include <Epetra_Map.h>
37 # ifdef DEAL_II_WITH_MPI
38 # include <Epetra_MpiComm.h>
39 # include "mpi.h"
40 # else
41 # include "Epetra_SerialComm.h"
42 # endif
44 
45 
46 DEAL_II_NAMESPACE_OPEN
47 
48 // forward declarations
49 class SparsityPattern;
51 
52 namespace TrilinosWrappers
53 {
54  // forward declarations
55  class SparsityPattern;
56 
57  namespace SparsityPatternIterators
58  {
59  // forward declaration
60  class Iterator;
61 
75  class Accessor
76  {
77  public:
81  typedef ::types::global_dof_index size_type;
82 
87  const size_type row,
88  const size_type index);
89 
93  Accessor (const Accessor &a);
94 
98  size_type row() const;
99 
103  size_type index() const;
104 
108  size_type column() const;
109 
113  DeclException0 (ExcBeyondEndOfSparsityPattern);
114 
118  DeclException3 (ExcAccessToNonlocalRow,
119  size_type, size_type, size_type,
120  << "You tried to access row " << arg1
121  << " of a distributed sparsity pattern, "
122  << " but only rows " << arg2 << " through " << arg3
123  << " are stored locally and can be accessed.");
124 
125  private:
130 
134  size_type a_row;
135 
139  size_type a_index;
140 
153  std_cxx11::shared_ptr<const std::vector<size_type> > colnum_cache;
154 
160  void visit_present_row ();
161 
165  friend class Iterator;
166  };
167 
173  class Iterator
174  {
175  public:
179  typedef ::types::global_dof_index size_type;
180 
186  const size_type row,
187  const size_type index);
188 
192  Iterator (const Iterator &i);
193 
197  Iterator &operator++ ();
198 
202  Iterator operator++ (int);
203 
207  const Accessor &operator* () const;
208 
212  const Accessor *operator-> () const;
213 
218  bool operator == (const Iterator &) const;
219 
223  bool operator != (const Iterator &) const;
224 
230  bool operator < (const Iterator &) const;
231 
235  DeclException2 (ExcInvalidIndexWithinRow,
236  size_type, size_type,
237  << "Attempt to access element " << arg2
238  << " of row " << arg1
239  << " which doesn't have that many elements.");
240 
241  private:
246 
248  };
249 
250  }
251 
252 
272  {
273  public:
274 
278  typedef ::types::global_dof_index size_type;
279 
284 
292  SparsityPattern ();
293 
308  SparsityPattern (const size_type m,
309  const size_type n,
310  const size_type n_entries_per_row = 0);
311 
320  SparsityPattern (const size_type m,
321  const size_type n,
322  const std::vector<size_type> &n_entries_per_row);
323 
328  SparsityPattern (const SparsityPattern &input_sparsity_pattern);
329 
333  virtual ~SparsityPattern ();
334 
346  void
347  reinit (const size_type m,
348  const size_type n,
349  const size_type n_entries_per_row = 0);
350 
359  void
360  reinit (const size_type m,
361  const size_type n,
362  const std::vector<size_type> &n_entries_per_row);
363 
368  void
369  copy_from (const SparsityPattern &input_sparsity_pattern);
370 
376  template<typename SparsityPatternType>
377  void
378  copy_from (const SparsityPatternType &nontrilinos_sparsity_pattern);
379 
386  SparsityPattern &operator = (const SparsityPattern &input_sparsity_pattern);
387 
395  void clear ();
396 
406  void compress ();
408 
412 
427  SparsityPattern (const Epetra_Map &parallel_partitioning,
428  const size_type n_entries_per_row = 0) DEAL_II_DEPRECATED;
429 
442  SparsityPattern (const Epetra_Map &parallel_partitioning,
443  const std::vector<size_type> &n_entries_per_row) DEAL_II_DEPRECATED;
444 
463  SparsityPattern (const Epetra_Map &row_parallel_partitioning,
464  const Epetra_Map &col_parallel_partitioning,
465  const size_type n_entries_per_row = 0) DEAL_II_DEPRECATED;
466 
480  SparsityPattern (const Epetra_Map &row_parallel_partitioning,
481  const Epetra_Map &col_parallel_partitioning,
482  const std::vector<size_type> &n_entries_per_row) DEAL_II_DEPRECATED;
483 
500  void
501  reinit (const Epetra_Map &parallel_partitioning,
502  const size_type n_entries_per_row = 0) DEAL_II_DEPRECATED;
503 
516  void
517  reinit (const Epetra_Map &parallel_partitioning,
518  const std::vector<size_type> &n_entries_per_row) DEAL_II_DEPRECATED;
519 
538  void
539  reinit (const Epetra_Map &row_parallel_partitioning,
540  const Epetra_Map &col_parallel_partitioning,
541  const size_type n_entries_per_row = 0) DEAL_II_DEPRECATED;
542 
556  void
557  reinit (const Epetra_Map &row_parallel_partitioning,
558  const Epetra_Map &col_parallel_partitioning,
559  const std::vector<size_type> &n_entries_per_row) DEAL_II_DEPRECATED;
560 
571  template<typename SparsityPatternType>
572  void
573  reinit (const Epetra_Map &row_parallel_partitioning,
574  const Epetra_Map &col_parallel_partitioning,
575  const SparsityPatternType &nontrilinos_sparsity_pattern,
576  const bool exchange_data = false) DEAL_II_DEPRECATED;
577 
588  template<typename SparsityPatternType>
589  void
590  reinit (const Epetra_Map &parallel_partitioning,
591  const SparsityPatternType &nontrilinos_sparsity_pattern,
592  const bool exchange_data = false) DEAL_II_DEPRECATED;
594 
598 
610  SparsityPattern (const IndexSet &parallel_partitioning,
611  const MPI_Comm &communicator = MPI_COMM_WORLD,
612  const size_type n_entries_per_row = 0);
613 
624  SparsityPattern (const IndexSet &parallel_partitioning,
625  const MPI_Comm &communicator,
626  const std::vector<size_type> &n_entries_per_row);
627 
642  SparsityPattern (const IndexSet &row_parallel_partitioning,
643  const IndexSet &col_parallel_partitioning,
644  const MPI_Comm &communicator = MPI_COMM_WORLD,
645  const size_type n_entries_per_row = 0);
646 
658  SparsityPattern (const IndexSet &row_parallel_partitioning,
659  const IndexSet &col_parallel_partitioning,
660  const MPI_Comm &communicator,
661  const std::vector<size_type> &n_entries_per_row);
662 
689  SparsityPattern (const IndexSet &row_parallel_partitioning,
690  const IndexSet &col_parallel_partitioning,
691  const IndexSet &writable_rows,
692  const MPI_Comm &communicator = MPI_COMM_WORLD,
693  const size_type n_entries_per_row = 0);
694 
710  void
711  reinit (const IndexSet &parallel_partitioning,
712  const MPI_Comm &communicator = MPI_COMM_WORLD,
713  const size_type n_entries_per_row = 0);
714 
725  void
726  reinit (const IndexSet &parallel_partitioning,
727  const MPI_Comm &communicator,
728  const std::vector<size_type> &n_entries_per_row);
729 
746  void
747  reinit (const IndexSet &row_parallel_partitioning,
748  const IndexSet &col_parallel_partitioning,
749  const MPI_Comm &communicator = MPI_COMM_WORLD,
750  const size_type n_entries_per_row = 0);
751 
777  void
778  reinit (const IndexSet &row_parallel_partitioning,
779  const IndexSet &col_parallel_partitioning,
780  const IndexSet &writeable_rows,
781  const MPI_Comm &communicator = MPI_COMM_WORLD,
782  const size_type n_entries_per_row = 0);
783 
788  void
789  reinit (const IndexSet &row_parallel_partitioning,
790  const IndexSet &col_parallel_partitioning,
791  const MPI_Comm &communicator,
792  const std::vector<size_type> &n_entries_per_row);
793 
803  template<typename SparsityPatternType>
804  void
805  reinit (const IndexSet &row_parallel_partitioning,
806  const IndexSet &col_parallel_partitioning,
807  const SparsityPatternType &nontrilinos_sparsity_pattern,
808  const MPI_Comm &communicator = MPI_COMM_WORLD,
809  const bool exchange_data = false);
810 
819  template<typename SparsityPatternType>
820  void
821  reinit (const IndexSet &parallel_partitioning,
822  const SparsityPatternType &nontrilinos_sparsity_pattern,
823  const MPI_Comm &communicator = MPI_COMM_WORLD,
824  const bool exchange_data = false);
826 
830 
835  bool is_compressed () const;
836 
840  unsigned int max_entries_per_row () const;
841 
845  size_type n_rows () const;
846 
850  size_type n_cols () const;
851 
861  unsigned int local_size () const;
862 
871  std::pair<size_type, size_type>
872  local_range () const;
873 
878  bool in_local_range (const size_type index) const;
879 
883  size_type n_nonzero_elements () const;
884 
888  size_type row_length (const size_type row) const;
889 
896  size_type bandwidth () const;
897 
902  bool empty () const;
903 
908  bool exists (const size_type i,
909  const size_type j) const;
910 
915  std::size_t memory_consumption () const;
916 
918 
925  void add (const size_type i,
926  const size_type j);
927 
928 
932  template <typename ForwardIterator>
933  void add_entries (const size_type row,
934  ForwardIterator begin,
935  ForwardIterator end,
936  const bool indices_are_sorted = false);
938 
942 
947  const Epetra_FECrsGraph &trilinos_sparsity_pattern () const;
948 
957  const Epetra_Map &domain_partitioner () const DEAL_II_DEPRECATED;
958 
967  const Epetra_Map &range_partitioner () const DEAL_II_DEPRECATED;
968 
976  const Epetra_Map &row_partitioner () const DEAL_II_DEPRECATED;
977 
987  const Epetra_Map &col_partitioner () const DEAL_II_DEPRECATED;
988 
994  const Epetra_Comm &trilinos_communicator () const DEAL_II_DEPRECATED;
995 
999  MPI_Comm get_mpi_communicator () const;
1001 
1006 
1012  IndexSet locally_owned_domain_indices() const;
1013 
1019  IndexSet locally_owned_range_indices() const;
1020 
1022 
1027 
1031  const_iterator begin () const;
1032 
1036  const_iterator end () const;
1037 
1046  const_iterator begin (const size_type r) const;
1047 
1056  const_iterator end (const size_type r) const;
1057 
1059 
1063 
1069  void write_ascii ();
1070 
1078  void print (std::ostream &out,
1079  const bool write_extended_trilinos_info = false) const;
1080 
1095  void print_gnuplot (std::ostream &out) const;
1096 
1098 
1105  DeclException1 (ExcTrilinosError,
1106  int,
1107  << "An error with error number " << arg1
1108  << " occurred while calling a Trilinos function");
1109 
1113  DeclException2 (ExcInvalidIndex,
1114  size_type, size_type,
1115  << "The entry with index <" << arg1 << ',' << arg2
1116  << "> does not exist.");
1117 
1121  DeclException0 (ExcSourceEqualsDestination);
1122 
1126  DeclException4 (ExcAccessToNonLocalElement,
1127  size_type, size_type, size_type, size_type,
1128  << "You tried to access element (" << arg1
1129  << "/" << arg2 << ")"
1130  << " of a distributed matrix, but only rows "
1131  << arg3 << " through " << arg4
1132  << " are stored locally and can be accessed.");
1133 
1137  DeclException2 (ExcAccessToNonPresentElement,
1138  size_type, size_type,
1139  << "You tried to access element (" << arg1
1140  << "/" << arg2 << ")"
1141  << " of a sparse matrix, but it appears to not"
1142  << " exist in the Trilinos sparsity pattern.");
1144  private:
1145 
1150  std_cxx11::shared_ptr<Epetra_Map> column_space_map;
1151 
1157  std_cxx11::shared_ptr<Epetra_FECrsGraph> graph;
1158 
1165  std_cxx11::shared_ptr<Epetra_CrsGraph> nonlocal_graph;
1166 
1167  friend class SparseMatrix;
1168  friend class SparsityPatternIterators::Accessor;
1169  friend class SparsityPatternIterators::Iterator;
1170  };
1171 
1172 
1173 
1174 // -------------------------- inline and template functions ----------------------
1175 
1176 
1177 #ifndef DOXYGEN
1178 
1179  namespace SparsityPatternIterators
1180  {
1181 
1182  inline
1184  const size_type row,
1185  const size_type index)
1186  :
1187  sparsity_pattern(const_cast<SparsityPattern *>(sp)),
1188  a_row(row),
1189  a_index(index)
1190  {
1191  visit_present_row ();
1192  }
1193 
1194 
1195  inline
1196  Accessor::Accessor (const Accessor &a)
1197  :
1198  sparsity_pattern(a.sparsity_pattern),
1199  a_row(a.a_row),
1200  a_index(a.a_index),
1201  colnum_cache (a.colnum_cache)
1202  {}
1203 
1204 
1205  inline
1207  Accessor::row() const
1208  {
1209  Assert (a_row < sparsity_pattern->n_rows(), ExcBeyondEndOfSparsityPattern());
1210  return a_row;
1211  }
1212 
1213 
1214 
1215  inline
1217  Accessor::column() const
1218  {
1219  Assert (a_row < sparsity_pattern->n_rows(), ExcBeyondEndOfSparsityPattern());
1220  return (*colnum_cache)[a_index];
1221  }
1222 
1223 
1224 
1225  inline
1227  Accessor::index() const
1228  {
1229  Assert (a_row < sparsity_pattern->n_rows(), ExcBeyondEndOfSparsityPattern());
1230  return a_index;
1231  }
1232 
1233 
1234 
1235  inline
1237  const size_type row,
1238  const size_type index)
1239  :
1240  accessor(sp, row, index)
1241  {}
1242 
1243 
1244  inline
1245  Iterator::Iterator(const Iterator &i)
1246  :
1247  accessor(i.accessor)
1248  {}
1249 
1250 
1251 
1252  inline
1253  Iterator &
1255  {
1256  Assert (accessor.a_row < accessor.sparsity_pattern->n_rows(),
1257  ExcIteratorPastEnd());
1258 
1259  ++accessor.a_index;
1260 
1261  // If at end of line: do one
1262  // step, then cycle until we
1263  // find a row with a nonzero
1264  // number of entries.
1265  if (accessor.a_index >= accessor.colnum_cache->size())
1266  {
1267  accessor.a_index = 0;
1268  ++accessor.a_row;
1269 
1270  while ((accessor.a_row < accessor.sparsity_pattern->n_rows())
1271  &&
1272  (accessor.sparsity_pattern->row_length(accessor.a_row) == 0))
1273  ++accessor.a_row;
1274 
1275  accessor.visit_present_row();
1276  }
1277  return *this;
1278  }
1279 
1280 
1281 
1282  inline
1283  Iterator
1285  {
1286  const Iterator old_state = *this;
1287  ++(*this);
1288  return old_state;
1289  }
1290 
1291 
1292 
1293  inline
1294  const Accessor &
1295  Iterator::operator* () const
1296  {
1297  return accessor;
1298  }
1299 
1300 
1301 
1302  inline
1303  const Accessor *
1304  Iterator::operator-> () const
1305  {
1306  return &accessor;
1307  }
1308 
1309 
1310 
1311  inline
1312  bool
1313  Iterator::operator == (const Iterator &other) const
1314  {
1315  return (accessor.a_row == other.accessor.a_row &&
1316  accessor.a_index == other.accessor.a_index);
1317  }
1318 
1319 
1320 
1321  inline
1322  bool
1323  Iterator::operator != (const Iterator &other) const
1324  {
1325  return ! (*this == other);
1326  }
1327 
1328 
1329 
1330  inline
1331  bool
1332  Iterator::operator < (const Iterator &other) const
1333  {
1334  return (accessor.row() < other.accessor.row() ||
1335  (accessor.row() == other.accessor.row() &&
1336  accessor.index() < other.accessor.index()));
1337  }
1338 
1339  }
1340 
1341 
1342 
1343  inline
1345  SparsityPattern::begin() const
1346  {
1347  return const_iterator(this, 0, 0);
1348  }
1349 
1350 
1351 
1352  inline
1354  SparsityPattern::end() const
1355  {
1356  return const_iterator(this, n_rows(), 0);
1357  }
1358 
1359 
1360 
1361  inline
1363  SparsityPattern::begin(const size_type r) const
1364  {
1365  Assert (r < n_rows(), ExcIndexRangeType<size_type>(r, 0, n_rows()));
1366  if (row_length(r) > 0)
1367  return const_iterator(this, r, 0);
1368  else
1369  return end (r);
1370  }
1371 
1372 
1373 
1374  inline
1376  SparsityPattern::end(const size_type r) const
1377  {
1378  Assert (r < n_rows(), ExcIndexRangeType<size_type>(r, 0, n_rows()));
1379 
1380  // place the iterator on the first entry
1381  // past this line, or at the end of the
1382  // matrix
1383  for (size_type i=r+1; i<n_rows(); ++i)
1384  if (row_length(i) > 0)
1385  return const_iterator(this, i, 0);
1386 
1387  // if there is no such line, then take the
1388  // end iterator of the matrix
1389  return end();
1390  }
1391 
1392 
1393 
1394  inline
1395  bool
1396  SparsityPattern::in_local_range (const size_type index) const
1397  {
1398  TrilinosWrappers::types::int_type begin, end;
1399 #ifndef DEAL_II_WITH_64BIT_INDICES
1400  begin = graph->RowMap().MinMyGID();
1401  end = graph->RowMap().MaxMyGID()+1;
1402 #else
1403  begin = graph->RowMap().MinMyGID64();
1404  end = graph->RowMap().MaxMyGID64()+1;
1405 #endif
1406 
1407  return ((index >= static_cast<size_type>(begin)) &&
1408  (index < static_cast<size_type>(end)));
1409  }
1410 
1411 
1412 
1413  inline
1414  bool
1416  {
1417  return graph->Filled();
1418  }
1419 
1420 
1421 
1422  inline
1423  bool
1424  SparsityPattern::empty () const
1425  {
1426  return ((n_rows() == 0) && (n_cols() == 0));
1427  }
1428 
1429 
1430 
1431  inline
1432  void
1433  SparsityPattern::add (const size_type i,
1434  const size_type j)
1435  {
1436  add_entries (i, &j, &j+1);
1437  }
1438 
1439 
1440 
1441  template <typename ForwardIterator>
1442  inline
1443  void
1444  SparsityPattern::add_entries (const size_type row,
1445  ForwardIterator begin,
1446  ForwardIterator end,
1447  const bool /*indices_are_sorted*/)
1448  {
1449  if (begin == end)
1450  return;
1451 
1452  // verify that the size of the data type Trilinos expects matches that the
1453  // iterator points to. we allow for some slippage between signed and
1454  // unsigned and only compare that they are both either 32 or 64 bit. to
1455  // write this test properly, not that we cannot compare the size of
1456  // '*begin' because 'begin' may be an iterator and '*begin' may be an
1457  // accessor class. consequently, we need to somehow get an actual value
1458  // from it which we can by evaluating an expression such as when
1459  // multiplying the value produced by 2
1460  Assert (sizeof(TrilinosWrappers::types::int_type) ==
1461  sizeof((*begin)*2),
1462  ExcNotImplemented());
1463 
1464  TrilinosWrappers::types::int_type *col_index_ptr =
1465  (TrilinosWrappers::types::int_type *)(&*begin);
1466  const int n_cols = static_cast<int>(end - begin);
1467 
1468  int ierr;
1469  if ( graph->RowMap().LID(static_cast<TrilinosWrappers::types::int_type>(row)) != -1)
1470  ierr = graph->InsertGlobalIndices (row, n_cols, col_index_ptr);
1471  else if (nonlocal_graph.get() != 0)
1472  {
1473  // this is the case when we have explicitly set the off-processor rows
1474  // and want to create a separate matrix object for them (to retain
1475  // thread-safety)
1476  Assert (nonlocal_graph->RowMap().LID(static_cast<TrilinosWrappers::types::int_type>(row)) != -1,
1477  ExcMessage("Attempted to write into off-processor matrix row "
1478  "that has not be specified as being writable upon "
1479  "initialization"));
1480  ierr = nonlocal_graph->InsertGlobalIndices (row, n_cols, col_index_ptr);
1481  }
1482  else
1483  ierr = graph->InsertGlobalIndices
1484  (1, (TrilinosWrappers::types::int_type *)&row, n_cols, col_index_ptr);
1485 
1486  AssertThrow (ierr >= 0, ExcTrilinosError(ierr));
1487  }
1488 
1489 
1490 
1491  inline
1492  const Epetra_FECrsGraph &
1494  {
1495  return *graph;
1496  }
1497 
1498 
1499 
1500  inline
1501  IndexSet
1503  {
1504  return IndexSet(static_cast<const Epetra_Map &>(graph->DomainMap()));
1505  }
1506 
1507 
1508 
1509  inline
1510  IndexSet
1512  {
1513  return IndexSet(static_cast<const Epetra_Map &>(graph->RangeMap()));
1514  }
1515 
1516 #endif // DOXYGEN
1517 }
1518 
1519 
1520 DEAL_II_NAMESPACE_CLOSE
1521 
1522 
1523 #endif // DEAL_II_WITH_TRILINOS
1524 
1525 
1526 /*-------------------- trilinos_sparsity_pattern.h --------------------*/
1527 
1528 #endif
1529 /*-------------------- trilinos_sparsity_pattern.h --------------------*/
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:552
IndexSet locally_owned_range_indices() const
const Epetra_FECrsGraph & trilinos_sparsity_pattern() const
::ExceptionBase & ExcMessage(std::string arg1)
STL namespace.
#define AssertThrow(cond, exc)
Definition: exceptions.h:358
void add(const size_type i, const size_type j)
void add_entries(const size_type row, ForwardIterator begin, ForwardIterator end, const bool indices_are_sorted=false)
const_iterator begin() const
BlockDynamicSparsityPattern BlockCompressedSparsityPattern DEAL_II_DEPRECATED
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:542
std_cxx11::shared_ptr< const std::vector< size_type > > colnum_cache
#define Assert(cond, exc)
Definition: exceptions.h:294
const_iterator end() const
SparsityPatternIterators::Iterator const_iterator
Iterator(const SparsityPattern *sparsity_pattern, const size_type row, const size_type index)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:572
bool in_local_range(const size_type index) const
IndexSet locally_owned_domain_indices() const
DeclException3(ExcAccessToNonlocalRow, size_type, size_type, size_type,<< "You tried to access row "<< arg1<< " of a distributed sparsity pattern, "<< " but only rows "<< arg2<< " through "<< arg3<< " are stored locally and can be accessed.")
Accessor(const SparsityPattern *sparsity_pattern, const size_type row, const size_type index)