DUNE-FUNCTIONS (2.8)

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
16namespace Dune::Functions {
17
18namespace 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
24namespace Experimental {
25
26
36{
37 using IndexPairSet = std::set<std::pair<std::size_t,std::size_t>>;
38public:
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
61private:
62 IndexPairSet indexPairSet_;
63};
64
65
66
67namespace Impl {
68
69// An index transformation for a TransformedIndexPreBasis
70// impelementing periodic functions by merging indices.
71// Currently only flat indices are supported.
72class PeriodicIndexingTransformation
73{
74public:
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
118private:
119 std::vector<std::size_t> mappedIdx_;
120 std::size_t numIndices_;
121};
122
123
124
125template<class RawPreBasisIndicator>
126class PeriodicPreBasisFactory
127{
128public:
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
172private:
173 RawPreBasisIndicator rawPreBasisIndicator_;
174 PeriodicIndexSet periodicIndexSet_;
175};
176
177} // end namespace BasisFactory::Impl
178
179
180
194template<class RawPreBasisIndicator, class PIS>
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
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:53
auto periodic(RawPreBasisIndicator &&rawPreBasisIndicator, PIS &&periodicIndexSet)
Create a pre-basis factory that can create a periodic pre-basis.
Definition: periodicbasis.hh:195
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)