dune-functions  2.8.0
periodicbasis.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_PERIODICBASIS_HH
4 #define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_PERIODICBASIS_HH
5 
6 #include <utility>
7 #include <type_traits>
8 #include <limits>
9 #include <set>
10 #include <vector>
11 
14 
15 
16 namespace Dune::Functions {
17 
18 namespace BasisFactory {
19 
20 // The PeriodicBasis class is in the Experimental namespace because we are
21 // not completely sure yet whether we like it. We reserve the right to
22 // modify it without advance warning. Use at your own risk!
23 
24 namespace Experimental {
25 
26 
36 {
37  using IndexPairSet = std::set<std::pair<std::size_t,std::size_t>>;
38 public:
39 
47  void unifyIndexPair(std::size_t a, std::size_t b)
48  {
49  if (a>b)
50  std::swap(a,b);
51  if (a==b)
52  return;
53  indexPairSet_.insert(std::make_pair(a,b));
54  }
55 
56  const auto& indexPairSet() const
57  {
58  return indexPairSet_;
59  }
60 
61 private:
62  IndexPairSet indexPairSet_;
63 };
64 
65 
66 
67 namespace Impl {
68 
69 // An index transformation for a TransformedIndexPreBasis
70 // impelementing periodic functions by merging indices.
71 // Currently only flat indices are supported.
72 class PeriodicIndexingTransformation
73 {
74 public:
75 
76  static constexpr std::size_t minIndexSize = 1;
77  static constexpr std::size_t maxIndexSize = 1;
78 
79  template<class RawPreBasis, class IndexPairSet>
80  PeriodicIndexingTransformation(const RawPreBasis& rawPreBasis, const IndexPairSet& indexPairSet)
81  {
82  std::size_t invalid = {std::numeric_limits<std::size_t>::max()};
83  mappedIdx_.resize(rawPreBasis.size(), invalid);
84  numIndices_ = 0;
85  std::size_t i = 0;
86  for(const auto& [a, b] : indexPairSet)
87  {
88  for(; i<=a; ++i)
89  if (mappedIdx_[i] == invalid)
90  mappedIdx_[i] = numIndices_++;
91  mappedIdx_[b] = mappedIdx_[a];
92  }
93  for(; i<rawPreBasis.size(); ++i)
94  if (mappedIdx_[i] == invalid)
95  mappedIdx_[i] = numIndices_++;
96  }
97 
98  template<class MultiIndex, class PreBasis>
99  void transformIndex(MultiIndex& multiIndex, const PreBasis& preBasis) const
100  {
101  multiIndex = {{ mappedIdx_[multiIndex[0]] }};
102  }
103 
104  template<class Prefix, class PreBasis>
105  std::size_t size(const Prefix& prefix, const PreBasis& preBasis) const
106  {
107  if (prefix.size() == 1)
108  return 0;
109  return numIndices_;
110  }
111 
112  template<class PreBasis>
113  auto dimension(const PreBasis& preBasis) const
114  {
115  return numIndices_;
116  }
117 
118 private:
119  std::vector<std::size_t> mappedIdx_;
120  std::size_t numIndices_;
121 };
122 
123 
124 
125 template<class RawPreBasisIndicator>
126 class PeriodicPreBasisFactory
127 {
128 public:
129  static const std::size_t requiredMultiIndexSize = 1;
130 
131  PeriodicPreBasisFactory()
132  {}
133 
134  template<class RPBI, class PIS>
135  PeriodicPreBasisFactory(RPBI&& rawPreBasisIndicator, PIS&& periodicIndexSet) :
136  rawPreBasisIndicator_(std::forward<RPBI>(rawPreBasisIndicator)),
137  periodicIndexSet_(std::forward<PIS>(periodicIndexSet))
138  {}
139 
140  template<class MultiIndex, class GridView,
141  std::enable_if_t<models<Concept::GlobalBasis<GridView>,RawPreBasisIndicator>(), int> = 0>
142  auto makePreBasis(const GridView& gridView) const
143  {
144  const auto& rawPreBasis = rawPreBasisIndicator_.preBasis();
145  using RawPreBasis = std::decay_t<decltype(rawPreBasis)>;
146  PeriodicIndexingTransformation transformation(rawPreBasis, periodicIndexSet_.indexPairSet());
148  }
149 
150  template<class MultiIndex, class GridView,
151  std::enable_if_t<models<Concept::PreBasis<GridView>,RawPreBasisIndicator>(), int> = 0>
152  auto makePreBasis(const GridView& gridView) const
153  {
154  const auto& rawPreBasis = rawPreBasisIndicator_;
155  using RawPreBasis = std::decay_t<decltype(rawPreBasis)>;
156  PeriodicIndexingTransformation transformation(rawPreBasis, periodicIndexSet_.indexPairSet());
158  }
159 
160  template<class MultiIndex, class GridView,
161  std::enable_if_t<not models<Concept::GlobalBasis<GridView>,RawPreBasisIndicator>(), int> = 0,
162  std::enable_if_t<not models<Concept::PreBasis<GridView>,RawPreBasisIndicator>(), int> = 0>
163  auto makePreBasis(const GridView& gridView) const
164  {
165  auto rawPreBasis = rawPreBasisIndicator_.template makePreBasis<MultiIndex>(gridView);
166  rawPreBasis.initializeIndices();
167  using RawPreBasis = std::decay_t<decltype(rawPreBasis)>;
168  PeriodicIndexingTransformation transformation(rawPreBasis, periodicIndexSet_.indexPairSet());
170  }
171 
172 private:
173  RawPreBasisIndicator rawPreBasisIndicator_;
174  PeriodicIndexSet periodicIndexSet_;
175 };
176 
177 } // end namespace BasisFactory::Impl
178 
179 
180 
194 template<class RawPreBasisIndicator, class PIS>
195 auto periodic(
196  RawPreBasisIndicator&& rawPreBasisIndicator,
197  PIS&& periodicIndexSet
198  )
199 {
200  return Impl::PeriodicPreBasisFactory<std::decay_t<RawPreBasisIndicator>>(
201  std::forward<RawPreBasisIndicator>(rawPreBasisIndicator),
202  std::forward<PIS>(periodicIndexSet));
203 }
204 
205 } // end namespace Experimental
206 
207 } // end namespace BasisFactory
208 
209 } // end namespace Dune::Functions
210 
211 #endif // DUNE_FUFEM_PERIODICBASIS_HH
auto periodic(RawPreBasisIndicator &&rawPreBasisIndicator, PIS &&periodicIndexSet)
Create a pre-basis factory that can create a periodic pre-basis.
Definition: periodicbasis.hh:195
Definition: polynomial.hh:11
Container storing identified indices for a periodic basis.
Definition: periodicbasis.hh:36
const auto & indexPairSet() const
Definition: periodicbasis.hh:56
void unifyIndexPair(std::size_t a, std::size_t b)
Insert a pair of indices.
Definition: periodicbasis.hh:47
A pre-basis transforming multi-indices.
Definition: transformedindexbasis.hh:53