1 // --------------------------------------------------------------------- 2 // 3 // Copyright (C) 2008 - 2020 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.md at 12 // the top level directory of deal.II. 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/index_set.h> 25 # include <deal.II/base/subscriptor.h> 26 27 # include <deal.II/lac/exceptions.h> 28 29 # include <Epetra_FECrsGraph.h> 30 # include <Epetra_Map.h> 31 32 # include <cmath> 33 # include <memory> 34 # include <vector> 35 # ifdef DEAL_II_WITH_MPI 36 # include <Epetra_MpiComm.h> 37 # include <mpi.h> 38 # else 39 # include <Epetra_SerialComm.h> 40 # endif 41 42 43 DEAL_II_NAMESPACE_OPEN 44 45 // forward declarations 46 # ifndef DOXYGEN 47 class SparsityPattern; 48 class DynamicSparsityPattern; 49 50 namespace TrilinosWrappers 51 { 52 class SparsityPattern; 53 class SparseMatrix; 54 55 namespace SparsityPatternIterators 56 { 57 class Iterator; 58 } 59 } // namespace TrilinosWrappers 60 # endif 61 62 namespace TrilinosWrappers 63 { 64 namespace SparsityPatternIterators 65 { 66 /** 67 * Accessor class for iterators into sparsity patterns. This class is also 68 * the base class for both const and non-const accessor classes into 69 * sparse matrices. 70 * 71 * Note that this class only allows read access to elements, providing 72 * their row and column number. It does not allow modifying the sparsity 73 * pattern itself. 74 * 75 * @ingroup TrilinosWrappers 76 */ 77 class Accessor 78 { 79 public: 80 /** 81 * Declare type for container size. 82 */ 83 using size_type = dealii::types::global_dof_index; 84 85 /** 86 * Constructor. 87 */ 88 Accessor(const SparsityPattern *sparsity_pattern, 89 const size_type row, 90 const size_type index); 91 92 /** 93 * Row number of the element represented by this object. 94 */ 95 size_type 96 row() const; 97 98 /** 99 * Index in row of the element represented by this object. 100 */ 101 size_type 102 index() const; 103 104 /** 105 * Column number of the element represented by this object. 106 */ 107 size_type 108 column() const; 109 110 /** 111 * Exception 112 */ 113 DeclException0(ExcBeyondEndOfSparsityPattern); 114 115 /** 116 * Exception 117 */ 118 DeclException3(ExcAccessToNonlocalRow, 119 size_type, 120 size_type, 121 size_type, 122 << "You tried to access row " << arg1 123 << " of a distributed sparsity pattern, " 124 << " but only rows " << arg2 << " through " << arg3 125 << " are stored locally and can be accessed."); 126 127 private: 128 /** 129 * The matrix accessed. 130 */ 131 mutable SparsityPattern *sparsity_pattern; 132 133 /** 134 * Current row number. 135 */ 136 size_type a_row; 137 138 /** 139 * Current index in row. 140 */ 141 size_type a_index; 142 143 /** 144 * Cache where we store the column indices of the present row. This is 145 * necessary, since Trilinos makes access to the elements of its 146 * matrices rather hard, and it is much more efficient to copy all 147 * column entries of a row once when we enter it than repeatedly asking 148 * Trilinos for individual ones. This also makes some sense since it is 149 * likely that we will access them sequentially anyway. 150 * 151 * In order to make copying of iterators/accessor of acceptable 152 * performance, we keep a shared pointer to these entries so that more 153 * than one accessor can access this data if necessary. 154 */ 155 std::shared_ptr<const std::vector<size_type>> colnum_cache; 156 157 /** 158 * Discard the old row caches (they may still be used by other 159 * accessors) and generate new ones for the row pointed to presently by 160 * this accessor. 161 */ 162 void 163 visit_present_row(); 164 165 // Make enclosing class a friend. 166 friend class Iterator; 167 }; 168 169 /** 170 * Iterator class for sparsity patterns of type 171 * TrilinosWrappers::SparsityPattern. Access to individual elements of the 172 * sparsity pattern is handled by the Accessor class in this namespace. 173 */ 174 class Iterator 175 { 176 public: 177 /** 178 * Declare type for container size. 179 */ 180 using size_type = dealii::types::global_dof_index; 181 182 /** 183 * Constructor. Create an iterator into the matrix @p matrix for the 184 * given row and the index within it. 185 */ 186 Iterator(const SparsityPattern *sparsity_pattern, 187 const size_type row, 188 const size_type index); 189 190 /** 191 * Copy constructor. 192 */ 193 Iterator(const Iterator &i); 194 195 /** 196 * Prefix increment. 197 */ 198 Iterator & 199 operator++(); 200 201 /** 202 * Postfix increment. 203 */ 204 Iterator 205 operator++(int); 206 207 /** 208 * Dereferencing operator. 209 */ 210 const Accessor &operator*() const; 211 212 /** 213 * Dereferencing operator. 214 */ 215 const Accessor *operator->() const; 216 217 /** 218 * Comparison. True, if both iterators point to the same matrix 219 * position. 220 */ 221 bool 222 operator==(const Iterator &) const; 223 224 /** 225 * Inverse of <tt>==</tt>. 226 */ 227 bool 228 operator!=(const Iterator &) const; 229 230 /** 231 * Comparison operator. Result is true if either the first row number is 232 * smaller or if the row numbers are equal and the first index is 233 * smaller. 234 */ 235 bool 236 operator<(const Iterator &) const; 237 238 /** 239 * Exception 240 */ 241 DeclException2(ExcInvalidIndexWithinRow, 242 size_type, 243 size_type, 244 << "Attempt to access element " << arg2 << " of row " 245 << arg1 << " which doesn't have that many elements."); 246 247 private: 248 /** 249 * Store an object of the accessor class. 250 */ 251 Accessor accessor; 252 253 friend class TrilinosWrappers::SparsityPattern; 254 }; 255 256 } // namespace SparsityPatternIterators 257 258 259 /** 260 * This class implements a wrapper class to use the Trilinos distributed 261 * sparsity pattern class Epetra_FECrsGraph. This class is designed to be 262 * used for construction of %parallel Trilinos matrices. The functionality 263 * of this class is modeled after the existing sparsity pattern classes, 264 * with the difference that this class can work fully in %parallel according 265 * to a partitioning of the sparsity pattern rows. 266 * 267 * This class has many similarities to the DynamicSparsityPattern, since it 268 * can dynamically add elements to the pattern without any memory being 269 * previously reserved for it. However, it also has a method 270 * SparsityPattern::compress(), that finalizes the pattern and enables its 271 * use with Trilinos sparse matrices. 272 * 273 * @ingroup TrilinosWrappers 274 * @ingroup Sparsity 275 */ 276 class SparsityPattern : public Subscriptor 277 { 278 public: 279 /** 280 * Declare type for container size. 281 */ 282 using size_type = dealii::types::global_dof_index; 283 284 /** 285 * Declare an alias for the iterator class. 286 */ 287 using const_iterator = SparsityPatternIterators::Iterator; 288 289 /** 290 * @name Basic constructors and initialization 291 */ 292 //@{ 293 /** 294 * Default constructor. Generates an empty (zero-size) sparsity pattern. 295 */ 296 SparsityPattern(); 297 298 /** 299 * Generate a sparsity pattern that is completely stored locally, having 300 * $m$ rows and $n$ columns. The resulting matrix will be completely 301 * stored locally, too. 302 * 303 * It is possible to specify the number of columns entries per row using 304 * the optional @p n_entries_per_row argument. However, this value does 305 * not need to be accurate or even given at all, since one does usually 306 * not have this kind of information before building the sparsity pattern 307 * (the usual case when the function DoFTools::make_sparsity_pattern() is 308 * called). The entries are allocated dynamically in a similar manner as 309 * for the deal.II DynamicSparsityPattern classes. However, a good 310 * estimate will reduce the setup time of the sparsity pattern. 311 */ 312 SparsityPattern(const size_type m, 313 const size_type n, 314 const size_type n_entries_per_row = 0); 315 316 /** 317 * Generate a sparsity pattern that is completely stored locally, having 318 * $m$ rows and $n$ columns. The resulting matrix will be completely 319 * stored locally, too. 320 * 321 * The vector <tt>n_entries_per_row</tt> specifies the number of entries 322 * in each row (an information usually not available, though). 323 */ 324 SparsityPattern(const size_type m, 325 const size_type n, 326 const std::vector<size_type> &n_entries_per_row); 327 328 /** 329 * Move constructor. Create a new sparse matrix by stealing the internal 330 * data. 331 */ 332 SparsityPattern(SparsityPattern &&other) noexcept; 333 334 /** 335 * Copy constructor. Sets the calling sparsity pattern to be the same as 336 * the input sparsity pattern. 337 */ 338 SparsityPattern(const SparsityPattern &input_sparsity_pattern); 339 340 /** 341 * Destructor. Made virtual so that one can use pointers to this class. 342 */ 343 virtual ~SparsityPattern() override = default; 344 345 /** 346 * Initialize a sparsity pattern that is completely stored locally, having 347 * $m$ rows and $n$ columns. The resulting matrix will be completely 348 * stored locally. 349 * 350 * The number of columns entries per row is specified as the maximum 351 * number of entries argument. This does not need to be an accurate 352 * number since the entries are allocated dynamically in a similar manner 353 * as for the deal.II DynamicSparsityPattern classes, but a good estimate 354 * will reduce the setup time of the sparsity pattern. 355 */ 356 void 357 reinit(const size_type m, 358 const size_type n, 359 const size_type n_entries_per_row = 0); 360 361 /** 362 * Initialize a sparsity pattern that is completely stored locally, having 363 * $m$ rows and $n$ columns. The resulting matrix will be completely 364 * stored locally. 365 * 366 * The vector <tt>n_entries_per_row</tt> specifies the number of entries 367 * in each row. 368 */ 369 void 370 reinit(const size_type m, 371 const size_type n, 372 const std::vector<size_type> &n_entries_per_row); 373 374 /** 375 * Copy function. Sets the calling sparsity pattern to be the same as the 376 * input sparsity pattern. 377 */ 378 void 379 copy_from(const SparsityPattern &input_sparsity_pattern); 380 381 /** 382 * Copy function from one of the deal.II sparsity patterns. If used in 383 * parallel, this function uses an ad-hoc partitioning of the rows and 384 * columns. 385 */ 386 template <typename SparsityPatternType> 387 void 388 copy_from(const SparsityPatternType &nontrilinos_sparsity_pattern); 389 390 /** 391 * Copy operator. This operation is only allowed for empty objects, to 392 * avoid potentially very costly operations automatically synthesized by 393 * the compiler. Use copy_from() instead if you know that you really want 394 * to copy a sparsity pattern with non-trivial content. 395 */ 396 SparsityPattern & 397 operator=(const SparsityPattern &input_sparsity_pattern); 398 399 /** 400 * Release all memory and return to a state just like after having called 401 * the default constructor. 402 * 403 * This is a collective operation that needs to be called on all 404 * processors in order to avoid a dead lock. 405 */ 406 void 407 clear(); 408 409 /** 410 * In analogy to our own SparsityPattern class, this function compresses 411 * the sparsity pattern and allows the resulting pattern to be used for 412 * actually generating a (Trilinos-based) matrix. This function also 413 * exchanges non-local data that might have accumulated during the 414 * addition of new elements. This function must therefore be called once 415 * the structure is fixed. This is a collective operation, i.e., it needs 416 * to be run on all processors when used in parallel. 417 */ 418 void 419 compress(); 420 //@} 421 422 /** 423 * @name Constructors and initialization using an IndexSet description 424 */ 425 //@{ 426 427 /** 428 * Constructor for a square sparsity pattern using an IndexSet and an MPI 429 * communicator for the description of the %parallel partitioning. 430 * Moreover, the number of nonzero entries in the rows of the sparsity 431 * pattern can be specified. Note that this number does not need to be 432 * exact, and it is even allowed that the actual sparsity structure has 433 * more nonzero entries than specified in the constructor. However it is 434 * still advantageous to provide good estimates here since a good value 435 * will avoid repeated allocation of memory, which considerably increases 436 * the performance when creating the sparsity pattern. 437 */ 438 SparsityPattern(const IndexSet ¶llel_partitioning, 439 const MPI_Comm &communicator = MPI_COMM_WORLD, 440 const size_type n_entries_per_row = 0); 441 442 /** 443 * Same as before, but now use the exact number of nonzeros in each m row. 444 * Since we know the number of elements in the sparsity pattern exactly in 445 * this case, we can already allocate the right amount of memory, which 446 * makes the creation process by the respective SparsityPattern::reinit 447 * call considerably faster. However, this is a rather unusual situation, 448 * since knowing the number of entries in each row is usually connected to 449 * knowing the indices of nonzero entries, which the sparsity pattern is 450 * designed to describe. 451 */ 452 SparsityPattern(const IndexSet & parallel_partitioning, 453 const MPI_Comm & communicator, 454 const std::vector<size_type> &n_entries_per_row); 455 456 /** 457 * This constructor is similar to the one above, but it now takes two 458 * different index sets to describe the %parallel partitioning of rows and 459 * columns. This interface is meant to be used for generating rectangular 460 * sparsity pattern. Note that there is no real parallelism along the 461 * columns – the processor that owns a certain row always owns all 462 * the column elements, no matter how far they might be spread out. The 463 * second Epetra_Map is only used to specify the number of columns and for 464 * internal arrangements when doing matrix-vector products with vectors 465 * based on that column map. 466 * 467 * The number of columns entries per row is specified as the maximum 468 * number of entries argument. 469 */ 470 SparsityPattern(const IndexSet &row_parallel_partitioning, 471 const IndexSet &col_parallel_partitioning, 472 const MPI_Comm &communicator = MPI_COMM_WORLD, 473 const size_type n_entries_per_row = 0); 474 475 /** 476 * This constructor is similar to the one above, but it now takes two 477 * different index sets for rows and columns. This interface is meant to 478 * be used for generating rectangular matrices, where one map specifies 479 * the %parallel distribution of rows and the second one specifies the 480 * distribution of degrees of freedom associated with matrix columns. This 481 * second map is however not used for the distribution of the columns 482 * themselves – rather, all column elements of a row are stored on 483 * the same processor. The vector <tt>n_entries_per_row</tt> specifies the 484 * number of entries in each row of the newly generated matrix. 485 */ 486 SparsityPattern(const IndexSet & row_parallel_partitioning, 487 const IndexSet & col_parallel_partitioning, 488 const MPI_Comm & communicator, 489 const std::vector<size_type> &n_entries_per_row); 490 491 /** 492 * This constructor constructs general sparsity patterns, possible non- 493 * square ones. Constructing a sparsity pattern this way allows the user 494 * to explicitly specify the rows into which we are going to add elements. 495 * This set is required to be a superset of the first index set @p 496 * row_parallel_partitioning that includes also rows that are owned by 497 * another processor (ghost rows). Note that elements can only be added to 498 * rows specified by @p writable_rows. 499 * 500 * This method is beneficial when the rows to which a processor is going 501 * to write can be determined before actually inserting elements into the 502 * matrix. For the typical parallel::distributed::Triangulation class used 503 * in deal.II, we know that a processor only will add row elements for 504 * what we call the locally relevant dofs (see 505 * DoFTools::extract_locally_relevant_dofs). The other constructors 506 * methods use general Trilinos facilities that allow to add elements to 507 * arbitrary rows (as done by all the other reinit functions). However, 508 * this flexibility come at a cost, the most prominent being that adding 509 * elements into the same matrix from multiple threads in shared memory is 510 * not safe whenever MPI is used. For these settings, the current method 511 * is the one to choose: It will store the off-processor data as an 512 * additional sparsity pattern (that is then passed to the Trilinos matrix 513 * via the reinit method) which can be organized in such a way that 514 * thread-safety can be ensured (as long as the user makes sure to never 515 * write into the same matrix row simultaneously, of course). 516 */ 517 SparsityPattern(const IndexSet &row_parallel_partitioning, 518 const IndexSet &col_parallel_partitioning, 519 const IndexSet &writable_rows, 520 const MPI_Comm &communicator = MPI_COMM_WORLD, 521 const size_type n_entries_per_row = 0); 522 523 /** 524 * Reinitialization function for generating a square sparsity pattern 525 * using an IndexSet and an MPI communicator for the description of the 526 * %parallel partitioning and the number of nonzero entries in the rows of 527 * the sparsity pattern. Note that this number does not need to be exact, 528 * and it is even allowed that the actual sparsity structure has more 529 * nonzero entries than specified in the constructor. However it is still 530 * advantageous to provide good estimates here since this will 531 * considerably increase the performance when creating the sparsity 532 * pattern. 533 * 534 * This function does not create any entries by itself, but provides the 535 * correct data structures that can be used by the respective add() 536 * function. 537 */ 538 void 539 reinit(const IndexSet ¶llel_partitioning, 540 const MPI_Comm &communicator = MPI_COMM_WORLD, 541 const size_type n_entries_per_row = 0); 542 543 /** 544 * Same as before, but now use the exact number of nonzeros in each m row. 545 * Since we know the number of elements in the sparsity pattern exactly in 546 * this case, we can already allocate the right amount of memory, which 547 * makes process of adding entries to the sparsity pattern considerably 548 * faster. However, this is a rather unusual situation, since knowing the 549 * number of entries in each row is usually connected to knowing the 550 * indices of nonzero entries, which the sparsity pattern is designed to 551 * describe. 552 */ 553 void 554 reinit(const IndexSet & parallel_partitioning, 555 const MPI_Comm & communicator, 556 const std::vector<size_type> &n_entries_per_row); 557 558 /** 559 * This reinit function is similar to the one above, but it now takes two 560 * different index sets for rows and columns. This interface is meant to 561 * be used for generating rectangular sparsity pattern, where one index 562 * set describes the %parallel partitioning of the dofs associated with 563 * the sparsity pattern rows and the other one of the sparsity pattern 564 * columns. Note that there is no real parallelism along the columns 565 * – the processor that owns a certain row always owns all the 566 * column elements, no matter how far they might be spread out. The second 567 * IndexSet is only used to specify the number of columns and for internal 568 * arrangements when doing matrix-vector products with vectors based on an 569 * EpetraMap based on that IndexSet. 570 * 571 * The number of columns entries per row is specified by the argument 572 * <tt>n_entries_per_row</tt>. 573 */ 574 void 575 reinit(const IndexSet &row_parallel_partitioning, 576 const IndexSet &col_parallel_partitioning, 577 const MPI_Comm &communicator = MPI_COMM_WORLD, 578 const size_type n_entries_per_row = 0); 579 580 /** 581 * This reinit function is used to specify general matrices, possibly non- 582 * square ones. In addition to the arguments of the other reinit method 583 * above, it allows the user to explicitly specify the rows into which we 584 * are going to add elements. This set is a superset of the first index 585 * set @p row_parallel_partitioning that includes also rows that are owned 586 * by another processor (ghost rows). 587 * 588 * This method is beneficial when the rows to which a processor is going 589 * to write can be determined before actually inserting elements into the 590 * matrix. For the typical parallel::distributed::Triangulation class used 591 * in deal.II, we know that a processor only will add row elements for 592 * what we call the locally relevant dofs (see 593 * DoFTools::extract_locally_relevant_dofs). Trilinos matrices allow to 594 * add elements to arbitrary rows (as done by all the other reinit 595 * functions) and this is what all the other reinit methods do, too. 596 * However, this flexibility come at a cost, the most prominent being that 597 * adding elements into the same matrix from multiple threads in shared 598 * memory is not safe whenever MPI is used. For these settings, the 599 * current method is the one to choose: It will store the off-processor 600 * data as an additional sparsity pattern (that is then passed to the 601 * Trilinos matrix via the reinit method) which can be organized in such a 602 * way that thread-safety can be ensured (as long as the user makes sure 603 * to never write into the same matrix row simultaneously, of course). 604 */ 605 void 606 reinit(const IndexSet &row_parallel_partitioning, 607 const IndexSet &col_parallel_partitioning, 608 const IndexSet &writeable_rows, 609 const MPI_Comm &communicator = MPI_COMM_WORLD, 610 const size_type n_entries_per_row = 0); 611 612 /** 613 * Same as before, but now using a vector <tt>n_entries_per_row</tt> for 614 * specifying the number of entries in each row of the sparsity pattern. 615 */ 616 void 617 reinit(const IndexSet & row_parallel_partitioning, 618 const IndexSet & col_parallel_partitioning, 619 const MPI_Comm & communicator, 620 const std::vector<size_type> &n_entries_per_row); 621 622 /** 623 * Reinit function. Takes one of the deal.II sparsity patterns and the 624 * %parallel partitioning of the rows and columns specified by two index 625 * sets and a %parallel communicator for initializing the current Trilinos 626 * sparsity pattern. The optional argument @p exchange_data can be used 627 * for reinitialization with a sparsity pattern that is not fully 628 * constructed. This feature is only implemented for input sparsity 629 * patterns of type DynamicSparsityPattern. 630 */ 631 template <typename SparsityPatternType> 632 void 633 reinit(const IndexSet & row_parallel_partitioning, 634 const IndexSet & col_parallel_partitioning, 635 const SparsityPatternType &nontrilinos_sparsity_pattern, 636 const MPI_Comm & communicator = MPI_COMM_WORLD, 637 const bool exchange_data = false); 638 639 /** 640 * Reinit function. Takes one of the deal.II sparsity patterns and a 641 * %parallel partitioning of the rows and columns for initializing the 642 * current Trilinos sparsity pattern. The optional argument @p 643 * exchange_data can be used for reinitialization with a sparsity pattern 644 * that is not fully constructed. This feature is only implemented for 645 * input sparsity patterns of type DynamicSparsityPattern. 646 */ 647 template <typename SparsityPatternType> 648 void 649 reinit(const IndexSet & parallel_partitioning, 650 const SparsityPatternType &nontrilinos_sparsity_pattern, 651 const MPI_Comm & communicator = MPI_COMM_WORLD, 652 const bool exchange_data = false); 653 //@} 654 /** 655 * @name Information on the sparsity pattern 656 */ 657 //@{ 658 659 /** 660 * Return the state of the sparsity pattern, i.e., whether compress() 661 * needs to be called after an operation requiring data exchange. 662 */ 663 bool 664 is_compressed() const; 665 666 /** 667 * Return the maximum number of entries per row on the current processor. 668 */ 669 unsigned int 670 max_entries_per_row() const; 671 672 /** 673 * Return the number of rows in this sparsity pattern. 674 */ 675 size_type 676 n_rows() const; 677 678 /** 679 * Return the number of columns in this sparsity pattern. 680 */ 681 size_type 682 n_cols() const; 683 684 /** 685 * Return the local dimension of the sparsity pattern, i.e. the number of 686 * rows stored on the present MPI process. In the sequential case, this 687 * number is the same as n_rows(), but for parallel matrices it may be 688 * smaller. 689 * 690 * To figure out which elements exactly are stored locally, use 691 * local_range(). 692 */ 693 unsigned int 694 local_size() const; 695 696 /** 697 * Return a pair of indices indicating which rows of this sparsity pattern 698 * are stored locally. The first number is the index of the first row 699 * stored, the second the index of the one past the last one that is 700 * stored locally. If this is a sequential matrix, then the result will be 701 * the pair (0,n_rows()), otherwise it will be a pair (i,i+n), where 702 * <tt>n=local_size()</tt>. 703 */ 704 std::pair<size_type, size_type> 705 local_range() const; 706 707 /** 708 * Return whether @p index is in the local range or not, see also 709 * local_range(). 710 */ 711 bool 712 in_local_range(const size_type index) const; 713 714 /** 715 * Return the number of nonzero elements of this sparsity pattern. 716 */ 717 size_type 718 n_nonzero_elements() const; 719 720 /** 721 * Return the number of entries in the given row. 722 * 723 * In a parallel context, the row in question may of course not be 724 * stored on the current processor, and in that case it is not 725 * possible to query the number of entries in it. In that case, 726 * the returned value is `static_cast<size_type>(-1)`. 727 */ 728 size_type 729 row_length(const size_type row) const; 730 731 /** 732 * Compute the bandwidth of the matrix represented by this structure. The 733 * bandwidth is the maximum of $|i-j|$ for which the index pair $(i,j)$ 734 * represents a nonzero entry of the matrix. Consequently, the maximum 735 * bandwidth a $n\times m$ matrix can have is $\max\{n-1,m-1\}$. 736 */ 737 size_type 738 bandwidth() const; 739 740 /** 741 * Return whether the object is empty. It is empty if no memory is 742 * allocated, which is the same as when both dimensions are zero. 743 */ 744 bool 745 empty() const; 746 747 /** 748 * Return whether the index (<i>i,j</i>) exists in the sparsity pattern 749 * (i.e., it may be non-zero) or not. 750 */ 751 bool 752 exists(const size_type i, const size_type j) const; 753 754 /** 755 * Return whether a given @p row is stored in the current object 756 * on this process. 757 */ 758 bool 759 row_is_stored_locally(const size_type i) const; 760 761 /** 762 * Determine an estimate for the memory consumption (in bytes) of this 763 * object. Currently not implemented for this class. 764 */ 765 std::size_t 766 memory_consumption() const; 767 768 //@} 769 /** 770 * @name Adding entries 771 */ 772 //@{ 773 /** 774 * Add the element (<i>i,j</i>) to the sparsity pattern. 775 */ 776 void 777 add(const size_type i, const size_type j); 778 779 780 /** 781 * Add several elements in one row to the sparsity pattern. 782 */ 783 template <typename ForwardIterator> 784 void 785 add_entries(const size_type row, 786 ForwardIterator begin, 787 ForwardIterator end, 788 const bool indices_are_sorted = false); 789 //@} 790 /** 791 * @name Access of underlying Trilinos data 792 */ 793 //@{ 794 795 /** 796 * Return a const reference to the underlying Trilinos Epetra_CrsGraph 797 * data that stores the sparsity pattern. 798 */ 799 const Epetra_FECrsGraph & 800 trilinos_sparsity_pattern() const; 801 802 /** 803 * Return a const reference to the underlying Trilinos Epetra_Map that 804 * sets the parallel partitioning of the domain space of this sparsity 805 * pattern, i.e., the partitioning of the vectors matrices based on this 806 * sparsity pattern are multiplied with. 807 */ 808 const Epetra_Map & 809 domain_partitioner() const; 810 811 /** 812 * Return a const reference to the underlying Trilinos Epetra_Map that 813 * sets the partitioning of the range space of this sparsity pattern, 814 * i.e., the partitioning of the vectors that are result from matrix- 815 * vector products. 816 */ 817 const Epetra_Map & 818 range_partitioner() const; 819 820 /** 821 * Return the MPI communicator object in use with this matrix. 822 */ 823 MPI_Comm 824 get_mpi_communicator() const; 825 //@} 826 827 /** 828 * @name Partitioners 829 */ 830 //@{ 831 832 /** 833 * Return the partitioning of the domain space of this pattern, i.e., the 834 * partitioning of the vectors a matrix based on this sparsity pattern has 835 * to be multiplied with. 836 */ 837 IndexSet 838 locally_owned_domain_indices() const; 839 840 /** 841 * Return the partitioning of the range space of this pattern, i.e., the 842 * partitioning of the vectors that are the result from matrix-vector 843 * products from a matrix based on this pattern. 844 */ 845 IndexSet 846 locally_owned_range_indices() const; 847 848 //@} 849 850 /** 851 * @name Iterators 852 */ 853 //@{ 854 855 /** 856 * Iterator starting at the first entry. 857 */ 858 const_iterator 859 begin() const; 860 861 /** 862 * Final iterator. 863 */ 864 const_iterator 865 end() const; 866 867 /** 868 * Iterator starting at the first entry of row @p r. 869 * 870 * Note that if the given row is empty, i.e. does not contain any nonzero 871 * entries, then the iterator returned by this function equals 872 * <tt>end(r)</tt>. Note also that the iterator may not be dereferenceable 873 * in that case. 874 */ 875 const_iterator 876 begin(const size_type r) const; 877 878 /** 879 * Final iterator of row <tt>r</tt>. It points to the first element past 880 * the end of line @p r, or past the end of the entire sparsity pattern. 881 * 882 * Note that the end iterator is not necessarily dereferenceable. This is 883 * in particular the case if it is the end iterator for the last row of a 884 * matrix. 885 */ 886 const_iterator 887 end(const size_type r) const; 888 889 //@} 890 /** 891 * @name Input/Output 892 */ 893 //@{ 894 895 /** 896 * Abstract Trilinos object that helps view in ASCII other Trilinos 897 * objects. Currently this function is not implemented. TODO: Not 898 * implemented. 899 */ 900 void 901 write_ascii(); 902 903 /** 904 * Print (the locally owned part of) the sparsity pattern to the given 905 * stream, using the format <tt>(line,col)</tt>. The optional flag outputs 906 * the sparsity pattern in Trilinos style, where even the according 907 * processor number is printed to the stream, as well as a summary before 908 * actually writing the entries. 909 */ 910 void 911 print(std::ostream &out, 912 const bool write_extended_trilinos_info = false) const; 913 914 /** 915 * Print the sparsity of the matrix in a format that <tt>gnuplot</tt> 916 * understands and which can be used to plot the sparsity pattern in a 917 * graphical way. The format consists of pairs <tt>i j</tt> of nonzero 918 * elements, each representing one entry of this matrix, one per line of 919 * the output file. Indices are counted from zero on, as usual. Since 920 * sparsity patterns are printed in the same way as matrices are 921 * displayed, we print the negative of the column index, which means that 922 * the <tt>(0,0)</tt> element is in the top left rather than in the bottom 923 * left corner. 924 * 925 * Print the sparsity pattern in gnuplot by setting the data style to dots 926 * or points and use the <tt>plot</tt> command. 927 */ 928 void 929 print_gnuplot(std::ostream &out) const; 930 931 //@} 932 /** 933 * @addtogroup Exceptions 934 * @{ 935 */ 936 /** 937 * Exception 938 */ 939 DeclException1(ExcTrilinosError, 940 int, 941 << "An error with error number " << arg1 942 << " occurred while calling a Trilinos function"); 943 944 /** 945 * Exception 946 */ 947 DeclException2(ExcInvalidIndex, 948 size_type, 949 size_type, 950 << "The entry with index <" << arg1 << ',' << arg2 951 << "> does not exist."); 952 953 /** 954 * Exception 955 */ 956 DeclExceptionMsg( 957 ExcSourceEqualsDestination, 958 "You are attempting an operation on two sparsity patterns that " 959 "are the same object, but the operation requires that the " 960 "two objects are in fact different."); 961 962 /** 963 * Exception 964 */ 965 DeclException4(ExcAccessToNonLocalElement, 966 size_type, 967 size_type, 968 size_type, 969 size_type, 970 << "You tried to access element (" << arg1 << "/" << arg2 971 << ")" 972 << " of a distributed matrix, but only rows " << arg3 973 << " through " << arg4 974 << " are stored locally and can be accessed."); 975 976 /** 977 * Exception 978 */ 979 DeclException2(ExcAccessToNonPresentElement, 980 size_type, 981 size_type, 982 << "You tried to access element (" << arg1 << "/" << arg2 983 << ")" 984 << " of a sparse matrix, but it appears to not" 985 << " exist in the Trilinos sparsity pattern."); 986 //@} 987 private: 988 /** 989 * Pointer to the user-supplied Epetra Trilinos mapping of the matrix 990 * columns that assigns parts of the matrix to the individual processes. 991 */ 992 std::unique_ptr<Epetra_Map> column_space_map; 993 994 /** 995 * A sparsity pattern object in Trilinos to be used for finite element 996 * based problems which allows for adding non-local elements to the 997 * pattern. 998 */ 999 std::unique_ptr<Epetra_FECrsGraph> graph; 1000 1001 /** 1002 * A sparsity pattern object for the non-local part of the sparsity 1003 * pattern that is going to be sent to the owning processor. Only used 1004 * when the particular constructor or reinit method with writable_rows 1005 * argument is set 1006 */ 1007 std::unique_ptr<Epetra_CrsGraph> nonlocal_graph; 1008 1009 friend class TrilinosWrappers::SparseMatrix; 1010 friend class SparsityPatternIterators::Accessor; 1011 friend class SparsityPatternIterators::Iterator; 1012 }; 1013 1014 1015 1016 // ----------------------- inline and template functions -------------------- 1017 1018 1019 # ifndef DOXYGEN 1020 1021 namespace SparsityPatternIterators 1022 { Accessor(const SparsityPattern * sp,const size_type row,const size_type index)1023 inline Accessor::Accessor(const SparsityPattern *sp, 1024 const size_type row, 1025 const size_type index) 1026 : sparsity_pattern(const_cast<SparsityPattern *>(sp)) 1027 , a_row(row) 1028 , a_index(index) 1029 { 1030 visit_present_row(); 1031 } 1032 1033 1034 1035 inline Accessor::size_type row()1036 Accessor::row() const 1037 { 1038 Assert(a_row < sparsity_pattern->n_rows(), 1039 ExcBeyondEndOfSparsityPattern()); 1040 return a_row; 1041 } 1042 1043 1044 1045 inline Accessor::size_type column()1046 Accessor::column() const 1047 { 1048 Assert(a_row < sparsity_pattern->n_rows(), 1049 ExcBeyondEndOfSparsityPattern()); 1050 return (*colnum_cache)[a_index]; 1051 } 1052 1053 1054 1055 inline Accessor::size_type index()1056 Accessor::index() const 1057 { 1058 Assert(a_row < sparsity_pattern->n_rows(), 1059 ExcBeyondEndOfSparsityPattern()); 1060 return a_index; 1061 } 1062 1063 1064 Iterator(const SparsityPattern * sp,const size_type row,const size_type index)1065 inline Iterator::Iterator(const SparsityPattern *sp, 1066 const size_type row, 1067 const size_type index) 1068 : accessor(sp, row, index) 1069 {} 1070 1071 1072 1073 inline Iterator::Iterator(const Iterator &) = default; 1074 1075 1076 1077 inline Iterator & 1078 Iterator::operator++() 1079 { 1080 Assert(accessor.a_row < accessor.sparsity_pattern->n_rows(), 1081 ExcIteratorPastEnd()); 1082 1083 ++accessor.a_index; 1084 1085 // If at end of line: do one step, then cycle until we find a row with a 1086 // nonzero number of entries that is stored locally. 1087 if (accessor.a_index >= accessor.colnum_cache->size()) 1088 { 1089 accessor.a_index = 0; 1090 ++accessor.a_row; 1091 1092 while (accessor.a_row < accessor.sparsity_pattern->n_rows()) 1093 { 1094 const auto row_length = 1095 accessor.sparsity_pattern->row_length(accessor.a_row); 1096 if (row_length == 0 || 1097 !accessor.sparsity_pattern->row_is_stored_locally( 1098 accessor.a_row)) 1099 ++accessor.a_row; 1100 else 1101 break; 1102 } 1103 1104 accessor.visit_present_row(); 1105 } 1106 return *this; 1107 } 1108 1109 1110 1111 inline Iterator 1112 Iterator::operator++(int) 1113 { 1114 const Iterator old_state = *this; 1115 ++(*this); 1116 return old_state; 1117 } 1118 1119 1120 1121 inline const Accessor &Iterator::operator*() const 1122 { 1123 return accessor; 1124 } 1125 1126 1127 1128 inline const Accessor *Iterator::operator->() const 1129 { 1130 return &accessor; 1131 } 1132 1133 1134 1135 inline bool 1136 Iterator::operator==(const Iterator &other) const 1137 { 1138 return (accessor.a_row == other.accessor.a_row && 1139 accessor.a_index == other.accessor.a_index); 1140 } 1141 1142 1143 1144 inline bool 1145 Iterator::operator!=(const Iterator &other) const 1146 { 1147 return !(*this == other); 1148 } 1149 1150 1151 1152 inline bool 1153 Iterator::operator<(const Iterator &other) const 1154 { 1155 return (accessor.row() < other.accessor.row() || 1156 (accessor.row() == other.accessor.row() && 1157 accessor.index() < other.accessor.index())); 1158 } 1159 1160 } // namespace SparsityPatternIterators 1161 1162 1163 1164 inline SparsityPattern::const_iterator begin()1165 SparsityPattern::begin() const 1166 { 1167 const size_type first_valid_row = this->local_range().first; 1168 return const_iterator(this, first_valid_row, 0); 1169 } 1170 1171 1172 1173 inline SparsityPattern::const_iterator end()1174 SparsityPattern::end() const 1175 { 1176 return const_iterator(this, n_rows(), 0); 1177 } 1178 1179 1180 1181 inline SparsityPattern::const_iterator begin(const size_type r)1182 SparsityPattern::begin(const size_type r) const 1183 { 1184 AssertIndexRange(r, n_rows()); 1185 if (row_length(r) > 0) 1186 return const_iterator(this, r, 0); 1187 else 1188 return end(r); 1189 } 1190 1191 1192 1193 inline SparsityPattern::const_iterator end(const size_type r)1194 SparsityPattern::end(const size_type r) const 1195 { 1196 AssertIndexRange(r, n_rows()); 1197 1198 // place the iterator on the first entry 1199 // past this line, or at the end of the 1200 // matrix 1201 for (size_type i = r + 1; i < n_rows(); ++i) 1202 if (row_length(i) > 0) 1203 return const_iterator(this, i, 0); 1204 1205 // if there is no such line, then take the 1206 // end iterator of the matrix 1207 return end(); 1208 } 1209 1210 1211 1212 inline bool in_local_range(const size_type index)1213 SparsityPattern::in_local_range(const size_type index) const 1214 { 1215 TrilinosWrappers::types::int_type begin, end; 1216 # ifndef DEAL_II_WITH_64BIT_INDICES 1217 begin = graph->RowMap().MinMyGID(); 1218 end = graph->RowMap().MaxMyGID() + 1; 1219 # else 1220 begin = graph->RowMap().MinMyGID64(); 1221 end = graph->RowMap().MaxMyGID64() + 1; 1222 # endif 1223 1224 return ((index >= static_cast<size_type>(begin)) && 1225 (index < static_cast<size_type>(end))); 1226 } 1227 1228 1229 1230 inline bool is_compressed()1231 SparsityPattern::is_compressed() const 1232 { 1233 return graph->Filled(); 1234 } 1235 1236 1237 1238 inline bool empty()1239 SparsityPattern::empty() const 1240 { 1241 return ((n_rows() == 0) && (n_cols() == 0)); 1242 } 1243 1244 1245 1246 inline void add(const size_type i,const size_type j)1247 SparsityPattern::add(const size_type i, const size_type j) 1248 { 1249 add_entries(i, &j, &j + 1); 1250 } 1251 1252 1253 1254 template <typename ForwardIterator> 1255 inline void add_entries(const size_type row,ForwardIterator begin,ForwardIterator end,const bool)1256 SparsityPattern::add_entries(const size_type row, 1257 ForwardIterator begin, 1258 ForwardIterator end, 1259 const bool /*indices_are_sorted*/) 1260 { 1261 if (begin == end) 1262 return; 1263 1264 // verify that the size of the data type Trilinos expects matches that the 1265 // iterator points to. we allow for some slippage between signed and 1266 // unsigned and only compare that they are both either 32 or 64 bit. to 1267 // write this test properly, not that we cannot compare the size of 1268 // '*begin' because 'begin' may be an iterator and '*begin' may be an 1269 // accessor class. consequently, we need to somehow get an actual value 1270 // from it which we can by evaluating an expression such as when 1271 // multiplying the value produced by 2 1272 Assert(sizeof(TrilinosWrappers::types::int_type) == sizeof((*begin) * 2), 1273 ExcNotImplemented()); 1274 1275 TrilinosWrappers::types::int_type *col_index_ptr = 1276 reinterpret_cast<TrilinosWrappers::types::int_type *>( 1277 const_cast<typename std::decay<decltype(*begin)>::type *>(&*begin)); 1278 // Check at least for the first index that the conversion actually works 1279 AssertDimension(*col_index_ptr, *begin); 1280 TrilinosWrappers::types::int_type trilinos_row_index = row; 1281 const int n_cols = static_cast<int>(end - begin); 1282 1283 int ierr; 1284 if (row_is_stored_locally(row)) 1285 ierr = 1286 graph->InsertGlobalIndices(trilinos_row_index, n_cols, col_index_ptr); 1287 else if (nonlocal_graph.get() != nullptr) 1288 { 1289 // this is the case when we have explicitly set the off-processor rows 1290 // and want to create a separate matrix object for them (to retain 1291 // thread-safety) 1292 Assert(nonlocal_graph->RowMap().LID( 1293 static_cast<TrilinosWrappers::types::int_type>(row)) != -1, 1294 ExcMessage("Attempted to write into off-processor matrix row " 1295 "that has not be specified as being writable upon " 1296 "initialization")); 1297 ierr = nonlocal_graph->InsertGlobalIndices(trilinos_row_index, 1298 n_cols, 1299 col_index_ptr); 1300 } 1301 else 1302 ierr = graph->InsertGlobalIndices(1, 1303 &trilinos_row_index, 1304 n_cols, 1305 col_index_ptr); 1306 1307 AssertThrow(ierr >= 0, ExcTrilinosError(ierr)); 1308 } 1309 1310 1311 1312 inline const Epetra_FECrsGraph & trilinos_sparsity_pattern()1313 SparsityPattern::trilinos_sparsity_pattern() const 1314 { 1315 return *graph; 1316 } 1317 1318 1319 1320 inline IndexSet locally_owned_domain_indices()1321 SparsityPattern::locally_owned_domain_indices() const 1322 { 1323 return IndexSet(graph->DomainMap()); 1324 } 1325 1326 1327 1328 inline IndexSet locally_owned_range_indices()1329 SparsityPattern::locally_owned_range_indices() const 1330 { 1331 return IndexSet(graph->RangeMap()); 1332 } 1333 1334 # endif // DOXYGEN 1335 } // namespace TrilinosWrappers 1336 1337 1338 DEAL_II_NAMESPACE_CLOSE 1339 1340 1341 # endif // DEAL_II_WITH_TRILINOS 1342 1343 1344 /*-------------------- trilinos_sparsity_pattern.h --------------------*/ 1345 1346 #endif 1347 /*-------------------- trilinos_sparsity_pattern.h --------------------*/ 1348