DiscreteFunction.hpp 4.71 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
#pragma once

#include <vector>

#include <dune/common/std/optional.hh>
#include <dune/functions/common/defaultderivativetraits.hh>
#include <dune/functions/functionspacebases/defaultnodetorangemap.hh>
#include <dune/functions/functionspacebases/flatvectorview.hh>
#include <dune/functions/gridfunctions/gridviewentityset.hh>
#include <dune/typetree/childextraction.hh>

#include <amdis/GridFunctions.hpp>
13 14
#include <amdis/typetree/FiniteElementType.hpp>
#include <amdis/typetree/TreePath.hpp>
15 16 17

namespace AMDiS
{
18
  /// \class DiscreteFunction
19 20 21
  /// \brief A view on a subspace of a \ref DOFVector
  /**
   * \ingroup GridFunctions
22
   *
23
   * \tparam GB  Type of the global basis
24
   * \tparam VT  Coefficient type of the DOFVector
25 26 27 28
   * \tparam TP  A realization of \ref Dune::TypeTree::HybridTreePath
   *
   * **Requirements:**
   * - GB models \ref Dune::Functions::Concept::GlobalBasis
29
   **/
30
  template <class GB, class VT, class TP>
31 32
  class DiscreteFunction
  {
33 34 35 36 37
    static_assert(std::is_arithmetic<VT>::value, "");

  private:
    using GlobalBasis = GB;
    using TreePath = TP;
38 39 40 41 42 43 44

    using Tree = typename GlobalBasis::LocalView::Tree;
    using SubTree = typename Dune::TypeTree::ChildForTreePath<Tree, TreePath>;
    using NodeToRangeEntry = Dune::Functions::DefaultNodeToRangeMap<SubTree>;

    using GridView = typename GlobalBasis::GridView;

45
  public:
46 47 48
    /// Set of entities the DiscreteFunction is defined on
    using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>;

49
    /// Global coordinates of the EntitySet
50 51
    using Domain = typename EntitySet::GlobalCoordinate;

52 53
    /// Range type of this DiscreteFunction
    using Range = RangeType_t<SubTree,VT>;
54

55 56
    /// \brief This GridFunction has no derivative function, it can be created
    /// by \ref DiscreteGridFunction.
57 58
    enum { hasDerivative = false };

59 60 61
  public:
    /// A LocalFunction representing the derivative of the DOFVector on a bound element
    class GradientLocalFunction;
62

63
    /// A LocalFunction representing the value the DOFVector on a bound element
64
    class LocalFunction;
65 66

  public:
67 68 69 70 71
    /// Constructor forwards to the treePath constructor, with empty TreePath
    DiscreteFunction(DOFVector<GB,VT> const& dofVector)
      : DiscreteFunction{dofVector, Dune::TypeTree::hybridTreePath()}
    {}

72
    /// Constructor. Stores a pointer to the dofVector and a copy of the treePath.
73
    DiscreteFunction(DOFVector<GB,VT> const& dofVector, TP const& treePath)
74 75 76 77 78 79
      : dofVector_(&dofVector)
      , treePath_(treePath)
      , entitySet_(dofVector.basis().gridView())
      , nodeToRangeEntry_(Dune::Functions::makeDefaultNodeToRangeMap(dofVector.basis(), treePath))
    {}

80
    /// \brief Evaluate DiscreteFunction in global coordinates. NOTE: expensive
81 82 83 84 85 86 87 88
    Range operator()(Domain const& x) const;

    /// \brief Create a local function for this view on the DOFVector. \relates LocalFunction
    friend LocalFunction localFunction(DiscreteFunction const& self)
    {
      return LocalFunction{self};
    }

89
    /// \brief Return a \ref Dune::Functions::GridViewEntitySet
90 91 92 93 94 95
    EntitySet const& entitySet() const
    {
      return entitySet_;
    }

  public:
96
    /// \brief Return global basis bound to the DOFVector
97 98 99 100 101
    GlobalBasis const& basis() const
    {
      return dofVector_->basis();
    }

102
    /// \brief Return treePath associated with this discrete function
103 104 105 106 107
    TreePath const& treePath() const
    {
      return treePath_;
    }

108 109
    /// \brief Return const coefficient vector
    DOFVector<GB,VT> const& coefficients() const
110 111 112 113 114
    {
      return *dofVector_;
    }

  protected:
115 116
    DOFVector<GB,VT> const* dofVector_;
    TreePath treePath_;
117 118 119 120
    EntitySet entitySet_;
    NodeToRangeEntry nodeToRangeEntry_;
  };

121 122 123 124 125 126 127 128

#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
  // Deduction guide for DiscreteFunction class
  template <class GlobalBasis, class ValueType>
  DiscreteFunction(DOFVector<GlobalBasis, ValueType> const& dofVector)
    -> DiscreteFunction<GlobalBasis, ValueType, Dune::TypeTree::HybridTreePath<>>;
#endif

129
  /// A Generator for a \ref DiscreteFunction
130 131
  template <class GlobalBasis, class ValueType, class PreTreePath>
  auto makeDiscreteFunction(DOFVector<GlobalBasis, ValueType> const& dofVector, PreTreePath const& preTreePath)
132
  {
133 134
    auto treePath = makeTreePath(preTreePath);
    return DiscreteFunction<GlobalBasis, ValueType, decltype(treePath)>{dofVector, treePath};
135 136 137
  }

  /// A Generator for a \ref DiscreteFunction
138 139
  template <class GlobalBasis, class ValueType>
  auto makeDiscreteFunction(DOFVector<GlobalBasis, ValueType> const& dofVector)
140 141
  {
    auto treePath = Dune::TypeTree::hybridTreePath();
142
    return DiscreteFunction<GlobalBasis, ValueType, Dune::TypeTree::HybridTreePath<>>{dofVector, treePath};
143 144 145 146 147
  }

} // end namespace AMDiS

#include "DiscreteFunction.inc.hpp"