Dune Core Modules (2.9.0)

periodicbasis.hh
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 
12 #include <dune/functions/functionspacebases/concepts.hh>
13 #include <dune/functions/functionspacebases/transformedindexbasis.hh>
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 // implementing 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  static_assert(RawPreBasis::maxMultiIndexSize==1, "PeriodicIndexingTransformation is only implemented for flat multi-indices");
83  std::size_t invalid = {std::numeric_limits<std::size_t>::max()};
84  mappedIdx_.resize(rawPreBasis.size(), invalid);
85  numIndices_ = 0;
86  std::size_t i = 0;
87  for(const auto& [a, b] : indexPairSet)
88  {
89  for(; i<=a; ++i)
90  if (mappedIdx_[i] == invalid)
91  mappedIdx_[i] = numIndices_++;
92  mappedIdx_[b] = mappedIdx_[a];
93  }
94  for(; i<rawPreBasis.size(); ++i)
95  if (mappedIdx_[i] == invalid)
96  mappedIdx_[i] = numIndices_++;
97  }
98 
99  template<class MultiIndex, class PreBasis>
100  void transformIndex(MultiIndex& multiIndex, const PreBasis& preBasis) const
101  {
102  multiIndex = {{ mappedIdx_[multiIndex[0]] }};
103  }
104 
105  template<class Prefix, class PreBasis>
106  std::size_t size(const Prefix& prefix, const PreBasis& preBasis) const
107  {
108  if (prefix.size() == 1)
109  return 0;
110  return numIndices_;
111  }
112 
113  template<class PreBasis>
114  auto dimension(const PreBasis& preBasis) const
115  {
116  return numIndices_;
117  }
118 
119 private:
120  std::vector<std::size_t> mappedIdx_;
121  std::size_t numIndices_;
122 };
123 
124 
125 
126 template<class RawPreBasisIndicator>
127 class PeriodicPreBasisFactory
128 {
129 public:
130  PeriodicPreBasisFactory()
131  {}
132 
133  template<class RPBI, class PIS>
134  PeriodicPreBasisFactory(RPBI&& rawPreBasisIndicator, PIS&& periodicIndexSet) :
135  rawPreBasisIndicator_(std::forward<RPBI>(rawPreBasisIndicator)),
136  periodicIndexSet_(std::forward<PIS>(periodicIndexSet))
137  {}
138 
139  template<class GridView,
140  std::enable_if_t<models<Concept::GlobalBasis<GridView>,RawPreBasisIndicator>(), int> = 0>
141  auto operator()(const GridView& gridView) const
142  {
143  const auto& rawPreBasis = rawPreBasisIndicator_.preBasis();
144  auto transformation = PeriodicIndexingTransformation(rawPreBasis, periodicIndexSet_.indexPairSet());
145  return Dune::Functions::Experimental::TransformedIndexPreBasis(std::move(rawPreBasis), std::move(transformation));
146  }
147 
148  template<class GridView,
149  std::enable_if_t<models<Concept::PreBasis<GridView>,RawPreBasisIndicator>(), int> = 0>
150  auto operator()(const GridView& gridView) const
151  {
152  const auto& rawPreBasis = rawPreBasisIndicator_;
153  auto transformation = PeriodicIndexingTransformation(rawPreBasis, periodicIndexSet_.indexPairSet());
154  return Dune::Functions::Experimental::TransformedIndexPreBasis(std::move(rawPreBasis), std::move(transformation));
155  }
156 
157  template<class GridView,
158  std::enable_if_t<not models<Concept::GlobalBasis<GridView>,RawPreBasisIndicator>(), int> = 0,
159  std::enable_if_t<not models<Concept::PreBasis<GridView>,RawPreBasisIndicator>(), int> = 0>
160  auto operator()(const GridView& gridView) const
161  {
162  auto rawPreBasis = rawPreBasisIndicator_(gridView);
163  rawPreBasis.initializeIndices();
164  auto transformation = PeriodicIndexingTransformation(rawPreBasis, periodicIndexSet_.indexPairSet());
165  return Dune::Functions::Experimental::TransformedIndexPreBasis(std::move(rawPreBasis), std::move(transformation));
166  }
167 
168 private:
169  RawPreBasisIndicator rawPreBasisIndicator_;
170  PeriodicIndexSet periodicIndexSet_;
171 };
172 
173 } // end namespace BasisFactory::Impl
174 
175 
176 
190 template<class RawPreBasisIndicator, class PIS>
191 auto periodic(
192  RawPreBasisIndicator&& rawPreBasisIndicator,
193  PIS&& periodicIndexSet
194  )
195 {
196  return Impl::PeriodicPreBasisFactory<std::decay_t<RawPreBasisIndicator>>(
197  std::forward<RawPreBasisIndicator>(rawPreBasisIndicator),
198  std::forward<PIS>(periodicIndexSet));
199 }
200 
201 } // end namespace Experimental
202 
203 } // end namespace BasisFactory
204 
205 } // end namespace Dune::Functions
206 
207 #endif // DUNE_FUFEM_PERIODICBASIS_HH
Container storing identified indices for a periodic basis.
Definition: periodicbasis.hh:36
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:52
constexpr auto models()
Check if concept is modeled by given types.
Definition: concept.hh:184
auto periodic(RawPreBasisIndicator &&rawPreBasisIndicator, PIS &&periodicIndexSet)
Create a pre-basis factory that can create a periodic pre-basis.
Definition: periodicbasis.hh:191
auto max(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::max()
Definition: defaults.hh:81
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)