NGSolve  4.9
comp/preconditioner.hpp
00001 #ifndef FILE_PRECONDITIONER
00002 #define FILE_PRECONDITIONER
00003 
00004 /*********************************************************************/
00005 /* File:   preconditioner.hh                                         */
00006 /* Author: Joachim Schoeberl                                         */
00007 /* Date:   10. Jul. 2000                                             */
00008 /*********************************************************************/
00009 
00010 
00011 
00012 namespace ngsolve
00013 {
00014   class PDE;
00015 }
00016 
00017 namespace ngcomp
00018 {
00019   using ngsolve::PDE;
00020 
00024   class NGS_DLL_HEADER Preconditioner : public NGS_Object, public BaseMatrix
00025   {
00026   protected:
00027     bool test;
00028     bool timing;
00029     bool print;
00030 
00032     bool laterupdate;
00033 
00034     double * testresult_ok;
00035     double * testresult_min;
00036     double * testresult_max;
00037   
00038     Flags flags; 
00039 
00040     // for calculation of eigenvalues
00041     bool uselapack;
00042 
00043     int on_proc;
00044 
00045   public:
00047     //Preconditioner ();
00049     //Preconditioner (const Flags & flags);
00051     Preconditioner (const PDE * const apde, const Flags & aflags,
00052                     const string aname = "precond");
00054     virtual ~Preconditioner ();
00055   
00057     virtual bool LaterUpdate (void) { return laterupdate; }
00059     virtual void Update () = 0;
00061     virtual void CleanUpLevel () { ; }
00063     virtual const BaseMatrix & GetMatrix() const
00064     {
00065       return *this; 
00066     }
00068     virtual void Mult (const BaseVector & x, BaseVector & y) const
00069     {
00070       GetMatrix().Mult(x, y);
00071     }
00072 
00073     virtual void InitLevel () { ; }
00074     virtual void FinalizeLevel () { ; }
00075     virtual void AddElementMatrix (const Array<int> & dnums,
00076                                    const FlatMatrix<double> & elmat,
00077                                    bool inner_element, int elnr,
00078                                    LocalHeap & lh) { ; }
00079 
00080     virtual void AddElementMatrix (const Array<int> & dnums,
00081                                    const FlatMatrix<Complex> & elmat,
00082                                    bool inner_element, int elnr,
00083                                    LocalHeap & lh) { ; }
00084 
00085 
00086 
00087     virtual const BaseMatrix & GetAMatrix() const
00088     { throw Exception ("Preconditioner, A-Matrix not available"); }
00089 
00091     virtual const char * ClassName() const
00092     { return "base-class Preconditioner"; }
00093 
00094 
00095     virtual void PrintReport (ostream & ost)
00096     {
00097       ost << "type = " << ClassName() << endl;
00098     }
00099 
00100     virtual void MemoryUsage (Array<MemoryUsageStruct*> & mu) const
00101     {
00102       cout << "MemoryUsage not implemented for preconditioner " << ClassName() << endl;
00103     }
00104 
00105     void Test () const;
00106     void Timing () const;
00107   };
00108 
00109 
00114   class NGS_DLL_HEADER MGPreconditioner : public Preconditioner
00115   {
00117     ngmg::MultigridPreconditioner * mgp;
00119     ngmg::TwoLevelMatrix * tlp;
00121     const BilinearForm * bfa;
00123     MGPreconditioner * low_order_preconditioner;
00125     const Preconditioner * coarse_pre;
00127     int finesmoothingsteps;
00129     string smoothertype;
00131     bool mgtest; 
00132     string mgfile; 
00133     int mgnumber; 
00134   
00135     string inversetype;
00136 
00137   public:
00139     MGPreconditioner (const PDE & pde, const Flags & aflags,
00140                       const string aname = "mgprecond");
00142     virtual ~MGPreconditioner();
00143 
00144     void FreeSmootherMem(void);
00145 
00147     virtual void Update ();
00149     virtual void CleanUpLevel ();
00151     virtual const BaseMatrix & GetMatrix() const;
00153     virtual const BaseMatrix & GetAMatrix() const
00154     {
00155       return bfa->GetMatrix(); 
00156     }
00158     virtual const char * ClassName() const
00159     { return "Multigrid Preconditioner"; }
00160 
00161     virtual void PrintReport (ostream & ost);
00162 
00163     virtual void MemoryUsage (Array<MemoryUsageStruct*> & mu) const;
00164 
00165     void MgTest () const;
00166   };
00167 
00168 
00169 
00171 
00172 
00176   class LocalPreconditioner : public Preconditioner
00177   {
00178   protected:
00180     BilinearForm * bfa;
00182     BaseMatrix * jacobi;
00184     bool block;
00185     bool locprectest; 
00186     string locprecfile; 
00187 
00188     string ct;
00189     const Preconditioner * coarse_pre;
00190   public:
00192     LocalPreconditioner (PDE * pde, Flags & aflags,
00193                          const string aname = "localprecond");
00195     virtual ~LocalPreconditioner();
00197     virtual void Update ();
00199     virtual const BaseMatrix & GetMatrix() const;
00201     virtual const BaseMatrix & GetAMatrix() const
00202     {
00203       return bfa->GetMatrix(); 
00204     }
00206     virtual const char * ClassName() const
00207     { return "Local Preconditioner"; }
00208     void LocPrecTest () const;
00209   };
00210 
00211 
00212 
00213 
00215   class TwoLevelPreconditioner : public Preconditioner
00216   {
00218     PDE * pde;
00220     BilinearForm * bfa;
00222     Preconditioner * cpre;
00224     ngmg::TwoLevelMatrix * premat;
00226     int smoothingsteps;
00227   public:
00229     TwoLevelPreconditioner (PDE * apde, Flags & aflags,
00230                             const string aname = "twolevelprecond");
00232     virtual ~TwoLevelPreconditioner();
00233 
00235     virtual void Update ();
00237     virtual const BaseMatrix & GetMatrix() const
00238     { return *new SparseMatrix<double> (1,1); } // *premat; }
00240     virtual const char * ClassName() const
00241     { return "TwoLevel Preconditioner"; }
00242   };
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00252   class ComplexPreconditioner : public Preconditioner
00253   {
00254   protected:
00256     Preconditioner * creal;
00258     // Real2ComplexMatrix<double,Complex> cm;
00259     int dim;
00260     BaseMatrix * cm;
00261   public:
00263     ComplexPreconditioner (PDE * apde, Flags & aflags,
00264                            const string aname = "complexprecond");
00266     virtual ~ComplexPreconditioner();
00268     virtual void Update ();
00270     virtual const BaseMatrix & GetMatrix() const
00271     { 
00272       return *cm; 
00273     }
00275     virtual const char * ClassName() const
00276     { return "Complex Preconditioner"; }
00277   };
00278 
00279 
00280 
00281 
00283   class ChebychevPreconditioner : public Preconditioner
00284   {
00285   protected:
00287     Preconditioner * csimple;
00289     ChebyshevIteration * cm;
00291     BilinearForm * bfa;
00293     int steps; 
00294   public:
00296     ChebychevPreconditioner (PDE * apde, Flags & aflags,
00297                              const string aname = "chebychevprecond");
00299     virtual ~ChebychevPreconditioner();
00301     virtual void Update ();
00303     virtual const BaseMatrix & GetMatrix() const
00304     { 
00305       return *cm; 
00306     }
00307     virtual const BaseMatrix & GetAMatrix() const
00308     {
00309       return bfa->GetMatrix(); 
00310     }
00311 
00313     virtual const char * ClassName() const
00314     { return "Chebychev Preconditioner"; }
00315   };
00316 
00317 
00318 
00319 
00320   class CommutingAMGPreconditioner : public Preconditioner
00321   {
00322   protected:
00323     PDE * pde;
00324     const BilinearForm * bfa;
00325     // CommutingAMG * amg;
00326     BaseMatrix * amg;
00327     CoefficientFunction *coefe, *coeff, *coefse;
00328     bool hcurl;
00329     bool coarsegrid;
00330     int levels;
00331   public:
00332     CommutingAMGPreconditioner (PDE * apde, Flags & aflags,
00333                                 const string aname = "commutingamgprecond");
00334 
00335     virtual ~CommutingAMGPreconditioner ();
00336 
00337     virtual void Update ();
00339 
00340     virtual const BaseMatrix & GetAMatrix() const
00341     {
00342       return bfa->GetMatrix(); 
00343     }
00344 
00345     virtual const BaseMatrix & GetMatrix() const
00346     { 
00347       return *amg; 
00348     }
00350     virtual void CleanUpLevel ();
00351 
00353     virtual const char * ClassName() const
00354     { return "CommutingAMG Preconditioner"; }
00355   };
00356 
00357 
00358 
00359 
00360 
00361 
00362   // added 08/19/2003:
00363 
00365   //
00366   // special preconditioner for system
00367   //   (  A   M  )
00368   //   ( -M   A  )
00369   //
00370   // 
00371   // C = (  1  1  ) (  A+M       )
00372   //     ( -1  1  ) (       A+M  )
00373   //
00375   class NonsymmetricPreconditioner : public Preconditioner
00376   {
00377   protected:
00379     Preconditioner * cbase;
00381     int dim;
00382     BaseMatrix * cm;
00383   public:
00385     NonsymmetricPreconditioner (PDE * apde, Flags & aflags,
00386                                 const string aname = "nonsymmetricprecond");
00388     virtual ~NonsymmetricPreconditioner();
00390     virtual void Update ();
00392     virtual const BaseMatrix & GetMatrix() const
00393     { 
00394       return *cm; 
00395     }
00397     virtual const char * ClassName() const
00398     { return "Nonsymmetric Preconditioner"; }
00399   };
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00408   class NGS_DLL_HEADER PreconditionerClasses
00409   {
00410   public:
00411     struct PreconditionerInfo
00412     {
00413       string name;
00414       Preconditioner* (*creator)(const PDE & pde, const Flags & aflags, const string & name);
00415       PreconditionerInfo (const string & aname,
00416                           Preconditioner* (*acreator)(const PDE & pde, 
00417                                                       const Flags & aflags,
00418                                                       const string & name));
00419     };
00420   
00421     Array<PreconditionerInfo*> prea;
00422   public:
00423     PreconditionerClasses();
00424     ~PreconditionerClasses();  
00425     void AddPreconditioner (const string & aname, 
00426                             Preconditioner* (*acreator)(const PDE & pde, 
00427                                                         const Flags & aflags, 
00428                                                         const string & name));
00429   
00430     const Array<PreconditionerInfo*> & GetPreconditioners() { return prea; }
00431     const PreconditionerInfo * GetPreconditioner(const string & name);
00432 
00433     void Print (ostream & ost) const;
00434   };
00435  
00436   extern NGS_DLL_HEADER PreconditionerClasses & GetPreconditionerClasses ();
00437 
00438   template <typename PRECOND>
00439   class RegisterPreconditioner
00440   {
00441   public:
00442     RegisterPreconditioner (string label, bool isparallel = true)
00443     {
00444       GetPreconditionerClasses().AddPreconditioner (label, Create);
00445       // cout << "register preconditioner '" << label << "'" << endl;
00446     }
00447     
00448     static Preconditioner * Create (const PDE & pde, const Flags & flags, const string & name)
00449     {
00450       return new PRECOND (pde, flags, name);
00451     }
00452   };
00453 
00454 }
00455 
00456 #endif
00457