Liebe Gitlab-Nutzerin, lieber Gitlab-Nutzer,
es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Die Konten der externen Nutzer:innen sind über den Reiter "Standard" erreichbar.
Die Administratoren


Dear Gitlab user,
it is now possible to log in to our service using the ZIH login/LDAP. The accounts of external users can be accessed via the "Standard" tab.
The administrators

Assembler.hpp 3.95 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 18 19 20
  /// Implementation of interface \ref AssemblerBase
  template <class LocalContext, class Operator, class... Nodes>
  class Assembler
      : public AssemblerInterface<LocalContext, Nodes...>
21
  {
22
    using Super = AssemblerInterface<LocalContext, Nodes...>;
23

24
  private:
25

26 27 28
    using Element = typename Super::Element;
    using Geometry = typename Super::Geometry;
    using ElementMatrixVector = typename Super::ElementMatrixVector;
29

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
  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()))
    {}
46

47 48 49 50 51 52
    /// \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
53
    {
54 55 56
      element_ = &element;
      geometry_ = &geometry;
      op_->bind(element, geometry);
57
    }
58

59 60 61 62 63 64 65 66 67 68 69
    /// \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;
    }
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 101 102 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 132 133 134
    /// Implementation of \ref AssemblerBase::assemble
    /**
     * Stores geometry and localGeometry and calls
     * \ref calculateElementVector or \ref calculateElementMatrix on the
     * vector or matrix operator, respectively.
     **/
    void assemble(LocalContext const& localContext,
                  Nodes const&... nodes,
                  ElementMatrixVector& elementMatrixVector) final
    {
      ContextGeometry<LocalContext> context{localContext, element(), geometry()};
      assembleImpl(context, nodes..., elementMatrixVector);
    }


#ifndef DOXYGEN

  protected: // implementation detail

    // matrix assembling
    template <class Context, class RowNode, class ColNode, class ElementMatrix>
    void assembleImpl(Context const& context,
                      RowNode const& rowNode, ColNode const& colNode,
                      ElementMatrix& elementMatrix)
    {
      op_->calculateElementMatrix(context, rowNode, colNode, elementMatrix);
    }

    // vector assembling
    template <class Context, class Node, class ElementVector>
    void assembleImpl(Context const& context,
                      Node const& node,
                      ElementVector& elementVector)
    {
      op_->calculateElementVector(context, node, elementVector);
    }

#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;
  };
135 136


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

144
} // end namespace AMDiS