LinearForm.hpp 4.5 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
      operators_.init(*basis);
48

Praetorius, Simon's avatar
Praetorius, Simon committed
49
      auto const localSize = basis->localView().maxSize();
50
51
52
      elementVector_.resize(localSize);
    }

53
54
55
56
57
58
59
    /// 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
60
61
    std::shared_ptr<GlobalBasis const> const& basis() const { return basis_; }

62
63
64
65
66
    /// \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.
67
68
     * The \p path tree paths specify the sub-basis for test functions the operator
     * is applied to.
69
70
     *
     * \tparam ContextTag  One of \ref tag::element_operator, \ref tag::intersection_operator
71
72
     *                     or \ref tag::boundary_operator indicating where to assemble
     *                     this operator.
73
     * \tparam Expr        An pre-operator that can be bound to a gridView, or a valid
74
75
     *                     GridOperator.
     * \tparam path        A tree-path for the Basis
76
77
78
79
80
81
82
83
84
85
86
     *
     * [[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 = {})
    {
87
      using E = typename GlobalBasis::LocalView::Element;
88
89
90
91
92
93
94
      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 = {})
    {
95
      using I = typename GlobalBasis::LocalView::GridView::Intersection;
96
97
98
99
      addOperator(tag::intersection_operator<I>{}, expr, path);
    }
    /// @}

100
101

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

    /// 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
115
116

    std::shared_ptr<GlobalBasis const> basis_;
117
118
  };

119

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

125

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

133
134
135
} // end namespace AMDiS

#include <amdis/LinearForm.inc.hpp>