LocalAssembler.hpp 4.04 KB
Newer Older
1
2
#pragma once

3
#include <functional>
4
#include <memory>
5
#include <type_traits>
6

7
#include <dune/common/shared_ptr.hh>
8
9
#include <dune/geometry/quadraturerules.hh>

10
11
12
13
#include <amdis/ContextGeometry.hpp>
#include <amdis/LocalAssemblerBase.hpp>
#include <amdis/common/Concepts.hpp>
#include <amdis/utility/FiniteElementType.hpp>
14
15
16

namespace AMDiS
{
17
18
  /// Implementation of interface \ref LocalAssemblerBase
  template <class LocalContext, class Operator, class... Nodes>
19
  class LocalAssembler
20
      : public LocalAssemblerBase<LocalContext, Nodes...>
21
  {
22
23
24
25
26
27
    using Super = LocalAssemblerBase<LocalContext, Nodes...>;

  private:

    using Element = typename Super::Element;
    using Geometry = typename Super::Geometry;
28
    using ElementMatrixVector = typename Super::ElementMatrixVector;
29
30

  public:
31
32
33

    /// Constructor. Stores a copy of operator `op`.
    explicit LocalAssembler(Operator const& op)
34
35
36
37
38
39
      : op_(Dune::wrap_or_move(op))
    {}

    /// Constructor. Stores a copy of operator `op`.
    explicit LocalAssembler(Operator&& op)
      : op_(Dune::wrap_or_move(std::move(op)))
40
41
42
    {}

    /// Constructor. Stores the reference to the operator.
43
44
    explicit LocalAssembler(std::reference_wrapper<Operator> op)
      : op_(Dune::wrap_or_move(op.get()))
45
46
    {}

47
48
49
50
51
52
    /// \brief Implementation of \ref LocalAssemblerBase::bind.
    /**
     * Binds the operator `op_` to the `element` and `geometry` and
     * stores point to the `element` and `geometry`.
     **/
    virtual void bind(Element const& element, Geometry const& geometry) final
53
    {
54
      element_ = &element;
55
      geometry_ = &geometry;
56
      op_->bind(element, geometry);
57
    }
58

59
60
61
62
63
64
    /// \brief Implementation of \ref LocalAssemblerBase::unbind
    /**
     * Unbinds the operator `op_` and sets \ref element_ and \ref geometry_
     * to nullptr.
     **/
    virtual void unbind() final
65
    {
66
      op_->unbind();
67
      geometry_ = nullptr;
68
      element_ = nullptr;
69
70
    }

71
    /// Implementation of \ref LocalAssemblerBase::assemble
72
    /**
73
     * Stores geometry and localGeometry and calls
74
75
     * \ref calculateElementVector or \ref calculateElementMatrix on the
     * vector or matrix operator, respectively.
76
     **/
77
78
79
    virtual void assemble(LocalContext const& localContext,
                          Nodes const&... nodes,
                          ElementMatrixVector& elementMatrixVector) final
80
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
81
      ContextGeometry<LocalContext> context{localContext, element(), geometry()};
82
      assembleImpl(context, nodes..., elementMatrixVector);
83
84
85
86
87
88
89
90
    }


#ifndef DOXYGEN

  protected: // implementation detail

    // matrix assembling
91
    template <class Context, class RowNode, class ColNode, class ElementMatrix>
92
93
    void assembleImpl(Context const& context,
                      RowNode const& rowNode, ColNode const& colNode,
94
                      ElementMatrix& elementMatrix)
95
    {
96
      op_->calculateElementMatrix(context, rowNode, colNode, elementMatrix);
97
98
99
    }

    // vector assembling
100
    template <class Context, class Node, class ElementVector>
101
    void assembleImpl(Context const& context,
102
103
                      Node const& node,
                      ElementVector& elementVector)
104
    {
105
      op_->calculateElementVector(context, node, elementVector);
106
107
108
109
110
111
    }

#endif // DOXYGEN

  public:

112
    /// return the bound entity (of codim 0)
Praetorius, Simon's avatar
Praetorius, Simon committed
113
    Element const& element() const
114
115
116
    {
      assert( element_ );
      return *element_;
117
118
    }

119
    /// return the geometry of the bound element
Praetorius, Simon's avatar
Praetorius, Simon committed
120
    Geometry const& geometry() const
121
    {
122
123
      assert( geometry_ );
      return *geometry_;
124
125
    }

126

127
128
  private:

129
    /// the stored operator, implementing \ref GridFunctionOperatorBase
130
    std::shared_ptr<Operator> op_;
131

132
133
    Element const* element_ = nullptr;
    Geometry const* geometry_ = nullptr;
134
135
  };

136
137
138

  /// Generate a \ref LocalAssembler on a given `LocalContext` (element or intersection)
  template <class LocalContext, class Operator, class... Nodes>
139
  auto makeLocalAssembler(Operator&& op, Nodes const&...)
140
  {
141
    return LocalAssembler<LocalContext, Underlying_t<Operator>, Nodes...>{std::forward<Operator>(op)};
142
143
  }

144
} // end namespace AMDiS