schwarz.hh

Go to the documentation of this file.
00001 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002 // vi: set et ts=4 sw=2 sts=2:
00003 #ifndef DUNE_SCHWARZ_HH
00004 #define DUNE_SCHWARZ_HH
00005 
00006 #include <iostream>              // for input/output to shell
00007 #include <fstream>               // for input/output to files
00008 #include <vector>                // STL vector class
00009 #include <sstream>
00010 
00011 #include <cmath>                // Yes, we do some math here
00012 #include <sys/times.h>           // for timing measurements
00013 
00014 #include <dune/common/timer.hh>
00015 
00016 #include"io.hh"
00017 #include"bvector.hh"
00018 #include"vbvector.hh"
00019 #include"bcrsmatrix.hh"
00020 #include"io.hh"
00021 #include"gsetc.hh"
00022 #include"ilu.hh"
00023 #include"operators.hh"
00024 #include"solvers.hh"
00025 #include"preconditioners.hh"
00026 #include"scalarproducts.hh"
00027 #include"owneroverlapcopy.hh"
00028 
00029 namespace Dune {
00030 
00059   template<class M, class X, class Y, class C>
00060   class OverlappingSchwarzOperator : public AssembledLinearOperator<M,X,Y>
00061   {
00062   public:
00064         typedef M matrix_type;
00066         typedef X domain_type;
00068         typedef Y range_type;
00070         typedef typename X::field_type field_type;
00072     typedef C communication_type;
00073     
00074         enum {
00076           category=SolverCategory::overlapping
00077         };
00078 
00086         OverlappingSchwarzOperator (const matrix_type& A, const communication_type& com) 
00087           : _A_(A), communication(com) 
00088         {}
00089 
00091         virtual void apply (const X& x, Y& y) const
00092         {
00093           y = 0;
00094           _A_.umv(x,y); // result is consistent on interior+border
00095           communication.project(y); // we want this here to avoid it before the preconditioner
00096                                     // since there d is const!
00097         }
00098 
00100         virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const
00101         {
00102           _A_.usmv(alpha,x,y); // result is consistent on interior+border
00103           communication.project(y); // we want this here to avoid it before the preconditioner
00104                                     // since there d is const!
00105         }
00106 
00108         virtual const matrix_type& getmat () const
00109         {
00110           return _A_;
00111         }
00112 
00113   private:
00114         const matrix_type& _A_;
00115         const communication_type& communication;
00116   };
00117 
00129   template<class X, class C>
00130   class OverlappingSchwarzScalarProduct : public ScalarProduct<X>
00131   {
00132   public:
00134         typedef X domain_type;
00136         typedef typename X::field_type field_type;
00138     typedef C communication_type;
00139     
00141         enum {category=SolverCategory::overlapping};
00142 
00147         OverlappingSchwarzScalarProduct (const communication_type& com)
00148           : communication(com)
00149         {}
00150 
00155         virtual field_type dot (const X& x, const X& y)
00156         {
00157           field_type result;
00158           communication.dot(x,y,result);
00159           return result;
00160         }
00161 
00165         virtual double norm (const X& x)
00166         {
00167           return communication.norm(x);
00168         }
00169 
00170   private:
00171         const communication_type& communication;
00172   };
00173 
00174   template<class X, class C>
00175   struct ScalarProductChooser<X,C,SolverCategory::overlapping>
00176   {
00178     typedef OverlappingSchwarzScalarProduct<X,C> ScalarProduct;
00180     typedef C communication_type;
00181 
00182     enum{
00184       solverCategory=SolverCategory::overlapping
00185         };
00186 
00187     static ScalarProduct* construct(const communication_type& comm)
00188     {
00189       return new ScalarProduct(comm);
00190     }
00191   };
00192 
00199 
00200   template<class M, class X, class Y, class C>
00201   class ParSSOR : public Preconditioner<X,Y> {
00202   public:
00204     typedef M matrix_type;
00206     typedef X domain_type;
00208     typedef Y range_type;
00210     typedef typename X::field_type field_type;
00212     typedef C communication_type;
00213     
00214     // define the category
00215     enum {
00217       category=SolverCategory::overlapping};
00218     
00228     ParSSOR (const matrix_type& A, int n, field_type w, const communication_type& c)
00229       : _A_(A), _n(n), _w(w), communication(c)
00230     {   }
00231 
00237     virtual void pre (X& x, Y& b) 
00238         {
00239           communication.copyOwnerToAll(x,x); // make dirichlet values consistent
00240         }
00241 
00247     virtual void apply (X& v, const Y& d)
00248     {
00249       for (int i=0; i<_n; i++){
00250                 bsorf(_A_,v,d,_w);
00251                 bsorb(_A_,v,d,_w);
00252       }
00253           communication.copyOwnerToAll(v,v);
00254     }
00255 
00261     virtual void post (X& x) {}
00262 
00263   private:
00265     const matrix_type& _A_;
00267     int _n;
00269     field_type _w;
00271         const communication_type& communication;
00272   };
00273 
00274   namespace Amg
00275   {
00276     template<class T> class ConstructionTraits;
00277   }
00278 
00287   template<class X, class Y, class C, class T=Preconditioner<X,Y> >
00288   class BlockPreconditioner : public Preconditioner<X,Y> {
00289     friend class Amg::ConstructionTraits<BlockPreconditioner<X,Y,C,T> >;
00290   public:
00292     typedef X domain_type;
00294     typedef Y range_type;
00296     typedef typename X::field_type field_type;
00298     typedef C communication_type;
00299 
00300     // define the category
00301     enum {
00303       category=SolverCategory::overlapping};
00304     
00312     BlockPreconditioner (T& p, const communication_type& c)
00313       : preconditioner(p), communication(c)
00314     {   }
00315 
00321     virtual void pre (X& x, Y& b) 
00322         {
00323           communication.copyOwnerToAll(x,x); // make dirichlet values consistent
00324           preconditioner.pre(x,b);
00325         }
00326 
00332     virtual void apply (X& v, const Y& d)
00333     {
00334           preconditioner.apply(v,d);
00335           communication.copyOwnerToAll(v,v);
00336     }
00337 
00338     template<bool forward>
00339     void apply (X& v, const Y& d)
00340     {
00341       preconditioner.template apply<forward>(v,d);
00342       communication.copyOwnerToAll(v,v);
00343     }
00344     
00350     virtual void post (X& x) 
00351         {
00352           preconditioner.post(x);
00353         }
00354 
00355   private:
00357         T& preconditioner;
00358 
00360         const communication_type& communication;
00361   };
00362 
00365 } // end namespace
00366 
00367 #endif

Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].