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_sparse_matrix_h
17 #  define dealii_trilinos_sparse_matrix_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 #    include <deal.II/lac/full_matrix.h>
29 #    include <deal.II/lac/trilinos_epetra_vector.h>
30 #    include <deal.II/lac/trilinos_index_access.h>
31 #    include <deal.II/lac/trilinos_tpetra_vector.h>
32 #    include <deal.II/lac/trilinos_vector.h>
33 #    include <deal.II/lac/vector_memory.h>
34 #    include <deal.II/lac/vector_operation.h>
35 
36 #    include <Epetra_Comm.h>
37 #    include <Epetra_CrsGraph.h>
38 #    include <Epetra_Export.h>
39 #    include <Epetra_FECrsMatrix.h>
40 #    include <Epetra_Map.h>
41 #    include <Epetra_MultiVector.h>
42 #    include <Epetra_Operator.h>
43 
44 #    include <cmath>
45 #    include <memory>
46 #    include <type_traits>
47 #    include <vector>
48 #    ifdef DEAL_II_WITH_MPI
49 #      include <Epetra_MpiComm.h>
50 #      include <mpi.h>
51 #    else
52 #      include <Epetra_SerialComm.h>
53 #    endif
54 
55 DEAL_II_NAMESPACE_OPEN
56 
57 // forward declarations
58 #    ifndef DOXYGEN
59 template <typename MatrixType>
60 class BlockMatrixBase;
61 
62 template <typename number>
63 class SparseMatrix;
64 class SparsityPattern;
65 class DynamicSparsityPattern;
66 
67 namespace TrilinosWrappers
68 {
69   class SparseMatrix;
70   class SparsityPattern;
71 
72   namespace SparseMatrixIterators
73   {
74     template <bool Constness>
75     class Iterator;
76   }
77 } // namespace TrilinosWrappers
78 #    endif
79 
80 namespace TrilinosWrappers
81 {
82   /**
83    * Iterators for Trilinos matrices
84    */
85   namespace SparseMatrixIterators
86   {
87     /**
88      * Exception
89      */
90     DeclException0(ExcBeyondEndOfMatrix);
91 
92     /**
93      * Exception
94      */
95     DeclException3(ExcAccessToNonlocalRow,
96                    std::size_t,
97                    std::size_t,
98                    std::size_t,
99                    << "You tried to access row " << arg1
100                    << " of a distributed sparsity pattern, "
101                    << " but only rows " << arg2 << " through " << arg3
102                    << " are stored locally and can be accessed.");
103 
104     /**
105      * Handling of indices for both constant and non constant Accessor objects
106      *
107      * For a regular dealii::SparseMatrix, we would use an accessor for the
108      * sparsity pattern. For Trilinos matrices, this does not seem so simple,
109      * therefore, we write a little base class here.
110      */
111     class AccessorBase
112     {
113     public:
114       /**
115        * Declare the type for container size.
116        */
117       using size_type = dealii::types::global_dof_index;
118 
119       /**
120        * Constructor.
121        */
122       AccessorBase(SparseMatrix *  matrix,
123                    const size_type row,
124                    const size_type index);
125 
126       /**
127        * Row number of the element represented by this object.
128        */
129       size_type
130       row() const;
131 
132       /**
133        * Index in row of the element represented by this object.
134        */
135       size_type
136       index() const;
137 
138       /**
139        * Column number of the element represented by this object.
140        */
141       size_type
142       column() const;
143 
144     protected:
145       /**
146        * Pointer to the matrix object. This object should be handled as a
147        * const pointer or non-const by the appropriate derived classes. In
148        * order to be able to implement both, it is not const here, so handle
149        * with care!
150        */
151       mutable SparseMatrix *matrix;
152       /**
153        * Current row number.
154        */
155       size_type a_row;
156 
157       /**
158        * Current index in row.
159        */
160       size_type a_index;
161 
162       /**
163        * Discard the old row caches (they may still be used by other
164        * accessors) and generate new ones for the row pointed to presently by
165        * this accessor.
166        */
167       void
168       visit_present_row();
169 
170       /**
171        * Cache where we store the column indices of the present row. This is
172        * necessary, since Trilinos makes access to the elements of its
173        * matrices rather hard, and it is much more efficient to copy all
174        * column entries of a row once when we enter it than repeatedly asking
175        * Trilinos for individual ones. This also makes some sense since it is
176        * likely that we will access them sequentially anyway.
177        *
178        * In order to make copying of iterators/accessor of acceptable
179        * performance, we keep a shared pointer to these entries so that more
180        * than one accessor can access this data if necessary.
181        */
182       std::shared_ptr<std::vector<size_type>> colnum_cache;
183 
184       /**
185        * Cache for the values of this row.
186        */
187       std::shared_ptr<std::vector<TrilinosScalar>> value_cache;
188     };
189 
190     /**
191      * General template for sparse matrix accessors. The first template
192      * argument denotes the underlying numeric type, the second the constness
193      * of the matrix.
194      *
195      * The general template is not implemented, only the specializations for
196      * the two possible values of the second template argument. Therefore, the
197      * interface listed here only serves as a template provided since doxygen
198      * does not link the specializations.
199      */
200     template <bool Constess>
201     class Accessor : public AccessorBase
202     {
203       /**
204        * Value of this matrix entry.
205        */
206       TrilinosScalar
207       value() const;
208 
209       /**
210        * Value of this matrix entry.
211        */
212       TrilinosScalar &
213       value();
214     };
215 
216     /**
217      * The specialization for a const Accessor.
218      */
219     template <>
220     class Accessor<true> : public AccessorBase
221     {
222     public:
223       /**
224        * Typedef for the type (including constness) of the matrix to be used
225        * here.
226        */
227       using MatrixType = const SparseMatrix;
228 
229       /**
230        * Constructor. Since we use accessors only for read access, a const
231        * matrix pointer is sufficient.
232        */
233       Accessor(MatrixType *matrix, const size_type row, const size_type index);
234 
235       /**
236        * Copy constructor to get from a const or non-const accessor to a const
237        * accessor.
238        */
239       template <bool Other>
240       Accessor(const Accessor<Other> &a);
241 
242       /**
243        * Value of this matrix entry.
244        */
245       TrilinosScalar
246       value() const;
247 
248     private:
249       // Make iterator class a friend.
250       template <bool>
251       friend class Iterator;
252     };
253 
254     /**
255      * The specialization for a mutable Accessor.
256      */
257     template <>
258     class Accessor<false> : public AccessorBase
259     {
260       class Reference
261       {
262       public:
263         /**
264          * Constructor.
265          */
266         Reference(const Accessor<false> &accessor);
267 
268         /**
269          * Conversion operator to the data type of the matrix.
270          */
271         operator TrilinosScalar() const;
272 
273         /**
274          * Set the element of the matrix we presently point to to @p n.
275          */
276         const Reference &
277         operator=(const TrilinosScalar n) const;
278 
279         /**
280          * Add @p n to the element of the matrix we presently point to.
281          */
282         const Reference &
283         operator+=(const TrilinosScalar n) const;
284 
285         /**
286          * Subtract @p n from the element of the matrix we presently point to.
287          */
288         const Reference &
289         operator-=(const TrilinosScalar n) const;
290 
291         /**
292          * Multiply the element of the matrix we presently point to by @p n.
293          */
294         const Reference &
295         operator*=(const TrilinosScalar n) const;
296 
297         /**
298          * Divide the element of the matrix we presently point to by @p n.
299          */
300         const Reference &
301         operator/=(const TrilinosScalar n) const;
302 
303       private:
304         /**
305          * Pointer to the accessor that denotes which element we presently
306          * point to.
307          */
308         Accessor &accessor;
309       };
310 
311     public:
312       /**
313        * Typedef for the type (including constness) of the matrix to be used
314        * here.
315        */
316       using MatrixType = SparseMatrix;
317 
318       /**
319        * Constructor. Since we use accessors only for read access, a const
320        * matrix pointer is sufficient.
321        */
322       Accessor(MatrixType *matrix, const size_type row, const size_type index);
323 
324       /**
325        * Value of this matrix entry.
326        */
327       Reference
328       value() const;
329 
330     private:
331       // Make iterator class a friend.
332       template <bool>
333       friend class Iterator;
334 
335       // Make Reference object a friend.
336       friend class Reference;
337     };
338 
339     /**
340      * This class acts as an iterator walking over the elements of Trilinos
341      * matrices. The implementation of this class is similar to the one for
342      * PETSc matrices.
343      *
344      * Note that Trilinos stores the elements within each row in ascending
345      * order. This is opposed to the deal.II sparse matrix style where the
346      * diagonal element (if it exists) is stored before all other values, and
347      * the PETSc sparse matrices, where one can't guarantee a certain order of
348      * the elements.
349      *
350      * @ingroup TrilinosWrappers
351      */
352     template <bool Constness>
353     class Iterator
354     {
355     public:
356       /**
357        * Declare type for container size.
358        */
359       using size_type = dealii::types::global_dof_index;
360 
361       /**
362        * Typedef for the matrix type (including constness) we are to operate
363        * on.
364        */
365       using MatrixType = typename Accessor<Constness>::MatrixType;
366 
367       /**
368        * Constructor. Create an iterator into the matrix @p matrix for the
369        * given row and the index within it.
370        */
371       Iterator(MatrixType *matrix, const size_type row, const size_type index);
372 
373       /**
374        * Copy constructor with optional change of constness.
375        */
376       template <bool Other>
377       Iterator(const Iterator<Other> &other);
378 
379       /**
380        * Prefix increment.
381        */
382       Iterator<Constness> &
383       operator++();
384 
385       /**
386        * Postfix increment.
387        */
388       Iterator<Constness>
389       operator++(int);
390 
391       /**
392        * Dereferencing operator.
393        */
394       const Accessor<Constness> &operator*() const;
395 
396       /**
397        * Dereferencing operator.
398        */
399       const Accessor<Constness> *operator->() const;
400 
401       /**
402        * Comparison. True, if both iterators point to the same matrix
403        * position.
404        */
405       bool
406       operator==(const Iterator<Constness> &) const;
407 
408       /**
409        * Inverse of <tt>==</tt>.
410        */
411       bool
412       operator!=(const Iterator<Constness> &) const;
413 
414       /**
415        * Comparison operator. Result is true if either the first row number is
416        * smaller or if the row numbers are equal and the first index is
417        * smaller.
418        */
419       bool
420       operator<(const Iterator<Constness> &) const;
421 
422       /**
423        * Comparison operator. The opposite of the previous operator
424        */
425       bool
426       operator>(const Iterator<Constness> &) const;
427 
428       /**
429        * Exception
430        */
431       DeclException2(ExcInvalidIndexWithinRow,
432                      size_type,
433                      size_type,
434                      << "Attempt to access element " << arg2 << " of row "
435                      << arg1 << " which doesn't have that many elements.");
436 
437     private:
438       /**
439        * Store an object of the accessor class.
440        */
441       Accessor<Constness> accessor;
442 
443       template <bool Other>
444       friend class Iterator;
445     };
446 
447   } // namespace SparseMatrixIterators
448 
449 
450   /**
451    * This class implements a wrapper to use the Trilinos distributed sparse
452    * matrix class Epetra_FECrsMatrix. This is precisely the kind of matrix we
453    * deal with all the time - we most likely get it from some assembly
454    * process, where also entries not locally owned might need to be written
455    * and hence need to be forwarded to the owner process.  This class is
456    * designed to be used in a distributed memory architecture with an MPI
457    * compiler on the bottom, but works equally well also for serial processes.
458    * The only requirement for this class to work is that Trilinos has been
459    * installed with the same compiler as is used for generating deal.II.
460    *
461    * The interface of this class is modeled after the existing SparseMatrix
462    * class in deal.II. It has almost the same member functions, and is often
463    * exchangeable. However, since Trilinos only supports a single scalar type
464    * (double), it is not templated, and only works with doubles.
465    *
466    * Note that Trilinos only guarantees that operations do what you expect if
467    * the functions @p GlobalAssemble has been called after matrix assembly.
468    * Therefore, you need to call SparseMatrix::compress() before you actually
469    * use the matrix. This also calls @p FillComplete that compresses the
470    * storage format for sparse matrices by discarding unused elements.
471    * Trilinos allows to continue with assembling the matrix after calls to
472    * these functions, though.
473    *
474    * <h3>Thread safety of Trilinos matrices</h3>
475    *
476    * When writing into Trilinos matrices from several threads in shared
477    * memory, several things must be kept in mind as there is no built-in locks
478    * in this class to prevent data races. Simultaneous access to the same
479    * matrix row at the same time can lead to data races and must be explicitly
480    * avoided by the user. However, it is possible to access <b>different</b>
481    * rows of the matrix from several threads simultaneously under the
482    * following three conditions:
483    * <ul>
484    * <li> The matrix uses only one MPI process.
485    * <li> The matrix has been initialized with the reinit() method with a
486    * DynamicSparsityPattern (that includes the set of locally relevant rows,
487    * i.e., the rows that an assembly routine will possibly write into).
488    * <li> The matrix has been initialized from a
489    * TrilinosWrappers::SparsityPattern object that in turn has been
490    * initialized with the reinit function specifying three index sets, one for
491    * the rows, one for the columns and for the larger set of @p
492    * writeable_rows, and the operation is an addition. At some point in the
493    * future, Trilinos support might be complete enough such that initializing
494    * from a TrilinosWrappers::SparsityPattern that has been filled by a
495    * function similar to DoFTools::make_sparsity_pattern always results in a
496    * matrix that allows several processes to write into the same matrix row.
497    * However, Trilinos until version at least 11.12 does not correctly support
498    * this feature.
499    * </ul>
500    *
501    * Note that all other reinit methods and constructors of
502    * TrilinosWrappers::SparsityPattern will result in a matrix that needs to
503    * allocate off-processor entries on demand, which breaks thread-safety. Of
504    * course, using the respective reinit method for the block Trilinos
505    * sparsity pattern and block matrix also results in thread-safety.
506    *
507    * @ingroup TrilinosWrappers
508    * @ingroup Matrix1
509    */
510   class SparseMatrix : public Subscriptor
511   {
512   public:
513     /**
514      * Declare the type for container size.
515      */
516     using size_type = dealii::types::global_dof_index;
517 
518     /**
519      * Exception
520      */
521     DeclException1(ExcAccessToNonlocalRow,
522                    std::size_t,
523                    << "You tried to access row " << arg1
524                    << " of a non-contiguous locally owned row set."
525                    << " The row " << arg1
526                    << " is not stored locally and can't be accessed.");
527 
528     /**
529      * A structure that describes some of the traits of this class in terms of
530      * its run-time behavior. Some other classes (such as the block matrix
531      * classes) that take one or other of the matrix classes as its template
532      * parameters can tune their behavior based on the variables in this
533      * class.
534      */
535     struct Traits
536     {
537       /**
538        * It is safe to elide additions of zeros to individual elements of this
539        * matrix.
540        */
541       static const bool zero_addition_can_be_elided = true;
542     };
543 
544     /**
545      * Declare an alias for the iterator class.
546      */
547     using iterator = SparseMatrixIterators::Iterator<false>;
548 
549     /**
550      * Declare an alias for the const iterator class.
551      */
552     using const_iterator = SparseMatrixIterators::Iterator<true>;
553 
554     /**
555      * Declare an alias in analogy to all the other container classes.
556      */
557     using value_type = TrilinosScalar;
558 
559     /**
560      * @name Constructors and initialization.
561      */
562     //@{
563     /**
564      * Default constructor. Generates an empty (zero-size) matrix.
565      */
566     SparseMatrix();
567 
568     /**
569      * Generate a matrix that is completely stored locally, having #m rows and
570      * #n columns.
571      *
572      * The number of columns entries per row is specified as the maximum
573      * number of entries argument.
574      */
575     SparseMatrix(const size_type    m,
576                  const size_type    n,
577                  const unsigned int n_max_entries_per_row);
578 
579     /**
580      * Generate a matrix that is completely stored locally, having #m rows and
581      * #n columns.
582      *
583      * The vector <tt>n_entries_per_row</tt> specifies the number of entries
584      * in each row.
585      */
586     SparseMatrix(const size_type                  m,
587                  const size_type                  n,
588                  const std::vector<unsigned int> &n_entries_per_row);
589 
590     /**
591      * Generate a matrix from a Trilinos sparsity pattern object.
592      */
593     SparseMatrix(const SparsityPattern &InputSparsityPattern);
594 
595     /**
596      * Move constructor. Create a new sparse matrix by stealing the internal
597      * data.
598      */
599     SparseMatrix(SparseMatrix &&other) noexcept;
600 
601     /**
602      * Copy constructor is deleted.
603      */
604     SparseMatrix(const SparseMatrix &) = delete;
605 
606     /**
607      * operator= is deleted.
608      */
609     SparseMatrix &
610     operator=(const SparseMatrix &) = delete;
611 
612     /**
613      * Destructor. Made virtual so that one can use pointers to this class.
614      */
615     virtual ~SparseMatrix() override = default;
616 
617     /**
618      * This function initializes the Trilinos matrix with a deal.II sparsity
619      * pattern, i.e. it makes the Trilinos Epetra matrix know the position of
620      * nonzero entries according to the sparsity pattern. This function is
621      * meant for use in serial programs, where there is no need to specify how
622      * the matrix is going to be distributed among different processors. This
623      * function works in %parallel, too, but it is recommended to manually
624      * specify the %parallel partitioning of the matrix using an Epetra_Map.
625      * When run in %parallel, it is currently necessary that each processor
626      * holds the sparsity_pattern structure because each processor sets its
627      * rows.
628      *
629      * This is a collective operation that needs to be called on all
630      * processors in order to avoid a dead lock.
631      */
632     template <typename SparsityPatternType>
633     void
634     reinit(const SparsityPatternType &sparsity_pattern);
635 
636     /**
637      * This function reinitializes the Trilinos sparse matrix from a (possibly
638      * distributed) Trilinos sparsity pattern.
639      *
640      * This is a collective operation that needs to be called on all
641      * processors in order to avoid a dead lock.
642      *
643      * If you want to write to the matrix from several threads and use MPI,
644      * you need to use this reinit method with a sparsity pattern that has
645      * been created with explicitly stating writeable rows. In all other
646      * cases, you cannot mix MPI with multithreaded writing into the matrix.
647      */
648     void
649     reinit(const SparsityPattern &sparsity_pattern);
650 
651     /**
652      * This function copies the layout of @p sparse_matrix to the calling
653      * matrix. The values are not copied, but you can use copy_from() for
654      * this.
655      *
656      * This is a collective operation that needs to be called on all
657      * processors in order to avoid a dead lock.
658      */
659     void
660     reinit(const SparseMatrix &sparse_matrix);
661 
662     /**
663      * This function initializes the Trilinos matrix using the deal.II sparse
664      * matrix and the entries stored therein. It uses a threshold to copy only
665      * elements with modulus larger than the threshold (so zeros in the
666      * deal.II matrix can be filtered away).
667      *
668      * The optional parameter <tt>copy_values</tt> decides whether only the
669      * sparsity structure of the input matrix should be used or the matrix
670      * entries should be copied, too.
671      *
672      * This is a collective operation that needs to be called on all
673      * processors in order to avoid a deadlock.
674      *
675      * @note If a different sparsity pattern is given in the last argument
676      * (i.e., one that differs from the one used in the sparse matrix given in
677      * the first argument), then the resulting Trilinos matrix will have the
678      * sparsity pattern so given. This of course also means that all entries
679      * in the given matrix that are not part of this separate sparsity pattern
680      * will in fact be dropped.
681      */
682     template <typename number>
683     void
684     reinit(const ::dealii::SparseMatrix<number> &dealii_sparse_matrix,
685            const double                          drop_tolerance    = 1e-13,
686            const bool                            copy_values       = true,
687            const ::dealii::SparsityPattern *     use_this_sparsity = nullptr);
688 
689     /**
690      * This reinit function takes as input a Trilinos Epetra_CrsMatrix and
691      * copies its sparsity pattern. If so requested, even the content (values)
692      * will be copied.
693      */
694     void
695     reinit(const Epetra_CrsMatrix &input_matrix, const bool copy_values = true);
696     //@}
697 
698     /**
699      * @name Constructors and initialization using an IndexSet description
700      */
701     //@{
702     /**
703      * Constructor using an IndexSet and an MPI communicator to describe the
704      * %parallel partitioning. The parameter @p n_max_entries_per_row sets the
705      * number of nonzero entries in each row that will be allocated. Note that
706      * this number does not need to be exact, and it is even allowed that the
707      * actual matrix structure has more nonzero entries than specified in the
708      * constructor. However it is still advantageous to provide good estimates
709      * here since this will considerably increase the performance of the
710      * matrix setup. However, there is no effect in the performance of matrix-
711      * vector products, since Trilinos reorganizes the matrix memory prior to
712      * use (in the compress() step).
713      */
714     SparseMatrix(const IndexSet &   parallel_partitioning,
715                  const MPI_Comm &   communicator          = MPI_COMM_WORLD,
716                  const unsigned int n_max_entries_per_row = 0);
717 
718     /**
719      * Same as before, but now set the number of nonzeros in each matrix row
720      * separately. Since we know the number of elements in the matrix exactly
721      * in this case, we can already allocate the right amount of memory, which
722      * makes the creation process including the insertion of nonzero elements
723      * by the respective SparseMatrix::reinit call considerably faster.
724      */
725     SparseMatrix(const IndexSet &                 parallel_partitioning,
726                  const MPI_Comm &                 communicator,
727                  const std::vector<unsigned int> &n_entries_per_row);
728 
729     /**
730      * This constructor is similar to the one above, but it now takes two
731      * different IndexSet partitions for row and columns. This interface is
732      * meant to be used for generating rectangular matrices, where the first
733      * index set describes the %parallel partitioning of the degrees of
734      * freedom associated with the matrix rows and the second one the
735      * partitioning of the matrix columns. The second index set specifies the
736      * partitioning of the vectors this matrix is to be multiplied with, not
737      * the distribution of the elements that actually appear in the matrix.
738      *
739      * The parameter @p n_max_entries_per_row defines how much memory will be
740      * allocated for each row. This number does not need to be accurate, as
741      * the structure is reorganized in the compress() call.
742      */
743     SparseMatrix(const IndexSet &row_parallel_partitioning,
744                  const IndexSet &col_parallel_partitioning,
745                  const MPI_Comm &communicator          = MPI_COMM_WORLD,
746                  const size_type n_max_entries_per_row = 0);
747 
748     /**
749      * This constructor is similar to the one above, but it now takes two
750      * different Epetra maps for rows and columns. This interface is meant to
751      * be used for generating rectangular matrices, where one map specifies
752      * the %parallel distribution of degrees of freedom associated with matrix
753      * rows and the second one specifies the %parallel distribution the dofs
754      * associated with columns in the matrix. The second map also provides
755      * information for the internal arrangement in matrix vector products
756      * (i.e., the distribution of vector this matrix is to be multiplied
757      * with), but is not used for the distribution of the columns &ndash;
758      * rather, all column elements of a row are stored on the same processor
759      * in any case. The vector <tt>n_entries_per_row</tt> specifies the number
760      * of entries in each row of the newly generated matrix.
761      */
762     SparseMatrix(const IndexSet &                 row_parallel_partitioning,
763                  const IndexSet &                 col_parallel_partitioning,
764                  const MPI_Comm &                 communicator,
765                  const std::vector<unsigned int> &n_entries_per_row);
766 
767     /**
768      * This function is initializes the Trilinos Epetra matrix according to
769      * the specified sparsity_pattern, and also reassigns the matrix rows to
770      * different processes according to a user-supplied index set and
771      * %parallel communicator. In programs following the style of the tutorial
772      * programs, this function (and the respective call for a rectangular
773      * matrix) are the natural way to initialize the matrix size, its
774      * distribution among the MPI processes (if run in %parallel) as well as
775      * the location of non-zero elements. Trilinos stores the sparsity pattern
776      * internally, so it won't be needed any more after this call, in contrast
777      * to the deal.II own object. The optional argument @p exchange_data can
778      * be used for reinitialization with a sparsity pattern that is not fully
779      * constructed. This feature is only implemented for input sparsity
780      * patterns of type DynamicSparsityPattern. If the flag is not set, each
781      * processor just sets the elements in the sparsity pattern that belong to
782      * its rows.
783      *
784      * This is a collective operation that needs to be called on all
785      * processors in order to avoid a dead lock.
786      */
787     template <typename SparsityPatternType>
788     void
789     reinit(const IndexSet &           parallel_partitioning,
790            const SparsityPatternType &sparsity_pattern,
791            const MPI_Comm &           communicator  = MPI_COMM_WORLD,
792            const bool                 exchange_data = false);
793 
794     /**
795      * This function is similar to the other initialization function above,
796      * but now also reassigns the matrix rows and columns according to two
797      * user-supplied index sets.  To be used for rectangular matrices. The
798      * optional argument @p exchange_data can be used for reinitialization
799      * with a sparsity pattern that is not fully constructed. This feature is
800      * only implemented for input sparsity patterns of type
801      * DynamicSparsityPattern.
802      *
803      * This is a collective operation that needs to be called on all
804      * processors in order to avoid a dead lock.
805      */
806     template <typename SparsityPatternType>
807     typename std::enable_if<
808       !std::is_same<SparsityPatternType,
809                     dealii::SparseMatrix<double>>::value>::type
810     reinit(const IndexSet &           row_parallel_partitioning,
811            const IndexSet &           col_parallel_partitioning,
812            const SparsityPatternType &sparsity_pattern,
813            const MPI_Comm &           communicator  = MPI_COMM_WORLD,
814            const bool                 exchange_data = false);
815 
816     /**
817      * This function initializes the Trilinos matrix using the deal.II sparse
818      * matrix and the entries stored therein. It uses a threshold to copy only
819      * elements with modulus larger than the threshold (so zeros in the
820      * deal.II matrix can be filtered away). In contrast to the other reinit
821      * function with deal.II sparse matrix argument, this function takes a
822      * %parallel partitioning specified by the user instead of internally
823      * generating it.
824      *
825      * The optional parameter <tt>copy_values</tt> decides whether only the
826      * sparsity structure of the input matrix should be used or the matrix
827      * entries should be copied, too.
828      *
829      * This is a collective operation that needs to be called on all
830      * processors in order to avoid a dead lock.
831      */
832     template <typename number>
833     void
834     reinit(const IndexSet &                      parallel_partitioning,
835            const ::dealii::SparseMatrix<number> &dealii_sparse_matrix,
836            const MPI_Comm &                      communicator = MPI_COMM_WORLD,
837            const double                          drop_tolerance    = 1e-13,
838            const bool                            copy_values       = true,
839            const ::dealii::SparsityPattern *     use_this_sparsity = nullptr);
840 
841     /**
842      * This function is similar to the other initialization function with
843      * deal.II sparse matrix input above, but now takes index sets for both
844      * the rows and the columns of the matrix. Chosen for rectangular
845      * matrices.
846      *
847      * The optional parameter <tt>copy_values</tt> decides whether only the
848      * sparsity structure of the input matrix should be used or the matrix
849      * entries should be copied, too.
850      *
851      * This is a collective operation that needs to be called on all
852      * processors in order to avoid a dead lock.
853      */
854     template <typename number>
855     void
856     reinit(const IndexSet &                      row_parallel_partitioning,
857            const IndexSet &                      col_parallel_partitioning,
858            const ::dealii::SparseMatrix<number> &dealii_sparse_matrix,
859            const MPI_Comm &                      communicator = MPI_COMM_WORLD,
860            const double                          drop_tolerance    = 1e-13,
861            const bool                            copy_values       = true,
862            const ::dealii::SparsityPattern *     use_this_sparsity = nullptr);
863     //@}
864     /**
865      * @name Information on the matrix
866      */
867     //@{
868 
869     /**
870      * Return the number of rows in this matrix.
871      */
872     size_type
873     m() const;
874 
875     /**
876      * Return the number of columns in this matrix.
877      */
878     size_type
879     n() const;
880 
881     /**
882      * Return the local dimension of the matrix, i.e. the number of rows
883      * stored on the present MPI process. For sequential matrices, this number
884      * is the same as m(), but for %parallel matrices it may be smaller.
885      *
886      * To figure out which elements exactly are stored locally, use
887      * local_range().
888      */
889     unsigned int
890     local_size() const;
891 
892     /**
893      * Return a pair of indices indicating which rows of this matrix are
894      * stored locally. The first number is the index of the first row stored,
895      * the second the index of the one past the last one that is stored
896      * locally. If this is a sequential matrix, then the result will be the
897      * pair (0,m()), otherwise it will be a pair (i,i+n), where
898      * <tt>n=local_size()</tt>.
899      */
900     std::pair<size_type, size_type>
901     local_range() const;
902 
903     /**
904      * Return whether @p index is in the local range or not, see also
905      * local_range().
906      */
907     bool
908     in_local_range(const size_type index) const;
909 
910     /**
911      * Return the total number of nonzero elements of this matrix (summed
912      * over all MPI processes).
913      */
914     size_type
915     n_nonzero_elements() const;
916 
917     /**
918      * Number of entries in a specific row.
919      */
920     unsigned int
921     row_length(const size_type row) const;
922 
923     /**
924      * Return the state of the matrix, i.e., whether compress() needs to be
925      * called after an operation requiring data exchange. A call to compress()
926      * is also needed when the method set() has been called (even when working
927      * in serial).
928      */
929     bool
930     is_compressed() const;
931 
932     /**
933      * Determine an estimate for the memory consumption (in bytes) of this
934      * object. Note that only the memory reserved on the current processor is
935      * returned in case this is called in an MPI-based program.
936      */
937     size_type
938     memory_consumption() const;
939 
940     /**
941      * Return the MPI communicator object in use with this matrix.
942      */
943     MPI_Comm
944     get_mpi_communicator() const;
945 
946     //@}
947     /**
948      * @name Modifying entries
949      */
950     //@{
951 
952     /**
953      * This operator assigns a scalar to a matrix. Since this does usually not
954      * make much sense (should we set all matrix entries to this value?  Only
955      * the nonzero entries of the sparsity pattern?), this operation is only
956      * allowed if the actual value to be assigned is zero. This operator only
957      * exists to allow for the obvious notation <tt>matrix=0</tt>, which sets
958      * all elements of the matrix to zero, but keeps the sparsity pattern
959      * previously used.
960      */
961     SparseMatrix &
962     operator=(const double d);
963 
964     /**
965      * Release all memory and return to a state just like after having called
966      * the default constructor.
967      *
968      * This is a collective operation that needs to be called on all
969      * processors in order to avoid a dead lock.
970      */
971     void
972     clear();
973 
974     /**
975      * This command does two things:
976      * <ul>
977      * <li> If the matrix was initialized without a sparsity pattern, elements
978      * have been added manually using the set() command. When this process is
979      * completed, a call to compress() reorganizes the internal data
980      * structures (sparsity pattern) so that a fast access to data is possible
981      * in matrix-vector products.
982      * <li> If the matrix structure has already been fixed (either by
983      * initialization with a sparsity pattern or by calling compress() during
984      * the setup phase), this command does the %parallel exchange of data.
985      * This is necessary when we perform assembly on more than one (MPI)
986      * process, because then some non-local row data will accumulate on nodes
987      * that belong to the current's processor element, but are actually held
988      * by another. This command is usually called after all elements have been
989      * traversed.
990      * </ul>
991      *
992      * In both cases, this function compresses the data structures and allows
993      * the resulting matrix to be used in all other operations like matrix-
994      * vector products. This is a collective operation, i.e., it needs to be
995      * run on all processors when used in %parallel.
996      *
997      * See
998      * @ref GlossCompress "Compressing distributed objects"
999      * for more information.
1000      */
1001     void
1002     compress(::dealii::VectorOperation::values operation);
1003 
1004     /**
1005      * Set the element (<i>i,j</i>) to @p value.
1006      *
1007      * This function is able to insert new elements into the matrix as long as
1008      * compress() has not been called, so the sparsity pattern will be
1009      * extended. When compress() is called for the first time (or in case the
1010      * matrix is initialized from a sparsity pattern), no new elements can be
1011      * added and an insertion of elements at positions which have not been
1012      * initialized will throw an exception.
1013      *
1014      * For the case that the matrix is constructed without a sparsity pattern
1015      * and new matrix entries are added on demand, please note the following
1016      * behavior imposed by the underlying Epetra_FECrsMatrix data structure:
1017      * If the same matrix entry is inserted more than once, the matrix entries
1018      * will be added upon calling compress() (since Epetra does not track
1019      * values to the same entry before the final compress() is called), even
1020      * if VectorOperation::insert is specified as argument to compress(). In
1021      * the case you cannot make sure that matrix entries are only set once,
1022      * initialize the matrix with a sparsity pattern to fix the matrix
1023      * structure before inserting elements.
1024      */
1025     void
1026     set(const size_type i, const size_type j, const TrilinosScalar value);
1027 
1028     /**
1029      * Set all elements given in a FullMatrix<double> into the sparse matrix
1030      * locations given by <tt>indices</tt>. In other words, this function
1031      * writes the elements in <tt>full_matrix</tt> into the calling matrix,
1032      * using the local-to-global indexing specified by <tt>indices</tt> for
1033      * both the rows and the columns of the matrix. This function assumes a
1034      * quadratic sparse matrix and a quadratic full_matrix, the usual
1035      * situation in FE calculations.
1036      *
1037      * This function is able to insert new elements into the matrix as long as
1038      * compress() has not been called, so the sparsity pattern will be
1039      * extended. After compress() has been called for the first time or the
1040      * matrix has been initialized from a sparsity pattern, extending the
1041      * sparsity pattern is no longer possible and an insertion of elements at
1042      * positions which have not been initialized will throw an exception.
1043      *
1044      * The optional parameter <tt>elide_zero_values</tt> can be used to
1045      * specify whether zero values should be inserted anyway or they should be
1046      * filtered away. The default value is <tt>false</tt>, i.e., even zero
1047      * values are inserted/replaced.
1048      *
1049      * For the case that the matrix is constructed without a sparsity pattern
1050      * and new matrix entries are added on demand, please note the following
1051      * behavior imposed by the underlying Epetra_FECrsMatrix data structure:
1052      * If the same matrix entry is inserted more than once, the matrix entries
1053      * will be added upon calling compress() (since Epetra does not track
1054      * values to the same entry before the final compress() is called), even
1055      * if VectorOperation::insert is specified as argument to compress(). In
1056      * the case you cannot make sure that matrix entries are only set once,
1057      * initialize the matrix with a sparsity pattern to fix the matrix
1058      * structure before inserting elements.
1059      */
1060     void
1061     set(const std::vector<size_type> &    indices,
1062         const FullMatrix<TrilinosScalar> &full_matrix,
1063         const bool                        elide_zero_values = false);
1064 
1065     /**
1066      * Same function as before, but now including the possibility to use
1067      * rectangular full_matrices and different local-to-global indexing on
1068      * rows and columns, respectively.
1069      */
1070     void
1071     set(const std::vector<size_type> &    row_indices,
1072         const std::vector<size_type> &    col_indices,
1073         const FullMatrix<TrilinosScalar> &full_matrix,
1074         const bool                        elide_zero_values = false);
1075 
1076     /**
1077      * Set several elements in the specified row of the matrix with column
1078      * indices as given by <tt>col_indices</tt> to the respective value.
1079      *
1080      * This function is able to insert new elements into the matrix as long as
1081      * compress() has not been called, so the sparsity pattern will be
1082      * extended. After compress() has been called for the first time or the
1083      * matrix has been initialized from a sparsity pattern, extending the
1084      * sparsity pattern is no longer possible and an insertion of elements at
1085      * positions which have not been initialized will throw an exception.
1086      *
1087      * The optional parameter <tt>elide_zero_values</tt> can be used to
1088      * specify whether zero values should be inserted anyway or they should be
1089      * filtered away. The default value is <tt>false</tt>, i.e., even zero
1090      * values are inserted/replaced.
1091      *
1092      * For the case that the matrix is constructed without a sparsity pattern
1093      * and new matrix entries are added on demand, please note the following
1094      * behavior imposed by the underlying Epetra_FECrsMatrix data structure:
1095      * If the same matrix entry is inserted more than once, the matrix entries
1096      * will be added upon calling compress() (since Epetra does not track
1097      * values to the same entry before the final compress() is called), even
1098      * if VectorOperation::insert is specified as argument to compress(). In
1099      * the case you cannot make sure that matrix entries are only set once,
1100      * initialize the matrix with a sparsity pattern to fix the matrix
1101      * structure before inserting elements.
1102      */
1103     void
1104     set(const size_type                    row,
1105         const std::vector<size_type> &     col_indices,
1106         const std::vector<TrilinosScalar> &values,
1107         const bool                         elide_zero_values = false);
1108 
1109     /**
1110      * Set several elements to values given by <tt>values</tt> in a given row
1111      * in columns given by col_indices into the sparse matrix.
1112      *
1113      * This function is able to insert new elements into the matrix as long as
1114      * compress() has not been called, so the sparsity pattern will be
1115      * extended. After compress() has been called for the first time or the
1116      * matrix has been initialized from a sparsity pattern, extending the
1117      * sparsity pattern is no longer possible and an insertion of elements at
1118      * positions which have not been initialized will throw an exception.
1119      *
1120      * The optional parameter <tt>elide_zero_values</tt> can be used to
1121      * specify whether zero values should be inserted anyway or they should be
1122      * filtered away. The default value is <tt>false</tt>, i.e., even zero
1123      * values are inserted/replaced.
1124      *
1125      * For the case that the matrix is constructed without a sparsity pattern
1126      * and new matrix entries are added on demand, please note the following
1127      * behavior imposed by the underlying Epetra_FECrsMatrix data structure:
1128      * If the same matrix entry is inserted more than once, the matrix entries
1129      * will be added upon calling compress() (since Epetra does not track
1130      * values to the same entry before the final compress() is called), even
1131      * if VectorOperation::insert is specified as argument to compress(). In
1132      * the case you cannot make sure that matrix entries are only set once,
1133      * initialize the matrix with a sparsity pattern to fix the matrix
1134      * structure before inserting elements.
1135      */
1136     template <typename Number>
1137     void
1138     set(const size_type  row,
1139         const size_type  n_cols,
1140         const size_type *col_indices,
1141         const Number *   values,
1142         const bool       elide_zero_values = false);
1143 
1144     /**
1145      * Add @p value to the element (<i>i,j</i>).
1146      *
1147      * Just as the respective call in deal.II SparseMatrix<Number> class (but
1148      * in contrast to the situation for PETSc based matrices), this function
1149      * throws an exception if an entry does not exist in the sparsity pattern.
1150      * Moreover, if <tt>value</tt> is not a finite number an exception is
1151      * thrown.
1152      */
1153     void
1154     add(const size_type i, const size_type j, const TrilinosScalar value);
1155 
1156     /**
1157      * Add all elements given in a FullMatrix<double> into sparse matrix
1158      * locations given by <tt>indices</tt>. In other words, this function adds
1159      * the elements in <tt>full_matrix</tt> to the respective entries in
1160      * calling matrix, using the local-to-global indexing specified by
1161      * <tt>indices</tt> for both the rows and the columns of the matrix. This
1162      * function assumes a quadratic sparse matrix and a quadratic full_matrix,
1163      * the usual situation in FE calculations.
1164      *
1165      * Just as the respective call in deal.II SparseMatrix<Number> class (but
1166      * in contrast to the situation for PETSc based matrices), this function
1167      * throws an exception if an entry does not exist in the sparsity pattern.
1168      *
1169      * The optional parameter <tt>elide_zero_values</tt> can be used to
1170      * specify whether zero values should be added anyway or these should be
1171      * filtered away and only non-zero data is added. The default value is
1172      * <tt>true</tt>, i.e., zero values won't be added into the matrix.
1173      */
1174     void
1175     add(const std::vector<size_type> &    indices,
1176         const FullMatrix<TrilinosScalar> &full_matrix,
1177         const bool                        elide_zero_values = true);
1178 
1179     /**
1180      * Same function as before, but now including the possibility to use
1181      * rectangular full_matrices and different local-to-global indexing on
1182      * rows and columns, respectively.
1183      */
1184     void
1185     add(const std::vector<size_type> &    row_indices,
1186         const std::vector<size_type> &    col_indices,
1187         const FullMatrix<TrilinosScalar> &full_matrix,
1188         const bool                        elide_zero_values = true);
1189 
1190     /**
1191      * Set several elements in the specified row of the matrix with column
1192      * indices as given by <tt>col_indices</tt> to the respective value.
1193      *
1194      * Just as the respective call in deal.II SparseMatrix<Number> class (but
1195      * in contrast to the situation for PETSc based matrices), this function
1196      * throws an exception if an entry does not exist in the sparsity pattern.
1197      *
1198      * The optional parameter <tt>elide_zero_values</tt> can be used to
1199      * specify whether zero values should be added anyway or these should be
1200      * filtered away and only non-zero data is added. The default value is
1201      * <tt>true</tt>, i.e., zero values won't be added into the matrix.
1202      */
1203     void
1204     add(const size_type                    row,
1205         const std::vector<size_type> &     col_indices,
1206         const std::vector<TrilinosScalar> &values,
1207         const bool                         elide_zero_values = true);
1208 
1209     /**
1210      * Add an array of values given by <tt>values</tt> in the given global
1211      * matrix row at columns specified by col_indices in the sparse matrix.
1212      *
1213      * Just as the respective call in deal.II SparseMatrix<Number> class (but
1214      * in contrast to the situation for PETSc based matrices), this function
1215      * throws an exception if an entry does not exist in the sparsity pattern.
1216      *
1217      * The optional parameter <tt>elide_zero_values</tt> can be used to
1218      * specify whether zero values should be added anyway or these should be
1219      * filtered away and only non-zero data is added. The default value is
1220      * <tt>true</tt>, i.e., zero values won't be added into the matrix.
1221      */
1222     void
1223     add(const size_type       row,
1224         const size_type       n_cols,
1225         const size_type *     col_indices,
1226         const TrilinosScalar *values,
1227         const bool            elide_zero_values      = true,
1228         const bool            col_indices_are_sorted = false);
1229 
1230     /**
1231      * Multiply the entire matrix by a fixed factor.
1232      */
1233     SparseMatrix &
1234     operator*=(const TrilinosScalar factor);
1235 
1236     /**
1237      * Divide the entire matrix by a fixed factor.
1238      */
1239     SparseMatrix &
1240     operator/=(const TrilinosScalar factor);
1241 
1242     /**
1243      * Copy the given (Trilinos) matrix (sparsity pattern and entries).
1244      */
1245     void
1246     copy_from(const SparseMatrix &source);
1247 
1248     /**
1249      * Add <tt>matrix</tt> scaled by <tt>factor</tt> to this matrix, i.e. the
1250      * matrix <tt>factor*matrix</tt> is added to <tt>this</tt>. If the
1251      * sparsity pattern of the calling matrix does not contain all the
1252      * elements in the sparsity pattern of the input matrix, this function
1253      * will throw an exception.
1254      */
1255     void
1256     add(const TrilinosScalar factor, const SparseMatrix &matrix);
1257 
1258     /**
1259      * Remove all elements from this <tt>row</tt> by setting them to zero. The
1260      * function does not modify the number of allocated nonzero entries, it
1261      * only sets the entries to zero.
1262      *
1263      * This operation is used in eliminating constraints (e.g. due to hanging
1264      * nodes) and makes sure that we can write this modification to the matrix
1265      * without having to read entries (such as the locations of non-zero
1266      * elements) from it &mdash; without this operation, removing constraints
1267      * on %parallel matrices is a rather complicated procedure.
1268      *
1269      * The second parameter can be used to set the diagonal entry of this row
1270      * to a value different from zero. The default is to set it to zero.
1271      *
1272      * @note If the matrix is stored in parallel across multiple processors
1273      * using MPI, this function only touches rows that are locally stored and
1274      * simply ignores all other row indices. Further, in the context of
1275      * parallel computations, you will get into trouble if you clear a row
1276      * while other processors still have pending writes or additions into the
1277      * same row. In other words, if another processor still wants to add
1278      * something to an element of a row and you call this function to zero out
1279      * the row, then the next time you call compress() may add the remote
1280      * value to the zero you just created. Consequently, you will want to call
1281      * compress() after you made the last modifications to a matrix and before
1282      * starting to clear rows.
1283      */
1284     void
1285     clear_row(const size_type row, const TrilinosScalar new_diag_value = 0);
1286 
1287     /**
1288      * Same as clear_row(), except that it works on a number of rows at once.
1289      *
1290      * The second parameter can be used to set the diagonal entries of all
1291      * cleared rows to something different from zero. Note that all of these
1292      * diagonal entries get the same value -- if you want different values for
1293      * the diagonal entries, you have to set them by hand.
1294      *
1295      * @note If the matrix is stored in parallel across multiple processors
1296      * using MPI, this function only touches rows that are locally stored and
1297      * simply ignores all other row indices. Further, in the context of
1298      * parallel computations, you will get into trouble if you clear a row
1299      * while other processors still have pending writes or additions into the
1300      * same row. In other words, if another processor still wants to add
1301      * something to an element of a row and you call this function to zero out
1302      * the row, then the next time you call compress() may add the remote
1303      * value to the zero you just created. Consequently, you will want to call
1304      * compress() after you made the last modifications to a matrix and before
1305      * starting to clear rows.
1306      */
1307     void
1308     clear_rows(const std::vector<size_type> &rows,
1309                const TrilinosScalar          new_diag_value = 0);
1310 
1311     /**
1312      * Sets an internal flag so that all operations performed by the matrix,
1313      * i.e., multiplications, are done in transposed order. However, this does
1314      * not reshape the matrix to transposed form directly, so care should be
1315      * taken when using this flag.
1316      *
1317      * @note Calling this function any even number of times in succession will
1318      * return the object to its original state.
1319      */
1320     void
1321     transpose();
1322 
1323     //@}
1324     /**
1325      * @name Entry Access
1326      */
1327     //@{
1328 
1329     /**
1330      * Return the value of the entry (<i>i,j</i>).  This may be an expensive
1331      * operation and you should always take care where to call this function.
1332      * As in the deal.II sparse matrix class, we throw an exception if the
1333      * respective entry doesn't exist in the sparsity pattern of this class,
1334      * which is requested from Trilinos. Moreover, an exception will be thrown
1335      * when the requested element is not saved on the calling process.
1336      */
1337     TrilinosScalar
1338     operator()(const size_type i, const size_type j) const;
1339 
1340     /**
1341      * Return the value of the matrix entry (<i>i,j</i>). If this entry does
1342      * not exist in the sparsity pattern, then zero is returned. While this
1343      * may be convenient in some cases, note that it is simple to write
1344      * algorithms that are slow compared to an optimal solution, since the
1345      * sparsity of the matrix is not used.  On the other hand, if you want to
1346      * be sure the entry exists, you should use operator() instead.
1347      *
1348      * The lack of error checking in this function can also yield surprising
1349      * results if you have a parallel matrix. In that case, just because you
1350      * get a zero result from this function does not mean that either the
1351      * entry does not exist in the sparsity pattern or that it does but has a
1352      * value of zero. Rather, it could also be that it simply isn't stored on
1353      * the current processor; in that case, it may be stored on a different
1354      * processor, and possibly so with a nonzero value.
1355      */
1356     TrilinosScalar
1357     el(const size_type i, const size_type j) const;
1358 
1359     /**
1360      * Return the main diagonal element in the <i>i</i>th row. This function
1361      * throws an error if the matrix is not quadratic and it also throws an
1362      * error if <i>(i,i)</i> is not element of the local matrix.  See also the
1363      * comment in trilinos_sparse_matrix.cc.
1364      */
1365     TrilinosScalar
1366     diag_element(const size_type i) const;
1367 
1368     //@}
1369     /**
1370      * @name Multiplications
1371      */
1372     //@{
1373 
1374     /**
1375      * Matrix-vector multiplication: let <i>dst = M*src</i> with <i>M</i>
1376      * being this matrix.
1377      *
1378      * Source and destination must not be the same vector.
1379      *
1380      * This function can be called with several types of vector objects,
1381      * namely @p VectorType can be
1382      * <ul>
1383      * <li> TrilinosWrappers::MPI::Vector,
1384      * <li> LinearAlgebra::EpetraWrappers::Vector,
1385      * <li> LinearAlgebra::TpetraWrappers::Vector,
1386      * <li> Vector<double>,
1387      * <li> LinearAlgebra::distributed::Vector<double>.
1388      * </ul>
1389      *
1390      * When using vectors of type TrilinosWrappers::MPI::Vector, the vector
1391      * @p dst has to be initialized with the same IndexSet that was used for
1392      * the row indices of the matrix and the vector @p src has to be
1393      * initialized with the same IndexSet that was used for the column indices
1394      * of the matrix.
1395      *
1396      * This function will be called when the underlying number type for the
1397      * matrix object and the one for the vector object are the same.
1398      * Despite looking complicated, the return type is just `void`.
1399      *
1400      * In case of a serial vector, this function will only work when
1401      * running on one processor, since the matrix object is inherently
1402      * distributed. Otherwise, an exception will be thrown.
1403      */
1404     template <typename VectorType>
1405     typename std::enable_if<std::is_same<typename VectorType::value_type,
1406                                          TrilinosScalar>::value>::type
1407     vmult(VectorType &dst, const VectorType &src) const;
1408 
1409     /**
1410      * Same as the function above for the case that the underlying number type
1411      * for the matrix object and the one for the vector object do not coincide.
1412      * This case is not implemented. Calling it will result in a runtime error.
1413      * Despite looking complicated, the return type is just `void`.
1414      */
1415     template <typename VectorType>
1416     typename std::enable_if<!std::is_same<typename VectorType::value_type,
1417                                           TrilinosScalar>::value>::type
1418     vmult(VectorType &dst, const VectorType &src) const;
1419 
1420     /**
1421      * Matrix-vector multiplication: let <i>dst = M<sup>T</sup>*src</i> with
1422      * <i>M</i> being this matrix. This function does the same as vmult() but
1423      * takes the transposed matrix.
1424      *
1425      * Source and destination must not be the same vector.
1426      *
1427      * This function can be called with several types of vector objects,
1428      * see the discussion about @p VectorType in vmult().
1429      *
1430      * This function will be called when the underlying number type for the
1431      * matrix object and the one for the vector object are the same.
1432      * Despite looking complicated, the return type is just `void`.
1433      */
1434     template <typename VectorType>
1435     typename std::enable_if<std::is_same<typename VectorType::value_type,
1436                                          TrilinosScalar>::value>::type
1437     Tvmult(VectorType &dst, const VectorType &src) const;
1438 
1439     /**
1440      * Same as the function above for the case that the underlying number type
1441      * for the matrix object and the one for the vector object do not coincide.
1442      * This case is not implemented. Calling it will result in a runtime error.
1443      * Despite looking complicated, the return type is just `void`.
1444      */
1445     template <typename VectorType>
1446     typename std::enable_if<!std::is_same<typename VectorType::value_type,
1447                                           TrilinosScalar>::value>::type
1448     Tvmult(VectorType &dst, const VectorType &src) const;
1449 
1450     /**
1451      * Adding matrix-vector multiplication. Add <i>M*src</i> on <i>dst</i>
1452      * with <i>M</i> being this matrix.
1453      *
1454      * Source and destination must not be the same vector.
1455      *
1456      * This function can be called with several types of vector objects,
1457      * see the discussion about @p VectorType in vmult().
1458      */
1459     template <typename VectorType>
1460     void
1461     vmult_add(VectorType &dst, const VectorType &src) const;
1462 
1463     /**
1464      * Adding matrix-vector multiplication. Add <i>M<sup>T</sup>*src</i> to
1465      * <i>dst</i> with <i>M</i> being this matrix. This function does the same
1466      * as vmult_add() but takes the transposed matrix.
1467      *
1468      * Source and destination must not be the same vector.
1469      *
1470      * This function can be called with several types of vector objects,
1471      * see the discussion about @p VectorType in vmult().
1472      */
1473     template <typename VectorType>
1474     void
1475     Tvmult_add(VectorType &dst, const VectorType &src) const;
1476 
1477     /**
1478      * Return the square of the norm of the vector $v$ with respect to the
1479      * norm induced by this matrix, i.e., $\left(v,Mv\right)$. This is useful,
1480      * e.g. in the finite element context, where the $L_2$ norm of a function
1481      * equals the matrix norm with respect to the mass matrix of the vector
1482      * representing the nodal values of the finite element function.
1483      *
1484      * Obviously, the matrix needs to be quadratic for this operation.
1485      *
1486      * The implementation of this function is not as efficient as the one in
1487      * the @p SparseMatrix class used in deal.II (i.e. the original one, not
1488      * the Trilinos wrapper class) since Trilinos doesn't support this
1489      * operation and needs a temporary vector.
1490      *
1491      * The vector has to be initialized with the same IndexSet the matrix
1492      * was initialized with.
1493      *
1494      * In case of a localized Vector, this function will only work when
1495      * running on one processor, since the matrix object is inherently
1496      * distributed. Otherwise, an exception will be thrown.
1497      */
1498     TrilinosScalar
1499     matrix_norm_square(const MPI::Vector &v) const;
1500 
1501     /**
1502      * Compute the matrix scalar product $\left(u,Mv\right)$.
1503      *
1504      * The implementation of this function is not as efficient as the one in
1505      * the @p SparseMatrix class used in deal.II (i.e. the original one, not
1506      * the Trilinos wrapper class) since Trilinos doesn't support this
1507      * operation and needs a temporary vector.
1508      *
1509      * The vector @p u has to be initialized with the same IndexSet that
1510      * was used for the row indices of the matrix and the vector @p v has
1511      * to be initialized with the same IndexSet that was used for the
1512      * column indices of the matrix.
1513      *
1514      * In case of a localized Vector, this function will only work when
1515      * running on one processor, since the matrix object is inherently
1516      * distributed. Otherwise, an exception will be thrown.
1517      *
1518      * This function is only implemented for square matrices.
1519      */
1520     TrilinosScalar
1521     matrix_scalar_product(const MPI::Vector &u, const MPI::Vector &v) const;
1522 
1523     /**
1524      * Compute the residual of an equation <i>Mx=b</i>, where the residual is
1525      * defined to be <i>r=b-Mx</i>. Write the residual into @p dst. The
1526      * <i>l<sub>2</sub></i> norm of the residual vector is returned.
1527      *
1528      * Source <i>x</i> and destination <i>dst</i> must not be the same vector.
1529      *
1530      * The vectors @p dst and @p b have to be initialized with the same
1531      * IndexSet that was used for the row indices of the matrix and the vector
1532      * @p x has to be initialized with the same IndexSet that was used for the
1533      * column indices of the matrix.
1534      *
1535      * In case of a localized Vector, this function will only work when
1536      * running on one processor, since the matrix object is inherently
1537      * distributed. Otherwise, an exception will be thrown.
1538      */
1539     TrilinosScalar
1540     residual(MPI::Vector &      dst,
1541              const MPI::Vector &x,
1542              const MPI::Vector &b) const;
1543 
1544     /**
1545      * Perform the matrix-matrix multiplication <tt>C = A * B</tt>, or, if an
1546      * optional vector argument is given, <tt>C = A * diag(V) * B</tt>, where
1547      * <tt>diag(V)</tt> defines a diagonal matrix with the vector entries.
1548      *
1549      * This function assumes that the calling matrix <tt>A</tt> and <tt>B</tt>
1550      * have compatible sizes. The size of <tt>C</tt> will be set within this
1551      * function.
1552      *
1553      * The content as well as the sparsity pattern of the matrix C will be
1554      * changed by this function, so make sure that the sparsity pattern is not
1555      * used somewhere else in your program. This is an expensive operation, so
1556      * think twice before you use this function.
1557      */
1558     void
1559     mmult(SparseMatrix &      C,
1560           const SparseMatrix &B,
1561           const MPI::Vector & V = MPI::Vector()) const;
1562 
1563 
1564     /**
1565      * Perform the matrix-matrix multiplication with the transpose of
1566      * <tt>this</tt>, i.e., <tt>C = A<sup>T</sup> * B</tt>, or, if an optional
1567      * vector argument is given, <tt>C = A<sup>T</sup> * diag(V) * B</tt>,
1568      * where <tt>diag(V)</tt> defines a diagonal matrix with the vector
1569      * entries.
1570      *
1571      * This function assumes that the calling matrix <tt>A</tt> and <tt>B</tt>
1572      * have compatible sizes. The size of <tt>C</tt> will be set within this
1573      * function.
1574      *
1575      * The content as well as the sparsity pattern of the matrix C will be
1576      * changed by this function, so make sure that the sparsity pattern is not
1577      * used somewhere else in your program. This is an expensive operation, so
1578      * think twice before you use this function.
1579      */
1580     void
1581     Tmmult(SparseMatrix &      C,
1582            const SparseMatrix &B,
1583            const MPI::Vector & V = MPI::Vector()) const;
1584 
1585     //@}
1586     /**
1587      * @name Matrix norms
1588      */
1589     //@{
1590 
1591     /**
1592      * Return the <i>l</i><sub>1</sub>-norm of the matrix, that is $|M|_1=
1593      * \max_{\mathrm{all\ columns\ } j} \sum_{\mathrm{all\ rows\ } i}
1594      * |M_{ij}|$, (max. sum of columns).  This is the natural matrix norm that
1595      * is compatible to the l1-norm for vectors, i.e.  $|Mv|_1 \leq |M|_1
1596      * |v|_1$.  (cf. Haemmerlin-Hoffmann: Numerische Mathematik)
1597      */
1598     TrilinosScalar
1599     l1_norm() const;
1600 
1601     /**
1602      * Return the linfty-norm of the matrix, that is
1603      * $|M|_\infty=\max_{\mathrm{all\ rows\ } i}\sum_{\mathrm{all\ columns\ }
1604      * j} |M_{ij}|$, (max. sum of rows).  This is the natural matrix norm that
1605      * is compatible to the linfty-norm of vectors, i.e.  $|Mv|_\infty \leq
1606      * |M|_\infty |v|_\infty$.  (cf. Haemmerlin-Hoffmann: Numerische
1607      * Mathematik)
1608      */
1609     TrilinosScalar
1610     linfty_norm() const;
1611 
1612     /**
1613      * Return the frobenius norm of the matrix, i.e. the square root of the
1614      * sum of squares of all entries in the matrix.
1615      */
1616     TrilinosScalar
1617     frobenius_norm() const;
1618 
1619     //@}
1620     /**
1621      * @name Access to underlying Trilinos data
1622      */
1623     //@{
1624 
1625     /**
1626      * Return a const reference to the underlying Trilinos Epetra_CrsMatrix
1627      * data.
1628      */
1629     const Epetra_CrsMatrix &
1630     trilinos_matrix() const;
1631 
1632     /**
1633      * Return a const reference to the underlying Trilinos Epetra_CrsGraph
1634      * data that stores the sparsity pattern of the matrix.
1635      */
1636     const Epetra_CrsGraph &
1637     trilinos_sparsity_pattern() const;
1638 
1639     //@}
1640 
1641     /**
1642      * @name Partitioners
1643      */
1644     //@{
1645 
1646     /**
1647      * Return the partitioning of the domain space of this matrix, i.e., the
1648      * partitioning of the vectors this matrix has to be multiplied with.
1649      */
1650     IndexSet
1651     locally_owned_domain_indices() const;
1652 
1653     /**
1654      * Return the partitioning of the range space of this matrix, i.e., the
1655      * partitioning of the vectors that are result from matrix-vector
1656      * products.
1657      */
1658     IndexSet
1659     locally_owned_range_indices() const;
1660 
1661     //@}
1662 
1663     /**
1664      * @name Iterators
1665      */
1666     //@{
1667 
1668     /**
1669      * Return an iterator pointing to the first element of the matrix.
1670      *
1671      * The elements accessed by iterators within each row are ordered in the
1672      * way in which Trilinos stores them, though the implementation guarantees
1673      * that all elements of one row are accessed before the elements of the
1674      * next row. If your algorithm relies on visiting elements within one row,
1675      * you will need to consult with the Trilinos documentation on the order
1676      * in which it stores data. It is, however, generally not a good and long-
1677      * term stable idea to rely on the order in which receive elements if you
1678      * iterate over them.
1679      *
1680      * When you iterate over the elements of a parallel matrix, you will only
1681      * be able to access the locally owned rows. (You can access the other
1682      * rows as well, but they will look empty.) In that case, you probably
1683      * want to call the begin() function that takes the row as an argument to
1684      * limit the range of elements to loop over.
1685      */
1686     const_iterator
1687     begin() const;
1688 
1689     /**
1690      * Like the function above, but for non-const matrices.
1691      */
1692     iterator
1693     begin();
1694 
1695     /**
1696      * Return an iterator pointing the element past the last one of this
1697      * matrix.
1698      */
1699     const_iterator
1700     end() const;
1701 
1702     /**
1703      * Like the function above, but for non-const matrices.
1704      */
1705     iterator
1706     end();
1707 
1708     /**
1709      * Return an iterator pointing to the first element of row @p r.
1710      *
1711      * Note that if the given row is empty, i.e. does not contain any nonzero
1712      * entries, then the iterator returned by this function equals
1713      * <tt>end(r)</tt>. The returned iterator may not be dereferenceable in
1714      * that case if neither row @p r nor any of the following rows contain any
1715      * nonzero entries.
1716      *
1717      * The elements accessed by iterators within each row are ordered in the
1718      * way in which Trilinos stores them, though the implementation guarantees
1719      * that all elements of one row are accessed before the elements of the
1720      * next row. If your algorithm relies on visiting elements within one row,
1721      * you will need to consult with the Trilinos documentation on the order
1722      * in which it stores data. It is, however, generally not a good and long-
1723      * term stable idea to rely on the order in which receive elements if you
1724      * iterate over them.
1725      *
1726      * @note When you access the elements of a parallel matrix, you can only
1727      * access the elements of rows that are actually stored locally. (You can
1728      * access the other rows as well, but they will look empty.) Even then, if
1729      * another processor has since written into, or added to, an element of
1730      * the matrix that is stored on the current processor, then you will still
1731      * see the old value of this entry unless you have called compress()
1732      * between modifying the matrix element on the remote processor and
1733      * accessing it on the current processor. See the documentation of the
1734      * compress() function for more information.
1735      */
1736     const_iterator
1737     begin(const size_type r) const;
1738 
1739     /**
1740      * Like the function above, but for non-const matrices.
1741      */
1742     iterator
1743     begin(const size_type r);
1744 
1745     /**
1746      * Return an iterator pointing the element past the last one of row @p r ,
1747      * or past the end of the entire sparsity pattern if none of the rows
1748      * after @p r contain any entries at all.
1749      *
1750      * Note that the end iterator is not necessarily dereferenceable. This is
1751      * in particular the case if it is the end iterator for the last row of a
1752      * matrix.
1753      */
1754     const_iterator
1755     end(const size_type r) const;
1756 
1757     /**
1758      * Like the function above, but for non-const matrices.
1759      */
1760     iterator
1761     end(const size_type r);
1762 
1763     //@}
1764     /**
1765      * @name Input/Output
1766      */
1767     //@{
1768 
1769     /**
1770      * Abstract Trilinos object that helps view in ASCII other Trilinos
1771      * objects. Currently this function is not implemented.  TODO: Not
1772      * implemented.
1773      */
1774     void
1775     write_ascii();
1776 
1777     /**
1778      * Print the matrix to the given stream, using the format <tt>(line,col)
1779      * value</tt>, i.e. one nonzero entry of the matrix per line. The optional
1780      * flag outputs the sparsity pattern in Trilinos style, where the data is
1781      * sorted according to the processor number when printed to the stream, as
1782      * well as a summary of the matrix like the global size.
1783      */
1784     void
1785     print(std::ostream &out,
1786           const bool    write_extended_trilinos_info = false) const;
1787 
1788     //@}
1789     /**
1790      * @addtogroup Exceptions
1791      */
1792     //@{
1793     /**
1794      * Exception
1795      */
1796     DeclException1(ExcTrilinosError,
1797                    int,
1798                    << "An error with error number " << arg1
1799                    << " occurred while calling a Trilinos function");
1800 
1801     /**
1802      * Exception
1803      */
1804     DeclException2(ExcInvalidIndex,
1805                    size_type,
1806                    size_type,
1807                    << "The entry with index <" << arg1 << ',' << arg2
1808                    << "> does not exist.");
1809 
1810     /**
1811      * Exception
1812      */
1813     DeclExceptionMsg(ExcSourceEqualsDestination,
1814                      "You are attempting an operation on two matrices that "
1815                      "are the same object, but the operation requires that the "
1816                      "two objects are in fact different.");
1817 
1818     /**
1819      * Exception
1820      */
1821     DeclException0(ExcMatrixNotCompressed);
1822 
1823     /**
1824      * Exception
1825      */
1826     DeclException4(ExcAccessToNonLocalElement,
1827                    size_type,
1828                    size_type,
1829                    size_type,
1830                    size_type,
1831                    << "You tried to access element (" << arg1 << "/" << arg2
1832                    << ")"
1833                    << " of a distributed matrix, but only rows " << arg3
1834                    << " through " << arg4
1835                    << " are stored locally and can be accessed.");
1836 
1837     /**
1838      * Exception
1839      */
1840     DeclException2(ExcAccessToNonPresentElement,
1841                    size_type,
1842                    size_type,
1843                    << "You tried to access element (" << arg1 << "/" << arg2
1844                    << ")"
1845                    << " of a sparse matrix, but it appears to not"
1846                    << " exist in the Trilinos sparsity pattern.");
1847     //@}
1848 
1849 
1850 
1851   protected:
1852     /**
1853      * For some matrix storage formats, in particular for the PETSc
1854      * distributed blockmatrices, set and add operations on individual
1855      * elements can not be freely mixed. Rather, one has to synchronize
1856      * operations when one wants to switch from setting elements to adding to
1857      * elements.  BlockMatrixBase automatically synchronizes the access by
1858      * calling this helper function for each block.  This function ensures
1859      * that the matrix is in a state that allows adding elements; if it
1860      * previously already was in this state, the function does nothing.
1861      */
1862     void
1863     prepare_add();
1864 
1865     /**
1866      * Same as prepare_add() but prepare the matrix for setting elements if
1867      * the representation of elements in this class requires such an
1868      * operation.
1869      */
1870     void
1871     prepare_set();
1872 
1873 
1874 
1875   private:
1876     /**
1877      * Pointer to the user-supplied Epetra Trilinos mapping of the matrix
1878      * columns that assigns parts of the matrix to the individual processes.
1879      */
1880     std::unique_ptr<Epetra_Map> column_space_map;
1881 
1882     /**
1883      * A sparse matrix object in Trilinos to be used for finite element based
1884      * problems which allows for assembling into non-local elements.  The
1885      * actual type, a sparse matrix, is set in the constructor.
1886      */
1887     std::unique_ptr<Epetra_FECrsMatrix> matrix;
1888 
1889     /**
1890      * A sparse matrix object in Trilinos to be used for collecting the non-
1891      * local elements if the matrix was constructed from a Trilinos sparsity
1892      * pattern with the respective option.
1893      */
1894     std::unique_ptr<Epetra_CrsMatrix> nonlocal_matrix;
1895 
1896     /**
1897      * An export object used to communicate the nonlocal matrix.
1898      */
1899     std::unique_ptr<Epetra_Export> nonlocal_matrix_exporter;
1900 
1901     /**
1902      * Trilinos doesn't allow to mix additions to matrix entries and
1903      * overwriting them (to make synchronization of %parallel computations
1904      * simpler). The way we do it is to, for each access operation, store
1905      * whether it is an insertion or an addition. If the previous one was of
1906      * different type, then we first have to flush the Trilinos buffers;
1907      * otherwise, we can simply go on. Luckily, Trilinos has an object for
1908      * this which does already all the %parallel communications in such a
1909      * case, so we simply use their model, which stores whether the last
1910      * operation was an addition or an insertion.
1911      */
1912     Epetra_CombineMode last_action;
1913 
1914     /**
1915      * A boolean variable to hold information on whether the vector is
1916      * compressed or not.
1917      */
1918     bool compressed;
1919 
1920     // To allow calling protected prepare_add() and prepare_set().
1921     friend class BlockMatrixBase<SparseMatrix>;
1922   };
1923 
1924 
1925 
1926   // forwards declarations
1927   class SolverBase;
1928   class PreconditionBase;
1929 
1930   namespace internal
1931   {
1932     inline void
check_vector_map_equality(const Epetra_CrsMatrix & mtrx,const Epetra_MultiVector & src,const Epetra_MultiVector & dst,const bool transpose)1933     check_vector_map_equality(const Epetra_CrsMatrix &  mtrx,
1934                               const Epetra_MultiVector &src,
1935                               const Epetra_MultiVector &dst,
1936                               const bool                transpose)
1937     {
1938       if (transpose == false)
1939         {
1940           Assert(src.Map().SameAs(mtrx.DomainMap()) == true,
1941                  ExcMessage(
1942                    "Column map of matrix does not fit with vector map!"));
1943           Assert(dst.Map().SameAs(mtrx.RangeMap()) == true,
1944                  ExcMessage("Row map of matrix does not fit with vector map!"));
1945         }
1946       else
1947         {
1948           Assert(src.Map().SameAs(mtrx.RangeMap()) == true,
1949                  ExcMessage(
1950                    "Column map of matrix does not fit with vector map!"));
1951           Assert(dst.Map().SameAs(mtrx.DomainMap()) == true,
1952                  ExcMessage("Row map of matrix does not fit with vector map!"));
1953         }
1954       (void)mtrx; // removes -Wunused-variable in optimized mode
1955       (void)src;
1956       (void)dst;
1957     }
1958 
1959     inline void
check_vector_map_equality(const Epetra_Operator & op,const Epetra_MultiVector & src,const Epetra_MultiVector & dst,const bool transpose)1960     check_vector_map_equality(const Epetra_Operator &   op,
1961                               const Epetra_MultiVector &src,
1962                               const Epetra_MultiVector &dst,
1963                               const bool                transpose)
1964     {
1965       if (transpose == false)
1966         {
1967           Assert(src.Map().SameAs(op.OperatorDomainMap()) == true,
1968                  ExcMessage(
1969                    "Column map of operator does not fit with vector map!"));
1970           Assert(dst.Map().SameAs(op.OperatorRangeMap()) == true,
1971                  ExcMessage(
1972                    "Row map of operator does not fit with vector map!"));
1973         }
1974       else
1975         {
1976           Assert(src.Map().SameAs(op.OperatorRangeMap()) == true,
1977                  ExcMessage(
1978                    "Column map of operator does not fit with vector map!"));
1979           Assert(dst.Map().SameAs(op.OperatorDomainMap()) == true,
1980                  ExcMessage(
1981                    "Row map of operator does not fit with vector map!"));
1982         }
1983       (void)op; // removes -Wunused-variable in optimized mode
1984       (void)src;
1985       (void)dst;
1986     }
1987 
1988     namespace LinearOperatorImplementation
1989     {
1990       /**
1991        * This is an extension class to LinearOperators for Trilinos sparse
1992        * matrix and preconditioner types. It provides the interface to
1993        * performing basic operations (<tt>vmult</tt> and <tt>Tvmult</tt>)  on
1994        * Trilinos vector types. It fulfills the requirements necessary for
1995        * wrapping a Trilinos solver, which calls Epetra_Operator functions, as a
1996        * LinearOperator.
1997        *
1998        * @note The TrilinosWrappers::SparseMatrix or
1999        * TrilinosWrappers::PreconditionBase that this payload wraps is passed by
2000        * reference to the <tt>vmult</tt> and <tt>Tvmult</tt> functions. This
2001        * object is not thread-safe when the transpose flag is set on it or the
2002        * Trilinos object to which it refers. See the docuemtation for the
2003        * TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload::SetUseTranspose()
2004        * function for further details.
2005        *
2006        *
2007        * @ingroup TrilinosWrappers
2008        */
2009       class TrilinosPayload : public Epetra_Operator
2010       {
2011       public:
2012         /**
2013          * Definition for the internally supported vector type.
2014          */
2015         using VectorType = Epetra_MultiVector;
2016 
2017         /**
2018          * Definition for the vector type for the domain space of the operator.
2019          */
2020         using Range = VectorType;
2021 
2022         /**
2023          * Definition for the vector type for the range space of the operator.
2024          */
2025         using Domain = VectorType;
2026 
2027         /**
2028          * @name Constructors / destructor
2029          */
2030         //@{
2031 
2032         /**
2033          * Default constructor
2034          *
2035          * @note By design, the resulting object is inoperable since there is
2036          * insufficient information with which to construct the domain and
2037          * range maps.
2038          */
2039         TrilinosPayload();
2040 
2041         /**
2042          * Constructor for a sparse matrix based on an exemplary matrix
2043          */
2044         TrilinosPayload(const TrilinosWrappers::SparseMatrix &matrix_exemplar,
2045                         const TrilinosWrappers::SparseMatrix &matrix);
2046 
2047         /**
2048          * Constructor for a preconditioner based on an exemplary matrix
2049          */
2050         TrilinosPayload(
2051           const TrilinosWrappers::SparseMatrix &    matrix_exemplar,
2052           const TrilinosWrappers::PreconditionBase &preconditioner);
2053 
2054         /**
2055          * Constructor for a preconditioner based on an exemplary preconditioner
2056          */
2057         TrilinosPayload(
2058           const TrilinosWrappers::PreconditionBase &preconditioner_exemplar,
2059           const TrilinosWrappers::PreconditionBase &preconditioner);
2060 
2061         /**
2062          * Default copy constructor
2063          */
2064         TrilinosPayload(const TrilinosPayload &payload);
2065 
2066         /**
2067          * Composite copy constructor
2068          *
2069          * This is required for PackagedOperations as it sets up the domain and
2070          * range maps, and composite <tt>vmult</tt> and <tt>Tvmult</tt>
2071          * operations based on the combined operation of both operations
2072          */
2073         TrilinosPayload(const TrilinosPayload &first_op,
2074                         const TrilinosPayload &second_op);
2075 
2076         /**
2077          * Destructor
2078          */
2079         virtual ~TrilinosPayload() override = default;
2080 
2081         /**
2082          * Return a payload configured for identity operations
2083          */
2084         TrilinosPayload
2085         identity_payload() const;
2086 
2087         /**
2088          * Return a payload configured for null operations
2089          */
2090         TrilinosPayload
2091         null_payload() const;
2092 
2093         /**
2094          * Return a payload configured for transpose operations
2095          */
2096         TrilinosPayload
2097         transpose_payload() const;
2098 
2099         /**
2100          * Return a payload configured for inverse operations
2101          *
2102          * Invoking this factory function will configure two additional
2103          * functions, namely <tt>inv_vmult</tt> and <tt>inv_Tvmult</tt>, both of
2104          * which wrap inverse operations. The <tt>vmult</tt> and <tt>Tvmult</tt>
2105          * operations retain the standard
2106          * definitions inherited from @p op.
2107          *
2108          * @note This function is enabled only if the solver and preconditioner
2109          * derive from the respective TrilinosWrappers base classes.
2110          * The C++ compiler will therefore only consider this function if the
2111          * following criterion are satisfied:
2112          * 1. the @p Solver derives from TrilinosWrappers::SolverBase, and
2113          * 2. the @p Preconditioner derives from TrilinosWrappers::PreconditionBase.
2114          */
2115         template <typename Solver, typename Preconditioner>
2116         typename std::enable_if<
2117           std::is_base_of<TrilinosWrappers::SolverBase, Solver>::value &&
2118             std::is_base_of<TrilinosWrappers::PreconditionBase,
2119                             Preconditioner>::value,
2120           TrilinosPayload>::type
2121         inverse_payload(Solver &, const Preconditioner &) const;
2122 
2123         /**
2124          * Return a payload configured for inverse operations
2125          *
2126          * Invoking this factory function will configure two additional
2127          * functions, namely <tt>inv_vmult</tt> and <tt>inv_Tvmult</tt>, both of
2128          * which
2129          * are disabled because the @p Solver or @p Preconditioner are not
2130          * compatible with Epetra_MultiVector.
2131          * The <tt>vmult</tt> and <tt>Tvmult</tt> operations retain the standard
2132          * definitions inherited from @p op.
2133          *
2134          * @note The C++ compiler will only consider this function if the
2135          * following criterion are satisfied:
2136          * 1. the @p Solver does not derive from TrilinosWrappers::SolverBase, and
2137          * 2. the @p Preconditioner does not derive from
2138          * TrilinosWrappers::PreconditionBase.
2139          */
2140         template <typename Solver, typename Preconditioner>
2141         typename std::enable_if<
2142           !(std::is_base_of<TrilinosWrappers::SolverBase, Solver>::value &&
2143             std::is_base_of<TrilinosWrappers::PreconditionBase,
2144                             Preconditioner>::value),
2145           TrilinosPayload>::type
2146         inverse_payload(Solver &, const Preconditioner &) const;
2147 
2148         //@}
2149 
2150         /**
2151          * @name LinearOperator functionality
2152          */
2153         //@{
2154 
2155         /**
2156          * Return an IndexSet that defines the partitioning of the domain space
2157          * of this matrix, i.e., the partitioning of the vectors this matrix has
2158          * to be multiplied with / operate on.
2159          */
2160         IndexSet
2161         locally_owned_domain_indices() const;
2162 
2163         /**
2164          * Return an IndexSet that defines the partitioning of the range space
2165          * of this matrix, i.e., the partitioning of the vectors that result
2166          * from matrix-vector products.
2167          */
2168         IndexSet
2169         locally_owned_range_indices() const;
2170 
2171         /**
2172          * Return the MPI communicator object in use with this Payload.
2173          */
2174         MPI_Comm
2175         get_mpi_communicator() const;
2176 
2177         /**
2178          * Sets an internal flag so that all operations performed by the matrix,
2179          * i.e., multiplications, are done in transposed order.
2180          * @note This does not reshape the matrix to transposed form directly,
2181          * so care should be taken when using this flag.
2182          */
2183         void
2184         transpose();
2185 
2186         /**
2187          * The standard matrix-vector operation to be performed by the payload
2188          * when Apply is called.
2189          *
2190          * @note This is not called by a LinearOperator, but rather by Trilinos
2191          * functions that expect this to mimic the action of the LinearOperator.
2192          */
2193         std::function<void(VectorType &, const VectorType &)> vmult;
2194 
2195         /**
2196          * The standard transpose matrix-vector operation to be performed by
2197          * the payload when Apply is called.
2198          *
2199          * @note This is not called by a LinearOperator, but rather by Trilinos
2200          * functions that expect this to mimic the action of the LinearOperator.
2201          */
2202         std::function<void(VectorType &, const VectorType &)> Tvmult;
2203 
2204         /**
2205          * The inverse matrix-vector operation to be performed by the payload
2206          * when ApplyInverse is called.
2207          *
2208          * @note This is not called by a LinearOperator, but rather by Trilinos
2209          * functions that expect this to mimic the action of the
2210          * InverseOperator.
2211          */
2212         std::function<void(VectorType &, const VectorType &)> inv_vmult;
2213 
2214         /**
2215          * The inverse transpose matrix-vector operation to be performed by
2216          * the payload when ApplyInverse is called.
2217          *
2218          * @note This is not called by a LinearOperator, but rather by Trilinos
2219          * functions that expect this to mimic the action of the
2220          * InverseOperator.
2221          */
2222         std::function<void(VectorType &, const VectorType &)> inv_Tvmult;
2223 
2224         //@}
2225 
2226         /**
2227          * @name Core Epetra_Operator functionality
2228          */
2229         //@{
2230 
2231         /**
2232          * Return the status of the transpose flag for this operator
2233          *
2234          * This overloads the same function from the Trilinos class
2235          * Epetra_Operator.
2236          */
2237         virtual bool
2238         UseTranspose() const override;
2239 
2240         /**
2241          * Sets an internal flag so that all operations performed by the matrix,
2242          * i.e., multiplications, are done in transposed order.
2243          *
2244          * This overloads the same function from the Trilinos class
2245          * Epetra_Operator.
2246          *
2247          * @note This does not reshape the matrix to transposed form directly,
2248          * so care should be taken when using this flag. When the flag is set to
2249          * true (either here or directly on the underlying Trilinos object
2250          * itself), this object is no longer thread-safe. In essence, it is not
2251          * possible ensure that the transposed state of the LinearOperator and
2252          * the underlying Trilinos object remain synchronized throughout all
2253          * operations that may occur on different threads simultaneously.
2254          */
2255         virtual int
2256         SetUseTranspose(bool UseTranspose) override;
2257 
2258         /**
2259          * Apply the vmult operation on a vector @p X (of internally defined
2260          * type VectorType) and store the result in the vector @p Y.
2261          *
2262          * This overloads the same function from the Trilinos class
2263          * Epetra_Operator.
2264          *
2265          * @note The intended operation depends on the status of the internal
2266          * transpose flag. If this flag is set to true, the result will be
2267          * the equivalent of performing a Tvmult operation.
2268          */
2269         virtual int
2270         Apply(const VectorType &X, VectorType &Y) const override;
2271 
2272         /**
2273          * Apply the vmult inverse operation on a vector @p X (of internally
2274          * defined type VectorType) and store the result in the vector @p Y.
2275          *
2276          * In practise, this function is only called from a Trilinos solver if
2277          * the wrapped object is to act as a preconditioner.
2278          *
2279          * This overloads the same function from the Trilinos class
2280          * Epetra_Operator.
2281          *
2282          * @note This function will only be operable if the payload has been
2283          * initialized with an InverseOperator, or is a wrapper to a
2284          * preconditioner. If not, then using this function will lead to an
2285          * error being thrown.
2286          * @note The intended operation depends on the status of the internal
2287          * transpose flag. If this flag is set to true, the result will be
2288          * the equivalent of performing a Tvmult operation.
2289          */
2290         virtual int
2291         ApplyInverse(const VectorType &Y, VectorType &X) const override;
2292         //@}
2293 
2294         /**
2295          * @name Additional Epetra_Operator functionality
2296          */
2297         //@{
2298 
2299         /**
2300          * Return a label to describe this class.
2301          *
2302          * This overloads the same function from the Trilinos class
2303          * Epetra_Operator.
2304          */
2305         virtual const char *
2306         Label() const override;
2307 
2308         /**
2309          * Return a reference to the underlying MPI communicator for
2310          * this object.
2311          *
2312          * This overloads the same function from the Trilinos class
2313          * Epetra_Operator.
2314          */
2315         virtual const Epetra_Comm &
2316         Comm() const override;
2317 
2318         /**
2319          * Return the partitioning of the domain space of this matrix, i.e., the
2320          * partitioning of the vectors this matrix has to be multiplied with.
2321          *
2322          * This overloads the same function from the Trilinos class
2323          * Epetra_Operator.
2324          */
2325         virtual const Epetra_Map &
2326         OperatorDomainMap() const override;
2327 
2328         /**
2329          * Return the partitioning of the range space of this matrix, i.e., the
2330          * partitioning of the vectors that are result from matrix-vector
2331          * products.
2332          *
2333          * This overloads the same function from the Trilinos class
2334          * Epetra_Operator.
2335          */
2336         virtual const Epetra_Map &
2337         OperatorRangeMap() const override;
2338         //@}
2339 
2340       private:
2341         /**
2342          * A flag recording whether the operator is to perform standard
2343          * matrix-vector multiplication, or the transpose operation.
2344          */
2345         bool use_transpose;
2346 
2347         /**
2348          * Internal communication pattern in case the matrix needs to be copied
2349          * from deal.II format.
2350          */
2351 #    ifdef DEAL_II_WITH_MPI
2352         Epetra_MpiComm communicator;
2353 #    else
2354         Epetra_SerialComm communicator;
2355 #    endif
2356 
2357         /**
2358          * Epetra_Map that sets the partitioning of the domain space of
2359          * this operator.
2360          */
2361         Epetra_Map domain_map;
2362 
2363         /**
2364          * Epetra_Map that sets the partitioning of the range space of
2365          * this operator.
2366          */
2367         Epetra_Map range_map;
2368 
2369         /**
2370          * Return a flag that describes whether this operator can return the
2371          * computation of the infinity norm. Since in general this is not the
2372          * case, this always returns a negetive result.
2373          *
2374          * This overloads the same function from the Trilinos class
2375          * Epetra_Operator.
2376          */
2377         virtual bool
2378         HasNormInf() const override;
2379 
2380         /**
2381          * Return the infinity norm of this operator.
2382          * Throws an error since, in general, we cannot compute this value.
2383          *
2384          * This overloads the same function from the Trilinos class
2385          * Epetra_Operator.
2386          */
2387         virtual double
2388         NormInf() const override;
2389       };
2390 
2391       /**
2392        * Return an operator that returns a payload configured to support the
2393        * addition of two LinearOperators
2394        */
2395       TrilinosPayload
2396       operator+(const TrilinosPayload &first_op,
2397                 const TrilinosPayload &second_op);
2398 
2399       /**
2400        * Return an operator that returns a payload configured to support the
2401        * multiplication of two LinearOperators
2402        */
2403       TrilinosPayload operator*(const TrilinosPayload &first_op,
2404                                 const TrilinosPayload &second_op);
2405 
2406     } // namespace LinearOperatorImplementation
2407   }   /* namespace internal */
2408 
2409 
2410 
2411   // ----------------------- inline and template functions --------------------
2412 
2413 #    ifndef DOXYGEN
2414 
2415   namespace SparseMatrixIterators
2416   {
AccessorBase(SparseMatrix * matrix,size_type row,size_type index)2417     inline AccessorBase::AccessorBase(SparseMatrix *matrix,
2418                                       size_type     row,
2419                                       size_type     index)
2420       : matrix(matrix)
2421       , a_row(row)
2422       , a_index(index)
2423     {
2424       visit_present_row();
2425     }
2426 
2427 
2428     inline AccessorBase::size_type
row()2429     AccessorBase::row() const
2430     {
2431       Assert(a_row < matrix->m(), ExcBeyondEndOfMatrix());
2432       return a_row;
2433     }
2434 
2435 
2436     inline AccessorBase::size_type
column()2437     AccessorBase::column() const
2438     {
2439       Assert(a_row < matrix->m(), ExcBeyondEndOfMatrix());
2440       return (*colnum_cache)[a_index];
2441     }
2442 
2443 
2444     inline AccessorBase::size_type
index()2445     AccessorBase::index() const
2446     {
2447       Assert(a_row < matrix->m(), ExcBeyondEndOfMatrix());
2448       return a_index;
2449     }
2450 
2451 
Accessor(MatrixType * matrix,const size_type row,const size_type index)2452     inline Accessor<true>::Accessor(MatrixType *    matrix,
2453                                     const size_type row,
2454                                     const size_type index)
2455       : AccessorBase(const_cast<SparseMatrix *>(matrix), row, index)
2456     {}
2457 
2458 
2459     template <bool Other>
Accessor(const Accessor<Other> & other)2460     inline Accessor<true>::Accessor(const Accessor<Other> &other)
2461       : AccessorBase(other)
2462     {}
2463 
2464 
2465     inline TrilinosScalar
value()2466     Accessor<true>::value() const
2467     {
2468       Assert(a_row < matrix->m(), ExcBeyondEndOfMatrix());
2469       return (*value_cache)[a_index];
2470     }
2471 
2472 
Reference(const Accessor<false> & acc)2473     inline Accessor<false>::Reference::Reference(const Accessor<false> &acc)
2474       : accessor(const_cast<Accessor<false> &>(acc))
2475     {}
2476 
2477 
TrilinosScalar()2478     inline Accessor<false>::Reference::operator TrilinosScalar() const
2479     {
2480       return (*accessor.value_cache)[accessor.a_index];
2481     }
2482 
2483     inline const Accessor<false>::Reference &
2484     Accessor<false>::Reference::operator=(const TrilinosScalar n) const
2485     {
2486       (*accessor.value_cache)[accessor.a_index] = n;
2487       accessor.matrix->set(accessor.row(),
2488                            accessor.column(),
2489                            static_cast<TrilinosScalar>(*this));
2490       return *this;
2491     }
2492 
2493 
2494     inline const Accessor<false>::Reference &
2495     Accessor<false>::Reference::operator+=(const TrilinosScalar n) const
2496     {
2497       (*accessor.value_cache)[accessor.a_index] += n;
2498       accessor.matrix->set(accessor.row(),
2499                            accessor.column(),
2500                            static_cast<TrilinosScalar>(*this));
2501       return *this;
2502     }
2503 
2504 
2505     inline const Accessor<false>::Reference &
2506     Accessor<false>::Reference::operator-=(const TrilinosScalar n) const
2507     {
2508       (*accessor.value_cache)[accessor.a_index] -= n;
2509       accessor.matrix->set(accessor.row(),
2510                            accessor.column(),
2511                            static_cast<TrilinosScalar>(*this));
2512       return *this;
2513     }
2514 
2515 
2516     inline const Accessor<false>::Reference &
2517     Accessor<false>::Reference::operator*=(const TrilinosScalar n) const
2518     {
2519       (*accessor.value_cache)[accessor.a_index] *= n;
2520       accessor.matrix->set(accessor.row(),
2521                            accessor.column(),
2522                            static_cast<TrilinosScalar>(*this));
2523       return *this;
2524     }
2525 
2526 
2527     inline const Accessor<false>::Reference &
2528     Accessor<false>::Reference::operator/=(const TrilinosScalar n) const
2529     {
2530       (*accessor.value_cache)[accessor.a_index] /= n;
2531       accessor.matrix->set(accessor.row(),
2532                            accessor.column(),
2533                            static_cast<TrilinosScalar>(*this));
2534       return *this;
2535     }
2536 
2537 
Accessor(MatrixType * matrix,const size_type row,const size_type index)2538     inline Accessor<false>::Accessor(MatrixType *    matrix,
2539                                      const size_type row,
2540                                      const size_type index)
2541       : AccessorBase(matrix, row, index)
2542     {}
2543 
2544 
2545     inline Accessor<false>::Reference
value()2546     Accessor<false>::value() const
2547     {
2548       Assert(a_row < matrix->m(), ExcBeyondEndOfMatrix());
2549       return {*this};
2550     }
2551 
2552 
2553 
2554     template <bool Constness>
Iterator(MatrixType * matrix,const size_type row,const size_type index)2555     inline Iterator<Constness>::Iterator(MatrixType *    matrix,
2556                                          const size_type row,
2557                                          const size_type index)
2558       : accessor(matrix, row, index)
2559     {}
2560 
2561 
2562     template <bool Constness>
2563     template <bool Other>
Iterator(const Iterator<Other> & other)2564     inline Iterator<Constness>::Iterator(const Iterator<Other> &other)
2565       : accessor(other.accessor)
2566     {}
2567 
2568 
2569     template <bool Constness>
2570     inline Iterator<Constness> &
2571     Iterator<Constness>::operator++()
2572     {
2573       Assert(accessor.a_row < accessor.matrix->m(), ExcIteratorPastEnd());
2574 
2575       ++accessor.a_index;
2576 
2577       // If at end of line: do one
2578       // step, then cycle until we
2579       // find a row with a nonzero
2580       // number of entries.
2581       if (accessor.a_index >= accessor.colnum_cache->size())
2582         {
2583           accessor.a_index = 0;
2584           ++accessor.a_row;
2585 
2586           while ((accessor.a_row < accessor.matrix->m()) &&
2587                  ((accessor.matrix->in_local_range(accessor.a_row) == false) ||
2588                   (accessor.matrix->row_length(accessor.a_row) == 0)))
2589             ++accessor.a_row;
2590 
2591           accessor.visit_present_row();
2592         }
2593       return *this;
2594     }
2595 
2596 
2597     template <bool Constness>
2598     inline Iterator<Constness>
2599     Iterator<Constness>::operator++(int)
2600     {
2601       const Iterator<Constness> old_state = *this;
2602       ++(*this);
2603       return old_state;
2604     }
2605 
2606 
2607 
2608     template <bool Constness>
2609     inline const Accessor<Constness> &Iterator<Constness>::operator*() const
2610     {
2611       return accessor;
2612     }
2613 
2614 
2615 
2616     template <bool Constness>
2617     inline const Accessor<Constness> *Iterator<Constness>::operator->() const
2618     {
2619       return &accessor;
2620     }
2621 
2622 
2623 
2624     template <bool Constness>
2625     inline bool
2626     Iterator<Constness>::operator==(const Iterator<Constness> &other) const
2627     {
2628       return (accessor.a_row == other.accessor.a_row &&
2629               accessor.a_index == other.accessor.a_index);
2630     }
2631 
2632 
2633 
2634     template <bool Constness>
2635     inline bool
2636     Iterator<Constness>::operator!=(const Iterator<Constness> &other) const
2637     {
2638       return !(*this == other);
2639     }
2640 
2641 
2642 
2643     template <bool Constness>
2644     inline bool
2645     Iterator<Constness>::operator<(const Iterator<Constness> &other) const
2646     {
2647       return (accessor.row() < other.accessor.row() ||
2648               (accessor.row() == other.accessor.row() &&
2649                accessor.index() < other.accessor.index()));
2650     }
2651 
2652 
2653     template <bool Constness>
2654     inline bool
2655     Iterator<Constness>::operator>(const Iterator<Constness> &other) const
2656     {
2657       return (other < *this);
2658     }
2659 
2660   } // namespace SparseMatrixIterators
2661 
2662 
2663 
2664   inline SparseMatrix::const_iterator
begin()2665   SparseMatrix::begin() const
2666   {
2667     return begin(0);
2668   }
2669 
2670 
2671 
2672   inline SparseMatrix::const_iterator
end()2673   SparseMatrix::end() const
2674   {
2675     return const_iterator(this, m(), 0);
2676   }
2677 
2678 
2679 
2680   inline SparseMatrix::const_iterator
begin(const size_type r)2681   SparseMatrix::begin(const size_type r) const
2682   {
2683     AssertIndexRange(r, m());
2684     if (in_local_range(r) && (row_length(r) > 0))
2685       return const_iterator(this, r, 0);
2686     else
2687       return end(r);
2688   }
2689 
2690 
2691 
2692   inline SparseMatrix::const_iterator
end(const size_type r)2693   SparseMatrix::end(const size_type r) const
2694   {
2695     AssertIndexRange(r, m());
2696 
2697     // place the iterator on the first entry
2698     // past this line, or at the end of the
2699     // matrix
2700     for (size_type i = r + 1; i < m(); ++i)
2701       if (in_local_range(i) && (row_length(i) > 0))
2702         return const_iterator(this, i, 0);
2703 
2704     // if there is no such line, then take the
2705     // end iterator of the matrix
2706     return end();
2707   }
2708 
2709 
2710 
2711   inline SparseMatrix::iterator
begin()2712   SparseMatrix::begin()
2713   {
2714     return begin(0);
2715   }
2716 
2717 
2718 
2719   inline SparseMatrix::iterator
end()2720   SparseMatrix::end()
2721   {
2722     return iterator(this, m(), 0);
2723   }
2724 
2725 
2726 
2727   inline SparseMatrix::iterator
begin(const size_type r)2728   SparseMatrix::begin(const size_type r)
2729   {
2730     AssertIndexRange(r, m());
2731     if (in_local_range(r) && (row_length(r) > 0))
2732       return iterator(this, r, 0);
2733     else
2734       return end(r);
2735   }
2736 
2737 
2738 
2739   inline SparseMatrix::iterator
end(const size_type r)2740   SparseMatrix::end(const size_type r)
2741   {
2742     AssertIndexRange(r, m());
2743 
2744     // place the iterator on the first entry
2745     // past this line, or at the end of the
2746     // matrix
2747     for (size_type i = r + 1; i < m(); ++i)
2748       if (in_local_range(i) && (row_length(i) > 0))
2749         return iterator(this, i, 0);
2750 
2751     // if there is no such line, then take the
2752     // end iterator of the matrix
2753     return end();
2754   }
2755 
2756 
2757 
2758   inline bool
in_local_range(const size_type index)2759   SparseMatrix::in_local_range(const size_type index) const
2760   {
2761     TrilinosWrappers::types::int_type begin, end;
2762 #      ifndef DEAL_II_WITH_64BIT_INDICES
2763     begin = matrix->RowMap().MinMyGID();
2764     end   = matrix->RowMap().MaxMyGID() + 1;
2765 #      else
2766     begin = matrix->RowMap().MinMyGID64();
2767     end   = matrix->RowMap().MaxMyGID64() + 1;
2768 #      endif
2769 
2770     return ((index >= static_cast<size_type>(begin)) &&
2771             (index < static_cast<size_type>(end)));
2772   }
2773 
2774 
2775 
2776   inline bool
is_compressed()2777   SparseMatrix::is_compressed() const
2778   {
2779     return compressed;
2780   }
2781 
2782 
2783 
2784   // Inline the set() and add() functions, since they will be called
2785   // frequently, and the compiler can optimize away some unnecessary loops
2786   // when the sizes are given at compile time.
2787   template <>
2788   void
2789   SparseMatrix::set<TrilinosScalar>(const size_type       row,
2790                                     const size_type       n_cols,
2791                                     const size_type *     col_indices,
2792                                     const TrilinosScalar *values,
2793                                     const bool            elide_zero_values);
2794 
2795 
2796 
2797   template <typename Number>
2798   void
set(const size_type row,const size_type n_cols,const size_type * col_indices,const Number * values,const bool elide_zero_values)2799   SparseMatrix::set(const size_type  row,
2800                     const size_type  n_cols,
2801                     const size_type *col_indices,
2802                     const Number *   values,
2803                     const bool       elide_zero_values)
2804   {
2805     std::vector<TrilinosScalar> trilinos_values(n_cols);
2806     std::copy(values, values + n_cols, trilinos_values.begin());
2807     this->set(
2808       row, n_cols, col_indices, trilinos_values.data(), elide_zero_values);
2809   }
2810 
2811 
2812 
2813   inline void
set(const size_type i,const size_type j,const TrilinosScalar value)2814   SparseMatrix::set(const size_type      i,
2815                     const size_type      j,
2816                     const TrilinosScalar value)
2817   {
2818     AssertIsFinite(value);
2819 
2820     set(i, 1, &j, &value, false);
2821   }
2822 
2823 
2824 
2825   inline void
set(const std::vector<size_type> & indices,const FullMatrix<TrilinosScalar> & values,const bool elide_zero_values)2826   SparseMatrix::set(const std::vector<size_type> &    indices,
2827                     const FullMatrix<TrilinosScalar> &values,
2828                     const bool                        elide_zero_values)
2829   {
2830     Assert(indices.size() == values.m(),
2831            ExcDimensionMismatch(indices.size(), values.m()));
2832     Assert(values.m() == values.n(), ExcNotQuadratic());
2833 
2834     for (size_type i = 0; i < indices.size(); ++i)
2835       set(indices[i],
2836           indices.size(),
2837           indices.data(),
2838           &values(i, 0),
2839           elide_zero_values);
2840   }
2841 
2842 
2843 
2844   inline void
add(const size_type i,const size_type j,const TrilinosScalar value)2845   SparseMatrix::add(const size_type      i,
2846                     const size_type      j,
2847                     const TrilinosScalar value)
2848   {
2849     AssertIsFinite(value);
2850 
2851     if (value == 0)
2852       {
2853         // we have to check after Insert/Add in any case to be consistent
2854         // with the MPI communication model, but we can save some
2855         // work if the addend is zero. However, these actions are done in case
2856         // we pass on to the other function.
2857 
2858         // TODO: fix this (do not run compress here, but fail)
2859         if (last_action == Insert)
2860           {
2861             int ierr;
2862             ierr = matrix->GlobalAssemble(*column_space_map,
2863                                           matrix->RowMap(),
2864                                           false);
2865 
2866             Assert(ierr == 0, ExcTrilinosError(ierr));
2867             (void)ierr; // removes -Wunused-but-set-variable in optimized mode
2868           }
2869 
2870         last_action = Add;
2871 
2872         return;
2873       }
2874     else
2875       add(i, 1, &j, &value, false);
2876   }
2877 
2878 
2879 
2880   // inline "simple" functions that are called frequently and do only involve
2881   // a call to some Trilinos function.
2882   inline SparseMatrix::size_type
m()2883   SparseMatrix::m() const
2884   {
2885 #      ifndef DEAL_II_WITH_64BIT_INDICES
2886     return matrix->NumGlobalRows();
2887 #      else
2888     return matrix->NumGlobalRows64();
2889 #      endif
2890   }
2891 
2892 
2893 
2894   inline SparseMatrix::size_type
n()2895   SparseMatrix::n() const
2896   {
2897     // If the matrix structure has not been fixed (i.e., we did not have a
2898     // sparsity pattern), it does not know about the number of columns so we
2899     // must always take this from the additional column space map
2900     Assert(column_space_map.get() != nullptr, ExcInternalError());
2901     return n_global_elements(*column_space_map);
2902   }
2903 
2904 
2905 
2906   inline unsigned int
local_size()2907   SparseMatrix::local_size() const
2908   {
2909     return matrix->NumMyRows();
2910   }
2911 
2912 
2913 
2914   inline std::pair<SparseMatrix::size_type, SparseMatrix::size_type>
local_range()2915   SparseMatrix::local_range() const
2916   {
2917     size_type begin, end;
2918 #      ifndef DEAL_II_WITH_64BIT_INDICES
2919     begin = matrix->RowMap().MinMyGID();
2920     end   = matrix->RowMap().MaxMyGID() + 1;
2921 #      else
2922     begin = matrix->RowMap().MinMyGID64();
2923     end   = matrix->RowMap().MaxMyGID64() + 1;
2924 #      endif
2925 
2926     return std::make_pair(begin, end);
2927   }
2928 
2929 
2930 
2931   inline SparseMatrix::size_type
n_nonzero_elements()2932   SparseMatrix::n_nonzero_elements() const
2933   {
2934 #      ifndef DEAL_II_WITH_64BIT_INDICES
2935     return matrix->NumGlobalNonzeros();
2936 #      else
2937     return matrix->NumGlobalNonzeros64();
2938 #      endif
2939   }
2940 
2941 
2942 
2943   template <typename SparsityPatternType>
2944   inline void
reinit(const IndexSet & parallel_partitioning,const SparsityPatternType & sparsity_pattern,const MPI_Comm & communicator,const bool exchange_data)2945   SparseMatrix::reinit(const IndexSet &           parallel_partitioning,
2946                        const SparsityPatternType &sparsity_pattern,
2947                        const MPI_Comm &           communicator,
2948                        const bool                 exchange_data)
2949   {
2950     reinit(parallel_partitioning,
2951            parallel_partitioning,
2952            sparsity_pattern,
2953            communicator,
2954            exchange_data);
2955   }
2956 
2957 
2958 
2959   template <typename number>
2960   inline void
reinit(const IndexSet & parallel_partitioning,const::dealii::SparseMatrix<number> & sparse_matrix,const MPI_Comm & communicator,const double drop_tolerance,const bool copy_values,const::dealii::SparsityPattern * use_this_sparsity)2961   SparseMatrix::reinit(const IndexSet &parallel_partitioning,
2962                        const ::dealii::SparseMatrix<number> &sparse_matrix,
2963                        const MPI_Comm &                      communicator,
2964                        const double                          drop_tolerance,
2965                        const bool                            copy_values,
2966                        const ::dealii::SparsityPattern *     use_this_sparsity)
2967   {
2968     Epetra_Map map =
2969       parallel_partitioning.make_trilinos_map(communicator, false);
2970     reinit(parallel_partitioning,
2971            parallel_partitioning,
2972            sparse_matrix,
2973            drop_tolerance,
2974            copy_values,
2975            use_this_sparsity);
2976   }
2977 
2978 
2979 
2980   inline const Epetra_CrsMatrix &
trilinos_matrix()2981   SparseMatrix::trilinos_matrix() const
2982   {
2983     return static_cast<const Epetra_CrsMatrix &>(*matrix);
2984   }
2985 
2986 
2987 
2988   inline const Epetra_CrsGraph &
trilinos_sparsity_pattern()2989   SparseMatrix::trilinos_sparsity_pattern() const
2990   {
2991     return matrix->Graph();
2992   }
2993 
2994 
2995 
2996   inline IndexSet
locally_owned_domain_indices()2997   SparseMatrix::locally_owned_domain_indices() const
2998   {
2999     return IndexSet(matrix->DomainMap());
3000   }
3001 
3002 
3003 
3004   inline IndexSet
locally_owned_range_indices()3005   SparseMatrix::locally_owned_range_indices() const
3006   {
3007     return IndexSet(matrix->RangeMap());
3008   }
3009 
3010 
3011 
3012   inline void
prepare_add()3013   SparseMatrix::prepare_add()
3014   {
3015     // nothing to do here
3016   }
3017 
3018 
3019 
3020   inline void
prepare_set()3021   SparseMatrix::prepare_set()
3022   {
3023     // nothing to do here
3024   }
3025 
3026 
3027   namespace internal
3028   {
3029     namespace LinearOperatorImplementation
3030     {
3031       template <typename Solver, typename Preconditioner>
3032       typename std::enable_if<
3033         std::is_base_of<TrilinosWrappers::SolverBase, Solver>::value &&
3034           std::is_base_of<TrilinosWrappers::PreconditionBase,
3035                           Preconditioner>::value,
3036         TrilinosPayload>::type
inverse_payload(Solver & solver,const Preconditioner & preconditioner)3037       TrilinosPayload::inverse_payload(
3038         Solver &              solver,
3039         const Preconditioner &preconditioner) const
3040       {
3041         const auto &payload = *this;
3042 
3043         TrilinosPayload return_op(payload);
3044 
3045         // Capture by copy so the payloads are always valid
3046 
3047         return_op.inv_vmult = [payload, &solver, &preconditioner](
3048                                 TrilinosPayload::Domain &     tril_dst,
3049                                 const TrilinosPayload::Range &tril_src) {
3050           // Duplicated from TrilinosWrappers::PreconditionBase::vmult
3051           // as well as from TrilinosWrappers::SparseMatrix::Tvmult
3052           Assert(&tril_src != &tril_dst,
3053                  TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
3054           internal::check_vector_map_equality(payload,
3055                                               tril_src,
3056                                               tril_dst,
3057                                               !payload.UseTranspose());
3058           solver.solve(payload, tril_dst, tril_src, preconditioner);
3059         };
3060 
3061         return_op.inv_Tvmult = [payload, &solver, &preconditioner](
3062                                  TrilinosPayload::Range &       tril_dst,
3063                                  const TrilinosPayload::Domain &tril_src) {
3064           // Duplicated from TrilinosWrappers::PreconditionBase::vmult
3065           // as well as from TrilinosWrappers::SparseMatrix::Tvmult
3066           Assert(&tril_src != &tril_dst,
3067                  TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
3068           internal::check_vector_map_equality(payload,
3069                                               tril_src,
3070                                               tril_dst,
3071                                               payload.UseTranspose());
3072 
3073           const_cast<TrilinosPayload &>(payload).transpose();
3074           solver.solve(payload, tril_dst, tril_src, preconditioner);
3075           const_cast<TrilinosPayload &>(payload).transpose();
3076         };
3077 
3078         // If the input operator is already setup for transpose operations, then
3079         // we must do similar with its inverse.
3080         if (return_op.UseTranspose() == true)
3081           std::swap(return_op.inv_vmult, return_op.inv_Tvmult);
3082 
3083         return return_op;
3084       }
3085 
3086       template <typename Solver, typename Preconditioner>
3087       typename std::enable_if<
3088         !(std::is_base_of<TrilinosWrappers::SolverBase, Solver>::value &&
3089           std::is_base_of<TrilinosWrappers::PreconditionBase,
3090                           Preconditioner>::value),
3091         TrilinosPayload>::type
inverse_payload(Solver &,const Preconditioner &)3092       TrilinosPayload::inverse_payload(Solver &, const Preconditioner &) const
3093       {
3094         TrilinosPayload return_op(*this);
3095 
3096         return_op.inv_vmult = [](TrilinosPayload::Domain &,
3097                                  const TrilinosPayload::Range &) {
3098           AssertThrow(false,
3099                       ExcMessage("Payload inv_vmult disabled because of "
3100                                  "incompatible solver/preconditioner choice."));
3101         };
3102 
3103         return_op.inv_Tvmult = [](TrilinosPayload::Range &,
3104                                   const TrilinosPayload::Domain &) {
3105           AssertThrow(false,
3106                       ExcMessage("Payload inv_vmult disabled because of "
3107                                  "incompatible solver/preconditioner choice."));
3108         };
3109 
3110         return return_op;
3111       }
3112     } // namespace LinearOperatorImplementation
3113   }   // namespace internal
3114 
3115   template <>
3116   void
3117   SparseMatrix::set<TrilinosScalar>(const size_type       row,
3118                                     const size_type       n_cols,
3119                                     const size_type *     col_indices,
3120                                     const TrilinosScalar *values,
3121                                     const bool            elide_zero_values);
3122 #    endif // DOXYGEN
3123 
3124 } /* namespace TrilinosWrappers */
3125 
3126 
3127 DEAL_II_NAMESPACE_CLOSE
3128 
3129 
3130 #  endif // DEAL_II_WITH_TRILINOS
3131 
3132 
3133 /*-----------------------   trilinos_sparse_matrix.h     --------------------*/
3134 
3135 #endif
3136 /*-----------------------   trilinos_sparse_matrix.h     --------------------*/
3137