Skip to content
Snippets Groups Projects
Forked from agnumpde / dune-solvers
47 commits behind the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
truncatedmgtransfer.hh 2.55 KiB
// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=8 sw=4 sts=4:
#ifndef TRUNCATED_MG_TRANSFER_HH
#define TRUNCATED_MG_TRANSFER_HH

#include <dune/istl/bcrsmatrix.hh>
#include <dune/common/fmatrix.hh>
#include <dune/common/bitsetvector.hh>
#include <dune/solvers/transferoperators/multigridtransfer.hh>

/** \brief Restriction and prolongation interface class for truncated multigrid
 *
 * This class provides prolongation and restriction operators for truncated
 * multigrid.  That means that you can explicitly switch off certain
 * fine grid degrees-of-freedom.  This often leads to better coarse
 * grid corrections when treating obstacle problems.  For an introduction
 * to the theory of truncated multigrid see 'Adaptive Monotone Multigrid
 * Methods for Nonlinear Variational Problems' by R. Kornhuber.
 *
 * Currently only works for first-order Lagrangian elements!
 */

template<
    class VectorType,
    class BitVectorType = Dune::BitSetVector<VectorType::block_type::dimension>,
    class MatrixType = Dune::BCRSMatrix< typename Dune::FieldMatrix<
        typename VectorType::field_type, VectorType::block_type::dimension, VectorType::block_type::dimension> > >
class TruncatedMGTransfer : virtual public MultigridTransfer<VectorType, BitVectorType, MatrixType>
{

    enum {blocksize = VectorType::block_type::dimension};

    typedef typename VectorType::field_type field_type;

public:

    /** \brief Default constructor */
    TruncatedMGTransfer() : recompute_(nullptr), critical_(nullptr) {}

    /** \brief Set recompute bitfield. */
    void setRecomputeBitField(const Dune::BitSetVector<blocksize>* recompute)
    {
        recompute_ = recompute;
    }

    /** \brief Set critical bitfield. */
    void setCriticalBitField(const BitVectorType* critical)
    {
        critical_ = critical;
    }

    /** \brief Bitfield specifying a subset of dofs which need to be recomputed
     * when doing Galerkin restriction
     *
     * If this pointer points to NULL it has no effect.  If not it is expected
     * to point to a bitfield with the size of the coarse function space.
     * Then, when calling galerkinRestrict(), only those matrix entries which
     * involve at least one dof which has a set bit get recomputed.  Depending
     * on the problem this can lead to considerable time savings.
     */
    const Dune::BitSetVector<blocksize>* recompute_;

    /**
     * \brief Has to contain an entry for each degree of freedom.
     *        Those dofs with a set bit are treated as critical.
     */
    const BitVectorType* critical_;
};

#endif