AMDiS  2.10
The Adaptive Multi-Dimensional Simulation Toolbox
LocalToGlobalAdapter.hpp
1 #pragma once
2 
3 #include <cstddef>
4 #include <vector>
5 
6 #include <dune/common/fmatrix.hh>
7 #include <dune/common/fvector.hh>
8 #include <dune/common/typetraits.hh>
9 #include <dune/geometry/type.hh>
10 
11 #include <amdis/common/DerivativeTraits.hpp>
12 #include <amdis/common/FieldMatVec.hpp>
13 
14 namespace AMDiS
15 {
17 
25  template <class LocalBasisTraits, std::size_t dimGlobal>
27  {
28  static const std::size_t dimDomainLocal = LocalBasisTraits::dimDomain;
29  static const std::size_t dimDomainGlobal = dimGlobal;
30  static const std::size_t dimRange = LocalBasisTraits::dimRange;
31 
32  using DomainField = typename LocalBasisTraits::DomainFieldType;
33  using DomainLocal = typename LocalBasisTraits::DomainType;
34  using DomainGlobal = FieldVector<DomainField, dimDomainGlobal>;
35 
36  using RangeField = typename LocalBasisTraits::RangeFieldType;
37  using Range = typename LocalBasisTraits::RangeType;
38 
41  };
42 
44 
63  template <class BasisCache, class Geometry>
65  {
66  using LocalBasis = typename BasisCache::LocalBasis;
67 
68  static_assert(std::is_same_v<typename LocalBasis::Traits::DomainFieldType, typename Geometry::ctype>,
69  "LocalToGlobalBasisAdapter: LocalBasis must use the same ctype as Geometry");
70 
71  static_assert(std::size_t(LocalBasis::Traits::dimDomain) == std::size_t(Geometry::mydimension),
72  "LocalToGlobalBasisAdapter: LocalBasis domain dimension must match local dimension of Geometry");
73 
74  public:
75  using Cache = BasisCache;
77 
79 
88  LocalToGlobalBasisAdapter(Cache const& cache, Geometry const& geometry)
89  : localBasis_(cache.finiteElement().localBasis())
90  , cache_(cache)
91  , geometry_(geometry)
92  , size_(localBasis_.size())
93  {}
94 
96  std::size_t size() const { return size_; }
97 
99 
106  std::size_t order() const
107  {
108  if (geometry_.affine())
109  // affine linear
110  return localBasis_.order();
111  else
112  // assume at most order dim
113  return localBasis_.order() + Traits::dimDomainGlobal - 1;
114  }
115 
117  void evaluateFunction(typename Traits::DomainLocal const& x,
118  std::vector<typename Traits::Range>& out) const
119  {
120  out = cache_.localBasisValuesAt(x);
121  }
122 
125  auto const& valuesAt(typename Traits::DomainLocal const& x) const
126  {
127  return cache_.localBasisValuesAt(x);
128  }
129 
132  void evaluateGradient(typename Traits::DomainLocal const& x,
133  std::vector<typename Traits::GradientRange>& out) const
134  {
135  auto const& localJacobian = cache_.localBasisJacobiansAt(x);
136  auto&& geoJacobian = geometry_.jacobianInverseTransposed(x);
137 
138  out.resize(size_);
139  for (std::size_t i = 0; i < size_; ++i)
140  geoJacobian.mv(Dune::MatVec::as_vector(localJacobian[i]),
141  Dune::MatVec::as_vector(out[i]));
142  }
143 
147  auto const& gradientsAt(typename Traits::DomainLocal const& x) const
148  {
149  evaluateGradient(x, outGrad_);
150  return outGrad_;
151  }
152 
155  void evaluatePartial(typename Traits::DomainLocal const& x,
156  std::size_t comp,
157  std::vector<typename Traits::PartialRange>& out) const
158  {
159  auto const& localJacobian = cache_.localBasisJacobiansAt(x);
160  // NOTE: geoJacobian might be a Dune::DiagonalMatrix with limited interface!
161  auto&& geoJacobian = geometry_.jacobianInverseTransposed(x);
162 
163  out.resize(size_);
164  typename Traits::GradientRange grad;
165  auto&& grad_ = Dune::MatVec::as_vector(grad);
166  for (std::size_t i = 0; i < size_; ++i) {
167  geoJacobian.mv(Dune::MatVec::as_vector(localJacobian[i]), grad_);
168  out[i] = grad_[comp];
169  }
170  }
171 
175  auto const& partialsAt(typename Traits::DomainLocal const& x, std::size_t comp) const
176  {
177  evaluatePartial(x, comp, outPartials_);
178  return outPartials_;
179  }
180 
181  private:
183  LocalBasis const& localBasis_;
184 
186  Cache const& cache_;
187 
189  Geometry const& geometry_;
190 
192  std::size_t size_;
193 
194  // data return as reference
195  mutable std::vector<typename Traits::GradientRange> outGrad_;
196  mutable std::vector<typename Traits::PartialRange> outPartials_;
197  };
198 
199 } // namespace AMDiS
auto const & valuesAt(typename Traits::DomainLocal const &x) const
Definition: LocalToGlobalAdapter.hpp:125
void evaluatePartial(typename Traits::DomainLocal const &x, std::size_t comp, std::vector< typename Traits::PartialRange > &out) const
Definition: LocalToGlobalAdapter.hpp:155
Convert a simple (scalar) local basis into a global basis.
Definition: LocalToGlobalAdapter.hpp:64
LocalToGlobalBasisAdapter(Cache const &cache, Geometry const &geometry)
Construct a LocalToGlobalBasisAdapter.
Definition: LocalToGlobalAdapter.hpp:88
void evaluateGradient(typename Traits::DomainLocal const &x, std::vector< typename Traits::GradientRange > &out) const
Definition: LocalToGlobalAdapter.hpp:132
Definition: AdaptBase.hpp:6
std::size_t size() const
Return the number of local basis functions.
Definition: LocalToGlobalAdapter.hpp:96
auto const & partialsAt(typename Traits::DomainLocal const &x, std::size_t comp) const
Definition: LocalToGlobalAdapter.hpp:175
Traits class for local-to-global basis adaptors.
Definition: LocalToGlobalAdapter.hpp:26
Definition: DerivativeTraits.hpp:29
void evaluateFunction(typename Traits::DomainLocal const &x, std::vector< typename Traits::Range > &out) const
Evaluate the local basis functions in the local coordinate x
Definition: LocalToGlobalAdapter.hpp:117
std::size_t order() const
Return maximum polynomial order of the base function.
Definition: LocalToGlobalAdapter.hpp:106
auto const & gradientsAt(typename Traits::DomainLocal const &x) const
Definition: LocalToGlobalAdapter.hpp:147