From 0fa28e4d12dfccfb16ba3ff643f03e05a30a61b3 Mon Sep 17 00:00:00 2001 From: guido Date: Wed, 14 Aug 2002 15:23:23 +0000 Subject: [PATCH] MGSmoother base class introduced as template git-svn-id: https://svn.dealii.org/trunk@6326 0785d39b-7218-0410-832d-ea1e28bc413d --- .../deal.II/include/multigrid/mg_smoother.h | 67 ++++++++--- .../include/multigrid/mg_smoother.templates.h | 2 +- deal.II/deal.II/include/multigrid/multigrid.h | 113 ++++++++---------- .../deal.II/source/multigrid/mg_smoother.cc | 63 +++++++--- 4 files changed, 146 insertions(+), 99 deletions(-) diff --git a/deal.II/deal.II/include/multigrid/mg_smoother.h b/deal.II/deal.II/include/multigrid/mg_smoother.h index b4808ebf21..b01defeb2a 100644 --- a/deal.II/deal.II/include/multigrid/mg_smoother.h +++ b/deal.II/deal.II/include/multigrid/mg_smoother.h @@ -21,15 +21,43 @@ template class MGDoFHandler; + +/** + * Base class for multigrid smoothers. Does nothing but defining the + * interface used by multigrid methods. + * + * @author Guido KAnschat, 2002 + */ +template +class MGSmoother : public Subscriptor +{ + public: + /** + * Virtual destructor. + */ + virtual ~MGSmoother(); + + /** + * Smoothing function. This is the + * function used in multigrid + * methods. + */ + virtual void smooth (const unsigned int level, + VECTOR& u, + const VECTOR& rhs) const = 0; +}; + + /** * Smoother doing nothing. This class is not useful for many applications other * than for testing some multigrid procedures. Also some applications might * get convergence without smoothing and then this class brings you the * cheapest possible multigrid. * - * @author Guido Kanschat, 1999 + * @author Guido Kanschat, 1999, 2002 */ -class MGSmootherIdentity : public Subscriptor +template +class MGSmootherIdentity : public MGSmoother { public: /** @@ -42,10 +70,9 @@ class MGSmootherIdentity : public Subscriptor * operator equals the null * operator. */ - template - void smooth (const unsigned int level, - VECTOR& u, - const VECTOR& rhs) const; + virtual void smooth (const unsigned int level, + VECTOR& u, + const VECTOR& rhs) const; }; @@ -56,9 +83,10 @@ class MGSmootherIdentity : public Subscriptor * triangulation) to zero, by building a list of these degrees of * freedom's indices at construction time. * - * @author Wolfgang Bangerth, Guido Kanschat, 1999 + * @author Wolfgang Bangerth, Guido Kanschat, 1999, 2002 */ -class MGSmootherContinuous : public Subscriptor +template +class MGSmootherContinuous : public MGSmoother { private: /** @@ -122,7 +150,6 @@ class MGSmootherContinuous : public Subscriptor * has no interior boundaries, this * function does nothing in this case. */ - template void set_zero_interior_boundary (const unsigned int level, VECTOR& u) const; @@ -173,7 +200,7 @@ class MGSmootherContinuous : public Subscriptor * @author Wolfgang Bangerth, Guido Kanschat, 1999 */ template -class MGSmootherRelaxation : public MGSmootherContinuous +class MGSmootherRelaxation : public MGSmootherContinuous { public: /** @@ -214,9 +241,9 @@ class MGSmootherRelaxation : public MGSmootherContinuous * work and find a way to keep * the boundary values. */ - void smooth (const unsigned int level, - VECTOR& u, - const VECTOR& rhs) const; + virtual void smooth (const unsigned int level, + VECTOR& u, + const VECTOR& rhs) const; private: /** * Pointer to the matrices. @@ -236,12 +263,12 @@ class MGSmootherRelaxation : public MGSmootherContinuous /** * Auxiliary vector. */ - mutable Vector h1; + mutable VECTOR h1; /** * Auxiliary vector. */ - mutable Vector h2; + mutable VECTOR h2; }; @@ -249,21 +276,25 @@ class MGSmootherRelaxation : public MGSmootherContinuous template inline void -MGSmootherIdentity::smooth (const unsigned int, VECTOR&, const VECTOR&) const +MGSmootherIdentity::smooth ( + const unsigned int, VECTOR&, + const VECTOR&) const {}; /*----------------------------------------------------------------------*/ +template inline void -MGSmootherContinuous::set_steps(unsigned int i) +MGSmootherContinuous::set_steps(unsigned int i) { steps = i; } +template inline unsigned int -MGSmootherContinuous::get_steps() const +MGSmootherContinuous::get_steps() const { return steps; } diff --git a/deal.II/deal.II/include/multigrid/mg_smoother.templates.h b/deal.II/deal.II/include/multigrid/mg_smoother.templates.h index c481c04359..3700a525fb 100644 --- a/deal.II/deal.II/include/multigrid/mg_smoother.templates.h +++ b/deal.II/deal.II/include/multigrid/mg_smoother.templates.h @@ -24,7 +24,7 @@ MGSmootherRelaxation const unsigned int steps, const double omega) : - MGSmootherContinuous(mg_dof, steps), + MGSmootherContinuous(mg_dof, steps), matrix(&matrix), relaxation(relaxation), omega(omega) diff --git a/deal.II/deal.II/include/multigrid/multigrid.h b/deal.II/deal.II/include/multigrid/multigrid.h index 809103a0e0..eb890b259a 100644 --- a/deal.II/deal.II/include/multigrid/multigrid.h +++ b/deal.II/deal.II/include/multigrid/multigrid.h @@ -87,6 +87,9 @@ class Multigrid : public Subscriptor */ template Multigrid(const MGDoFHandler& mg_dof_handler, + const MGTransfer& transfer, + const MGSmoother& pre_smooth, + const MGSmoother& post_smooth, const unsigned int minlevel = 0, const unsigned int maxlevel = 1000000); @@ -111,11 +114,8 @@ class Multigrid : public Subscriptor * function is done in * @p{level_mgstep}. */ - template + template void vcycle(const MGLevelObject& matrix, - const MGTransfer& transfer, - const SMOOTHER& pre_smooth, - const SMOOTHER& post_smooth, const COARSE& cgs); /** @@ -143,12 +143,9 @@ class Multigrid : public Subscriptor * is used to solve the matrix of * this level. */ - template + template void level_mgstep (const unsigned int level, const MGLevelObject& matrix, - const MGTransfer& transfer, - const SMOOTHER& pre_smooth, - const SMOOTHER& post_smooth, const COARSE& cgs); /** * Level for coarse grid solution. @@ -181,6 +178,20 @@ class Multigrid : public Subscriptor private: + /** + * Object for grid tranfer. + */ + SmartPointer > transfer; + /** + * The pre-smoothing object. + */ + SmartPointer > pre_smooth; + + /** + * The post-smoothing object. + */ + SmartPointer > post_smooth; + /** @@ -189,7 +200,7 @@ class Multigrid : public Subscriptor DeclException2(ExcSwitchedLevels, int, int, << "minlevel and maxlevel switched, should be: " << arg1 << "<=" << arg2); - template friend class PreconditionMG; + template friend class PreconditionMG; }; @@ -205,7 +216,7 @@ class Multigrid : public Subscriptor * * @author Guido Kanschat, 1999, 2000, 2001, 2002 */ -template +template class PreconditionMG : public Subscriptor { public: @@ -219,8 +230,6 @@ class PreconditionMG : public Subscriptor Multigrid& mg, const MGLevelObject& matrix, const TRANSFER& transfer, - const SMOOTHER& pre, - const SMOOTHER& post, const COARSE& coarse); /** @@ -287,16 +296,6 @@ class PreconditionMG : public Subscriptor */ SmartPointer transfer; - /** - * The pre-smoothing object. - */ - SmartPointer pre; - - /** - * The post-smoothing object. - */ - SmartPointer post; - /** * The coarse grid solver. */ @@ -312,27 +311,30 @@ class PreconditionMG : public Subscriptor template template Multigrid::Multigrid (const MGDoFHandler& mg_dof_handler, + const MGTransfer& transfer, + const MGSmoother& pre_smooth, + const MGSmoother& post_smooth, const unsigned int min_level, const unsigned int max_level) : minlevel(min_level), - maxlevel(std::min(mg_dof_handler.get_tria().n_levels()-1, - max_level)), - defect(minlevel,maxlevel), - solution(minlevel,maxlevel), - t(minlevel,maxlevel) + maxlevel(std::min(mg_dof_handler.get_tria().n_levels()-1, + max_level)), + defect(minlevel,maxlevel), + solution(minlevel,maxlevel), + t(minlevel,maxlevel), + transfer(&transfer), + pre_smooth(&pre_smooth), + post_smooth(&post_smooth) { }; template -template +template void Multigrid::level_mgstep(const unsigned int level, const MGLevelObject& matrix, - const MGTransfer& transfer, - const SMOOTHER &pre_smooth, - const SMOOTHER &post_smooth, const COARSE &coarse_grid_solver) { #ifdef MG_DEBUG @@ -354,7 +356,7 @@ Multigrid::level_mgstep(const unsigned int level, } // smoothing of the residual by modifying s - pre_smooth.smooth(level, solution[level], defect[level]); + pre_smooth->smooth(level, solution[level], defect[level]); #ifdef MG_DEBUG sprintf(name, "MG%d-pre",level); @@ -373,7 +375,7 @@ Multigrid::level_mgstep(const unsigned int level, for (unsigned int l = level;l>minlevel;--l) { t[l-1] = 0.; - transfer.restrict_and_add (l, t[l-1], t[l]); + transfer->restrict_and_add (l, t[l-1], t[l]); defect[l-1] += t[l-1]; } @@ -381,7 +383,7 @@ Multigrid::level_mgstep(const unsigned int level, // edge_vmult(level, defect[level-1], defect[level]); // do recursion - level_mgstep(level-1, matrix, transfer, pre_smooth, post_smooth, coarse_grid_solver); + level_mgstep(level-1, matrix, coarse_grid_solver); // reset size of the auxiliary // vector, since it has been @@ -391,7 +393,7 @@ Multigrid::level_mgstep(const unsigned int level, // do coarse grid correction - transfer.prolongate(level, t[level], solution[level-1]); + transfer->prolongate(level, t[level], solution[level-1]); #ifdef MG_DEBUG sprintf(name, "MG%d-cgc",level); @@ -401,7 +403,7 @@ Multigrid::level_mgstep(const unsigned int level, solution[level] += t[level]; // post-smoothing - post_smooth.smooth(level, solution[level], defect[level]); + post_smooth->smooth(level, solution[level], defect[level]); #ifdef MG_DEBUG sprintf(name, "MG%d-post",level); @@ -413,12 +415,9 @@ Multigrid::level_mgstep(const unsigned int level, template -template +template void Multigrid::vcycle(const MGLevelObject& matrix, - const MGTransfer& transfer, - const SMOOTHER &pre_smooth, - const SMOOTHER &post_smooth, const COARSE &coarse_grid_solver) { // The defect vector has been @@ -433,7 +432,7 @@ Multigrid::vcycle(const MGLevelObject& matrix, t[level].reinit(defect[level]); } - level_mgstep (maxlevel, matrix, transfer, pre_smooth, post_smooth, coarse_grid_solver); + level_mgstep (maxlevel, matrix, coarse_grid_solver); // abort (); } @@ -441,29 +440,25 @@ Multigrid::vcycle(const MGLevelObject& matrix, /* ------------------------------------------------------------------- */ -template -PreconditionMG +template +PreconditionMG ::PreconditionMG(const MGDoFHandler& mg_dof_handler, Multigrid& mg, const MGLevelObject& matrix, const TRANSFER& transfer, - const SMOOTHER& pre, - const SMOOTHER& post, const COARSE& coarse) : mg_dof_handler(&mg_dof_handler), multigrid(&mg), level_matrices(&matrix), transfer(&transfer), - pre(&pre), - post(&post), coarse(&coarse) {} -template +template void -PreconditionMG::vmult ( +PreconditionMG::vmult ( VECTOR& dst, const VECTOR& src) const { @@ -471,9 +466,7 @@ PreconditionMG::vmult ( multigrid->defect, src); - multigrid->vcycle(*level_matrices, - *transfer, - *pre, *post, *coarse); + multigrid->vcycle(*level_matrices, *coarse); transfer->copy_from_mg(*mg_dof_handler, dst, @@ -481,9 +474,9 @@ PreconditionMG::vmult ( } -template +template void -PreconditionMG::vmult_add ( +PreconditionMG::vmult_add ( VECTOR& dst, const VECTOR& src) const { @@ -491,9 +484,7 @@ PreconditionMG::vmult_add ( multigrid->defect, src); - multigrid->vcycle(*level_matrices, - *transfer, - *pre, *post, *coarse); + multigrid->vcycle(*level_matrices, *coarse); transfer->copy_from_mg_add(*mg_dof_handler, dst, @@ -501,9 +492,9 @@ PreconditionMG::vmult_add ( } -template +template void -PreconditionMG::Tvmult ( +PreconditionMG::Tvmult ( VECTOR&, const VECTOR&) const { @@ -511,9 +502,9 @@ PreconditionMG::Tvmult ( } -template +template void -PreconditionMG::Tvmult_add ( +PreconditionMG::Tvmult_add ( VECTOR&, const VECTOR&) const { diff --git a/deal.II/deal.II/source/multigrid/mg_smoother.cc b/deal.II/deal.II/source/multigrid/mg_smoother.cc index 827b0b1672..18e0cef626 100644 --- a/deal.II/deal.II/source/multigrid/mg_smoother.cc +++ b/deal.II/deal.II/source/multigrid/mg_smoother.cc @@ -18,7 +18,6 @@ #include #include #include -//#include #include #include #include @@ -29,14 +28,21 @@ #include +template +MGSmoother::~MGSmoother() +{} + + ////////////////////////////////////////////////////////////////////// #if deal_II_dimension == 1 -MGSmootherContinuous::MGSmootherContinuous (const MGDoFHandler<1> &/*mg_dof*/, - const unsigned int steps) +template +MGSmootherContinuous::MGSmootherContinuous ( + const MGDoFHandler<1> &/*mg_dof*/, + const unsigned int steps) : steps(steps) { @@ -48,9 +54,11 @@ MGSmootherContinuous::MGSmootherContinuous (const MGDoFHandler<1> &/*mg_dof*/, #if deal_II_dimension > 1 +template template -MGSmootherContinuous::MGSmootherContinuous (const MGDoFHandler &mg_dof, - const unsigned int steps) +MGSmootherContinuous::MGSmootherContinuous ( + const MGDoFHandler &mg_dof, + const unsigned int steps) : steps(steps) { @@ -115,7 +123,7 @@ MGSmootherContinuous::MGSmootherContinuous (const MGDoFHandler &mg_dof, template void -MGSmootherContinuous::set_zero_interior_boundary (const unsigned int level, +MGSmootherContinuous::set_zero_interior_boundary (const unsigned int level, VECTOR& u) const { if (level==0) @@ -130,28 +138,45 @@ MGSmootherContinuous::set_zero_interior_boundary (const unsigned int level, // explicit instantiations + +template MGSmoother >::~MGSmoother(); +template MGSmoother >::~MGSmoother(); +template MGSmoother >::~MGSmoother(); +template MGSmoother >::~MGSmoother(); + // don't do the following instantiation in 1d, since there is a specialized // function there #if deal_II_dimension > 1 -template MGSmootherContinuous::MGSmootherContinuous (const MGDoFHandler&, - const unsigned int); +template MGSmootherContinuous >::MGSmootherContinuous ( + const MGDoFHandler&, + const unsigned int); +template MGSmootherContinuous >::MGSmootherContinuous ( + const MGDoFHandler&, + const unsigned int); +template MGSmootherContinuous >::MGSmootherContinuous ( + const MGDoFHandler&, + const unsigned int); +template MGSmootherContinuous >::MGSmootherContinuous ( + const MGDoFHandler&, + const unsigned int); #endif template -void MGSmootherContinuous::set_zero_interior_boundary > (const unsigned int, - Vector&) const; - +void MGSmootherContinuous >::set_zero_interior_boundary ( + const unsigned int, + Vector&) const; template -void MGSmootherContinuous::set_zero_interior_boundary > (const unsigned int, - Vector&) const; - +void MGSmootherContinuous >::set_zero_interior_boundary ( + const unsigned int, + Vector&) const; template -void MGSmootherContinuous::set_zero_interior_boundary > (const unsigned int, - BlockVector&) const; - +void MGSmootherContinuous >::set_zero_interior_boundary ( + const unsigned int, + BlockVector&) const; template -void MGSmootherContinuous::set_zero_interior_boundary > (const unsigned int, - BlockVector&) const; +void MGSmootherContinuous >::set_zero_interior_boundary ( + const unsigned int, + BlockVector&) const; -- 2.39.5