9#include <kernel/solver/base.hpp> 
   10#include <kernel/adjacency/graph.hpp> 
   11#include <kernel/lafem/dense_vector.hpp> 
   12#include <kernel/lafem/dense_vector_blocked.hpp> 
   13#include <kernel/lafem/power_vector.hpp> 
   14#include <kernel/lafem/tuple_vector.hpp> 
   15#include <kernel/lafem/sparse_matrix_csr.hpp> 
   16#include <kernel/lafem/sparse_matrix_bcsr.hpp> 
   17#include <kernel/lafem/power_diag_matrix.hpp> 
   18#include <kernel/lafem/power_full_matrix.hpp> 
   19#include <kernel/lafem/power_row_matrix.hpp> 
   20#include <kernel/lafem/power_col_matrix.hpp> 
   21#include <kernel/lafem/power_full_matrix.hpp> 
   22#include <kernel/lafem/saddle_point_matrix.hpp> 
   23#include <kernel/util/stop_watch.hpp> 
   50      template<
typename Vector_>
 
   69      template<
typename Matrix_>
 
   72      template<
typename DT_, 
typename IT_>
 
   73      class VankaVector<LAFEM::DenseVector<DT_, IT_>>
 
   76        typedef LAFEM::DenseVector<DT_, IT_> VectorType;
 
   77        static constexpr int dim = 1;
 
   83        explicit VankaVector(VectorType& vec_cor) :
 
   84          _vec_cor(vec_cor.elements())
 
   88        IT_ gather_def(DT_* x, 
const VectorType& vec, 
const IT_* idx, 
const IT_ n, 
const IT_ off)
 const 
   90          const DT_* vdef = vec.elements();
 
   92          for(IT_ i(0); i < n; ++i)
 
   94            x[off+i] = vdef[idx[i]];
 
   99        IT_ scatter_cor(
const DT_ omega, 
const DT_* x, 
const IT_* idx, 
const IT_ n, 
const IT_ off)
 
  101          for(IT_ i(0); i < n; ++i)
 
  103            _vec_cor[idx[i]] += omega * x[off+i];
 
  109      template<
typename DT_, 
typename IT_, 
int dim_>
 
  110      class VankaVector<LAFEM::DenseVectorBlocked<DT_, IT_, dim_>>
 
  113        typedef LAFEM::DenseVectorBlocked<DT_, IT_, dim_> VectorType;
 
  114        typedef typename VectorType::ValueType ValueType;
 
  115        static constexpr int dim = dim_;
 
  121        explicit VankaVector(VectorType& vec_cor) :
 
  122          _vec_cor(vec_cor.elements())
 
  126        IT_ gather_def(DT_* x, 
const VectorType& vec, 
const IT_* idx, 
const IT_ n, 
const IT_ off)
 const 
  128          const ValueType* vdef = vec.elements();
 
  130          for(IT_ i(0); i < n; ++i)
 
  132            const ValueType& vi = vdef[idx[i]];
 
  133            for(
int j(0); j < dim; ++j)
 
  135              x[off + i*IT_(dim) + IT_(j)] = vi[j];
 
  138          return off + IT_(dim)*n;
 
  141        IT_ scatter_cor(
const DT_ omega, 
const DT_* x, 
const IT_* idx, 
const IT_ n, 
const IT_ off)
 
  143          for(IT_ i(0); i < n; ++i)
 
  145            ValueType& vi = _vec_cor[idx[i]];
 
  146            for(
int j(0); j < dim; ++j)
 
  148              vi[j] += omega * x[off + i*IT_(dim) + IT_(j)];
 
  151          return off + IT_(dim)*n;
 
  155      template<
typename SubVector_, 
int dim_>
 
  156      class VankaVector<LAFEM::PowerVector<SubVector_, dim_>>
 
  159        typedef LAFEM::PowerVector<SubVector_, dim_> VectorType;
 
  160        typedef VankaVector<SubVector_> FirstClass;
 
  161        typedef VankaVector<LAFEM::PowerVector<SubVector_, dim_-1>> RestClass;
 
  163        static constexpr int dim = FirstClass::dim + RestClass::dim;
 
  170        explicit VankaVector(VectorType& vec_cor) :
 
  171          _first(vec_cor.first()),
 
  172          _rest(vec_cor.
rest())
 
  176        template<
typename DT_, 
typename IT_>
 
  177        IT_ gather_def(DT_* x, 
const VectorType& vec, 
const IT_* idx, 
const IT_ n, 
const IT_ off)
 const 
  179          IT_ noff = _first.gather_def(x, vec.first(), idx, n, off);
 
  180          return _rest.gather_def(x, vec.rest(), idx, n, noff);
 
  183        template<
typename DT_, 
typename IT_>
 
  184        IT_ scatter_cor(
const DT_ omega, 
const DT_* x, 
const IT_* idx, 
const IT_ n, 
const IT_ off)
 
  186          IT_ noff = _first.scatter_cor(omega, x, idx, n, off);
 
  187          return _rest.scatter_cor(omega, x, idx, n, noff);
 
  191      template<
typename SubVector_>
 
  192      class VankaVector<LAFEM::PowerVector<SubVector_, 1>>
 
  195        typedef LAFEM::PowerVector<SubVector_, 1> VectorType;
 
  196        typedef VankaVector<SubVector_> FirstClass;
 
  198        static constexpr int dim = FirstClass::dim;
 
  204        explicit VankaVector(VectorType& vec_cor) :
 
  205          _first(vec_cor.first())
 
  209        template<
typename DT_, 
typename IT_>
 
  210        IT_ gather_def(DT_* x, 
const VectorType& vec, 
const IT_* idx, 
const IT_ n, 
const IT_ off)
 const 
  212          return _first.gather_def(x, vec.first(), idx, n, off);
 
  215        template<
typename DT_, 
typename IT_>
 
  216        IT_ scatter_cor(
const DT_ omega, 
const DT_* x, 
const IT_* idx, 
const IT_ n, 
const IT_ off)
 
  218          return _first.scatter_cor(omega, x, idx, n, off);
 
  222      template<
typename DT_, 
typename IT_>
 
  223      class VankaMatrix<LAFEM::SparseMatrixCSR<DT_, IT_>>
 
  226        typedef LAFEM::SparseMatrixCSR<DT_, IT_> MatrixType;
 
  227        typedef LAFEM::DenseVector<DT_, IT_> VectorTypeR;
 
  229        static constexpr int row_dim = 1;
 
  230        static constexpr int col_dim = 1;
 
  238        explicit VankaMatrix(
const MatrixType& matrix) :
 
  239          _row_ptr(matrix.row_ptr()),
 
  240          _col_idx(matrix.col_ind()),
 
  241          _mat_val(matrix.val())
 
  245        std::pair<IT_, IT_> gather_full(
 
  246          DT_* data, 
const IT_* ridx, 
const IT_* cidx,
 
  247          const IT_ m, 
const IT_ n, 
const IT_ stride,
 
  248          const IT_ mo = IT_(0), 
const IT_ no = IT_(0))
 const 
  251          if(_mat_val == 
nullptr)
 
  252            return std::make_pair(mo+m, no+n);
 
  255          for(IT_ i(0); i < m; ++i)
 
  258            const IT_ ri = ridx[i];
 
  264            for(IT_ ai = _row_ptr[ri]; ai < _row_ptr[ri+1]; ++ai)
 
  267              const IT_ rj = _col_idx[ai];
 
  270              while((j < n) && (cidx[j] < rj))
 
  275              if((j < n) && (cidx[j] == rj))
 
  278                data[(mo + i) * stride + no + j] = _mat_val[ai];
 
  282          return std::make_pair(mo+m, no+n);
 
  285        IT_ gather_diag(DT_* data, 
const IT_* idx, 
const IT_ m, 
const IT_ mo = IT_(0))
 const 
  288          for(IT_ i(0); i < m; ++i)
 
  291            const IT_ ri = idx[i];
 
  294            for(IT_ ai = _row_ptr[ri]; ai < _row_ptr[ri+1]; ++ai)
 
  297              if(_col_idx[ai] == ri)
 
  299                data[mo+i] = _mat_val[ai];
 
  307        IT_ mult_cor(DT_* x, 
const DT_ alpha, 
const VectorTypeR& vec_cor, 
const IT_* idx, 
const IT_ m, 
const IT_ off)
 const 
  309          if(_mat_val == 
nullptr)
 
  312          const DT_* v = vec_cor.elements();
 
  315          for(IT_ i(0); i < m; ++i)
 
  317            const IT_ vi = idx[i];
 
  321            for(IT_ k = _row_ptr[vi]; k < _row_ptr[vi+1]; ++k)
 
  323              r += _mat_val[k] * v[_col_idx[k]];
 
  325            x[off+i] += alpha * r;
 
  335      template<
typename DT_, 
typename IT_, 
int row_dim_, 
int col_dim_>
 
  336      class VankaMatrix<LAFEM::SparseMatrixBCSR<DT_, IT_, row_dim_, col_dim_>>
 
  339        typedef LAFEM::SparseMatrixBCSR<DT_, IT_, row_dim_, col_dim_> MatrixType;
 
  341        typedef typename MatrixType::ValueType MatVal;
 
  343        static constexpr int row_dim = row_dim_;
 
  344        static constexpr int col_dim = col_dim_;
 
  349        const MatVal* _mat_val;
 
  352        explicit VankaMatrix(
const MatrixType& matrix) :
 
  353          _row_ptr(matrix.row_ptr()),
 
  354          _col_idx(matrix.col_ind()),
 
  355          _mat_val(matrix.val())
 
  359        std::pair<IT_, IT_> gather_full(
 
  360          DT_* data, 
const IT_* ridx, 
const IT_* cidx,
 
  361          const IT_ m, 
const IT_ n, 
const IT_ stride,
 
  362          const IT_ mo = IT_(0), 
const IT_ no = IT_(0))
 const 
  365          XASSERTM(_mat_val != 
nullptr, 
"Vanka: invalid empty BCSR matrix");
 
  368          for(IT_ i(0); i < m; ++i)
 
  371            const IT_ ri = ridx[i];
 
  377            for(IT_ ai = _row_ptr[ri]; ai < _row_ptr[ri+1]; ++ai)
 
  380              const IT_ rj = _col_idx[ai];
 
  383              while((j < n) && (cidx[j] < rj))
 
  388              if((j < n) && (cidx[j] == rj))
 
  391                const MatVal& mv = _mat_val[ai];
 
  394                for(
int ii(0); ii < row_dim; ++ii)
 
  397                  const IT_ lro = (mo + i * IT_(row_dim) + IT_(ii)) * stride + no + j * IT_(col_dim);
 
  400                  for(
int jj(0); jj < col_dim; ++jj)
 
  402                    data[lro + IT_(jj)] = mv[ii][jj];
 
  408          return std::make_pair(mo + IT_(row_dim)*m, no + IT_(col_dim)*n);
 
  411        IT_ gather_diag(DT_* data, 
const IT_* idx, 
const IT_ m, 
const IT_ mo = IT_(0))
 const 
  414          for(IT_ i(0); i < m; ++i)
 
  417            const IT_ ri = idx[i];
 
  420            for(IT_ ai = _row_ptr[ri]; ai < _row_ptr[ri+1]; ++ai)
 
  423              if(_col_idx[ai] == ri)
 
  425                const MatVal& mv = _mat_val[ai];
 
  428                for(
int k(0); k < row_dim; ++k)
 
  430                  data[mo + i*IT_(row_dim) + IT_(k)] = mv[k][k];
 
  439        IT_ mult_cor(DT_* x, 
const DT_ alpha, 
const LAFEM::DenseVectorBlocked<DT_, IT_, col_dim_>& vec_cor,
 
  440          const IT_* idx, 
const IT_ m, 
const IT_ off)
 const 
  442          if(_mat_val == 
nullptr)
 
  445          typedef LAFEM::DenseVectorBlocked<DT_, IT_, col_dim_> VectorType;
 
  446          typedef typename VectorType::ValueType VecVal;
 
  447          const VecVal* v = vec_cor.elements();
 
  450          for(IT_ i(0); i < m; ++i)
 
  452            const IT_ vi = idx[i];
 
  455            for(IT_ k = _row_ptr[vi]; k < _row_ptr[vi+1]; ++k)
 
  458              const MatVal& mv = _mat_val[k];
 
  459              const VecVal& vv = v[_col_idx[k]];
 
  462              for(
int ii(0); ii < row_dim; ++ii)
 
  466                for(
int jj(0); jj < col_dim; ++jj)
 
  468                  r += mv[ii][jj] * vv[jj];
 
  470                x[off + i*IT_(row_dim) + IT_(ii)] += alpha * r;
 
  474          return off + m* IT_(row_dim);
 
  477        IT_ mult_cor(DT_* x, 
const DT_ alpha, 
const LAFEM::DenseVector<DT_, IT_>& vec_cor,
 
  478          const IT_* idx, 
const IT_ m, 
const IT_ off)
 const 
  480          if(_mat_val == 
nullptr)
 
  483          const DT_* v = vec_cor.elements();
 
  486          for(IT_ i(0); i < m; ++i)
 
  488            const IT_ vi = idx[i];
 
  491            for(IT_ k = _row_ptr[vi]; k < _row_ptr[vi+1]; ++k)
 
  494              const MatVal& mv = _mat_val[k];
 
  498              const IT_ vo = _col_idx[k] * IT_(col_dim);
 
  501              for(
int ii(0); ii < row_dim; ++ii)
 
  505                for(
int jj(0); jj < col_dim; ++jj)
 
  507                  r += mv[ii][jj] * v[vo + IT_(jj)];
 
  509                x[off + i*IT_(row_dim) + IT_(ii)] += alpha * r;
 
  513          return off + m* IT_(row_dim);
 
  521      template<
typename SubMatrix_, 
int dim_>
 
  522      class VankaMatrix<LAFEM::PowerDiagMatrix<SubMatrix_, dim_>>
 
  525        typedef LAFEM::PowerDiagMatrix<SubMatrix_, dim_> MatrixType;
 
  526        typedef typename MatrixType::VectorTypeR VectorTypeR;
 
  527        typedef VankaMatrix<SubMatrix_> FirstClass;
 
  528        typedef VankaMatrix<LAFEM::PowerDiagMatrix<SubMatrix_, dim_-1>> RestClass;
 
  530        static constexpr int row_dim = FirstClass::row_dim + RestClass::row_dim;
 
  531        static constexpr int col_dim = FirstClass::col_dim + RestClass::col_dim;
 
  538        explicit VankaMatrix(
const MatrixType& matrix) :
 
  539          _first(matrix.first()),
 
  544        template<
typename DT_, 
typename IT_>
 
  545        std::pair<IT_, IT_> gather_full(
 
  546          DT_* data, 
const IT_* ridx, 
const IT_* cidx,
 
  547          const IT_ m, 
const IT_ n, 
const IT_ stride,
 
  548          const IT_ mo = IT_(0), 
const IT_ no = IT_(0))
 const 
  550          std::pair<IT_, IT_> mn = _first.gather_full(data, ridx, cidx, m, n, stride, mo, no);
 
  551          return _rest.gather_full(data, ridx, cidx, m, n, stride, mn.first, mn.second);
 
  554        template<
typename DT_, 
typename IT_>
 
  555        IT_ gather_diag(DT_* data, 
const IT_* idx, 
const IT_ m, 
const IT_ mo = IT_(0))
 const 
  557          IT_ mno = _first.gather_diag(data, idx, m, mo);
 
  558          return _rest.gather_diag(data, idx, m, mno);
 
  561        template<
typename DT_, 
typename IT_>
 
  562        IT_ mult_cor(DT_* x, 
const DT_ alpha, 
const VectorTypeR& vec_cor, 
const IT_* idx, 
const IT_ m, 
const IT_ off)
 const 
  564          IT_ noff = _first.mult_cor(x, alpha, vec_cor.first(), idx, m, off);
 
  565          return _rest.mult_cor(x, alpha, vec_cor.rest(), idx, m, noff);
 
  569      template<
typename SubMatrix_>
 
  570      class VankaMatrix<LAFEM::PowerDiagMatrix<SubMatrix_, 1>>
 
  573        typedef LAFEM::PowerDiagMatrix<SubMatrix_, 1> MatrixType;
 
  574        typedef typename MatrixType::VectorTypeR VectorTypeR;
 
  575        typedef VankaMatrix<SubMatrix_> FirstClass;
 
  577        static constexpr int row_dim = FirstClass::row_dim;
 
  578        static constexpr int col_dim = FirstClass::col_dim;
 
  584        explicit VankaMatrix(
const MatrixType& matrix) :
 
  585          _first(matrix.first())
 
  589        template<
typename DT_, 
typename IT_>
 
  590        std::pair<IT_, IT_> gather_full(
 
  591          DT_* data, 
const IT_* ridx, 
const IT_* cidx,
 
  592          const IT_ m, 
const IT_ n, 
const IT_ stride,
 
  593          const IT_ mo = IT_(0), 
const IT_ no = IT_(0))
 const 
  595          return _first.gather_full(data, ridx, cidx, m, n, stride, mo, no);
 
  598        template<
typename DT_, 
typename IT_>
 
  599        IT_ gather_diag(DT_* data, 
const IT_* idx, 
const IT_ m, 
const IT_ mo = IT_(0))
 const 
  601          return _first.gather_diag(data, idx, m, mo);
 
  604        template<
typename DT_, 
typename IT_>
 
  605        IT_ mult_cor(DT_* x, 
const DT_ alpha, 
const VectorTypeR& vec_cor, 
const IT_* idx, 
const IT_ m, 
const IT_ off)
 const 
  607          return _first.mult_cor(x, alpha, vec_cor.first(), idx, m, off);
 
  611      template<
typename SubMatrix_, 
int dim_>
 
  612      class VankaMatrix<LAFEM::PowerColMatrix<SubMatrix_, dim_>>
 
  615        typedef LAFEM::PowerColMatrix<SubMatrix_, dim_> MatrixType;
 
  616        typedef typename MatrixType::VectorTypeR VectorTypeR;
 
  617        typedef VankaMatrix<SubMatrix_> FirstClass;
 
  618        typedef VankaMatrix<LAFEM::PowerColMatrix<SubMatrix_, dim_-1>> RestClass;
 
  620        static constexpr int row_dim = FirstClass::row_dim + RestClass::row_dim;
 
  621        static constexpr int col_dim = FirstClass::col_dim;
 
  628        explicit VankaMatrix(
const MatrixType& matrix) :
 
  629          _first(matrix.first()),
 
  634        template<
typename DT_, 
typename IT_>
 
  635        std::pair<IT_, IT_> gather_full(
 
  636          DT_* data, 
const IT_* ridx, 
const IT_* cidx,
 
  637          const IT_ m, 
const IT_ n, 
const IT_ stride,
 
  638          const IT_ mo = IT_(0), 
const IT_ no = IT_(0))
 const 
  640          std::pair<IT_, IT_> mno = _first.gather_full(data, ridx, cidx, m, n, stride, mo, no);
 
  641          return _rest.gather_full(data, ridx, cidx, m, n, stride, mno.first, no);
 
  644        template<
int ro_, 
int co_, 
typename DT_, 
typename IT_>
 
  645        IT_ gather_diag_pfm(DT_* data, 
const IT_* idx, 
const IT_ m, 
const IT_ mo = IT_(0))
 const 
  647          IT_ mno = _first.template gather_diag_pfm<ro_, co_>(data, idx, m, mo);
 
  648          return _rest.template gather_diag_pfm<ro_+1, co_>(data, idx, m, mno);
 
  651        template<
typename DT_, 
typename IT_>
 
  652        IT_ mult_cor(DT_* x, 
const DT_ alpha, 
const VectorTypeR& vec_cor, 
const IT_* idx, 
const IT_ m, 
const IT_ off)
 const 
  654          IT_ noff = _first.mult_cor(x, alpha, vec_cor, idx, m, off);
 
  655          return _rest.mult_cor(x, alpha, vec_cor, idx, m, noff);
 
  659      template<
typename SubMatrix_>
 
  660      class VankaMatrix<LAFEM::PowerColMatrix<SubMatrix_, 1>>
 
  663        typedef LAFEM::PowerColMatrix<SubMatrix_, 1> MatrixType;
 
  664        typedef typename MatrixType::VectorTypeR VectorTypeR;
 
  665        typedef VankaMatrix<SubMatrix_> FirstClass;
 
  667        static constexpr int row_dim = FirstClass::row_dim;
 
  668        static constexpr int col_dim = FirstClass::col_dim;
 
  671        VankaMatrix<SubMatrix_> _first;
 
  674        explicit VankaMatrix(
const MatrixType& matrix) :
 
  675          _first(matrix.first())
 
  679        template<
typename DT_, 
typename IT_>
 
  680        std::pair<IT_, IT_> gather_full(
 
  681          DT_* data, 
const IT_* ridx, 
const IT_* cidx,
 
  682          const IT_ m, 
const IT_ n, 
const IT_ stride,
 
  683          const IT_ mo = IT_(0), 
const IT_ no = IT_(0))
 const 
  685          return _first.gather_full(data, ridx, cidx, m, n, stride, mo, no);
 
  688        template<
int ro_, 
int co_, 
typename DT_, 
typename IT_>
 
  689        IT_ gather_diag_pfm(DT_* data, 
const IT_* idx, 
const IT_ m, 
const IT_ mo = IT_(0))
 const 
  691          return _first.template gather_diag_pfm<ro_, co_>(data, idx, m, mo);
 
  694        template<
typename DT_, 
typename IT_>
 
  695        IT_ mult_cor(DT_* x, 
const DT_ alpha, 
const VectorTypeR& vec_cor, 
const IT_* idx, 
const IT_ m, 
const IT_ off)
 const 
  697          return _first.mult_cor(x, alpha, vec_cor, idx, m, off);
 
  701      template<
typename SubMatrix_, 
int dim_>
 
  702      class VankaMatrix<LAFEM::PowerRowMatrix<SubMatrix_, dim_>>
 
  705        typedef LAFEM::PowerRowMatrix<SubMatrix_, dim_> MatrixType;
 
  706        typedef typename MatrixType::VectorTypeR VectorTypeR;
 
  707        typedef VankaMatrix<SubMatrix_> FirstClass;
 
  708        typedef VankaMatrix<LAFEM::PowerRowMatrix<SubMatrix_, dim_-1>> RestClass;
 
  710        static constexpr int row_dim = FirstClass::row_dim;
 
  711        static constexpr int col_dim = FirstClass::col_dim + RestClass::col_dim;
 
  718        explicit VankaMatrix(
const MatrixType& matrix) :
 
  719          _first(matrix.first()),
 
  724        template<
typename DT_, 
typename IT_>
 
  725        std::pair<IT_, IT_> gather_full(
 
  726          DT_* data, 
const IT_* ridx, 
const IT_* cidx,
 
  727          const IT_ m, 
const IT_ n, 
const IT_ stride,
 
  728          const IT_ mo = IT_(0), 
const IT_ no = IT_(0))
 const 
  730          std::pair<IT_, IT_> mno = _first.gather_full(data, ridx, cidx, m, n, stride, mo, no);
 
  731          return _rest.gather_full(data, ridx, cidx, m, n, stride, mo, mno.second);
 
  734        template<
int ro_, 
int co_, 
typename DT_, 
typename IT_>
 
  735        IT_ gather_diag_pfm(DT_* data, 
const IT_* idx, 
const IT_ m, 
const IT_ mo = IT_(0))
 const 
  738            return _first.gather_diag(data, idx, m, mo);
 
  740            return _rest.template gather_diag_pfm<ro_, co_+1>(data, idx, m, mo);
 
  743        template<
typename DT_, 
typename IT_>
 
  744        IT_ mult_cor(DT_* x, 
const DT_ alpha, 
const VectorTypeR& vec_cor, 
const IT_* idx, 
const IT_ m, 
const IT_ off)
 const 
  746          _first.mult_cor(x, alpha, vec_cor.first(), idx, m, off);
 
  747          return _rest.mult_cor(x, alpha, vec_cor.rest(), idx, m, off);
 
  751      template<
typename SubMatrix_>
 
  752      class VankaMatrix<LAFEM::PowerRowMatrix<SubMatrix_, 1>>
 
  755        typedef LAFEM::PowerRowMatrix<SubMatrix_, 1> MatrixType;
 
  756        typedef VankaMatrix<SubMatrix_> FirstClass;
 
  757        typedef typename MatrixType::VectorTypeR VectorTypeR;
 
  759        static constexpr int row_dim = FirstClass::row_dim;
 
  760        static constexpr int col_dim = FirstClass::col_dim;
 
  766        explicit VankaMatrix(
const MatrixType& matrix) :
 
  767          _first(matrix.first())
 
  771        template<
typename DT_, 
typename IT_>
 
  772        std::pair<IT_, IT_> gather_full(
 
  773          DT_* data, 
const IT_* ridx, 
const IT_* cidx,
 
  774          const IT_ m, 
const IT_ n, 
const IT_ stride,
 
  775          const IT_ mo = IT_(0), 
const IT_ no = IT_(0))
 const 
  777          return _first.gather_full(data, ridx, cidx, m, n, stride, mo, no);
 
  780        template<
int ro_, 
int co_, 
typename DT_, 
typename IT_>
 
  781        IT_ gather_diag_pfm(DT_* data, 
const IT_* idx, 
const IT_ m, 
const IT_ mo = IT_(0))
 const 
  784            return _first.gather_diag(data, idx, m, mo);
 
  789        template<
typename DT_, 
typename IT_>
 
  790        IT_ mult_cor(DT_* x, 
const DT_ alpha, 
const VectorTypeR& vec_cor, 
const IT_* idx, 
const IT_ m, 
const IT_ off)
 const 
  792          return _first.mult_cor(x, alpha, vec_cor.first(), idx, m, off);
 
  796      template<
typename SubMatrix_, 
int dim_w_, 
int dim_h_>
 
  797      class VankaMatrix<LAFEM::PowerFullMatrix<SubMatrix_, dim_w_, dim_h_>>
 
  800        typedef LAFEM::PowerFullMatrix<SubMatrix_, dim_w_, dim_h_> MatrixType;
 
  801        typedef typename MatrixType::VectorTypeR VectorTypeR;
 
  802        typedef VankaMatrix<typename MatrixType::ContClass> ContClass;
 
  804        static constexpr int row_dim = ContClass::row_dim;
 
  805        static constexpr int col_dim = ContClass::col_dim;
 
  811        explicit VankaMatrix(
const MatrixType& matrix) :
 
  812          _cont(matrix.get_container())
 
  816        template<
typename DT_, 
typename IT_>
 
  817        std::pair<IT_, IT_> gather_full(
 
  818          DT_* data, 
const IT_* ridx, 
const IT_* cidx,
 
  819          const IT_ m, 
const IT_ n, 
const IT_ stride,
 
  820          const IT_ mo = IT_(0), 
const IT_ no = IT_(0))
 const 
  822          return _cont.gather_full(data, ridx, cidx, m, n, stride, mo, no);
 
  825        template<
typename DT_, 
typename IT_>
 
  826        IT_ gather_diag(DT_* data, 
const IT_* idx, 
const IT_ m, 
const IT_ mo = IT_(0))
 const 
  828          return _cont.template gather_diag_pfm<0,0>(data, idx, m, mo);
 
  831        template<
typename DT_, 
typename IT_>
 
  832        IT_ mult_cor(DT_* x, 
const DT_ alpha, 
const VectorTypeR& vec_cor, 
const IT_* idx, 
const IT_ m, 
const IT_ off)
 const 
  834          return _cont.mult_cor(x, alpha, vec_cor, idx, m, off);
 
  838      template<
typename DT_, 
typename IT_>
 
  839      std::pair<const IT_*, const IT_*> vanka_graph(
const LAFEM::SparseMatrixCSR<DT_, IT_>& matrix)
 
  841        return std::make_pair(matrix.row_ptr(), matrix.col_ind());
 
  844      template<
typename DT_, 
typename IT_, 
int m_, 
int n_>
 
  845      std::pair<const IT_*, const IT_*> vanka_graph(
const LAFEM::SparseMatrixBCSR<DT_, IT_, m_, n_>& matrix)
 
  847        return std::make_pair(matrix.row_ptr(), matrix.col_ind());
 
  850      template<
typename DT_, 
typename IT_, 
int dim_>
 
  851      std::pair<const IT_*, const IT_*> vanka_graph(
 
  852        const LAFEM::PowerColMatrix<LAFEM::SparseMatrixCSR<DT_, IT_>, dim_>& matrix)
 
  854        const auto& m = matrix.first();
 
  855        return std::make_pair(m.row_ptr(), m.col_ind());
 
  858      template<
typename DT_, 
typename IT_, 
int dim_>
 
  859      std::pair<const IT_*, const IT_*> vanka_graph(
 
  860        const LAFEM::PowerRowMatrix<LAFEM::SparseMatrixCSR<DT_, IT_>, dim_>& matrix)
 
  862        const auto& m = matrix.first();
 
  863        return std::make_pair(m.row_ptr(), m.col_ind());
 
  866      template<
typename DT_, 
typename IT_, 
int dim_>
 
  867      std::pair<const IT_*, const IT_*> vanka_graph(
 
  868        const LAFEM::PowerDiagMatrix<LAFEM::SparseMatrixCSR<DT_, IT_>, dim_>& matrix)
 
  870        const auto& m = matrix.first();
 
  871        return std::make_pair(m.row_ptr(), m.col_ind());
 
  874      template<
typename DT_, 
typename IT_, 
int row_dim_, 
int col_dim_>
 
  875      std::pair<const IT_*, const IT_*> vanka_graph(
 
  876        const LAFEM::PowerFullMatrix<LAFEM::SparseMatrixCSR<DT_, IT_>, row_dim_, col_dim_>& matrix)
 
  878        const auto& m = matrix.template at<0,0>();
 
  879        return std::make_pair(m.row_ptr(), m.col_ind());
 
  933    template<
typename Matrix_, 
typename Filter_>
 
 1008    template<
typename MatrixA_, 
typename MatrixB_, 
typename MatrixD_, 
typename Filter_>
 
 1009    class Vanka<LAFEM::SaddlePointMatrix<MatrixA_, MatrixB_, MatrixD_>, Filter_> :
 
 1010      public SolverBase<LAFEM::TupleVector<typename MatrixB_::VectorTypeL, typename MatrixD_::VectorTypeL>>
 
 1032      typedef Intern::VankaMatrix<MatrixA_> VankaMatrixA;
 
 1033      typedef Intern::VankaMatrix<MatrixB_> VankaMatrixB;
 
 1034      typedef Intern::VankaMatrix<MatrixD_> VankaMatrixD;
 
 1037      static_assert(VankaMatrixA::row_dim == VankaMatrixA::col_dim, 
"Matrix A has invalid dimensions");
 
 1038      static_assert(VankaMatrixA::row_dim == VankaMatrixB::row_dim, 
"Matrices A and B have incompatible dimensions");
 
 1039      static_assert(VankaMatrixA::col_dim == VankaMatrixD::col_dim, 
"Matrices A and D have incompatible dimensions");
 
 1040      static_assert(VankaMatrixB::col_dim == VankaMatrixD::row_dim, 
"Matrices B and D have incompatible dimensions");
 
 1043      static_assert(VankaMatrixB::col_dim == 1, 
"Invalid pressure space dimension");
 
 1115        watch_init_symbolic.
start();
 
 1117        bool block = ((int(_type) & 0x010) != 0);
 
 1118        bool multi = ((int(_type) & 0x100) == 0);
 
 1123          this->_build_p_block();
 
 1127          this->_build_p_nodal();
 
 1131        this->_build_v_block();
 
 1134        this->_alloc_data();
 
 1144        watch_init_symbolic.
stop();
 
 1156        _block_v_ptr.clear();
 
 1157        _block_v_idx.clear();
 
 1158        _block_p_ptr.clear();
 
 1159        _block_p_idx.clear();
 
 1165        watch_init_numeric.
start();
 
 1167        bool full = ((int(_type) & 0x001) != 0);
 
 1168        bool multi = ((int(_type) & 0x100) == 0);
 
 1172          this->_factor_full();
 
 1176          this->_factor_diag();
 
 1181          this->_calc_scale();
 
 1184        watch_init_numeric.
stop();
 
 1187      virtual Status apply(VectorType& vec_cor, 
const VectorType& vec_def)
 override 
 1189        watch_apply.
start();
 
 1191        bool full = ((int(_type) & 0x001) != 0);
 
 1194          this->_apply_full(vec_cor, vec_def);
 
 1198          this->_apply_diag(vec_cor, vec_def);
 
 1206      std::size_t data_size()
 const 
 1208        return _data.size();
 
 1211      std::size_t bytes()
 const 
 1213        return sizeof(IndexType) * (_block_v_ptr.size() + _block_v_idx.size() + _block_p_ptr.size() + _block_p_idx.size())
 
 1214          + 
sizeof(DataType) * (_data.size() + _vdef.size() + _vcor.size())
 
 1223        watch_init_symbolic.
reset();
 
 1224        watch_init_numeric.
reset();
 
 1225        watch_apply.
reset();
 
 1233        return watch_init_symbolic.
elapsed();
 
 1241        return watch_init_numeric.
elapsed();
 
 1265        auto graph_b = Intern::vanka_graph(_matrix.
block_b());
 
 1266        const IndexType* row_ptr_b = graph_b.first;
 
 1267        const IndexType* col_idx_b = graph_b.second;
 
 1268        auto graph_d = Intern::vanka_graph(_matrix.
block_d());
 
 1269        const IndexType* row_ptr_d = graph_d.first;
 
 1270        const IndexType* col_idx_d = graph_d.second;
 
 1273        _block_p_ptr.clear();
 
 1274        _block_p_idx.clear();
 
 1278        std::map<IndexType, int> map_s;
 
 1281        std::vector<int> mask(std::size_t(m), 0);
 
 1284        for(
Index i(0); i < m; ++i)
 
 1294          for(
IndexType kd = row_ptr_d[i]; kd < row_ptr_d[i+1]; ++kd)
 
 1300            for(
IndexType kb = row_ptr_b[col_d]; kb < row_ptr_b[col_d+1]; ++kb)
 
 1306              auto ib = map_s.emplace(col_b, 1);
 
 1310                ++(ib.first->second);
 
 1317          for(
auto it = map_s.begin(); it != map_s.end(); ++it)
 
 1321          for(
auto it = map_s.begin(); it != map_s.end(); ++it)
 
 1323            if(ideg == it->second)
 
 1326              _block_p_idx.push_back(it->first);
 
 1327              mask[it->first] = 1;
 
 1332          _block_p_ptr.push_back(
IndexType(_block_p_idx.size()));
 
 1344        _block_p_ptr.clear();
 
 1345        _block_p_idx.clear();
 
 1346        _block_p_ptr.reserve(m+1);
 
 1347        _block_p_idx.reserve(m);
 
 1350          _block_p_ptr.push_back(i);
 
 1351          _block_p_idx.push_back(i);
 
 1353        _block_p_ptr.push_back(m);
 
 1360        auto graph_d = Intern::vanka_graph(_matrix.
block_d());
 
 1361        const IndexType* row_ptr_d = graph_d.first;
 
 1362        const IndexType* col_idx_d = graph_d.second;
 
 1368        _block_v_ptr.clear();
 
 1369        _block_v_idx.clear();
 
 1370        _block_v_ptr.reserve(m+1);
 
 1373        std::set<IndexType> set_v;
 
 1379          for(
IndexType j = _block_p_ptr[i]; j < _block_p_ptr[i+1]; ++j)
 
 1385            for(
IndexType k = row_ptr_d[pix]; k < row_ptr_d[pix+1]; ++k)
 
 1388              set_v.insert(col_idx_d[k]);
 
 1393          for(
auto it = set_v.begin(); it != set_v.end(); ++it)
 
 1395            _block_v_idx.push_back(*it);
 
 1399          _block_v_ptr.push_back(
IndexType(_block_v_idx.size()));
 
 1413        bool diag = ((int(_type) & 1) == 0);
 
 1426          IndexType nv = _block_v_ptr[i+1] - _block_v_ptr[i];
 
 1427          IndexType np = _block_p_ptr[i+1] - _block_p_ptr[i];
 
 1452        _vdef.resize(dim*_degree_v + _degree_p);
 
 1453        _vcor.resize(dim*_degree_v + _degree_p);
 
 1460        this->_vec_scale.
format();
 
 1461        Intern::VankaVector<VectorV> vanka_v(this->_vec_scale.template at<0>());
 
 1462        Intern::VankaVector<VectorP> vanka_p(this->_vec_scale.template at<1>());
 
 1465        const IndexType* vptr = _block_v_ptr.data();
 
 1466        const IndexType* vidx = _block_v_idx.data();
 
 1467        const IndexType* pptr = _block_p_ptr.data();
 
 1468        const IndexType* pidx = _block_p_idx.data();
 
 1471        std::vector<DataType> vec_one(vanka_v.dim*_degree_v + _degree_p, 
DataType(1));
 
 1472        const DataType* vone = vec_one.data();
 
 1476        for(
IndexType iblock(0); iblock < nblocks; ++iblock)
 
 1479          const IndexType nv = vptr[iblock+1] - vptr[iblock];
 
 1480          const IndexType np = pptr[iblock+1] - pptr[iblock];
 
 1488        this->_vec_scale.component_invert(this->_vec_scale);
 
 1494        Intern::VankaMatrix<MatrixA_> vanka_a(_matrix.
block_a());
 
 1495        Intern::VankaMatrix<MatrixB_> vanka_b(_matrix.
block_b());
 
 1496        Intern::VankaMatrix<MatrixD_> vanka_d(_matrix.
block_d());
 
 1503        const IndexType* vptr = _block_v_ptr.data();
 
 1504        const IndexType* vidx = _block_v_idx.data();
 
 1505        const IndexType* pptr = _block_p_ptr.data();
 
 1506        const IndexType* pidx = _block_p_idx.data();
 
 1509        ::memset(data, 0, 
sizeof(
DataType) * _data.size());
 
 1512        std::vector<IndexType> pivot(3*(dim*_degree_v + _degree_p));
 
 1519        for(
IndexType iblock(0); iblock < nblocks; ++iblock)
 
 1522          const IndexType nv = vptr[iblock+1] - vptr[iblock];
 
 1523          const IndexType np = pptr[iblock+1] - pptr[iblock];
 
 1526          const IndexType* loc_vidx = &vidx[vptr[iblock]];
 
 1527          const IndexType* loc_pidx = &pidx[pptr[iblock]];
 
 1534          DataType* block_data = &data[block_offset];
 
 1537          std::pair<IndexType,IndexType> ao =
 
 1538            vanka_a.gather_full(block_data, loc_vidx, loc_vidx, nv, nv, n);
 
 1539          vanka_b.gather_full(block_data, loc_vidx, loc_pidx, nv, np, n, 
IndexType(0), ao.second);
 
 1540          vanka_d.gather_full(block_data, loc_pidx, loc_vidx, np, nv, n, ao.first, 
IndexType(0));
 
 1551          block_offset += block_size;
 
 1562        const bool multi = ((int(_type) & 0x100) == 0);
 
 1567          this->_vec_tmp1.
copy(vec_def);
 
 1568          this->_vec_tmp2.
format();
 
 1572        VectorV& vec_cv = (multi ? vec_cor.template at<0>() : this->_vec_tmp2.template at<0>());
 
 1573        VectorP& vec_cp = (multi ? vec_cor.template at<1>() : this->_vec_tmp2.template at<1>());
 
 1574        const VectorV& vec_dv = (multi ? vec_def.template at<0>() : this->_vec_tmp1.template at<0>());
 
 1575        const VectorP& vec_dp = (multi ? vec_def.template at<1>() : this->_vec_tmp1.template at<1>());
 
 1578        Intern::VankaMatrix<MatrixA_> vanka_a(_matrix.
block_a());
 
 1579        Intern::VankaMatrix<MatrixB_> vanka_b(_matrix.
block_b());
 
 1580        Intern::VankaMatrix<MatrixD_> vanka_d(_matrix.
block_d());
 
 1581        Intern::VankaVector<VectorV> vanka_v(vec_cv);
 
 1582        Intern::VankaVector<VectorP> vanka_p(vec_cp);
 
 1591        const IndexType* vptr = _block_v_ptr.data();
 
 1592        const IndexType* vidx = _block_v_idx.data();
 
 1593        const IndexType* pptr = _block_p_ptr.data();
 
 1594        const IndexType* pidx = _block_p_idx.data();
 
 1597        const DataType* lmat_data = _data.data();
 
 1610            this->_matrix.
apply(_vec_tmp1, vec_cor, vec_def, -
DataType(1));
 
 1620          for(
IndexType iblock(0); iblock < num_blocks; ++iblock)
 
 1623            const IndexType nv = vptr[iblock+1] - vptr[iblock];
 
 1624            const IndexType np = pptr[iblock+1] - pptr[iblock];
 
 1627            const IndexType* loc_vidx = &vidx[vptr[iblock]];
 
 1628            const IndexType* loc_pidx = &pidx[pptr[iblock]];
 
 1634            const DataType* lmat = &lmat_data[block_offset];
 
 1638            DataType* lcor_p = &lcor[velo_dim * nv];
 
 1640            DataType* ldef_p = &ldef[velo_dim * nv];
 
 1643            vanka_v.gather_def(ldef_v, vec_dv, loc_vidx, nv, 
IndexType(0));
 
 1644            vanka_p.gather_def(ldef_p, vec_dp, loc_pidx, np, 
IndexType(0));
 
 1661                lcor[i] += lmat[i*n + j] * ldef[j];
 
 1667            vanka_v.scatter_cor(_omega, lcor_v, loc_vidx, nv, 
IndexType(0));
 
 1668            vanka_p.scatter_cor(_omega, lcor_p, loc_pidx, np, 
IndexType(0));
 
 1671            block_offset += n*n;
 
 1674          Statistics::add_time_precon(stamp_kernel.
elapsed_now());
 
 1680            this->_vec_tmp2.component_product(this->_vec_tmp2, this->_vec_scale);
 
 1683            vec_cor.axpy(this->_vec_tmp2);
 
 1687          _filter.filter_cor(vec_cor);
 
 1696        Intern::VankaMatrix<MatrixA_> vanka_a(_matrix.
block_a());
 
 1697        Intern::VankaMatrix<MatrixB_> vanka_b(_matrix.
block_b());
 
 1698        Intern::VankaMatrix<MatrixD_> vanka_d(_matrix.
block_d());
 
 1705        const IndexType* vptr = _block_v_ptr.data();
 
 1706        const IndexType* vidx = _block_v_idx.data();
 
 1707        const IndexType* pptr = _block_p_ptr.data();
 
 1708        const IndexType* pidx = _block_p_idx.data();
 
 1711        ::memset(data, 0, 
sizeof(
DataType) * _data.size());
 
 1714        std::vector<IndexType> pivot(3*_degree_p);
 
 1721        for(
IndexType iblock(0); iblock < nblocks; ++iblock)
 
 1724          const IndexType nv = vptr[iblock+1] - vptr[iblock];
 
 1725          const IndexType np = pptr[iblock+1] - pptr[iblock];
 
 1729          const IndexType* loc_vidx = &vidx[vptr[iblock]];
 
 1730          const IndexType* loc_pidx = &pidx[pptr[iblock]];
 
 1736          DataType* block_data = &data[block_offset];
 
 1740          DataType* loc_b = &block_data[dnv];
 
 1741          DataType* loc_d = &block_data[dnv + dnv*np];
 
 1745          vanka_a.gather_diag(loc_a, loc_vidx, nv);
 
 1747          vanka_b.gather_full(loc_b, loc_vidx, loc_pidx, nv, np, np);
 
 1748          vanka_d.gather_full(loc_d, loc_pidx, loc_vidx, np, nv, dnv);
 
 1765              loc_d[j*dnv + i] *= loc_a[i];
 
 1779                s += loc_d[i*dnv + k] * loc_b[k*np + j];
 
 1781              loc_s[i*np + j] = -s;
 
 1794          block_offset += block_size;
 
 1805        const bool multi = ((int(_type) & 0x100) == 0);
 
 1810          this->_vec_tmp1.
copy(vec_def);
 
 1811          this->_vec_tmp2.
format();
 
 1815        VectorV& vec_cv = (multi ? vec_cor.template at<0>() : this->_vec_tmp2.template at<0>());
 
 1816        VectorP& vec_cp = (multi ? vec_cor.template at<1>() : this->_vec_tmp2.template at<1>());
 
 1817        const VectorV& vec_dv = (multi ? vec_def.template at<0>() : this->_vec_tmp1.template at<0>());
 
 1818        const VectorP& vec_dp = (multi ? vec_def.template at<1>() : this->_vec_tmp1.template at<1>());
 
 1821        Intern::VankaMatrix<MatrixA_> vanka_a(_matrix.
block_a());
 
 1822        Intern::VankaMatrix<MatrixB_> vanka_b(_matrix.
block_b());
 
 1823        Intern::VankaMatrix<MatrixD_> vanka_d(_matrix.
block_d());
 
 1824        Intern::VankaVector<VectorV> vanka_v(vec_cv);
 
 1825        Intern::VankaVector<VectorP> vanka_p(vec_cp);
 
 1834        const IndexType* vptr = _block_v_ptr.data();
 
 1835        const IndexType* vidx = _block_v_idx.data();
 
 1836        const IndexType* pptr = _block_p_ptr.data();
 
 1837        const IndexType* pidx = _block_p_idx.data();
 
 1840        const DataType* data = _data.data();
 
 1853            this->_matrix.
apply(_vec_tmp1, vec_cor, vec_def, -
DataType(1));
 
 1863          for(
IndexType iblock(0); iblock < num_blocks; ++iblock)
 
 1866            const IndexType nv = vptr[iblock+1] - vptr[iblock];
 
 1867            const IndexType np = pptr[iblock+1] - pptr[iblock];
 
 1871            const IndexType* loc_vidx = &vidx[vptr[iblock]];
 
 1872            const IndexType* loc_pidx = &pidx[pptr[iblock]];
 
 1878            const DataType* block_data = &data[block_offset];
 
 1881            const DataType* loc_a =  block_data;
 
 1882            const DataType* loc_b = &block_data[dnv];
 
 1883            const DataType* loc_d = &block_data[dnv + dnv*np];
 
 1893            vanka_v.gather_def(ldef_v, vec_dv, loc_vidx, nv, 
IndexType(0));
 
 1894            vanka_p.gather_def(ldef_p, vec_dp, loc_pidx, np, 
IndexType(0));
 
 1913                r += loc_d[i*dnv + j] * ldef_v[j];
 
 1926                r += loc_s[i*np + j] * ldef_p[j];
 
 1938                xb += loc_b[i*np + j] * lcor_p[j];
 
 1941              lcor_v[i] = loc_a[i] * (ldef_v[i] - xb);
 
 1943            flops += dnv * (2*np + 2);
 
 1946            vanka_v.scatter_cor(_omega, lcor_v, loc_vidx, nv, 
IndexType(0));
 
 1947            vanka_p.scatter_cor(_omega, lcor_p, loc_pidx, np, 
IndexType(0));
 
 1950            block_offset += block_size;
 
 1953          Statistics::add_time_precon(stamp_kernel.
elapsed_now());
 
 1959            this->_vec_tmp2.component_product(this->_vec_tmp2, this->_vec_scale);
 
 1962            vec_cor.axpy(this->_vec_tmp2);
 
 1966          _filter.filter_cor(vec_cor);
 
 1994    template<
typename MatrixA_, 
typename MatrixB_, 
typename MatrixD_, 
typename Filter_>
 
 1995    std::shared_ptr<Vanka<LAFEM::SaddlePointMatrix<MatrixA_, MatrixB_, MatrixD_>, Filter_>> 
new_vanka(
 
 1997      const Filter_& filter,
 
 1999      typename MatrixA_::DataType omega = 
typename MatrixA_::DataType(1),
 
 2002      return std::make_shared<Vanka<LAFEM::SaddlePointMatrix<MatrixA_, MatrixB_, MatrixD_>, Filter_>>
 
 2003        (matrix, filter, type, omega, num_iter);
 
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Saddle-Point matrix meta class template.
MatrixTypeA::DataType DataType
data type
MatrixTypeA & block_a()
Returns the sub-matrix block A.
VectorTypeR create_vector_r() const
Returns a new compatible R-Vector.
void apply(VectorTypeL &r, const VectorTypeR &x) const
Applies this matrix onto a vector.
MatrixTypeA::IndexType IndexType
index type
MatrixTypeB & block_b()
Returns the sub-matrix block B.
MatrixTypeD & block_d()
Returns the sub-matrix block D.
Variadic TupleVector class template.
std::size_t bytes() const
Returns the total amount of bytes allocated.
void copy(const TupleVector &x, bool full=false)
Performs .
void format(DataType value=DataType(0))
Reset all elements of the container to a given value or zero if missing.
void clear()
Free all allocated arrays.
Polymorphic solver interface.
Base-class for solver generated exceptions.
MatrixType::DataType DataType
our data type
virtual void init_numeric() override
Performs numeric factorization.
void _calc_scale()
Calculate the scaling vector for additive Vanka.
double time_apply() const
Returns the total accumulated time for the solver application.
virtual void done_symbolic() override
Releases the symbolic factorization data.
DataType _omega
relaxation parameter
void _factor_full()
Performs the 'full' numerical factorization.
Index _num_iter
desired number of iterations
void _factor_diag()
Performs the 'diagonal' numerical factorization.
IndexType _degree_p
maximum pressure block degree
void _build_p_block()
Builds the 'blocked' pressure graph.
void _alloc_data()
Allocates the data arrays for numerical factorization.
virtual void init_symbolic() override
Performs symbolic factorization.
std::vector< IndexType > _block_v_ptr
velocity block structure
MatrixType::IndexType IndexType
our index type
std::vector< DataType > _data
factorization data
Filter_ FilterType
our filter type
void _apply_full(VectorType &vec_cor, const VectorType &vec_def)
Applies the 'full' Vanka iteration.
MatrixB_::VectorTypeR VectorP
pressure vector type
double time_init_numeric() const
Returns the total accumulated time for numeric initialization.
MatrixType::VectorTypeR VectorType
our vector type
virtual String name() const override
Returns the name of the solver.
void _build_v_block()
Builds the velocity graph.
std::vector< IndexType > _block_p_ptr
pressure block structure
const FilterType & _filter
the system filter
void reset_timings()
Resets the internal stop watches for time measurement.
VectorType _vec_scale
temporary vectors (additive types only)
VankaType _type
the Vanka type
IndexType _degree_v
maximum velocity block degree
Vanka(const MatrixType &matrix, const FilterType &filter, VankaType type, DataType omega=DataType(1), Index num_iter=Index(1))
Constructor.
void _apply_diag(VectorType &vec_cor, const VectorType &vec_def)
Applies the 'diagonal' Vanka iteration.
void _build_p_nodal()
Builds the 'nodal' pressure graph.
MatrixD_::VectorTypeR VectorV
velocity vector type
const MatrixType & _matrix
the system matrix
std::vector< DataType > _vdef
local defect/correction vectors
double time_init_symbolic() const
Returns the total accumulated time for symbolic initialization.
LAFEM::SaddlePointMatrix< MatrixA_, MatrixB_, MatrixD_ > MatrixType
our matrix type
Vanka Factorization Error.
Vanka preconditioner/smoother class template.
static void add_flops(Index flops)
Add an amount of flops to the global flop counter.
double elapsed() const
Returns the total elapsed time in seconds.
void start()
Starts the stop-watch.
void reset()
Resets the elapsed time.
void stop()
Stops the stop-watch and increments elapsed time.
String class implementation.
double elapsed_now() const
Calculates the time elapsed between the time stamp and now.
bool isnormal(T_ x)
Checks whether a value is normal.
T_ sqr(T_ x)
Returns the square of a value.
DT_ invert_matrix(const IT_ n, const IT_ stride, DT_ a[], IT_ p[])
Inverts a matrix and returns its determinant.
T_ max(T_ a, T_ b)
Returns the maximum of two values.
VankaType
Vanka type enumeration.
@ nodal_full_mult
Nodal full Vanka type (multiplicative)
@ block_diag_add
Blocked diagonal Vanka type (additive)
@ nodal_full_add
Nodal full Vanka type (additive)
@ block_diag_mult
Blocked diagonal Vanka type (multiplicative)
@ nodal_diag_mult
Nodal diagonal Vanka type (multiplicative)
@ block_full_mult
Blocked full Vanka type (multiplicative)
@ nodal_diag_add
Nodal diagonal Vanka type (additive)
@ block_full_add
Blocked full Vanka type (additive)
@ iter
Plot every iteration (if applicable)
@ full
full Uzawa preconditioner
@ rest
restriction (multigrid)
std::shared_ptr< Vanka< LAFEM::SaddlePointMatrix< MatrixA_, MatrixB_, MatrixD_ >, Filter_ > > new_vanka(const LAFEM::SaddlePointMatrix< MatrixA_, MatrixB_, MatrixD_ > &matrix, const Filter_ &filter, VankaType type, typename MatrixA_::DataType omega=typename MatrixA_::DataType(1), Index num_iter=Index(1))
Creates a new Vanka solver object.
Status
Solver status return codes enumeration.
@ success
solving successful (convergence criterion fulfilled)
std::uint64_t Index
Index data type.