- Home
- About DUNE
- Download
- Documentation
- Community
- Development
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].