ug4
preconditioner.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2015: G-CSC, Goethe University Frankfurt
3  * Author: Andreas Vogel
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 #ifndef __H__LIB_ALGEBRA__OPERATOR__INTERFACE__PRECONDITIONER__
34 #define __H__LIB_ALGEBRA__OPERATOR__INTERFACE__PRECONDITIONER__
35 
36 #include "linear_iterator.h"
37 #include "matrix_operator.h"
40 
41 #ifdef UG_PARALLEL
43 #endif
44 
45 namespace ug{
47 // Matrix Iterator Operator (Preconditioner)
49 
51 
99 template <typename TAlgebra>
101  public ILinearIterator<typename TAlgebra::vector_type>,
102  public DebugWritingObject<TAlgebra>
103 {
104  public:
106  typedef TAlgebra algebra_type;
107 
109  typedef typename TAlgebra::vector_type vector_type;
110 
112  typedef typename TAlgebra::matrix_type matrix_type;
113 
117  protected:
119 
122 
123  public:
127  {};
128 
131  DebugWritingObject<TAlgebra>(spDebugWriter),
133  {};
134 
137  ILinearIterator<vector_type>(parent),
138  DebugWritingObject<TAlgebra>(parent),
140  {
141  }
142  protected:
144 
151  virtual const char* name() const = 0;
152 
154 
164 
166 
176 
178  virtual bool postprocess() = 0;
179 
180  public:
182 
193  const vector_type& u)
194  {
195  // cast to matrix based operator
197  J.template cast_dynamic<MatrixOperator<matrix_type, vector_type> >();
198 
199  // Check that matrix if of correct type
200  if(pOp.invalid())
201  UG_THROW(name() << "::init': Passed Operator is "
202  "not based on matrix. This Preconditioner can only "
203  "handle matrix-based operators.");
204 
205  // forward request to matrix based implementation
206  return init(pOp);
207  }
208 
210 
220  {
221  // Remember operator
222  m_spDefectOperator = L;
223  if(m_bOtherApproxOperator) return true;
224 
225  // cast to matrix based operator
227  L.template cast_dynamic<MatrixOperator<matrix_type, vector_type> >();
228 
229  // Check that matrix if of correct type
230  if(pOp.invalid())
231  UG_THROW(name() << "::init': Passed Operator is "
232  "not based on matrix. This Preconditioner can only "
233  "handle matrix-based operators.");
234 
235  // forward request to matrix based implementation
236  return init(pOp);
237 
238  }
239 
240 
242 
251  {
252  // Remember operator
253  m_spApproxOperator = Op;
254  m_spDefectOperator = Op;
255 
256  // Check that matrix exists
257  if(m_spApproxOperator.invalid())
258  UG_THROW(name() << "::init': Passed Operator is invalid.");
259 
260  // Preprocess
262  {
263  UG_LOG("ERROR in '"<<name()<<"::init': Preprocess failed.\n");
264  return false;
265  }
266 
267  // Remember, that operator has been initialized
268  m_bInit = true;
269 
270  // we're done
271  return true;
272  }
273 
275 
284  virtual bool apply(vector_type& c, const vector_type& d)
285  {
286  // Check that operator is initialized
287  if(!m_bInit)
288  {
289  UG_LOG("ERROR in '"<<name()<<"::apply': Iterator not initialized.\n");
290  return false;
291  }
292 
293  // Check parallel status
294  #ifdef UG_PARALLEL
295  if(!d.has_storage_type(PST_ADDITIVE))
296  UG_THROW(name() << "::apply: Wrong parallel "
297  "storage format. Defect must be additive.");
298  #endif
299 
300  // Check sizes
301  THROW_IF_NOT_EQUAL_4(c.size(), d.size(),
302  m_spApproxOperator->num_rows(), m_spApproxOperator->num_cols());
303 
304  // apply iterator: c = B*d
305  if(!step(m_spApproxOperator, c, d))
306  {
307  UG_LOG("ERROR in '"<<name()<<"::apply': Step Routine failed.\n");
308  return false;
309  }
310 
311  // apply scaling
312  const number kappa = damping()->damping(c, d, m_spApproxOperator);
313  if(kappa != 1.0){
314  c *= kappa;
315  }
316 
317  // Correction is always consistent
318  #ifdef UG_PARALLEL
319  if(!c.change_storage_type(PST_CONSISTENT))
320  UG_THROW(name() << "::apply': Cannot change "
321  "parallel storage type of correction to consistent.");
322  #endif
323 
324  // we're done
325  return true;
326  }
327 
329 
339  {
340  // compute new correction
341  if(!apply(c, d)) return false;
342 
343  // update defect d := d - A*c
344  m_spDefectOperator->apply_sub(d, c);
345 
346  // we're done
347  return true;
348  }
349 
351  {
352  UG_COND_THROW(!approx.valid(), "");
353  m_spApproxOperator = approx;
355  {
356  UG_THROW("ERROR in '"<<name()<<"::init': Preprocess failed.\n");
357  return;
358  }
359  m_bOtherApproxOperator = true;
360  }
361 
363  virtual ~IPreconditioner() {};
364 
367  {
368  return m_spDefectOperator;
369  }
370 
373  {
374  return m_spApproxOperator;
375  }
376 
377  protected:
382 
383 
385  bool m_bInit;
386 
388 };
389 
390 
391 
392 } // end namespace ug
393 #endif /* __H__LIB_ALGEBRA__OPERATOR__INTERFACE__PRECONDITIONER__ */
Definition: smart_pointer.h:108
bool invalid() const
returns true if the pointer is invalid, false if not.
Definition: smart_pointer.h:212
Definition: debug_writer.h:354
TAlgebra::vector_type vector_type
type of vector
Definition: debug_writer.h:360
base class for all debug writer
Definition: debug_writer.h:244
describes a linear iterator
Definition: linear_iterator.h:81
SmartPtr< IDamping< TAlgebra::vector_type, TAlgebra::vector_type > > damping()
returns the scaling
Definition: linear_iterator.h:173
describes a linear mapping X->Y
Definition: linear_operator.h:80
describes a linear iterator that is based on a matrix operator
Definition: preconditioner.h:103
TAlgebra algebra_type
Algebra type.
Definition: preconditioner.h:106
virtual ~IPreconditioner()
virtual destructor
Definition: preconditioner.h:363
bool m_bInit
init flag indicating if init has been called
Definition: preconditioner.h:385
SmartPtr< ILinearOperator< vector_type > > m_spDefectOperator
underlying matrix based operator for calculation of defect
Definition: preconditioner.h:379
TAlgebra::matrix_type matrix_type
Matrix type.
Definition: preconditioner.h:112
virtual bool apply(vector_type &c, const vector_type &d)
compute new correction c = B*d
Definition: preconditioner.h:284
IPreconditioner(const IPreconditioner< TAlgebra > &parent)
clone constructor
Definition: preconditioner.h:136
bool m_bOtherApproxOperator
Definition: preconditioner.h:387
IPreconditioner(SmartPtr< IDebugWriter< algebra_type > > spDebugWriter)
constructor setting debug writer
Definition: preconditioner.h:130
virtual bool postprocess()=0
cleans the operator
MatrixOperator< matrix_type, vector_type > matrix_operator_type
Matrix Operator type.
Definition: preconditioner.h:115
SmartPtr< MatrixOperator< matrix_type, vector_type > > approx_operator()
underlying matrix based operator used for the preconditioner
Definition: preconditioner.h:372
virtual const char * name() const =0
returns the name of iterator
SmartPtr< MatrixOperator< matrix_type, vector_type > > m_spApproxOperator
underlying matrix based operator used for the preconditioner
Definition: preconditioner.h:381
bool init(SmartPtr< MatrixOperator< matrix_type, vector_type > > Op)
initializes the preconditioner for a matrix based operator
Definition: preconditioner.h:250
virtual bool apply_update_defect(vector_type &c, vector_type &d)
compute new correction c = B*d and update defect d:= d - L*c
Definition: preconditioner.h:338
virtual bool preprocess(SmartPtr< MatrixOperator< matrix_type, vector_type > > pOp)=0
initializes the preconditioner
virtual void set_approximation(SmartPtr< MatrixOperator< matrix_type, vector_type > > approx)
Definition: preconditioner.h:350
virtual bool init(SmartPtr< ILinearOperator< vector_type > > J, const vector_type &u)
implements the ILinearIterator-interface for matrix based preconditioner
Definition: preconditioner.h:192
SmartPtr< MatrixOperator< matrix_type, vector_type > > defect_operator()
underlying matrix based operator for calculation of defect
Definition: preconditioner.h:366
virtual bool step(SmartPtr< MatrixOperator< matrix_type, vector_type > > pOp, vector_type &c, const vector_type &d)=0
computes a new correction c = B*d
bool init(SmartPtr< ILinearOperator< vector_type > > L)
implements the ILinearIterator-interface for matrix based preconditioner
Definition: preconditioner.h:219
TAlgebra::vector_type vector_type
Vector type.
Definition: preconditioner.h:109
IPreconditioner()
default constructor
Definition: preconditioner.h:125
Definition: matrix_operator.h:49
@ PST_CONSISTENT
Definition: parallel_storage_type.h:68
@ PST_ADDITIVE
Definition: parallel_storage_type.h:69
number kappa
#define THROW_IF_NOT_EQUAL_4(s1, s2, s3, s4)
Definition: error.h:183
#define UG_THROW(msg)
Definition: error.h:57
#define UG_LOG(msg)
Definition: log.h:367
#define UG_COND_THROW(cond, msg)
UG_COND_THROW(cond, msg) : performs a UG_THROW(msg) if cond == true.
Definition: error.h:61
double number
Definition: types.h:124
the ug namespace