DOFMatrix.hpp 2.83 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
#pragma once

#include <list>
#include <memory>
#include <string>
#include <vector>

#include <Eigen/SparseCore>

#include <dune/common/timer.hh>

#include <amdis/Output.hpp>
13
14
#include <amdis/linearalgebra/Common.hpp>
#include <amdis/linearalgebra/DOFMatrixBase.hpp>
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

namespace AMDiS
{
  /// \brief The basic container that stores a base matrix and a corresponding
  /// row/column feSpace.
  template <class ValueType, int Orientation = Eigen::RowMajor>
  class EigenMatrix
  {
  public:
    /// The matrix type of the underlying base matrix
    using BaseMatrix = Eigen::SparseMatrix<ValueType, Orientation>;

    /// The type of the elements of the DOFMatrix
    using value_type = ValueType;

    /// The index/size - type
    using size_type = typename BaseMatrix::Index;

  public:
    /// Constructor. Constructs new BaseMatrix.
    EigenMatrix() = default;

    /// Return a reference to the data-matrix \ref matrix
    BaseMatrix& matrix()
    {
      return matrix_;
    }

    /// Return a reference to the data-matrix \ref matrix
    BaseMatrix const& matrix() const
    {
      return matrix_;
    }


    /// \brief Returns an update-proxy of the inserter, to inserte/update a value at
    /// position (\p r, \p c) in the matrix. Need an insertionMode inserter, that can
    /// be created by \ref init and must be closed by \ref finish after insertion.
    void insert(size_type r, size_type c, value_type const& value)
    {
      test_exit_dbg(r < matrix_.rows() && c < matrix_.cols(),
          "Indices out of range [0,{})x[0,{})", matrix_.rows(), matrix_.cols());
      tripletList_.emplace_back(r, c, value);
    }


    /// Create inserter. Assumes that no inserter is currently active on this matrix.
    template <class RowBasis, class ColBasis>
    void init(RowBasis const& rowBasis, ColBasis const& colBasis,
              bool prepareForInsertion)
    {
      matrix_.resize(rowBasis.dimension(), colBasis.dimension());
      if (prepareForInsertion) {
        matrix_.setZero(); // maybe not necessary
      }
    }

    /// Delete inserter -> finish insertion. Must be called in order to fill the
    /// final construction of the matrix.
    void finish()
    {
      matrix_.setFromTriplets(tripletList_.begin(), tripletList_.end());
      matrix_.makeCompressed();

      tripletList_.clear(); // NOTE: this does not free the memory
    }

    /// Return the number of nonzeros in the matrix
    std::size_t nnz() const
    {
      return matrix_.nonZeros();
    }

  private:
    /// The data-matrix
    BaseMatrix matrix_;

    /// A list of row,col indices and values
    std::vector<Eigen::Triplet<ValueType, Eigen::Index>> tripletList_;
  };

  template <class RowBasisType, class ColBasisType,
            class T = double, int O = Eigen::RowMajor>
  using DOFMatrix = DOFMatrixBase<RowBasisType, ColBasisType, EigenMatrix<T, O>>;

} // end namespace AMDiS