Assembler.hpp 3.84 KB
Newer Older
1
2
#pragma once

3
4
5
6
7
8
9
10
11
12
13
14
#include <functional>
#include <memory>
#include <type_traits>

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

#include <amdis/ContextGeometry.hpp>
#include <amdis/AssemblerInterface.hpp>
#include <amdis/common/Concepts.hpp>
#include <amdis/typetree/FiniteElementType.hpp>

15
16
namespace AMDiS
{
17
  /// Implementation of interface \ref AssemblerBase
18
  /**
19
   * \tparam Traits  See \ref DefaultAssemblerTraits
20
   **/
21
  template <class Traits, class Operator, class... Nodes>
22
  class Assembler
23
      : public AssemblerInterface<Traits, Nodes...>
24
  {
25
    using Super = AssemblerInterface<Traits, Nodes...>;
26

27
    using LocalContext = typename Traits::LocalContext;
28
29
    using Element = typename Super::Element;
    using Geometry = typename Super::Geometry;
30
    using ElementContainer = typename Traits::ElementContainer;
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
  public:

    /// Constructor. Stores a copy of operator `op`.
    explicit Assembler(Operator const& op)
      : op_(Dune::wrap_or_move(op))
    {}

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

    /// Constructor. Stores the reference to the operator.
    explicit Assembler(std::reference_wrapper<Operator> op)
      : op_(Dune::wrap_or_move(op.get()))
    {}
48

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

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

73
74
75
76
77
78
    /// Implementation of \ref AssemblerBase::assemble
    /**
     * Stores geometry and localGeometry and calls
     * \ref calculateElementVector or \ref calculateElementMatrix on the
     * vector or matrix operator, respectively.
     **/
79
80
    void assemble(LocalContext const& localContext, Nodes const&... nodes,
                  ElementContainer& ElementContainer) final
81
    {
82
83
      ContextGeometry<LocalContext> contextGeo{localContext, element(), geometry()};
      assembleImpl(contextGeo, nodes..., ElementContainer);
84
85
86
87
88
89
90
91
    }


#ifndef DOXYGEN

  protected: // implementation detail

    // matrix assembling
92
93
    template <class CG, class RN, class CN, class Mat>
    void assembleImpl(CG const& contextGeo, RN const& rowNode, CN const& colNode, Mat& elementMatrix)
94
    {
95
      op_->calculateElementMatrix(contextGeo, rowNode, colNode, elementMatrix);
96
97
98
    }

    // vector assembling
99
100
    template <class CG, class Node, class Vec>
    void assembleImpl(CG const& contextGeo, Node const& node, Vec& elementVector)
101
    {
102
      op_->calculateElementVector(contextGeo, node, elementVector);
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
    }

#endif // DOXYGEN

  public:

    /// return the bound entity (of codim 0)
    Element const& element() const
    {
      assert( element_ );
      return *element_;
    }

    /// return the geometry of the bound element
    Geometry const& geometry() const
    {
      assert( geometry_ );
      return *geometry_;
    }


  private:

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

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


134
  /// Generate a \ref Assembler on a given LocalContext `LC` (element or intersection)
135
  template <class Traits, class Operator, class... Nodes>
136
  auto makeAssembler(Operator&& op, Nodes const&...)
137
  {
138
    return Assembler<Traits, Underlying_t<Operator>, Nodes...>{FWD(op)};
139
140
  }

141
} // end namespace AMDiS