Reference documentation for deal.II version 9.0.0
trilinos_block_sparse_matrix.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2008 - 2017 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 at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/lac/trilinos_block_sparse_matrix.h>
17 
18 #ifdef DEAL_II_WITH_TRILINOS
19 
20 # include <deal.II/lac/block_sparse_matrix.h>
21 # include <deal.II/lac/block_sparsity_pattern.h>
22 
23 DEAL_II_NAMESPACE_OPEN
24 
25 namespace TrilinosWrappers
26 {
28  {
29  // delete previous content of
30  // the subobjects array
31  try
32  {
33  clear ();
34  }
35  catch (...)
36  {}
37  }
38 
39 
40 
41  void
43  reinit (const size_type n_block_rows,
44  const size_type n_block_columns)
45  {
46  // first delete previous content of
47  // the subobjects array
48  clear ();
49 
50  // then resize. set sizes of blocks to
51  // zero. user will later have to call
52  // collect_sizes for this
53  this->sub_objects.reinit (n_block_rows,
54  n_block_columns);
55  this->row_block_indices.reinit (n_block_rows, 0);
56  this->column_block_indices.reinit (n_block_columns, 0);
57 
58  // and reinitialize the blocks
59  for (size_type r=0; r<this->n_block_rows(); ++r)
60  for (size_type c=0; c<this->n_block_cols(); ++c)
61  {
62  BlockType *p = new BlockType();
63 
64  Assert (this->sub_objects[r][c] == nullptr,
66  this->sub_objects[r][c] = p;
67  }
68  }
69 
70 
71 
72  template <typename BlockSparsityPatternType>
73  void
75  reinit (const std::vector<Epetra_Map> &parallel_partitioning,
76  const BlockSparsityPatternType &block_sparsity_pattern,
77  const bool exchange_data)
78  {
79  Assert (parallel_partitioning.size() == block_sparsity_pattern.n_block_rows(),
80  ExcDimensionMismatch (parallel_partitioning.size(),
81  block_sparsity_pattern.n_block_rows()));
82  Assert (parallel_partitioning.size() == block_sparsity_pattern.n_block_cols(),
83  ExcDimensionMismatch (parallel_partitioning.size(),
84  block_sparsity_pattern.n_block_cols()));
85 
86  const size_type n_block_rows = parallel_partitioning.size();
87  (void)n_block_rows;
88 
89  Assert (n_block_rows == block_sparsity_pattern.n_block_rows(),
91  block_sparsity_pattern.n_block_rows()));
92  Assert (n_block_rows == block_sparsity_pattern.n_block_cols(),
94  block_sparsity_pattern.n_block_cols()));
95 
96 
97  // Call the other basic reinit function, ...
98  reinit (block_sparsity_pattern.n_block_rows(),
99  block_sparsity_pattern.n_block_cols());
100 
101  // ... set the correct sizes, ...
102  this->row_block_indices = block_sparsity_pattern.get_row_indices();
103  this->column_block_indices = block_sparsity_pattern.get_column_indices();
104 
105  // ... and then assign the correct
106  // data to the blocks.
107  for (size_type r=0; r<this->n_block_rows(); ++r)
108  for (size_type c=0; c<this->n_block_cols(); ++c)
109  {
110  this->sub_objects[r][c]->reinit (parallel_partitioning[r],
111  parallel_partitioning[c],
112  block_sparsity_pattern.block(r,c),
113  exchange_data);
114  }
115  }
116 
117 
118 
119  template <typename BlockSparsityPatternType>
120  void
122  reinit (const std::vector<IndexSet> &parallel_partitioning,
123  const BlockSparsityPatternType &block_sparsity_pattern,
124  const MPI_Comm &communicator,
125  const bool exchange_data)
126  {
127  std::vector<Epetra_Map> epetra_maps;
128  for (size_type i=0; i<block_sparsity_pattern.n_block_rows(); ++i)
129  epetra_maps.push_back
130  (parallel_partitioning[i].make_trilinos_map(communicator, false));
131 
132  reinit (epetra_maps, block_sparsity_pattern, exchange_data);
133 
134  }
135 
136 
137 
138  template <typename BlockSparsityPatternType>
139  void
141  reinit (const BlockSparsityPatternType &block_sparsity_pattern)
142  {
143  std::vector<Epetra_Map> parallel_partitioning;
144  for (size_type i=0; i<block_sparsity_pattern.n_block_rows(); ++i)
145  parallel_partitioning.emplace_back
146  (static_cast<TrilinosWrappers::types::int_type>(block_sparsity_pattern.block(i,0).n_rows()),
147  0,
149 
150  reinit (parallel_partitioning, block_sparsity_pattern);
151  }
152 
153 
154 
155  template <>
156  void
158  reinit (const BlockSparsityPattern &block_sparsity_pattern)
159  {
160 
161  // Call the other basic reinit function, ...
162  reinit (block_sparsity_pattern.n_block_rows(),
163  block_sparsity_pattern.n_block_cols());
164 
165  // ... set the correct sizes, ...
166  this->row_block_indices = block_sparsity_pattern.get_row_indices();
167  this->column_block_indices = block_sparsity_pattern.get_column_indices();
168 
169  // ... and then assign the correct
170  // data to the blocks.
171  for (size_type r=0; r<this->n_block_rows(); ++r)
172  for (size_type c=0; c<this->n_block_cols(); ++c)
173  {
174  this->sub_objects[r][c]->reinit (block_sparsity_pattern.block(r,c));
175  }
176  }
177 
178 
179 
180  void
182  reinit (const std::vector<Epetra_Map> &parallel_partitioning,
183  const ::BlockSparseMatrix<double> &dealii_block_sparse_matrix,
184  const double drop_tolerance)
185  {
186  const size_type n_block_rows = parallel_partitioning.size();
187 
188  Assert (n_block_rows == dealii_block_sparse_matrix.n_block_rows(),
190  dealii_block_sparse_matrix.n_block_rows()));
191  Assert (n_block_rows == dealii_block_sparse_matrix.n_block_cols(),
193  dealii_block_sparse_matrix.n_block_cols()));
194 
195  // Call the other basic reinit function ...
197 
198  // ... and then assign the correct
199  // data to the blocks.
200  for (size_type r=0; r<this->n_block_rows(); ++r)
201  for (size_type c=0; c<this->n_block_cols(); ++c)
202  {
203  this->sub_objects[r][c]->reinit(parallel_partitioning[r],
204  parallel_partitioning[c],
205  dealii_block_sparse_matrix.block(r,c),
206  drop_tolerance);
207  }
208 
209  collect_sizes();
210  }
211 
212 
213 
214  void
216  reinit (const ::BlockSparseMatrix<double> &dealii_block_sparse_matrix,
217  const double drop_tolerance)
218  {
219  Assert (dealii_block_sparse_matrix.n_block_rows() ==
220  dealii_block_sparse_matrix.n_block_cols(),
221  ExcDimensionMismatch (dealii_block_sparse_matrix.n_block_rows(),
222  dealii_block_sparse_matrix.n_block_cols()));
223  Assert (dealii_block_sparse_matrix.m() ==
224  dealii_block_sparse_matrix.n(),
225  ExcDimensionMismatch (dealii_block_sparse_matrix.m(),
226  dealii_block_sparse_matrix.n()));
227 
228  // produce a dummy local map and pass it
229  // off to the other function
230 #ifdef DEAL_II_WITH_MPI
231  Epetra_MpiComm trilinos_communicator (MPI_COMM_SELF);
232 #else
233  Epetra_SerialComm trilinos_communicator;
234 #endif
235 
236  std::vector<Epetra_Map> parallel_partitioning;
237  for (size_type i=0; i<dealii_block_sparse_matrix.n_block_rows(); ++i)
238  parallel_partitioning.emplace_back
239  (static_cast<TrilinosWrappers::types::int_type>(dealii_block_sparse_matrix.block(i,0).m()),
240  0,
241  trilinos_communicator);
242 
243  reinit (parallel_partitioning, dealii_block_sparse_matrix, drop_tolerance);
244  }
245 
246 
247 
248 
249 
250  void
252  {
253  // simply forward to the (non-public) function of the base class
255  }
256 
257 
258 
259  BlockSparseMatrix::size_type
261  {
262  size_type n_nonzero = 0;
263  for (size_type rows = 0; rows<this->n_block_rows(); ++rows)
264  for (size_type cols = 0; cols<this->n_block_cols(); ++cols)
265  n_nonzero += this->block(rows,cols).n_nonzero_elements();
266 
267  return n_nonzero;
268  }
269 
270 
271 
272  TrilinosScalar
274  const MPI::BlockVector &x,
275  const MPI::BlockVector &b) const
276  {
277  vmult (dst, x);
278  dst -= b;
279  dst *= -1.;
280 
281  return dst.l2_norm();
282  }
283 
284 
285 
286  // TODO: In the following we
287  // use the same code as just
288  // above three more times. Use
289  // templates.
290  TrilinosScalar
292  const MPI::Vector &x,
293  const MPI::BlockVector &b) const
294  {
295  vmult (dst, x);
296  dst -= b;
297  dst *= -1.;
298 
299  return dst.l2_norm();
300  }
301 
302 
303 
304  TrilinosScalar
306  const MPI::BlockVector &x,
307  const MPI::Vector &b) const
308  {
309  vmult (dst, x);
310  dst -= b;
311  dst *= -1.;
312 
313  return dst.l2_norm();
314  }
315 
316 
317 
318  TrilinosScalar
320  const MPI::Vector &x,
321  const MPI::Vector &b) const
322  {
323  vmult (dst, x);
324  dst -= b;
325  dst *= -1.;
326 
327  return dst.l2_norm();
328  }
329 
330 
331 
332  std::vector<Epetra_Map>
334  {
335  Assert (this->n_block_cols() != 0, ExcNotInitialized());
336  Assert (this->n_block_rows() != 0, ExcNotInitialized());
337 
338  std::vector<Epetra_Map> domain_partitioner;
339  for (size_type c = 0; c < this->n_block_cols(); ++c)
340  domain_partitioner.push_back(this->sub_objects[0][c]->domain_partitioner());
341 
342  return domain_partitioner;
343  }
344 
345 
346 
347  std::vector<Epetra_Map>
349  {
350  Assert (this->n_block_cols() != 0, ExcNotInitialized());
351  Assert (this->n_block_rows() != 0, ExcNotInitialized());
352 
353  std::vector<Epetra_Map> range_partitioner;
354  for (size_type r = 0; r < this->n_block_rows(); ++r)
355  range_partitioner.push_back(this->sub_objects[r][0]->range_partitioner());
356 
357  return range_partitioner;
358  }
359 
360 
361 
362  MPI_Comm
364  {
365  Assert (this->n_block_cols() != 0, ExcNotInitialized());
366  Assert (this->n_block_rows() != 0, ExcNotInitialized());
367  return this->sub_objects[0][0]->get_mpi_communicator();
368  }
369 
370 
371 
372  // -------------------- explicit instantiations -----------------------
373  //
374  template void
375  BlockSparseMatrix::reinit (const ::BlockSparsityPattern &);
376  template void
377  BlockSparseMatrix::reinit (const ::BlockDynamicSparsityPattern &);
378 
379  template void
380  BlockSparseMatrix::reinit (const std::vector<Epetra_Map> &,
381  const ::BlockSparsityPattern &,
382  const bool);
383  template void
384  BlockSparseMatrix::reinit (const std::vector<Epetra_Map> &,
385  const ::BlockDynamicSparsityPattern &,
386  const bool);
387 
388  template void
389  BlockSparseMatrix::reinit (const std::vector<IndexSet> &,
390  const ::BlockDynamicSparsityPattern &,
391  const MPI_Comm &,
392  const bool);
393 
394 }
395 
396 
397 DEAL_II_NAMESPACE_CLOSE
398 
399 #endif
std::vector< Epetra_Map > range_partitioner() const
real_type l2_norm() const
static ::ExceptionBase & ExcNotInitialized()
const Epetra_Comm & comm_self()
Definition: utilities.cc:777
SparsityPatternType & block(const size_type row, const size_type column)
std::size_t n_nonzero_elements() const
unsigned int n_block_cols() const
std::vector< Epetra_Map > domain_partitioner() const
void vmult(VectorType1 &dst, const VectorType2 &src) const
void reinit(const TableIndices< N > &new_size, const bool omit_default_initialization=false)
#define Assert(cond, exc)
Definition: exceptions.h:1142
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void reinit(const unsigned int n_blocks, const size_type n_elements_per_block)
void reinit(const size_type n_block_rows, const size_type n_block_columns)
const BlockIndices & get_row_indices() const
BlockType & block(const unsigned int row, const unsigned int column)
Table< 2, SmartPointer< BlockType, BlockMatrixBase< SparseMatrix > > > sub_objects
unsigned int n_block_rows() const
const BlockIndices & get_column_indices() const
TrilinosScalar residual(MPI::BlockVector &dst, const MPI::BlockVector &x, const MPI::BlockVector &b) const
static ::ExceptionBase & ExcInternalError()