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 &parallel_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 &ndash; 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 &ndash; 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 &parallel_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      * &ndash; 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