schwarz.hh

00001 #ifndef DUNE_SCHWARZ_HH
00002 #define DUNE_SCHWARZ_HH
00003 
00004 #include <iostream>              // for input/output to shell
00005 #include <fstream>               // for input/output to files
00006 #include <vector>                // STL vector class
00007 #include <sstream>
00008 
00009 #include <cmath>                // Yes, we do some math here
00010 #include <sys/times.h>           // for timing measurements
00011 
00012 #include <dune/common/timer.hh>
00013 
00014 #include"io.hh"
00015 #include"bvector.hh"
00016 #include"vbvector.hh"
00017 #include"bcrsmatrix.hh"
00018 #include"io.hh"
00019 #include"gsetc.hh"
00020 #include"ilu.hh"
00021 #include"operators.hh"
00022 #include"solvers.hh"
00023 #include"preconditioners.hh"
00024 #include"scalarproducts.hh"
00025 #include"owneroverlapcopy.hh"
00026 
00027 namespace Dune {
00028 
00057   template<class M, class X, class Y, class C>
00058   class OverlappingSchwarzOperator : public AssembledLinearOperator<M,X,Y>
00059   {
00060   public:
00062         typedef M matrix_type;
00064         typedef X domain_type;
00066         typedef Y range_type;
00068         typedef typename X::field_type field_type;
00070     typedef C communication_type;
00071     
00072         enum {
00074           category=SolverCategory::overlapping
00075         };
00076 
00084         OverlappingSchwarzOperator (const matrix_type& A, const communication_type& com) 
00085           : _A_(A), communication(com) 
00086         {}
00087 
00089         virtual void apply (const X& x, Y& y) const
00090         {
00091           y = 0;
00092           _A_.umv(x,y); // result is consistent on interior+border
00093           communication.project(y); // we want this here to avoid it before the preconditioner
00094                                     // since there d is const!
00095         }
00096 
00098         virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const
00099         {
00100           _A_.usmv(alpha,x,y); // result is consistent on interior+border
00101           communication.project(y); // we want this here to avoid it before the preconditioner
00102                                     // since there d is const!
00103         }
00104 
00106         virtual const matrix_type& getmat () const
00107         {
00108           return _A_;
00109         }
00110 
00111   private:
00112         const matrix_type& _A_;
00113         const communication_type& communication;
00114   };
00115 
00127   template<class X, class C>
00128   class OverlappingSchwarzScalarProduct : public ScalarProduct<X>
00129   {
00130   public:
00132         typedef X domain_type;
00134         typedef typename X::field_type field_type;
00136     typedef C communication_type;
00137     
00139         enum {category=SolverCategory::overlapping};
00140 
00145         OverlappingSchwarzScalarProduct (const communication_type& com)
00146           : communication(com)
00147         {}
00148 
00153         virtual field_type dot (const X& x, const X& y)
00154         {
00155           field_type result;
00156           communication.dot(x,y,result);
00157           return result;
00158         }
00159 
00163         virtual double norm (const X& x)
00164         {
00165           return communication.norm(x);
00166         }
00167 
00168   private:
00169         const communication_type& communication;
00170   };
00171 
00172   template<class X, class C>
00173   struct ScalarProductChooser<X,C,SolverCategory::overlapping>
00174   {
00176     typedef OverlappingSchwarzScalarProduct<X,C> ScalarProduct;
00178     typedef C communication_type;
00179 
00180     enum{
00182       solverCategory=SolverCategory::overlapping
00183         };
00184 
00185     static ScalarProduct* construct(const communication_type& comm)
00186     {
00187       return new ScalarProduct(comm);
00188     }
00189   };
00190 
00197 
00198   template<class M, class X, class Y, class C>
00199   class ParSSOR : public Preconditioner<X,Y> {
00200   public:
00202     typedef M matrix_type;
00204     typedef X domain_type;
00206     typedef Y range_type;
00208     typedef typename X::field_type field_type;
00210     typedef C communication_type;
00211     
00212     // define the category
00213     enum {
00215       category=SolverCategory::overlapping};
00216     
00226     ParSSOR (const matrix_type& A, int n, field_type w, const communication_type& c)
00227       : _A_(A), _n(n), _w(w), communication(c)
00228     {   }
00229 
00235     virtual void pre (X& x, Y& b) 
00236         {
00237           communication.copyOwnerToAll(x,x); // make dirichlet values consistent
00238         }
00239 
00245     virtual void apply (X& v, const Y& d)
00246     {
00247       for (int i=0; i<_n; i++){
00248                 bsorf(_A_,v,d,_w);
00249                 bsorb(_A_,v,d,_w);
00250       }
00251           communication.copyOwnerToAll(v,v);
00252     }
00253 
00259     virtual void post (X& x) {}
00260 
00261   private:
00263     const matrix_type& _A_;
00265     int _n;
00267     field_type _w;
00269         const communication_type& communication;
00270   };
00271 
00272   namespace Amg
00273   {
00274     template<class T> class ConstructionTraits;
00275   }
00276 
00285   template<class X, class Y, class C, class T=Preconditioner<X,Y> >
00286   class BlockPreconditioner : public Preconditioner<X,Y> {
00287     friend class Amg::ConstructionTraits<BlockPreconditioner<X,Y,C,T> >;
00288   public:
00290     typedef X domain_type;
00292     typedef Y range_type;
00294     typedef typename X::field_type field_type;
00296     typedef C communication_type;
00297 
00298     // define the category
00299     enum {
00301       category=SolverCategory::overlapping};
00302     
00310     BlockPreconditioner (T& p, const communication_type& c)
00311       : preconditioner(p), communication(c)
00312     {   }
00313 
00319     virtual void pre (X& x, Y& b) 
00320         {
00321           communication.copyOwnerToAll(x,x); // make dirichlet values consistent
00322           preconditioner.pre(x,b);
00323         }
00324 
00330     virtual void apply (X& v, const Y& d)
00331     {
00332           preconditioner.apply(v,d);
00333           communication.copyOwnerToAll(v,v);
00334     }
00335 
00341     virtual void post (X& x) 
00342         {
00343           preconditioner.post(x);
00344         }
00345 
00346   private:
00348         Preconditioner<X,Y>& preconditioner;
00349 
00351         const communication_type& communication;
00352   };
00353 
00356 } // end namespace
00357 
00358 #endif

Generated on 6 Nov 2008 with Doxygen (ver 1.5.6) [logfile].