LinearForm.hpp 4.47 KB
Newer Older
1
2
#pragma once

3
4
#include <dune/common/typeutilities.hh>

5
6
#include <amdis/LinearAlgebra.hpp>
#include <amdis/OperatorList.hpp>
7
8
#include <amdis/common/Concepts.hpp>
#include <amdis/common/ConceptsBase.hpp>
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <amdis/common/FlatVector.hpp>
#include <amdis/common/TypeTraits.hpp>
#include <amdis/typetree/TreePath.hpp>

namespace AMDiS
{
  /// \brief The basic container that stores a base vector and a corresponding basis
  /**
   * A vector storing all the assembled Operators indexed with DOF indices. The vector
   * data is associated to a global basis.
   *
   * \tparam GB  Basis of the vector
   * \tparam T   Coefficient type to store in the vector
Praetorius, Simon's avatar
Praetorius, Simon committed
22
   * \tparam Traits  Collection of parameter for the linear-algebra backend
23
   **/
Praetorius, Simon's avatar
Praetorius, Simon committed
24
  template <class GB, class T = double, class Traits = BackendTraits<GB>>
25
  class LinearForm
Praetorius, Simon's avatar
Praetorius, Simon committed
26
      : public VectorFacade<T, Traits::template VectorImpl>
27
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
28
    using Super = VectorFacade<T, Traits::template VectorImpl>;
29
    using Self = LinearForm;
30
31
32
33
34
35

  public:
    /// The type of the functionspace basis associated to this linearform
    using GlobalBasis = GB;

    /// The type of the elements of the DOFVector
Praetorius, Simon's avatar
Praetorius, Simon committed
36
    using CoefficientType = T;
37
38
39
40
41
42

    /// The type of the vector filled on an element with local contributions
    using ElementVector = FlatVector<CoefficientType>;

  public:
    /// Constructor. Stores the shared_ptr of the basis and creates a new DataTransfer.
Praetorius, Simon's avatar
Praetorius, Simon committed
43
44
45
    explicit LinearForm(std::shared_ptr<GB> const& basis)
      : Super(*basis)
      , basis_(basis)
46
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
47
      auto const localSize = basis->localView().maxSize();
48
49
50
      elementVector_.resize(localSize);
    }

51
52
53
54
55
56
57
    /// Wraps the passed global basis into a (non-destroying) shared_ptr
    template <class GB_,
      REQUIRES(Concepts::Similar<GB_,GB>)>
    explicit LinearForm(GB_&& basis)
      : LinearForm(Dune::wrap_or_move(FWD(basis)))
    {}

Praetorius, Simon's avatar
Praetorius, Simon committed
58
59
    std::shared_ptr<GlobalBasis const> const& basis() const { return basis_; }

60
61
62
63
64
    /// \brief Associate a local operator with this LinearForm
    /**
     * Stores an operator in a list that gets assembled during a call to \ref assemble().
     * The operator may be assigned to a specific context, i.e. either an element
     * operator, an intersection operator, or a boundary operator.
65
66
     * The \p path tree paths specify the sub-basis for test functions the operator
     * is applied to.
67
68
     *
     * \tparam ContextTag  One of \ref tag::element_operator, \ref tag::intersection_operator
69
70
     *                     or \ref tag::boundary_operator indicating where to assemble
     *                     this operator.
71
     * \tparam Expr        An pre-operator that can be bound to a gridView, or a valid
72
73
     *                     GridOperator.
     * \tparam path        A tree-path for the Basis
74
75
76
77
78
79
80
81
82
83
84
     *
     * [[expects: path is valid tree-path in Basis]]
     * @{
     **/
    template <class ContextTag, class Expr, class TreePath>
    void addOperator(ContextTag contextTag, Expr const& expr, TreePath path);

    // Add an operator to be assembled on the elements of the grid
    template <class Expr, class TreePath = RootTreePath>
    void addOperator(Expr const& expr, TreePath path = {})
    {
85
      using E = typename GlobalBasis::LocalView::Element;
86
87
88
89
90
91
92
      addOperator(tag::element_operator<E>{}, expr, path);
    }

    // Add an operator to be assembled on the intersections of the grid
    template <class Expr, class TreePath = RootTreePath>
    void addIntersectionOperator(Expr const& expr, TreePath path = {})
    {
93
      using I = typename GlobalBasis::LocalView::GridView::Intersection;
94
95
96
97
      addOperator(tag::intersection_operator<I>{}, expr, path);
    }
    /// @}

98
99

    /// Assemble the vector operators on the bound element.
100
101
    template <class LocalView,
      REQUIRES(Concepts::LocalView<LocalView>)>
102
    void assemble(LocalView const& localView);
103
104
105
106
107
108
109
110
111
112

    /// Assemble all vector operators added by \ref addOperator().
    void assemble();

  private:
    /// Dense vector to store coefficients during \ref assemble()
    ElementVector elementVector_;

    /// List of operators associated to nodes, filled in \ref addOperator().
    VectorOperators<GlobalBasis,ElementVector> operators_;
Praetorius, Simon's avatar
Praetorius, Simon committed
113
114

    std::shared_ptr<GlobalBasis const> basis_;
115
116
  };

117

118
  // deduction guide
119
120
121
  template <class GB>
  LinearForm(GB&& basis)
    -> LinearForm<Underlying_t<GB>>;
122

123

124
125
  template <class T = double, class GB>
  auto makeLinearForm(GB&& basis)
126
127
  {
    using LF = LinearForm<Underlying_t<GB>, T>;
128
    return LF{FWD(basis)};
129
130
  }

131
132
133
} // end namespace AMDiS

#include <amdis/LinearForm.inc.hpp>