1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2016 - 2019 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_linear_operator_h
17 #define dealii_trilinos_linear_operator_h
18 
19 #include <deal.II/base/config.h>
20 
21 #if defined(DEAL_II_WITH_TRILINOS)
22 
23 #  include <deal.II/lac/block_linear_operator.h>
24 #  include <deal.II/lac/linear_operator.h>
25 
26 DEAL_II_NAMESPACE_OPEN
27 
28 namespace TrilinosWrappers
29 {
30   // Forward declarations:
31 #  ifndef DOXYGEN
32   class SparseMatrix;
33   class PreconditionBase;
34   class BlockSparseMatrix;
35 
36   namespace internal
37   {
38     namespace LinearOperatorImplementation
39     {
40       class TrilinosPayload;
41     }
42 
43     namespace BlockLinearOperatorImplementation
44     {
45       template <typename PayloadBlockType>
46       class TrilinosBlockPayload;
47     }
48   } // namespace internal
49 #  endif
50 
51   /**
52    * @name Creation of a LinearOperator
53    */
54   //@{
55 
56 
57   /**
58    * @relatesalso LinearOperator
59    *
60    * A function that encapsulates generic @p matrix objects, based on an
61    * @p operator_exemplar, that act on a compatible Vector type into a
62    * LinearOperator.
63    *
64    * This function is the equivalent of the dealii::linear_operator, but
65    * ensures full compatibility with Trilinos operations by preselecting the
66    * appropriate template parameters.
67    *
68    *
69    * @ingroup TrilinosWrappers
70    */
71   template <typename Range, typename Domain = Range, typename Matrix>
72   inline LinearOperator<
73     Range,
74     Domain,
75     TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload>
linear_operator(const TrilinosWrappers::SparseMatrix & operator_exemplar,const Matrix & matrix)76   linear_operator(const TrilinosWrappers::SparseMatrix &operator_exemplar,
77                   const Matrix &                        matrix)
78   {
79     using OperatorExemplar = TrilinosWrappers::SparseMatrix;
80     using Payload =
81       TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
82     return dealii::
83       linear_operator<Range, Domain, Payload, OperatorExemplar, Matrix>(
84         operator_exemplar, matrix);
85   }
86 
87 
88   /**
89    * @relatesalso LinearOperator
90    *
91    * A function that encapsulates generic @p matrix objects that act on a
92    * compatible Vector type into a LinearOperator.
93    *
94    * This function is the equivalent of the dealii::linear_operator, but
95    * ensures full compatibility with Trilinos operations by preselecting the
96    * appropriate template parameters.
97    *
98    *
99    * @ingroup TrilinosWrappers
100    */
101   template <typename Range, typename Domain = Range>
102   inline LinearOperator<
103     Range,
104     Domain,
105     TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload>
linear_operator(const TrilinosWrappers::SparseMatrix & matrix)106   linear_operator(const TrilinosWrappers::SparseMatrix &matrix)
107   {
108     using Matrix = TrilinosWrappers::SparseMatrix;
109     using Payload =
110       TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
111     return dealii::linear_operator<Range, Domain, Payload, Matrix, Matrix>(
112       matrix, matrix);
113   }
114 
115 
116   //@}
117   /**
118    * @name Creation of a BlockLinearOperator
119    */
120   //@{
121 
122 
123   /**
124    * @relatesalso BlockLinearOperator
125    *
126    * A function that encapsulates a @p block_matrix into a BlockLinearOperator.
127    *
128    * This function is the equivalent of the dealii::block_operator, but
129    * ensures full compatibility with Trilinos operations by preselecting the
130    * appropriate template parameters.
131    *
132    *
133    * @ingroup TrilinosWrappers
134    */
135   template <typename Range, typename Domain = Range>
136   inline BlockLinearOperator<
137     Range,
138     Domain,
139     TrilinosWrappers::internal::BlockLinearOperatorImplementation::
140       TrilinosBlockPayload<TrilinosWrappers::internal::
141                              LinearOperatorImplementation::TrilinosPayload>>
block_operator(const TrilinosWrappers::BlockSparseMatrix & block_matrix)142   block_operator(const TrilinosWrappers::BlockSparseMatrix &block_matrix)
143   {
144     using BlockMatrix = TrilinosWrappers::BlockSparseMatrix;
145     using PayloadBlockType =
146       TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
147     using BlockPayload = TrilinosWrappers::internal::
148       BlockLinearOperatorImplementation::TrilinosBlockPayload<PayloadBlockType>;
149     return dealii::block_operator<Range, Domain, BlockPayload, BlockMatrix>(
150       block_matrix);
151   }
152 
153 
154   /**
155    * @relatesalso BlockLinearOperator
156    *
157    * A variant of above function that builds up a block diagonal linear operator
158    * from an array @p ops of diagonal elements (off-diagonal blocks are assumed
159    * to be 0).
160    *
161    * This function is the equivalent of the dealii::block_operator, but
162    * ensures full compatibility with Trilinos operations by preselecting the
163    * appropriate template parameters.
164    *
165    *
166    * @ingroup TrilinosWrappers
167    */
168   template <std::size_t m,
169             std::size_t n,
170             typename Range,
171             typename Domain = Range>
172   inline BlockLinearOperator<
173     Range,
174     Domain,
175     TrilinosWrappers::internal::BlockLinearOperatorImplementation::
176       TrilinosBlockPayload<TrilinosWrappers::internal::
177                              LinearOperatorImplementation::TrilinosPayload>>
block_operator(const std::array<std::array<LinearOperator<typename Range::BlockType,typename Domain::BlockType,TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload>,n>,m> & ops)178   block_operator(
179     const std::array<
180       std::array<
181         LinearOperator<typename Range::BlockType,
182                        typename Domain::BlockType,
183                        TrilinosWrappers::internal::
184                          LinearOperatorImplementation::TrilinosPayload>,
185         n>,
186       m> &ops)
187   {
188     using PayloadBlockType =
189       TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
190     using BlockPayload = TrilinosWrappers::internal::
191       BlockLinearOperatorImplementation::TrilinosBlockPayload<PayloadBlockType>;
192     return dealii::block_operator<m, n, Range, Domain, BlockPayload>(ops);
193   }
194 
195 
196   /**
197    * @relatesalso BlockLinearOperator
198    *
199    * This function extracts the diagonal blocks of @p block_matrix (either a
200    * block matrix type or a BlockLinearOperator) and creates a
201    * BlockLinearOperator with the diagonal. Off-diagonal elements are
202    * initialized as null_operator (with correct reinit_range_vector and
203    * reinit_domain_vector methods).
204    *
205    * This function is the equivalent of the dealii::block_diagonal_operator, but
206    * ensures full compatibility with Trilinos operations by preselecting the
207    * appropriate template parameters.
208    *
209    *
210    * @ingroup TrilinosWrappers
211    */
212   template <typename Range, typename Domain = Range>
213   inline BlockLinearOperator<
214     Range,
215     Domain,
216     TrilinosWrappers::internal::BlockLinearOperatorImplementation::
217       TrilinosBlockPayload<TrilinosWrappers::internal::
218                              LinearOperatorImplementation::TrilinosPayload>>
block_diagonal_operator(const TrilinosWrappers::BlockSparseMatrix & block_matrix)219   block_diagonal_operator(
220     const TrilinosWrappers::BlockSparseMatrix &block_matrix)
221   {
222     using BlockMatrix = TrilinosWrappers::BlockSparseMatrix;
223     using PayloadBlockType =
224       TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
225     using BlockPayload = TrilinosWrappers::internal::
226       BlockLinearOperatorImplementation::TrilinosBlockPayload<PayloadBlockType>;
227     return dealii::
228       block_diagonal_operator<Range, Domain, BlockPayload, BlockMatrix>(
229         block_matrix);
230   }
231 
232 
233   /**
234    * @relatesalso BlockLinearOperator
235    *
236    * A variant of above function that builds up a block diagonal linear operator
237    * from an array @p ops of diagonal elements (off-diagonal blocks are assumed
238    * to be 0).
239    *
240    * This function is the equivalent of the dealii::block_diagonal_operator, but
241    * ensures full compatibility with Trilinos operations by preselecting the
242    * appropriate template parameters.
243    *
244    *
245    * @ingroup TrilinosWrappers
246    */
247   template <std::size_t m, typename Range, typename Domain = Range>
248   inline BlockLinearOperator<
249     Range,
250     Domain,
251     TrilinosWrappers::internal::BlockLinearOperatorImplementation::
252       TrilinosBlockPayload<TrilinosWrappers::internal::
253                              LinearOperatorImplementation::TrilinosPayload>>
block_diagonal_operator(const std::array<LinearOperator<typename Range::BlockType,typename Domain::BlockType,TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload>,m> & ops)254   block_diagonal_operator(
255     const std::array<
256       LinearOperator<typename Range::BlockType,
257                      typename Domain::BlockType,
258                      TrilinosWrappers::internal::LinearOperatorImplementation::
259                        TrilinosPayload>,
260       m> &ops)
261   {
262     using PayloadBlockType =
263       TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
264     using BlockPayload = TrilinosWrappers::internal::
265       BlockLinearOperatorImplementation::TrilinosBlockPayload<PayloadBlockType>;
266     return dealii::block_diagonal_operator<m, Range, Domain, BlockPayload>(ops);
267   }
268 
269   //@}
270 
271 } // namespace TrilinosWrappers
272 
273 DEAL_II_NAMESPACE_CLOSE
274 
275 #endif // DEAL_II_WITH_TRILINOS
276 #endif
277