deal.II version GIT relicensing-6842-g793a97d2aa 2026-10-02 14:00:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
trilinos_block_sparse_matrix.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2008 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
14
15#ifdef DEAL_II_WITH_TRILINOS
16
19
20
21#endif
22
24
25#ifdef DEAL_II_WITH_TRILINOS
26
27namespace TrilinosWrappers
28{
30 {
31 // delete previous content of
32 // the subobjects array
33 try
34 {
35 clear();
36 }
37 catch (...)
38 {}
39 }
40
41
42
43# ifndef DOXYGEN
44 void
45 BlockSparseMatrix::reinit(const size_type n_block_rows,
46 const size_type n_block_columns)
47 {
48 // first delete previous content of
49 // the subobjects array
50 clear();
51
52 // then resize. set sizes of blocks to
53 // zero. user will later have to call
54 // collect_sizes for this
55 this->sub_objects.reinit(n_block_rows, n_block_columns);
56 this->row_block_indices.reinit(n_block_rows, 0);
57 this->column_block_indices.reinit(n_block_columns, 0);
58
59 // and reinitialize the blocks
60 for (size_type r = 0; r < this->n_block_rows(); ++r)
61 for (size_type c = 0; c < this->n_block_cols(); ++c)
62 {
63 BlockType *p = new BlockType();
64
65 Assert(this->sub_objects[r][c] == nullptr, ExcInternalError());
66 this->sub_objects[r][c] = p;
67 }
68 }
69# endif
70
71
72
73 template <typename BlockSparsityPatternType>
74 void
76 const std::vector<IndexSet> &parallel_partitioning,
77 const BlockSparsityPatternType &block_sparsity_pattern,
78 const MPI_Comm communicator,
79 const bool exchange_data)
80 {
81 std::vector<Epetra_Map> epetra_maps;
82 epetra_maps.reserve(block_sparsity_pattern.n_block_rows());
83 for (size_type i = 0; i < block_sparsity_pattern.n_block_rows(); ++i)
84 epetra_maps.push_back(
85 parallel_partitioning[i].make_trilinos_map(communicator, false));
86
87 Assert(epetra_maps.size() == block_sparsity_pattern.n_block_rows(),
88 ExcDimensionMismatch(epetra_maps.size(),
89 block_sparsity_pattern.n_block_rows()));
90 Assert(epetra_maps.size() == block_sparsity_pattern.n_block_cols(),
91 ExcDimensionMismatch(epetra_maps.size(),
92 block_sparsity_pattern.n_block_cols()));
93
94 const size_type n_block_rows = epetra_maps.size();
95 Assert(n_block_rows == block_sparsity_pattern.n_block_rows(),
97 block_sparsity_pattern.n_block_rows()));
98 Assert(n_block_rows == block_sparsity_pattern.n_block_cols(),
100 block_sparsity_pattern.n_block_cols()));
101
102 // Call the other basic reinit function, ...
103 reinit(block_sparsity_pattern.n_block_rows(),
104 block_sparsity_pattern.n_block_cols());
105
106 // ... set the correct sizes, ...
107 this->row_block_indices = block_sparsity_pattern.get_row_indices();
108 this->column_block_indices = block_sparsity_pattern.get_column_indices();
109
110 // ... and then assign the correct
111 // data to the blocks.
112 for (size_type r = 0; r < this->n_block_rows(); ++r)
113 for (size_type c = 0; c < this->n_block_cols(); ++c)
114 {
115 this->sub_objects[r][c]->reinit(parallel_partitioning[r],
116 parallel_partitioning[c],
117 block_sparsity_pattern.block(r, c),
118 communicator,
119 exchange_data);
120 }
121 }
122
123
124
125 template <typename BlockSparsityPatternType>
126 void
128 const BlockSparsityPatternType &block_sparsity_pattern)
129 {
130 std::vector<IndexSet> parallel_partitioning;
131 parallel_partitioning.reserve(block_sparsity_pattern.n_block_rows());
132 for (size_type i = 0; i < block_sparsity_pattern.n_block_rows(); ++i)
133 parallel_partitioning.emplace_back(
134 complete_index_set(block_sparsity_pattern.block(i, 0).n_rows()));
135
136 reinit(parallel_partitioning, block_sparsity_pattern);
137 }
138
139
140
141 template <>
142 void
143 BlockSparseMatrix::reinit(const BlockSparsityPattern &block_sparsity_pattern)
144 {
145 // Call the other basic reinit function, ...
146 reinit(block_sparsity_pattern.n_block_rows(),
147 block_sparsity_pattern.n_block_cols());
148
149 // ... set the correct sizes, ...
150 this->row_block_indices = block_sparsity_pattern.get_row_indices();
151 this->column_block_indices = block_sparsity_pattern.get_column_indices();
152
153 // ... and then assign the correct
154 // data to the blocks.
155 for (size_type r = 0; r < this->n_block_rows(); ++r)
156 for (size_type c = 0; c < this->n_block_cols(); ++c)
157 {
158 this->sub_objects[r][c]->reinit(block_sparsity_pattern.block(r, c));
159 }
160 }
161
162
163
164 void
166 const std::vector<IndexSet> &parallel_partitioning,
167 const ::BlockSparseMatrix<double> &dealii_block_sparse_matrix,
168 const MPI_Comm communicator,
169 const double drop_tolerance)
170 {
171 const size_type n_block_rows = parallel_partitioning.size();
172
173 Assert(n_block_rows == dealii_block_sparse_matrix.n_block_rows(),
175 dealii_block_sparse_matrix.n_block_rows()));
176 Assert(n_block_rows == dealii_block_sparse_matrix.n_block_cols(),
178 dealii_block_sparse_matrix.n_block_cols()));
179
180 // Call the other basic reinit function ...
182
183 // ... and then assign the correct
184 // data to the blocks.
185 for (size_type r = 0; r < this->n_block_rows(); ++r)
186 for (size_type c = 0; c < this->n_block_cols(); ++c)
187 {
188 this->sub_objects[r][c]->reinit(parallel_partitioning[r],
189 parallel_partitioning[c],
190 dealii_block_sparse_matrix.block(r,
191 c),
192 communicator,
193 drop_tolerance);
194 }
195
197 }
198
199
200
201 void
203 const ::BlockSparseMatrix<double> &dealii_block_sparse_matrix,
204 const double drop_tolerance)
205 {
206 Assert(dealii_block_sparse_matrix.n_block_rows() ==
207 dealii_block_sparse_matrix.n_block_cols(),
208 ExcDimensionMismatch(dealii_block_sparse_matrix.n_block_rows(),
209 dealii_block_sparse_matrix.n_block_cols()));
210 Assert(dealii_block_sparse_matrix.m() == dealii_block_sparse_matrix.n(),
211 ExcDimensionMismatch(dealii_block_sparse_matrix.m(),
212 dealii_block_sparse_matrix.n()));
213
214 std::vector<IndexSet> parallel_partitioning;
215 parallel_partitioning.reserve(dealii_block_sparse_matrix.n_block_rows());
216 for (size_type i = 0; i < dealii_block_sparse_matrix.n_block_rows(); ++i)
217 parallel_partitioning.emplace_back(
218 complete_index_set(dealii_block_sparse_matrix.block(i, 0).m()));
219
220 reinit(parallel_partitioning,
221 dealii_block_sparse_matrix,
222 MPI_COMM_SELF,
223 drop_tolerance);
224 }
225
226
227
228 void
230 {
231 // simply forward to the (non-public) function of the base class
233 }
234
235
236
237 std::uint64_t
239 {
240 std::uint64_t n_nonzero = 0;
241 for (size_type rows = 0; rows < this->n_block_rows(); ++rows)
242 for (size_type cols = 0; cols < this->n_block_cols(); ++cols)
243 n_nonzero += this->block(rows, cols).n_nonzero_elements();
244
245 return n_nonzero;
246 }
247
248
249
252 const MPI::BlockVector &x,
253 const MPI::BlockVector &b) const
254 {
255 vmult(dst, x);
256 dst -= b;
257 dst *= -1.;
258
259 return dst.l2_norm();
260 }
261
262
263
264 // TODO: In the following we
265 // use the same code as just
266 // above three more times. Use
267 // templates.
270 const MPI::Vector &x,
271 const MPI::BlockVector &b) const
272 {
273 vmult(dst, x);
274 dst -= b;
275 dst *= -1.;
276
277 return dst.l2_norm();
278 }
279
280
281
284 const MPI::BlockVector &x,
285 const MPI::Vector &b) const
286 {
287 vmult(dst, x);
288 dst -= b;
289 dst *= -1.;
290
291 return dst.l2_norm();
292 }
293
294
295
298 const MPI::Vector &x,
299 const MPI::Vector &b) const
300 {
301 vmult(dst, x);
302 dst -= b;
303 dst *= -1.;
304
305 return dst.l2_norm();
306 }
307
308
309
312 {
313 Assert(this->n_block_cols() != 0, ExcNotInitialized());
314 Assert(this->n_block_rows() != 0, ExcNotInitialized());
315 return this->sub_objects[0][0]->get_mpi_communicator();
316 }
317
318
319
320# ifndef DOXYGEN
321 // -------------------- explicit instantiations -----------------------
322 //
323 template void
324 BlockSparseMatrix::reinit(const ::BlockSparsityPattern &);
325 template void
326 BlockSparseMatrix::reinit(const ::BlockDynamicSparsityPattern &);
327
328 template void
329 BlockSparseMatrix::reinit(const std::vector<IndexSet> &,
330 const ::BlockDynamicSparsityPattern &,
331 const MPI_Comm,
332 const bool);
333# endif // DOXYGEN
334
335} // namespace TrilinosWrappers
336
337
338
339#endif
void reinit(const unsigned int n_blocks, const size_type n_elements_per_block)
unsigned int n_block_rows() const
unsigned int n_block_cols() const
BlockType & block(const unsigned int row, const unsigned int column)
Table< 2, ObserverPointer< BlockType, BlockMatrixBase< SparseMatrix > > > sub_objects
SparsityPatternType & block(const size_type row, const size_type column)
const BlockIndices & get_column_indices() const
const BlockIndices & get_row_indices() const
real_type l2_norm() const
std::size_t n_nonzero_elements() const
TrilinosScalar residual(MPI::BlockVector &dst, const MPI::BlockVector &x, const MPI::BlockVector &b) const
void reinit(const size_type n_block_rows, const size_type n_block_columns)
void vmult(VectorType1 &dst, const VectorType2 &src) const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcNotInitialized()
IndexSet complete_index_set(const IndexSet::size_type N)
Definition index_set.h:1187
double TrilinosScalar
Definition types.h:188