*
* @author Wolfgang Bangerth, 1998 */
template <int dim>
-class DoFHandler : public DoFDimensionInfo<dim> {
+class DoFHandler
+ :
+ public Subscriptor,
+ public DoFDimensionInfo<dim>
+{
public:
typedef typename DoFDimensionInfo<dim>::raw_line_iterator raw_line_iterator;
typedef typename DoFDimensionInfo<dim>::line_iterator line_iterator;
template <int dim>
-class MGDoFHandler : public DoFHandler<dim> {
+class MGDoFHandler
+ :
+ public DoFHandler<dim>
+{
public:
typedef typename MGDoFDimensionInfo<dim>::raw_line_iterator raw_line_iterator;
typedef typename MGDoFDimensionInfo<dim>::line_iterator line_iterator;
template <int dim>
-class MGDoFHandler : public DoFHandler<dim> {
+class MGDoFHandler
+ :
+ public DoFHandler<dim>
+{
public:
typedef typename MGDoFDimensionInfo<dim>::raw_line_iterator raw_line_iterator;
typedef typename MGDoFDimensionInfo<dim>::line_iterator line_iterator;
#include <lac/forward-declarations.h>
#include <basic/forward-declarations.h>
-#include <base/subscriptor.h>
+#include <base/smartpointer.h>
#include <vector>
+/**
+ * Abstract base class for multigrid smoothers.
+ * In fact, this class only provides the interface of the smoothing function.
+ * Using deal.II grid handling, #MGSmoother# is a good point to start.
+ *
+ * @author Wolfgang Bangerth, Guido Kanschat, 1999
+ */
+class MGSmootherBase
+ :
+ public Subscriptor
+{
+ public:
+ /**
+ * Virtual destructor.
+ */
+ virtual ~MGSmootherBase();
+
+ /**
+ * Smoothen the residual of #u# on the given
+ * level. This function should keep the interior
+ * level boundary values, so you may want
+ * to call #set_zero_interior_boundary#
+ * in the derived class #MGSmoother#
+ * somewhere in your derived function,
+ * or another function doing similar
+ * things.
+ */
+ virtual void smooth (const unsigned int level,
+ Vector<float> &u,
+ const Vector<float> &rhs) const = 0;
+
+};
/**
- * Abstract base class for multigrid smoothers. It declares the interface
- * to smoothers and implements some functionality for setting the values
+ * Base class for multigrid smoothers. It declares the interface
+ * to smoothers by inheriting #MGSmootherBase# and implements some functionality for setting
+ * the values
* of vectors at interior boundaries (i.e. boundaries between differing
* levels of the triangulation) to zero, by building a list of these degrees
* of freedom's indices at construction time.
*
* @author Wolfgang Bangerth, Guido Kanschat, 1999
*/
-class MGSmoother : public Subscriptor
+class MGSmoother
+ : public MGSmootherBase
{
private:
/**
* the different levels, which are
* needed by the function
* #set_zero_interior_boundaries#.
- */
- template <int dim>
- MGSmoother (const MGDoFHandler<dim> &mg_dof);
-
- /**
- * Destructor, made virtual.
- */
- virtual ~MGSmoother ();
-
- /**
- * Smooth the vector #u# on the given
- * level. This function should set the
- * interior boundary values of u to zero
- * at the end of its work, so you may want
- * to call #set_zero_interior_boundary#
- * at the end of your derived function,
- * or another function doing similar
- * things.
*
- * This function is responsible for the
- * presmoothing, postsmoothing is done
- * by another function, which, however,
- * calls this function if not overloaded.
- */
- virtual void pre_smooth (const unsigned int level,
- Vector<float> &u) const = 0;
-
- /**
- * Postsmoothing; the same applies as for
- * the presmoothing function. If you
- * want pre- and postsmoothing to do the
- * same operations, you may want to not
- * overload this function, since its
- * default implementation simply calls
- * #pre_smooth#.
+ * The parameter steps indicates the number of smoothing
+ * steps to be executed by #smooth#.
*/
- virtual void post_smooth (const unsigned int level,
- Vector<float> &u) const;
+ template <int dim>
+ MGSmoother (const MGDoFHandler<dim> &mg_dof, unsigned int steps);
/**
* Reset the values of the degrees of
*/
void set_zero_interior_boundary (const unsigned int level,
Vector<float> &u) const;
+ /**
+ * Modify the number of smoothing steps.
+ */
+ void set_steps(unsigned int steps);
+ /**
+ * How many steps should be used?
+ */
+ unsigned int get_steps() const;
private:
+ /**
+ * Number of smoothing steps.
+ */
+ unsigned int steps;
/**
* For each level, we store a list of
* degree of freedom indices which are
* entry refers to the second level.
*
* These arrays are set by the constructor.
+ * The entries for each level are sorted ascendingly.
*/
vector<vector<int> > interior_boundary_dofs;
};
+/**
+ * Implementation of an SOR smoother.
+ *
+ * This class is an implementation of a smootin algorithm for multigrid. It
+ * knows the actual instance of the multigrid matrix and uses the SOR method of the level
+ * matrices.
+ * @author Wolfgang Bangerth, Guido Kanschat, 1999
+ */
+class MGSmootherSOR
+ :
+ public MGSmoother
+{
+ public:
+ /**
+ * Constructor.
+ * The constructor uses an #MGDoFHandler# to initialize
+ * data structures for interior level boundary handling
+ * in #MGSmoother#. Furthermore, it takes a pointer to the
+ * matrices and the number of SOR steps required in each
+ * smoothing operation.
+ */
+
+ template<int dim>
+ MGSmootherSOR(const MGDoFHandler<dim> &mg_dof,
+ const MGMatrix& matrix,
+ unsigned int steps);
+ /**
+ * Implementation of the interface in #MGSmootherBase#.
+ * We use the SOR method in #SparseMatrix# for the real work
+ * and find a way to keep the boundary values.
+ */
+ virtual void smooth (const unsigned int level,
+ Vector<float> &u,
+ const Vector<float> &rhs) const;
+ private:
+ /**
+ * Pointer to the matrices.
+ */
+ SmartPointer< const MGMatrix > matrix;
+};
+
+inline
+void
+MGSmoother::set_steps(unsigned int i)
+{
+ steps = i;
+}
+
+inline
+unsigned int
+MGSmoother::get_steps() const
+{
+ return steps;
+}
/*---------------------------- mg_smoother.h ---------------------------*/
#define __multigrid_H
/*---------------------------- multigrid.h ---------------------------*/
+#include <base/subscriptor.h>
#include <base/smartpointer.h>
#include <lac/forward-declarations.h>
#include <basic/forward-declarations.h>
#include <vector>
class MGTransferBase;
-class MGSmoother;
+class MGSmootherBase;
/**
const MultiGridBase& operator=(const MultiGridBase&);
/**
- * Auxiliary vector.
+ * Auxiliary vector, defect.
*/
vector<Vector<float> > d;
/**
- * Auxiliary vector.
+ * Auxiliary vector, solution.
*/
vector<Vector<float> > s;
*/
Vector<float> t;
- /**
- * Highest level of cells.
- */
- unsigned maxlevel;
-
- /**
- * Level for coarse grid solution.
- */
- unsigned minlevel;
-
/**
* Prolongation and restriction object.
*/
- SmartPointer<MGTransferBase> transfer;
+ SmartPointer<const MGTransferBase> transfer;
protected:
/**
- * Number of pre-smoothing steps. Is used
- * as a parameter to #pre_smooth#.
+ * Highest level of cells.
*/
- unsigned n_pre_smooth;
-
+ unsigned int maxlevel;
+
/**
- * Number of post-smoothing steps Is used
- * as a parameter to #post_smooth#.
+ * Level for coarse grid solution.
*/
- unsigned n_post_smooth;
+ unsigned int minlevel;
+
/**
* The actual v-cycle multigrid method.
* This function is called on the
* #coarse_grid_solution# and
* proceeds back up.
*/
- void level_mgstep(unsigned level, MGSmoother& smoother);
+ void level_mgstep(unsigned int level,
+ const MGSmootherBase& pre_smooth,
+ const MGSmootherBase& post_smooth);
/**
* Apply residual operator on all
* This is implemented in a
* derived class.
*/
- virtual void level_residual(unsigned level,
+ virtual void level_residual(unsigned int level,
Vector<float>& dst,
const Vector<float>& src,
const Vector<float>& rhs) = 0;
* n_post_smooth)#
* smoothing steps of #pre_smooth#.
*/
- virtual void coarse_grid_solution(unsigned l,
+ virtual void coarse_grid_solution(unsigned int l,
Vector<float>& dst,
const Vector<float>& src);
/**
* Constructor, subject to change.
*/
- MultiGridBase(MGTransferBase& transfer,
- unsigned maxlevel, unsigned minlevel,
- unsigned pre_smooth, unsigned post_smooth);
+ MultiGridBase(const MGTransferBase& transfer,
+ unsigned int maxlevel, unsigned int minlevel);
virtual ~MultiGridBase();
};
const Vector<float> &src) const = 0;
};
+/**
+ * An array of matrices for each level.
+ * This class provides the functionality of #vector<SparseMatrix<float> ># combined
+ * with a subscriptor for smart pointers.
+ * @author Guido Kanschat, 1999
+ */
+class MGMatrix
+ :
+ public Subscriptor,
+ public Vector<SparseMatrix<float> >
+{
+ public:
+ /**
+ * Standard constructor.
+ */
+ MGMatrix()
+ {}
+ /**
+ * Constructor allowing to initialize the number of levels.
+ */
+ MGMatrix(unsigned int n_levels);
+};
+
+
/**
* Implementation of multigrid with matrices.
* While #MultiGridBase# was only an abstract framework for the v-cycle,
*
* @author Wolfgang Bangerth, Guido Kanschat, 1999
*/
-template<int dim, class Matrix>
+template<int dim>
class MultiGrid
+ :
+ public MultiGridBase
{
public:
- MultiGrid(const MGDoFHandler<dim>&);
+ MultiGrid(const MGDoFHandler<dim>&, const MGTransferBase& transfer);
/** Transfer from dVector to
* MGVector.
template<typename number>
void copy_from_mg(Vector<number>& dst,
const vector<Vector<float> >& src) const;
+
+ /**
+ * Access to matrix structure.
+ */
+ SparseMatrixStruct& get_sparsity_pattern(unsigned int level);
+
+ /**
+ * Read-only access to matrix structure.
+ */
+ const SparseMatrixStruct& get_sparsity_pattern(unsigned int level) const;
+
+ /**
+ * Access to level matrices.
+ */
+ SparseMatrix<float>& get_matrix(unsigned int level);
+
+ /**
+ * Read-only access to level matrices.
+ */
+ const SparseMatrix<float>& get_matrix(unsigned int level) const;
+
private:
/**
* Associated #MGDoFHandler#.
*/
- SmartPointer<MGDoFHandler<dim> > dofs;
+ SmartPointer<const MGDoFHandler<dim> > dofs;
/**
* Matrix structures for each level.
vector<SparseMatrix<float> > prolongation_matrices;
};
+template<int dim>
+inline
+SparseMatrix<float>&
+MultiGrid<dim>::get_matrix(unsigned int level)
+{
+ Assert((level>=minlevel) && (level<maxlevel), ExcIndexRange(level, minlevel, maxlevel));
+
+ return matrices[level];
+}
+
+template<int dim>
+inline
+const SparseMatrix<float>&
+MultiGrid<dim>::get_matrix(unsigned int level) const
+{
+ Assert((level>=minlevel) && (level<maxlevel), ExcIndexRange(level, minlevel, maxlevel));
+
+ return matrices[level];
+}
+
/*---------------------------- multigrid.h ---------------------------*/
* Write a patch for each grid cell using
* #accuracy# subintervals per dimension.
*/
- void write_gnuplot (ostream &out, const unsigned accuracy=1) const;
+ void write_gnuplot (ostream &out, const unsigned int accuracy=1) const;
/**
* Write data and grid in GNUPLOT format.
#include <lac/forward-declarations.h>
#include <basic/forward-declarations.h>
-#include <base/subscriptor.h>
+#include <base/smartpointer.h>
#include <vector>
+/**
+ * Abstract base class for multigrid smoothers.
+ * In fact, this class only provides the interface of the smoothing function.
+ * Using deal.II grid handling, #MGSmoother# is a good point to start.
+ *
+ * @author Wolfgang Bangerth, Guido Kanschat, 1999
+ */
+class MGSmootherBase
+ :
+ public Subscriptor
+{
+ public:
+ /**
+ * Virtual destructor.
+ */
+ virtual ~MGSmootherBase();
+
+ /**
+ * Smoothen the residual of #u# on the given
+ * level. This function should keep the interior
+ * level boundary values, so you may want
+ * to call #set_zero_interior_boundary#
+ * in the derived class #MGSmoother#
+ * somewhere in your derived function,
+ * or another function doing similar
+ * things.
+ */
+ virtual void smooth (const unsigned int level,
+ Vector<float> &u,
+ const Vector<float> &rhs) const = 0;
+
+};
/**
- * Abstract base class for multigrid smoothers. It declares the interface
- * to smoothers and implements some functionality for setting the values
+ * Base class for multigrid smoothers. It declares the interface
+ * to smoothers by inheriting #MGSmootherBase# and implements some functionality for setting
+ * the values
* of vectors at interior boundaries (i.e. boundaries between differing
* levels of the triangulation) to zero, by building a list of these degrees
* of freedom's indices at construction time.
*
* @author Wolfgang Bangerth, Guido Kanschat, 1999
*/
-class MGSmoother : public Subscriptor
+class MGSmoother
+ : public MGSmootherBase
{
private:
/**
* the different levels, which are
* needed by the function
* #set_zero_interior_boundaries#.
- */
- template <int dim>
- MGSmoother (const MGDoFHandler<dim> &mg_dof);
-
- /**
- * Destructor, made virtual.
- */
- virtual ~MGSmoother ();
-
- /**
- * Smooth the vector #u# on the given
- * level. This function should set the
- * interior boundary values of u to zero
- * at the end of its work, so you may want
- * to call #set_zero_interior_boundary#
- * at the end of your derived function,
- * or another function doing similar
- * things.
*
- * This function is responsible for the
- * presmoothing, postsmoothing is done
- * by another function, which, however,
- * calls this function if not overloaded.
- */
- virtual void pre_smooth (const unsigned int level,
- Vector<float> &u) const = 0;
-
- /**
- * Postsmoothing; the same applies as for
- * the presmoothing function. If you
- * want pre- and postsmoothing to do the
- * same operations, you may want to not
- * overload this function, since its
- * default implementation simply calls
- * #pre_smooth#.
+ * The parameter steps indicates the number of smoothing
+ * steps to be executed by #smooth#.
*/
- virtual void post_smooth (const unsigned int level,
- Vector<float> &u) const;
+ template <int dim>
+ MGSmoother (const MGDoFHandler<dim> &mg_dof, unsigned int steps);
/**
* Reset the values of the degrees of
*/
void set_zero_interior_boundary (const unsigned int level,
Vector<float> &u) const;
+ /**
+ * Modify the number of smoothing steps.
+ */
+ void set_steps(unsigned int steps);
+ /**
+ * How many steps should be used?
+ */
+ unsigned int get_steps() const;
private:
+ /**
+ * Number of smoothing steps.
+ */
+ unsigned int steps;
/**
* For each level, we store a list of
* degree of freedom indices which are
* entry refers to the second level.
*
* These arrays are set by the constructor.
+ * The entries for each level are sorted ascendingly.
*/
vector<vector<int> > interior_boundary_dofs;
};
+/**
+ * Implementation of an SOR smoother.
+ *
+ * This class is an implementation of a smootin algorithm for multigrid. It
+ * knows the actual instance of the multigrid matrix and uses the SOR method of the level
+ * matrices.
+ * @author Wolfgang Bangerth, Guido Kanschat, 1999
+ */
+class MGSmootherSOR
+ :
+ public MGSmoother
+{
+ public:
+ /**
+ * Constructor.
+ * The constructor uses an #MGDoFHandler# to initialize
+ * data structures for interior level boundary handling
+ * in #MGSmoother#. Furthermore, it takes a pointer to the
+ * matrices and the number of SOR steps required in each
+ * smoothing operation.
+ */
+
+ template<int dim>
+ MGSmootherSOR(const MGDoFHandler<dim> &mg_dof,
+ const MGMatrix& matrix,
+ unsigned int steps);
+ /**
+ * Implementation of the interface in #MGSmootherBase#.
+ * We use the SOR method in #SparseMatrix# for the real work
+ * and find a way to keep the boundary values.
+ */
+ virtual void smooth (const unsigned int level,
+ Vector<float> &u,
+ const Vector<float> &rhs) const;
+ private:
+ /**
+ * Pointer to the matrices.
+ */
+ SmartPointer< const MGMatrix > matrix;
+};
+
+inline
+void
+MGSmoother::set_steps(unsigned int i)
+{
+ steps = i;
+}
+
+inline
+unsigned int
+MGSmoother::get_steps() const
+{
+ return steps;
+}
/*---------------------------- mg_smoother.h ---------------------------*/
#define __multigrid_H
/*---------------------------- multigrid.h ---------------------------*/
+#include <base/subscriptor.h>
#include <base/smartpointer.h>
#include <lac/forward-declarations.h>
#include <basic/forward-declarations.h>
#include <vector>
class MGTransferBase;
-class MGSmoother;
+class MGSmootherBase;
/**
const MultiGridBase& operator=(const MultiGridBase&);
/**
- * Auxiliary vector.
+ * Auxiliary vector, defect.
*/
vector<Vector<float> > d;
/**
- * Auxiliary vector.
+ * Auxiliary vector, solution.
*/
vector<Vector<float> > s;
*/
Vector<float> t;
- /**
- * Highest level of cells.
- */
- unsigned maxlevel;
-
- /**
- * Level for coarse grid solution.
- */
- unsigned minlevel;
-
/**
* Prolongation and restriction object.
*/
- SmartPointer<MGTransferBase> transfer;
+ SmartPointer<const MGTransferBase> transfer;
protected:
/**
- * Number of pre-smoothing steps. Is used
- * as a parameter to #pre_smooth#.
+ * Highest level of cells.
*/
- unsigned n_pre_smooth;
-
+ unsigned int maxlevel;
+
/**
- * Number of post-smoothing steps Is used
- * as a parameter to #post_smooth#.
+ * Level for coarse grid solution.
*/
- unsigned n_post_smooth;
+ unsigned int minlevel;
+
/**
* The actual v-cycle multigrid method.
* This function is called on the
* #coarse_grid_solution# and
* proceeds back up.
*/
- void level_mgstep(unsigned level, MGSmoother& smoother);
+ void level_mgstep(unsigned int level,
+ const MGSmootherBase& pre_smooth,
+ const MGSmootherBase& post_smooth);
/**
* Apply residual operator on all
* This is implemented in a
* derived class.
*/
- virtual void level_residual(unsigned level,
+ virtual void level_residual(unsigned int level,
Vector<float>& dst,
const Vector<float>& src,
const Vector<float>& rhs) = 0;
* n_post_smooth)#
* smoothing steps of #pre_smooth#.
*/
- virtual void coarse_grid_solution(unsigned l,
+ virtual void coarse_grid_solution(unsigned int l,
Vector<float>& dst,
const Vector<float>& src);
/**
* Constructor, subject to change.
*/
- MultiGridBase(MGTransferBase& transfer,
- unsigned maxlevel, unsigned minlevel,
- unsigned pre_smooth, unsigned post_smooth);
+ MultiGridBase(const MGTransferBase& transfer,
+ unsigned int maxlevel, unsigned int minlevel);
virtual ~MultiGridBase();
};
const Vector<float> &src) const = 0;
};
+/**
+ * An array of matrices for each level.
+ * This class provides the functionality of #vector<SparseMatrix<float> ># combined
+ * with a subscriptor for smart pointers.
+ * @author Guido Kanschat, 1999
+ */
+class MGMatrix
+ :
+ public Subscriptor,
+ public Vector<SparseMatrix<float> >
+{
+ public:
+ /**
+ * Standard constructor.
+ */
+ MGMatrix()
+ {}
+ /**
+ * Constructor allowing to initialize the number of levels.
+ */
+ MGMatrix(unsigned int n_levels);
+};
+
+
/**
* Implementation of multigrid with matrices.
* While #MultiGridBase# was only an abstract framework for the v-cycle,
*
* @author Wolfgang Bangerth, Guido Kanschat, 1999
*/
-template<int dim, class Matrix>
+template<int dim>
class MultiGrid
+ :
+ public MultiGridBase
{
public:
- MultiGrid(const MGDoFHandler<dim>&);
+ MultiGrid(const MGDoFHandler<dim>&, const MGTransferBase& transfer);
/** Transfer from dVector to
* MGVector.
template<typename number>
void copy_from_mg(Vector<number>& dst,
const vector<Vector<float> >& src) const;
+
+ /**
+ * Access to matrix structure.
+ */
+ SparseMatrixStruct& get_sparsity_pattern(unsigned int level);
+
+ /**
+ * Read-only access to matrix structure.
+ */
+ const SparseMatrixStruct& get_sparsity_pattern(unsigned int level) const;
+
+ /**
+ * Access to level matrices.
+ */
+ SparseMatrix<float>& get_matrix(unsigned int level);
+
+ /**
+ * Read-only access to level matrices.
+ */
+ const SparseMatrix<float>& get_matrix(unsigned int level) const;
+
private:
/**
* Associated #MGDoFHandler#.
*/
- SmartPointer<MGDoFHandler<dim> > dofs;
+ SmartPointer<const MGDoFHandler<dim> > dofs;
/**
* Matrix structures for each level.
vector<SparseMatrix<float> > prolongation_matrices;
};
+template<int dim>
+inline
+SparseMatrix<float>&
+MultiGrid<dim>::get_matrix(unsigned int level)
+{
+ Assert((level>=minlevel) && (level<maxlevel), ExcIndexRange(level, minlevel, maxlevel));
+
+ return matrices[level];
+}
+
+template<int dim>
+inline
+const SparseMatrix<float>&
+MultiGrid<dim>::get_matrix(unsigned int level) const
+{
+ Assert((level>=minlevel) && (level<maxlevel), ExcIndexRange(level, minlevel, maxlevel));
+
+ return matrices[level];
+}
+
/*---------------------------- multigrid.h ---------------------------*/
*/
enum PreparationState {
none, pure_refinement, coarsening_and_refinement
- } prepared_for;
+ };
+
+ /**
+ * ???
+ */
+ PreparationState prepared_for;
+
/**
* Is used for #prepare_for_refining#
* Enum denoting the type of problem
* which will have to be solved next.
*/
- enum {
+ enum SolutionState {
primal_problem = 0x0,
dual_problem = 0x1,
postprocess = 0x2
* can take effect of the triangulation
* already existing.
*/
- virtual void wake_up (const unsigned);
+ virtual void wake_up (const unsigned int);
/**
* This is the opposite function
* By default, this function does
* nothing.
*/
- virtual void sleep (const unsigned);
+ virtual void sleep (const unsigned int);
/**
* This function is called each time
* cass denoting the next action to be
* done.
*/
- enum {
+ enum SolutionState {
grid_refinement = 0x1000
};
* can take effect of the triangulation
* already existing.
*/
- virtual void wake_up (const unsigned wakeup_level);
+ virtual void wake_up (const unsigned int wakeup_level);
/**
* This is the opposite function
* that your function can use the
* triangulation as long as ou need it.
*/
- virtual void sleep (const unsigned);
+ virtual void sleep (const unsigned int);
/**
* Do the refinement according to the
* vectors therefore hold the history
* of the grid.
*/
- vector<vector<bool> > refine_flags, coarsen_flags;
+ vector<vector<bool> > refine_flags;
+
+ /**
+ * @see refine_flags
+ */
+ vector<vector<bool> > coarsen_flags;
/**
* Restore the grid according to the saved
* (first: top deviation, second: bottom
* deviation).
*/
- const double cell_number_corridor_top, cell_number_corridor_bottom;
+ const double cell_number_corridor_top;
+ /**
+ * @see cell_number_corridor_top
+ */
+ const double cell_number_corridor_bottom;
/**
* List of relaxations to the correction
#include <grid/mg_dof_accessor.h>
#include <grid/tria_iterator.h>
#include <fe/fe.h>
+#include <numerics/multigrid.h>
#include <numerics/mg_smoother.h>
#include <lac/vector.h>
#if deal_II_dimension == 1
-MGSmoother::MGSmoother (const MGDoFHandler<1> &/*mg_dof*/)
+MGSmoother::MGSmoother (const MGDoFHandler<1> &/*mg_dof*/, unsigned int steps)
+ :
+ steps(steps)
{
Assert (false, ExcNotImplemented());
};
#if deal_II_dimension > 1
template <int dim>
-MGSmoother::MGSmoother (const MGDoFHandler<dim> &mg_dof)
+MGSmoother::MGSmoother (const MGDoFHandler<dim> &mg_dof, unsigned int steps)
+ :
+ steps(steps)
{
const unsigned int n_levels = mg_dof.get_tria().n_levels();
#endif
+//////////////////////////////////////////////////////////////////////
-
-MGSmoother::~MGSmoother ()
+MGSmootherBase::~MGSmootherBase ()
{};
-
+//////////////////////////////////////////////////////////////////////
void
MGSmoother::set_zero_interior_boundary (const unsigned int level,
u(*p) = 0;
};
+//////////////////////////////////////////////////////////////////////
-
+template<int dim>
+MGSmootherSOR::MGSmootherSOR(const MGDoFHandler<dim> &mg_dof,
+ const MGMatrix& matrix,
+ unsigned int steps)
+ :
+ MGSmoother(mg_dof, steps),
+ matrix(&matrix)
+{}
void
-MGSmoother::post_smooth (const unsigned int level,
- Vector<float> &u) const
+MGSmootherSOR::smooth (const unsigned int /*level*/,
+ Vector<float> &/*u*/,
+ const Vector<float> &/*rhs*/) const
{
- pre_smooth (level, u);
-};
-
-
+}
// explicit instantiations
// don't do the following instantiation in 1d, since there is a specialized
// function there
#if deal_II_dimension > 1
-template MGSmoother::MGSmoother (const MGDoFHandler<deal_II_dimension>&);
+template MGSmoother::MGSmoother (const MGDoFHandler<deal_II_dimension>&, unsigned int);
#endif
+
+template MGSmootherSOR::MGSmootherSOR(const MGDoFHandler<deal_II_dimension> &mg_dof,
+ const MGMatrix& matrix, unsigned int steps);
+
#include <grid/tria_iterator.h>
#include <fe/fe.h>
#include <numerics/multigrid.h>
+#include <numerics/multigrid.templates.h>
+#include <numerics/mg_smoother.h>
#include <lac/vector.h>
-MultiGridBase::MultiGridBase(MGTransferBase& transfer,
- unsigned maxlevel, unsigned minlevel,
- unsigned pre_smooth, unsigned post_smooth)
+MultiGridBase::MultiGridBase(const MGTransferBase& transfer,
+ unsigned maxlevel, unsigned minlevel)
:
d(maxlevel-minlevel),
s(maxlevel-minlevel),
- maxlevel(maxlevel), minlevel(minlevel),
transfer(&transfer),
- n_pre_smooth(pre_smooth), n_post_smooth(post_smooth)
+ maxlevel(maxlevel), minlevel(minlevel)
{}
void
-MultiGridBase::level_mgstep(unsigned level, MGSmoother& smoother)
+MultiGridBase::level_mgstep(unsigned level,
+ const MGSmootherBase& pre_smooth,
+ const MGSmootherBase& post_smooth)
{
if (level == minlevel)
{
}
// smoothing of the residual by modifying s
-// smooth(level, d[level], s[level], n_pre_smooth);
+ pre_smooth.smooth(level, s[level], d[level]);
// t = d-As
level_residual(level, t, s[level], d[level]);
// make t rhs of lower level
transfer->restrict(level, t, d[level-1]);
// do recursion
- level_mgstep(level-1, smoother);
+ level_mgstep(level-1, pre_smooth, post_smooth);
// do coarse grid correction
transfer->prolongate(level, s[level], s[level-1]);
// smoothing (modify s again)
-// post_smooth(level, d[level], s[level], n_post_smooth);
+ post_smooth.smooth(level, s[level], d[level]);
}
template
void MGTransferPrebuilt::build_matrices (const MGDoFHandler<deal_II_dimension> &mg_dof);
-
+template MultiGrid<deal_II_dimension>;
#include <grid/mg_dof_accessor.h>
#include <grid/tria_iterator.h>
#include <fe/fe.h>
+#include <numerics/multigrid.h>
#include <numerics/mg_smoother.h>
#include <lac/vector.h>
#if deal_II_dimension == 1
-MGSmoother::MGSmoother (const MGDoFHandler<1> &/*mg_dof*/)
+MGSmoother::MGSmoother (const MGDoFHandler<1> &/*mg_dof*/, unsigned int steps)
+ :
+ steps(steps)
{
Assert (false, ExcNotImplemented());
};
#if deal_II_dimension > 1
template <int dim>
-MGSmoother::MGSmoother (const MGDoFHandler<dim> &mg_dof)
+MGSmoother::MGSmoother (const MGDoFHandler<dim> &mg_dof, unsigned int steps)
+ :
+ steps(steps)
{
const unsigned int n_levels = mg_dof.get_tria().n_levels();
#endif
+//////////////////////////////////////////////////////////////////////
-
-MGSmoother::~MGSmoother ()
+MGSmootherBase::~MGSmootherBase ()
{};
-
+//////////////////////////////////////////////////////////////////////
void
MGSmoother::set_zero_interior_boundary (const unsigned int level,
u(*p) = 0;
};
+//////////////////////////////////////////////////////////////////////
-
+template<int dim>
+MGSmootherSOR::MGSmootherSOR(const MGDoFHandler<dim> &mg_dof,
+ const MGMatrix& matrix,
+ unsigned int steps)
+ :
+ MGSmoother(mg_dof, steps),
+ matrix(&matrix)
+{}
void
-MGSmoother::post_smooth (const unsigned int level,
- Vector<float> &u) const
+MGSmootherSOR::smooth (const unsigned int /*level*/,
+ Vector<float> &/*u*/,
+ const Vector<float> &/*rhs*/) const
{
- pre_smooth (level, u);
-};
-
-
+}
// explicit instantiations
// don't do the following instantiation in 1d, since there is a specialized
// function there
#if deal_II_dimension > 1
-template MGSmoother::MGSmoother (const MGDoFHandler<deal_II_dimension>&);
+template MGSmoother::MGSmoother (const MGDoFHandler<deal_II_dimension>&, unsigned int);
#endif
+
+template MGSmootherSOR::MGSmootherSOR(const MGDoFHandler<deal_II_dimension> &mg_dof,
+ const MGMatrix& matrix, unsigned int steps);
+
#include <grid/tria_iterator.h>
#include <fe/fe.h>
#include <numerics/multigrid.h>
+#include <numerics/multigrid.templates.h>
+#include <numerics/mg_smoother.h>
#include <lac/vector.h>
-MultiGridBase::MultiGridBase(MGTransferBase& transfer,
- unsigned maxlevel, unsigned minlevel,
- unsigned pre_smooth, unsigned post_smooth)
+MultiGridBase::MultiGridBase(const MGTransferBase& transfer,
+ unsigned maxlevel, unsigned minlevel)
:
d(maxlevel-minlevel),
s(maxlevel-minlevel),
- maxlevel(maxlevel), minlevel(minlevel),
transfer(&transfer),
- n_pre_smooth(pre_smooth), n_post_smooth(post_smooth)
+ maxlevel(maxlevel), minlevel(minlevel)
{}
void
-MultiGridBase::level_mgstep(unsigned level, MGSmoother& smoother)
+MultiGridBase::level_mgstep(unsigned level,
+ const MGSmootherBase& pre_smooth,
+ const MGSmootherBase& post_smooth)
{
if (level == minlevel)
{
}
// smoothing of the residual by modifying s
-// smooth(level, d[level], s[level], n_pre_smooth);
+ pre_smooth.smooth(level, s[level], d[level]);
// t = d-As
level_residual(level, t, s[level], d[level]);
// make t rhs of lower level
transfer->restrict(level, t, d[level-1]);
// do recursion
- level_mgstep(level-1, smoother);
+ level_mgstep(level-1, pre_smooth, post_smooth);
// do coarse grid correction
transfer->prolongate(level, s[level], s[level-1]);
// smoothing (modify s again)
-// post_smooth(level, d[level], s[level], n_post_smooth);
+ post_smooth.smooth(level, s[level], d[level]);
}
template
void MGTransferPrebuilt::build_matrices (const MGDoFHandler<deal_II_dimension> &mg_dof);
-
+template MultiGrid<deal_II_dimension>;
%x LINECOMMENT
%x EXC_IGNORE
%x INSTRING
+%x INFUNCTION
+%x BASEINIT
-NAME [a-zA-Z][_a-zA-Z0-9]*
+NAME [_a-zA-Z][_a-zA-Z0-9]*
INT [+-]?[0-9]+
WHITE [ \t\n\f\v]
CLASS (class)|(struct)|(union)
<LINECOMMENT>.
<LINECOMMENT>\n { yy_pop_state(); }
+ /* Ignore function bodies */
+
+<INFUNCTION>"{" { yy_push_state(INFUNCTION); }
+<INFUNCTION>"}" { yy_pop_state(); }
+<INFUNCTION>.
+<INFUNCTION>\n
+
+ /* Ignore base initializers */
+<BASEINIT>"{" { yy_pop_state(); yy_push_state(INFUNCTION); }
+<BASEINIT>.
+<BASEINIT>\n
+
/* Ignore preprocessor commands */
-^#.*\n
+^#.*(\\\n.*)*\n
/* Ignore friend declarations so far */
enum { return ENUM; }
friend { return FRIEND; }
typedef { return TYPEDEF; }
+namespace { return NAMESPACE; }
typename {}
{CLASS} { yylval = string(yytext); return CLASS; }
cerr << "[" << yylval << "]"; return IDENTIFIER; }
. { yylval = string(yytext); return yytext[0]; }
+"..." { yylval = string(yytext); return THREEDOTS; }
%%
+void enterfunction()
+{
+ yy_push_state(INFUNCTION);
+}
+
+void enterbaseinitializers()
+{
+ yy_push_state(BASEINIT);
+}
stack<string> access_stack;
int yylex();
-void yy_push_fargs();
+void enterfunction();
+void enterbaseinitializers();
void yyerror(const char* s)
{
}
%}
+%token NAMESPACE
%token CLASS
%token TYPEDEF
%token ACCESS
%token COMTEMP
%token DECLEXCEPTION
%token INLINE
+%token THREEDOTS
%token ENDOFDECL
%%
declaration_list: declaration
| declaration_list { cout << "@@@" << endl; } declaration
+ | NAMESPACE '{' declaration_list '}' ';'
| declaration_list ';'
;
declaration:
class_declaration ';'
+ | function_declaration '{' { enterfunction(); }
+ | function_declaration ':' { enterbaseinitializers(); }
| function_declaration ';'
- | function_declaration '{' '}' ';'
- | function_declaration '{' '}'
| variable_declaration ';'
| enum_declaration ';'
| typedef_declaration ';'
| template_declaration class_declaration ';'
- { cout << setw(OUTW) << "Template-Description:" << $1 << endl; }
+ { cout << setw(OUTW) << "@Template-Description:" << $1 << endl; }
| template_declaration function_declaration ';'
- { cout << setw(OUTW) << "Template-Description:" << $1 << endl; }
+ { cout << setw(OUTW) << "@Template-Description:" << $1 << endl; }
+ | template_declaration function_declaration '{' { enterfunction();
+ cout << setw(OUTW) << "@Template-Description:" << $1 << endl; }
+ | template_declaration function_declaration ':' { enterbaseinitializers();
+ cout << setw(OUTW) << "@Template-Description:" << $1 << endl; }
| deal_exception_declaration ';'
+ | ';'
;
variable_declaration:
vartype identifier
- { cout << setw(OUTW) << "Variable-Declaration:" << $2 << endl
- << setw(OUTW) << "Type:" << $1 << endl
- << setw(OUTW) << "In-Class:" << class_stack.top() << endl
- << setw(OUTW) << "Access:" << access_stack.top() << endl; }
+ { cout << setw(OUTW) << "@Variable-Declaration:" << $2 << endl
+ << setw(OUTW) << "@Type:" << $1 << endl
+ << setw(OUTW) << "@In-Class:" << class_stack.top() << endl
+ << setw(OUTW) << "@Access:" << access_stack.top() << endl; }
| vartype identifier array_dimensions
- { cout << setw(OUTW) << "Variable-Declaration:" << $2 << endl
- << setw(OUTW) << "Type:" << $1 << endl
- << setw(OUTW) << "In-Class:" << class_stack.top() << endl
- << setw(OUTW) << "Access:" << access_stack.top() << endl
- << setw(OUTW) << "Array-Dimension:" << $3 << endl; }
+ { cout << setw(OUTW) << "@Variable-Declaration:" << $2 << endl
+ << setw(OUTW) << "@Type:" << $1 << endl
+ << setw(OUTW) << "@In-Class:" << class_stack.top() << endl
+ << setw(OUTW) << "@Access:" << access_stack.top() << endl
+ << setw(OUTW) << "@Array-Dimension:" << $3 << endl; }
| variable_declaration '=' expression
+/* | enum_declaration identifier*/
;
typedef_declaration:
TYPEDEF vartype identifier
- { cout << setw(OUTW) << "Typedef:" << $3 << endl
- << setw(OUTW) << "Type:" << $2 << endl
- << setw(OUTW) << "Access:" << access_stack.top() << endl; }
+ { cout << setw(OUTW) << "@Typedef:" << $3 << endl
+ << setw(OUTW) << "@Type:" << $2 << endl
+ << setw(OUTW) << "@Access:" << access_stack.top() << endl; }
| TYPEDEF vartype identifier array_dimensions
- { cout << setw(OUTW) << "Typedef:" << $3 << endl
- << setw(OUTW) << "Type:" << $2 << endl
- << setw(OUTW) << "Access:" << access_stack.top() << endl
- << setw(OUTW) << "Array-Dimension:" << $4 << endl; }
+ { cout << setw(OUTW) << "@Typedef:" << $3 << endl
+ << setw(OUTW) << "@Type:" << $2 << endl
+ << setw(OUTW) << "@Access:" << access_stack.top() << endl
+ << setw(OUTW) << "@Array-Dimension:" << $4 << endl; }
;
array_dimensions:
function_declaration:
function_name argument_declaration
{
- cout << setw(OUTW) << "Function-Definition:" << $1 << endl
- << setw(OUTW) << "Function-Parameters:" << $2 << endl
- << setw(OUTW) << "In-Class:" << class_stack.top() << endl
- << setw(OUTW) << "Access:" << access_stack.top() << endl;
+ cout << setw(OUTW) << "@Function-Definition:" << $1 << endl
+ << setw(OUTW) << "@Function-Parameters:" << $2 << endl
+ << setw(OUTW) << "@In-Class:" << class_stack.top() << endl
+ << setw(OUTW) << "@Access:" << access_stack.top() << endl;
}
| function_name argument_declaration CONST
{
- cout << setw(OUTW) << "Function-Definition:" << $1 << endl
- << setw(OUTW) << "Function-Parameters:" << $2 << endl
- << setw(OUTW) << "Const:" << "const" << endl
- << setw(OUTW) << "In-Class:" << class_stack.top() << endl
- << setw(OUTW) << "Access:" << access_stack.top() << endl;
+ cout << setw(OUTW) << "@Function-Definition:" << $1 << endl
+ << setw(OUTW) << "@Function-Parameters:" << $2 << endl
+ << setw(OUTW) << "@Const:" << "const" << endl
+ << setw(OUTW) << "@In-Class:" << class_stack.top() << endl
+ << setw(OUTW) << "@Access:" << access_stack.top() << endl;
}
| vartype function_declaration
{
- cout << setw(OUTW) << "Return-Type:" << $1 << endl;
+ cout << setw(OUTW) << "@Return-Type:" << $1 << endl;
}
;
| '~' identifier { $$ = string("~") + $2; }
| OPERATOR operator { $$ = string("operator") + $2; }
| OPERATOR vartype { $$ = string("operator") + $2; }
-
+ | identifier ':' ':' function_name { $$ = $1 + string("::") + $4; }
;
operator: OP
argument_declaration:
'(' ')' { $$ = string(""); }
+ | '(' THREEDOTS ')' { $$ = $2; }
| '(' arguments ')'
{ $$ = $2; }
;
{
class_stack.pop();
access_stack.pop();
- cout << "@@@" << endl << setw(OUTW) << "Class-Definition:" << $1 << endl
- << setw(OUTW) << "In-Class:" << class_stack.top() << endl;
+ cout << "@@@" << endl << setw(OUTW) << "@Class-Definition:" << $1 << endl
+ << setw(OUTW) << "@In-Class:" << class_stack.top() << endl;
}
;
declaration
| VIRTUAL declaration
{
- cout << setw(OUTW) << "Virtual:" << "virtual" << endl;
+ cout << setw(OUTW) << "@Virtual:" << "virtual" << endl;
}
| VIRTUAL function_declaration '=' INT
{
- cout << setw(OUTW) << "Virtual:" << "pure" << endl;
+ cout << setw(OUTW) << "@Virtual:" << "pure" << endl;
}
| ACCESS ':' { access_stack.top() = $1; }
| friend_declaration
identifier { $$ = $1; }
| UNSIGNED IDENTIFIER { $$ = string("unsigned ") + $2; }
| CONST vartype { $$ = string("const ") + $2; }
-/* | vartype CONST { $$ = $1 + string(" const"); } */
+ | vartype '*' CONST { $$ = $1 + string("* const"); }
| vartype '&' { $$ = $1 + string("&"); }
| vartype '*' { $$ = $1 + string("*"); }
| STATIC vartype { $$ = string("static ") + $2; }
| expression OP expression { $$ = $1 + $2 + $3; }
| expression INT { $$ = $1 + $2; }
| identifier argument_declaration { $$ = $1 + $2; }
+ | '(' expression ')' { $$ = $1 + $2 + $3; }
;
literal:
| CLASS IDENTIFIER { $$ = $1 + SPC + $2; }
;
-template_declaration:
+template_statement:
TEMPLATE '<' arguments '>' { $$ = $3; }
;
+template_declaration:
+ template_statement
+ | template_declaration template_statement { $$ = $1 + $2; }
+;
+
deal_exception_declaration:
DECLEXCEPTION '(' IDENTIFIER deal_exception_arglist ')'
;
DoFHandler<dim> dof(&tr);
dof.distribute_dofs(fe);
StraightBoundary<dim> boundary;
- DoFHandler<dim>::active_cell_iterator cell = dof.begin_active();
+// DoFHandler<dim>::active_cell_iterator cell = dof.begin_active();
DoFHandler<dim>::active_face_iterator face = dof.begin_active_face();
vector<Point<dim> > unit_points(fe.total_dofs);
// deal_II_libraries=-ldeal_II_2d
#include <numerics/multigrid.h>
+#include <numerics/mg_smoother.h>
class TransferTest
:
friend class MultiGridBase;
};
+class SmoothTest
+ :
+ public MGSmootherBase
+{
+ public:
+ virtual void smooth (const unsigned int level,
+ Vector<float> &u,
+ const Vector<float>& rhs) const;
+};
+
+
class MGTest
:
public MultiGridBase
{
+ MGSmootherBase& smoother;
+
public:
- MGTest(TransferTest& t)
- : MultiGridBase(t, 9, 3, 2, 4)
+ MGTest(TransferTest& t, SmoothTest& s)
+ : MultiGridBase(t, 9, 3),
+ smoother(s)
{}
virtual void level_residual(unsigned level,
const Vector<float>& src,
const Vector<float>& rhs);
- virtual void smooth(unsigned level,
- Vector<float>& x,
- const Vector<float>& b,
- unsigned steps);
void doit()
{
- level_mgstep(9);
+ level_mgstep(9, smoother, smoother);
}
};
main()
{
TransferTest tr;
- MGTest mg(tr);
+ SmoothTest s;
+ MGTest mg(tr, s);
mg.doit();
}
cout << "Restricting " << l << " to " << l-1 << endl;
}
+void
+SmoothTest::smooth (const unsigned int level,
+ Vector<float> &,
+ const Vector<float>&) const
+{
+ cout << "Smoothing on" << level << endl;
+}
+
void
MGTest::level_residual(unsigned l,
Vector<float>&,
{
cout << "Residual on " << l << endl;
}
-
-void
-MGTest::smooth(unsigned l,
- Vector<float>&,
- const Vector<float>&,
- unsigned steps)
-{
- cout << "Smooth on " << l << " : " << steps << " steps" << endl;
-}