Reference documentation for deal.II version 9.0.0
matrix_out.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2001 - 2018 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 #ifndef dealii_matrix_out_h
17 #define dealii_matrix_out_h
18 
19 #include <deal.II/base/config.h>
20 #include <deal.II/base/data_out_base.h>
21 #include <deal.II/lac/sparse_matrix.h>
22 #include <deal.II/lac/block_sparse_matrix.h>
23 
24 #ifdef DEAL_II_WITH_TRILINOS
25 # include <deal.II/lac/trilinos_sparse_matrix.h>
26 # include <deal.II/lac/trilinos_block_sparse_matrix.h>
27 #endif
28 
29 
30 DEAL_II_NAMESPACE_OPEN
31 
69 class MatrixOut : public DataOutInterface<2,2>
70 {
71 public:
76 
81  struct Options
82  {
88 
98  unsigned int block_size;
99 
104 
109  Options (const bool show_absolute_values = false,
110  const unsigned int block_size = 1,
111  const bool discontinuous = false);
112  };
113 
117  virtual ~MatrixOut () = default;
118 
136  template <class Matrix>
137  void build_patches (const Matrix &matrix,
138  const std::string &name,
139  const Options options = Options(false, 1, false));
140 
141 private:
142 
148 
154  std::vector<Patch> patches;
155 
159  std::string name;
160 
165  virtual const std::vector<Patch> &
166  get_patches () const;
167 
172  virtual std::vector<std::string> get_dataset_names () const;
173 
181  template <class Matrix>
182  static double get_gridpoint_value (const Matrix &matrix,
183  const size_type i,
184  const size_type j,
185  const Options &options);
186 };
187 
188 
189 /* ---------------------- Template and inline functions ------------- */
190 
191 
192 namespace internal
193 {
194  namespace MatrixOutImplementation
195  {
196  namespace
197  {
201  template <typename number>
202  double get_element (const ::SparseMatrix<number> &matrix,
203  const types::global_dof_index i,
204  const types::global_dof_index j)
205  {
206  return matrix.el(i,j);
207  }
208 
209 
210 
214  template <typename number>
215  double get_element (const ::BlockSparseMatrix<number> &matrix,
216  const types::global_dof_index i,
217  const types::global_dof_index j)
218  {
219  return matrix.el(i,j);
220  }
221 
222 
223 #ifdef DEAL_II_WITH_TRILINOS
224 
227  inline
228  double get_element (const TrilinosWrappers::SparseMatrix &matrix,
229  const types::global_dof_index i,
230  const types::global_dof_index j)
231  {
232  return matrix.el(i,j);
233  }
234 
235 
236 
241  inline
242  double get_element (const TrilinosWrappers::BlockSparseMatrix &matrix,
243  const types::global_dof_index i,
244  const types::global_dof_index j)
245  {
246  return matrix.el(i,j);
247  }
248 #endif
249 
250 
251 #ifdef DEAL_II_WITH_PETSC
252  // no need to do anything: PETSc matrix objects do not distinguish
253  // between operator() and el(i,j), so we can safely access elements
254  // through the generic function below
255 #endif
256 
257 
263  template <class Matrix>
264  double get_element (const Matrix &matrix,
265  const types::global_dof_index i,
266  const types::global_dof_index j)
267  {
268  return matrix(i,j);
269  }
270  }
271  }
272 }
273 
274 
275 
276 template <class Matrix>
277 inline
278 double
279 MatrixOut::get_gridpoint_value (const Matrix &matrix,
280  const size_type i,
281  const size_type j,
282  const Options &options)
283 {
284  // special case if block size is
285  // one since we then don't need all
286  // that loop overhead
287  if (options.block_size == 1)
288  {
289  if (options.show_absolute_values == true)
290  return std::fabs(internal::MatrixOutImplementation::get_element (matrix, i, j));
291  else
292  return internal::MatrixOutImplementation::get_element (matrix, i, j);
293  }
294 
295  // if blocksize greater than one,
296  // then compute average of elements
297  double average = 0;
298  size_type n_elements = 0;
299  for (size_type row=i*options.block_size;
300  row < std::min(size_type(matrix.m()),
301  size_type((i+1)*options.block_size)); ++row)
302  for (size_type col=j*options.block_size;
303  col < std::min(size_type(matrix.m()),
304  size_type((j+1)*options.block_size)); ++col, ++n_elements)
305  if (options.show_absolute_values == true)
306  average += std::fabs(internal::MatrixOutImplementation::get_element (matrix, row, col));
307  else
308  average += internal::MatrixOutImplementation::get_element (matrix, row, col);
309  average /= n_elements;
310  return average;
311 }
312 
313 
314 
315 template <class Matrix>
316 void
317 MatrixOut::build_patches (const Matrix &matrix,
318  const std::string &name,
319  const Options options)
320 {
321  size_type
322  gridpoints_x = (matrix.n() / options.block_size
323  +
324  (matrix.n() % options.block_size != 0 ? 1 : 0)),
325  gridpoints_y = (matrix.m() / options.block_size
326  +
327  (matrix.m() % options.block_size != 0 ? 1 : 0));
328 
329  // If continuous, the number of
330  // plotted patches is matrix size-1
331  if (!options.discontinuous)
332  {
333  --gridpoints_x;
334  --gridpoints_y;
335  }
336 
337  // first clear old data and set it
338  // to virgin state
339  patches.clear ();
340  patches.resize ((gridpoints_x) * (gridpoints_y));
341 
342  // now build the patches
343  size_type index=0;
344  for (size_type i=0; i<gridpoints_y; ++i)
345  for (size_type j=0; j<gridpoints_x; ++j, ++index)
346  {
347  // within each patch, order
348  // the points in such a way
349  // that if some graphical
350  // output program (such as
351  // gnuplot) plots the
352  // quadrilaterals as two
353  // triangles, then the
354  // diagonal of the
355  // quadrilateral which cuts
356  // it into the two printed
357  // triangles is parallel to
358  // the diagonal of the
359  // matrix, rather than
360  // perpendicular to it. this
361  // has the advantage that,
362  // for example, the unit
363  // matrix is plotted as a
364  // straight rim, rather than
365  // as a series of bumps and
366  // valleys along the diagonal
367  patches[index].vertices[0](0) = j;
368  patches[index].vertices[0](1) = static_cast<signed int>(-i);
369  patches[index].vertices[1](0) = j;
370  patches[index].vertices[1](1) = static_cast<signed int>(-i-1);
371  patches[index].vertices[2](0) = j+1;
372  patches[index].vertices[2](1) = static_cast<signed int>(-i);
373  patches[index].vertices[3](0) = j+1;
374  patches[index].vertices[3](1) = static_cast<signed int>(-i-1);
375  // next scale all the patch
376  // coordinates by the block
377  // size, to get original
378  // coordinates
379  for (unsigned int v=0; v<4; ++v)
380  patches[index].vertices[v] *= options.block_size;
381 
382  patches[index].n_subdivisions = 1;
383 
384  patches[index].data.reinit (1,4);
385  if (options.discontinuous)
386  {
387  patches[index].data(0,0) = get_gridpoint_value(matrix, i, j, options);
388  patches[index].data(0,1) = get_gridpoint_value(matrix, i, j, options);
389  patches[index].data(0,2) = get_gridpoint_value(matrix, i, j, options);
390  patches[index].data(0,3) = get_gridpoint_value(matrix, i, j, options);
391  }
392  else
393  {
394  patches[index].data(0,0) = get_gridpoint_value(matrix, i, j, options);
395  patches[index].data(0,1) = get_gridpoint_value(matrix, i+1, j, options);
396  patches[index].data(0,2) = get_gridpoint_value(matrix, i, j+1, options);
397  patches[index].data(0,3) = get_gridpoint_value(matrix, i+1, j+1, options);
398  }
399  };
400 
401  // finally set the name
402  this->name = name;
403 }
404 
405 
406 
407 /*---------------------------- matrix_out.h ---------------------------*/
408 
409 DEAL_II_NAMESPACE_CLOSE
410 
411 #endif
412 /*---------------------------- matrix_out.h ---------------------------*/
static double get_gridpoint_value(const Matrix &matrix, const size_type i, const size_type j, const Options &options)
Definition: matrix_out.h:279
Contents is actually a matrix.
std::vector< Patch > patches
Definition: matrix_out.h:154
DataOutBase::Patch< 2, 2 > Patch
Definition: matrix_out.h:147
unsigned int block_size
Definition: matrix_out.h:98
virtual ~MatrixOut()=default
unsigned int global_dof_index
Definition: types.h:88
virtual const std::vector< Patch > & get_patches() const
Definition: matrix_out.cc:33
std::string name
Definition: matrix_out.h:159
void build_patches(const Matrix &matrix, const std::string &name, const Options options=Options(false, 1, false))
Definition: matrix_out.h:317
bool show_absolute_values
Definition: matrix_out.h:87
types::global_dof_index size_type
Definition: matrix_out.h:75
virtual std::vector< std::string > get_dataset_names() const
Definition: matrix_out.cc:41
Options(const bool show_absolute_values=false, const unsigned int block_size=1, const bool discontinuous=false)
Definition: matrix_out.cc:21