From 389a9d44a4157c88cc527fb54e3327287d7fe8ad Mon Sep 17 00:00:00 2001 From: Jonathan Youett <youett@math.fu-berlin.de> Date: Tue, 8 Nov 2016 13:37:36 +0100 Subject: [PATCH] Add a blockmatrix view that computes global indices from block-indices This class also provides a static method to combine submatrices into one block matrix by copying the entries. --- dune/matrix-vector/CMakeLists.txt | 1 + dune/matrix-vector/blockmatrixview.hh | 109 ++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 dune/matrix-vector/blockmatrixview.hh diff --git a/dune/matrix-vector/CMakeLists.txt b/dune/matrix-vector/CMakeLists.txt index 9acfb4a..9112065 100644 --- a/dune/matrix-vector/CMakeLists.txt +++ b/dune/matrix-vector/CMakeLists.txt @@ -5,6 +5,7 @@ install(FILES addtodiagonal.hh axpy.hh axy.hh + blockmatrixview.hh componentwisematrixmap.hh crossproduct.hh genericvectortools.hh diff --git a/dune/matrix-vector/blockmatrixview.hh b/dune/matrix-vector/blockmatrixview.hh new file mode 100644 index 0000000..54af5ae --- /dev/null +++ b/dune/matrix-vector/blockmatrixview.hh @@ -0,0 +1,109 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set ts=4 sw=2 et sts=2: +#ifndef DUNE_MATRIX_VECTOR_BLOCK_MATRIX_VIEW_HH +#define DUNE_MATRIX_VECTOR_BLOCK_MATRIX_VIEW_HH + +#include <array> +#include <vector> + +#include <dune/istl/matrixindexset.hh> + +namespace Dune { +namespace MatrixVector { + +/** \brief Class that provides global indices for a block matrix given local indices of the blocks. Furthermore, it provides a method to construct a block matrix from given sub matrices. + * + * This class provides a method to combine matrices \f A_1,\ldots,A_n\f into one single block matrix + * \f B = \begin{pmatrix} A_1 & 0 & \ldots & 0 \\ + * 0 & A_2 & \ldots & 0 \\ + * \ldots \\ + * 0 & \ldots & 0 & A_n \end{pmatrix} \f, + * by copying the corresponding entries. + * A BlockMatrixView object provides methods that return global indices for \f B\f given a local index of \f A_i\f and the block index \f i\f. + * + * \tparam MatrixType The matrix type of the matrix blocks. + */ +template <class MatrixType> +class BlockMatrixView +{ +public: + //! Construct block view from vector of matrices corr. to the blocks + BlockMatrixView(const std::vector<const MatrixType*>& submat) { + + offsets_.resize(submat.size()); + offsets_[0] = {0, 0}; + + for (size_t i=0; i<submat.size()-1; i++) + offsets_[i+1] = {offsets_[i][0] + submat[i]->N(), + offsets_[i][1] + submat[i]->M()}; + + nRows_ = offsets_.back()[0] + submat.back()->N(); + nCols_ = offsets_.back()[1] + submat.back()->M(); + } + + //! Get global row index for given block and a local row index + size_t row(size_t block, size_t index) const { + return offsets_[block][0] + index; + } + + //! Get global column index given a block and a local column index + size_t col(size_t block, size_t index) const { + return offsets_[block][1] + index; + } + + //! Return the total number of rows + size_t nRows() const { + return nRows_; + } + + //! Return the total number of columns + size_t nCols() const { + return nCols_; + } + + /** \brief Combine submatrices in a big matrix. */ + static void setupBlockMatrix(const std::vector<MatrixType>& submat, MatrixType& mat) { + std::vector<const MatrixType*> dummy(submat.size()); + for (size_t i=0; i<dummy.size(); i++) + dummy[i] = &submat[i]; + setupBlockMatrix(dummy,mat); + } + + /** \brief Combine submatrices in a big matrix. */ + static void setupBlockMatrix(const std::vector<const MatrixType*>& submat, MatrixType& mat) + { + BlockMatrixView<MatrixType> blockView(submat); + MatrixIndexSet indexSet(blockView.nRows(), blockView.nCols()); + + for (size_t i=0; i<submat.size(); i++) + indexSet.import(*submat[i], blockView.row(i,0), blockView.col(i,0)); + + indexSet.exportIdx(mat); + + for (size_t i=0; i<submat.size(); i++) { + + auto row = submat[i]->begin(); + auto rowEnd = submat[i]->end(); + + for (; row != rowEnd; row++) { + + auto col = row->begin(); + auto colEnd = row->end(); + + for (; col != colEnd; col++) + mat[blockView.row(i,row.index())][blockView.col(i,col.index())] = *col; + } + } + } + +protected: + //! Offsets for the different blocks + std::vector<std::array<size_t, 2> > offsets_; + //! Total numbers of rows and columns + size_t nRows_, nCols_; +}; + +} // end namespace MatrixVector +} // end namespace Dune + +#endif -- GitLab