Reference documentation for deal.II version 9.0.0
mg_block_smoother.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2005 - 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 #ifndef dealii_mg_block_smoother_h
17 #define dealii_mg_block_smoother_h
18 
19 
20 #include <deal.II/base/config.h>
21 #include <deal.II/base/mg_level_object.h>
22 #include <deal.II/base/smartpointer.h>
23 #include <deal.II/lac/block_vector.h>
24 #include <deal.II/lac/linear_operator.h>
25 #include <deal.II/lac/vector_memory.h>
26 #include <deal.II/multigrid/mg_smoother.h>
27 #include <vector>
28 
29 DEAL_II_NAMESPACE_OPEN
30 
31 /*
32  * MGSmootherBase is defined in mg_base.h
33  */
34 
37 
46 template <typename MatrixType, class RelaxationType, typename number>
48  : public MGSmoother<BlockVector<number> >
49 {
50 public:
57  DEAL_II_DEPRECATED
59  const unsigned int steps = 1,
60  const bool variable = false,
61  const bool symmetric = false,
62  const bool transpose = false,
63  const bool reverse = false);
64 
68  MGSmootherBlock (const unsigned int steps = 1,
69  const bool variable = false,
70  const bool symmetric = false,
71  const bool transpose = false,
72  const bool reverse = false);
73 
87  template <class MGMatrixType, class MGRelaxationType>
88  void initialize (const MGMatrixType &matrices,
89  const MGRelaxationType &smoothers);
90 
94  void clear ();
95 
99  void set_reverse (const bool);
100 
106  virtual void smooth (const unsigned int level,
108  const BlockVector<number> &rhs) const;
109 
113  std::size_t memory_consumption () const;
114 private:
119 
124 
128  bool reverse;
129 
134 };
135 
138 //---------------------------------------------------------------------------
139 
140 #ifndef DOXYGEN
141 
142 template <typename MatrixType, class RelaxationType, typename number>
143 inline
146  const unsigned int steps,
147  const bool variable,
148  const bool symmetric,
149  const bool transpose,
150  const bool reverse)
151  : MGSmoother<BlockVector<number> >(steps, variable, symmetric, transpose),
152  reverse(reverse),
153  mem(&mem)
154 {}
155 
156 template <typename MatrixType, class RelaxationType, typename number>
157 inline
159 (const unsigned int steps,
160  const bool variable,
161  const bool symmetric,
162  const bool transpose,
163  const bool reverse)
164  : MGSmoother<BlockVector<number> >(steps, variable, symmetric, transpose),
165  reverse(reverse),
166  mem(&this->vector_memory)
167 {}
168 
169 
170 template <typename MatrixType, class RelaxationType, typename number>
171 inline void
173 {
174  unsigned int i=matrices.min_level(),
175  max_level=matrices.max_level();
176  for (; i<=max_level; ++i)
177  {
178  smoothers[i] = LinearOperator<BlockVector<number> >();
179  matrices[i] = LinearOperator<BlockVector<number> >();
180  }
181 }
182 
183 
184 template <typename MatrixType, class RelaxationType, typename number>
185 template <class MGMatrixType, class MGRelaxationType>
186 inline void
188  const MGRelaxationType &s)
189 {
190  const unsigned int min = m.min_level();
191  const unsigned int max = m.max_level();
192 
193  matrices.resize(min, max);
194  smoothers.resize(min, max);
195 
196  for (unsigned int i=min; i<=max; ++i)
197  {
198  // Workaround: Unfortunately, not every "m[i]" object has a
199  // rich enough interface to populate reinit_(domain|range)_vector.
200  // Thus, apply an empty LinearOperator exemplar.
201  matrices[i] = linear_operator<BlockVector<number> >(
203  smoothers[i] = linear_operator<BlockVector<number> >(matrices[i], s[i]);
204  }
205 }
206 
207 
208 template <typename MatrixType, class RelaxationType, typename number>
209 inline void
211 set_reverse (const bool flag)
212 {
213  reverse = flag;
214 }
215 
216 
217 template <typename MatrixType, class RelaxationType, typename number>
218 inline std::size_t
220 memory_consumption () const
221 {
222  return sizeof(*this)
223  + matrices.memory_consumption()
224  + smoothers.memory_consumption()
225  + this->vector_memory.memory_consumption();
226 }
227 
228 
229 template <typename MatrixType, class RelaxationType, typename number>
230 inline void
233  const BlockVector<number> &rhs) const
234 {
235  LogStream::Prefix prefix("Smooth");
236 
237  unsigned int maxlevel = matrices.max_level();
238  unsigned int steps2 = this->steps;
239 
240  if (this->variable)
241  steps2 *= (1<<(maxlevel-level));
242 
243  typename VectorMemory<BlockVector<number> >::Pointer r(*this->mem);
244  typename VectorMemory<BlockVector<number> >::Pointer d(*this->mem);
245  r->reinit(u);
246  d->reinit(u);
247 
248  bool T = this->transpose;
249  if (this->symmetric && (steps2 % 2 == 0))
250  T = false;
251 
252  for (unsigned int i=0; i<steps2; ++i)
253  {
254  if (T)
255  {
256  matrices[level].vmult(*r,u);
257  r->sadd(-1.,1.,rhs);
258  smoothers[level].Tvmult(*d, *r);
259  }
260  else
261  {
262  matrices[level].vmult(*r,u);
263  r->sadd(-1.,1.,rhs);
264  smoothers[level].vmult(*d, *r);
265  }
266  u += *d;
267  if (this->symmetric)
268  T = !T;
269  }
270 }
271 
272 #endif // DOXYGEN
273 
274 DEAL_II_NAMESPACE_CLOSE
275 
276 #endif
Matrix is symmetric.
void initialize(const MGMatrixType &matrices, const MGRelaxationType &smoothers)
MGLevelObject< LinearOperator< BlockVector< number > > > smoothers
void set_reverse(const bool)
virtual void smooth(const unsigned int level, BlockVector< number > &u, const BlockVector< number > &rhs) const
VectorizedArray< Number > min(const ::VectorizedArray< Number > &x, const ::VectorizedArray< Number > &y)
SmartPointer< VectorMemory< BlockVector< number > >, MGSmootherBlock< MatrixType, RelaxationType, number > > mem
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
MGSmootherBlock(VectorMemory< BlockVector< number > > &mem, const unsigned int steps=1, const bool variable=false, const bool symmetric=false, const bool transpose=false, const bool reverse=false)
MGLevelObject< LinearOperator< BlockVector< number > > > matrices
std::size_t memory_consumption() const
DerivativeForm< 1, spacedim, dim, Number > transpose(const DerivativeForm< 1, dim, spacedim, Number > &DF)
VectorizedArray< Number > max(const ::VectorizedArray< Number > &x, const ::VectorizedArray< Number > &y)