Reference documentation for deal.II version 8.5.1
schur_matrix.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2001 - 2015 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__schur_matrix_h
17 #define dealii__schur_matrix_h
18 
19 #include <deal.II/base/config.h>
20 #include <deal.II/base/subscriptor.h>
21 #include <deal.II/base/smartpointer.h>
22 #include <deal.II/base/logstream.h>
23 #include <deal.II/lac/vector_memory.h>
24 #include <deal.II/lac/block_vector.h>
25 #include <vector>
26 
27 DEAL_II_NAMESPACE_OPEN
28 
29 
96 template <class MA_inverse, class MB, class MDt, class MC>
97 class SchurMatrix : public Subscriptor
98 {
99 public:
100 
110  SchurMatrix(const MA_inverse &Ainv,
111  const MB &B,
112  const MDt &Dt,
113  const MC &C,
115  const std::vector<types::global_dof_index> &signature = std::vector<types::global_dof_index>(0));
116 
127  void prepare_rhs (BlockVector<double> &dst,
128  const BlockVector<double> &src) const;
129 
133  void vmult (BlockVector<double> &dst,
134  const BlockVector<double> &src) const;
135 
136 // void Tmult(BlockVector<double>& dst, const BlockVector<double>& src) const;
137 
141  double residual (BlockVector<double> &dst,
142  const BlockVector<double> &src,
143  const BlockVector<double> &rhs) const;
144 
149  void postprocess (BlockVector<double> &dst,
150  const BlockVector<double> &src,
151  const BlockVector<double> &rhs) const;
152 
158  void debug_level(unsigned int l);
159 private:
168 
189 
193  std::vector<types::global_dof_index> signature;
194 
198  unsigned int debug;
199 };
200 
202 //---------------------------------------------------------------------------
203 
204 template <class MA_inverse, class MB, class MDt, class MC>
206 ::SchurMatrix(const MA_inverse &Ainv,
207  const MB &B,
208  const MDt &Dt,
209  const MC &C,
211  const std::vector<types::global_dof_index> &signature)
212  : Ainv(&Ainv), B(&B), Dt(&Dt), C(&C),
213  mem(mem),
214  signature(signature),
215  debug(0)
216 {
217 }
218 
219 
220 template <class MA_inverse, class MB, class MDt, class MC>
221 void
223 ::debug_level(unsigned int l)
224 {
225  debug = l;
226 }
227 
228 
229 template <class MA_inverse, class MB, class MDt, class MC>
232  const BlockVector<double> &src) const
233 {
234  deallog.push("Schur");
235  if (debug > 0)
236  deallog << "src:" << src.l2_norm() << std::endl;
237 
238  C->vmult(dst, src);
239  if (debug > 0)
240  deallog << "C:" << dst.l2_norm() << std::endl;
241 
242  BlockVector<double> *h1 = mem.alloc();
243  if (signature.size()>0)
244  h1->reinit(signature);
245  else
246  h1->reinit(B->n_block_cols(), src.block(0).size());
247  Dt->Tvmult(*h1,src);
248  if (debug > 0)
249  deallog << "Dt:" << h1->l2_norm() << std::endl;
250 
251  BlockVector<double> *h2 = mem.alloc();
252  h2->reinit(*h1);
253  Ainv->vmult(*h2, *h1);
254  if (debug > 0)
255  deallog << "Ainverse:" << h2->l2_norm() << std::endl;
256 
257  mem.free(h1);
258  B->vmult_add(dst, *h2);
259  if (debug > 0)
260  deallog << "dst:" << dst.l2_norm() << std::endl;
261 
262  mem.free(h2);
263  deallog.pop();
264 }
265 
266 
267 template <class MA_inverse, class MB, class MDt, class MC>
270  const BlockVector<double> &src,
271  const BlockVector<double> &rhs) const
272 {
273  vmult(dst, src);
274  dst *= -1.;
275  dst += rhs;
276  return dst.l2_norm();
277 }
278 
279 
280 template <class MA_inverse, class MB, class MDt, class MC>
283  const BlockVector<double> &src) const
284 {
285  Assert (src.n_blocks() == B->n_block_cols(),
286  ExcDimensionMismatch(src.n_blocks(), B->n_block_cols()));
287  Assert (dst.n_blocks() == B->n_block_rows(),
288  ExcDimensionMismatch(dst.n_blocks(), B->n_block_rows()));
289 
290  deallog.push("Schur-prepare");
291  if (debug > 0)
292  deallog << "src:" << src.l2_norm() << std::endl;
293  BlockVector<double> *h1 = mem.alloc();
294  if (signature.size()>0)
295  h1->reinit(signature);
296  else
297  h1->reinit(B->n_block_cols(), src.block(0).size());
298  Ainv->vmult(*h1, src);
299  if (debug > 0)
300  deallog << "Ainverse:" << h1->l2_norm() << std::endl;
301  B->vmult_add(dst, *h1);
302  if (debug > 0)
303  deallog << "dst:" << dst.l2_norm() << std::endl;
304  mem.free(h1);
305  deallog.pop();
306 }
307 
308 
309 template <class MA_inverse, class MB, class MDt, class MC>
312  const BlockVector<double> &src,
313  const BlockVector<double> &rhs) const
314 {
315  Assert (dst.n_blocks() == B->n_block_cols(),
316  ExcDimensionMismatch(dst.n_blocks(), B->n_block_cols()));
317  Assert (rhs.n_blocks() == B->n_block_cols(),
318  ExcDimensionMismatch(rhs.n_blocks(), B->n_block_cols()));
319  Assert (src.n_blocks() == B->n_block_rows(),
320  ExcDimensionMismatch(src.n_blocks(), B->n_block_rows()));
321 
322  deallog.push("Schur-post");
323  if (debug > 0)
324  deallog << "src:" << src.l2_norm() << std::endl;
325  BlockVector<double> *h1 = mem.alloc();
326  if (signature.size()>0)
327  h1->reinit(signature);
328  else
329  h1->reinit(B->n_block_cols(), src.block(0).size());
330  Dt->Tvmult(*h1, src);
331  if (debug > 0)
332  deallog << "Dt:" << h1->l2_norm() << std::endl;
333  h1->sadd(-1.,rhs);
334  Ainv->vmult(dst,*h1);
335  if (debug > 0)
336  deallog << "dst:" << dst.l2_norm() << std::endl;
337  mem.free(h1);
338  deallog.pop();
339 }
340 
341 
342 DEAL_II_NAMESPACE_CLOSE
343 
344 #endif
void pop()
Definition: logstream.cc:306
void prepare_rhs(BlockVector< double > &dst, const BlockVector< double > &src) const
Definition: schur_matrix.h:282
double residual(BlockVector< double > &dst, const BlockVector< double > &src, const BlockVector< double > &rhs) const
Definition: schur_matrix.h:269
std::vector< types::global_dof_index > signature
Definition: schur_matrix.h:193
unsigned int debug
Definition: schur_matrix.h:198
const SmartPointer< const MB, SchurMatrix< MA_inverse, MB, MDt, MC > > B
Definition: schur_matrix.h:176
void postprocess(BlockVector< double > &dst, const BlockVector< double > &src, const BlockVector< double > &rhs) const
Definition: schur_matrix.h:311
void debug_level(unsigned int l)
Definition: schur_matrix.h:223
VectorMemory< BlockVector< double > > & mem
Definition: schur_matrix.h:188
SchurMatrix & operator=(const SchurMatrix< MA_inverse, MB, MDt, MC > &)
const SmartPointer< const MA_inverse, SchurMatrix< MA_inverse, MB, MDt, MC > > Ainv
Definition: schur_matrix.h:172
#define Assert(cond, exc)
Definition: exceptions.h:313
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
SchurMatrix(const MA_inverse &Ainv, const MB &B, const MDt &Dt, const MC &C, VectorMemory< BlockVector< double > > &mem, const std::vector< types::global_dof_index > &signature=std::vector< types::global_dof_index >(0))
Definition: schur_matrix.h:206
void reinit(const unsigned int n_blocks, const size_type block_size=0, const bool omit_zeroing_entries=false)
void vmult(BlockVector< double > &dst, const BlockVector< double > &src) const
Definition: schur_matrix.h:231
const SmartPointer< const MDt, SchurMatrix< MA_inverse, MB, MDt, MC > > Dt
Definition: schur_matrix.h:180
void sadd(const value_type s, const BlockVectorBase &V)
void push(const std::string &text)
Definition: logstream.cc:294
BlockType & block(const unsigned int i)
const SmartPointer< const MC, SchurMatrix< MA_inverse, MB, MDt, MC > > C
Definition: schur_matrix.h:184