DUNE PDELab (git)

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/containerdescriptors.hh>
14#include <dune/functions/functionspacebases/transformedindexbasis.hh>
15
16
17namespace Dune::Functions {
18
19namespace BasisFactory {
20
21// The PeriodicBasis class is in the Experimental namespace because we are
22// not completely sure yet whether we like it. We reserve the right to
23// modify it without advance warning. Use at your own risk!
24
25namespace Experimental {
26
27
37{
38 using IndexPairSet = std::set<std::pair<std::size_t,std::size_t>>;
39public:
40
48 void unifyIndexPair(std::size_t a, std::size_t b)
49 {
50 if (a>b)
51 std::swap(a,b);
52 if (a==b)
53 return;
54 indexPairSet_.insert(std::make_pair(a,b));
55 }
56
57 const auto& indexPairSet() const
58 {
59 return indexPairSet_;
60 }
61
62private:
63 IndexPairSet indexPairSet_;
64};
65
66
67
68namespace Impl {
69
70// An index transformation for a TransformedIndexPreBasis
71// implementing periodic functions by merging indices.
72// Currently only flat indices are supported.
73class PeriodicIndexingTransformation
74{
75public:
76
77 static constexpr std::size_t minIndexSize = 1;
78 static constexpr std::size_t maxIndexSize = 1;
79
80 template<class RawPreBasis, class IndexPairSet>
81 PeriodicIndexingTransformation(const RawPreBasis& rawPreBasis, const IndexPairSet& indexPairSet)
82 {
83 static_assert(RawPreBasis::maxMultiIndexSize==1, "PeriodicIndexingTransformation is only implemented for flat multi-indices");
84 std::size_t invalid = {std::numeric_limits<std::size_t>::max()};
85 mappedIdx_.resize(rawPreBasis.size(), invalid);
86 numIndices_ = 0;
87 std::size_t i = 0;
88 for(const auto& [a, b] : indexPairSet)
89 {
90 for(; i<=a; ++i)
91 if (mappedIdx_[i] == invalid)
92 mappedIdx_[i] = numIndices_++;
93 mappedIdx_[b] = mappedIdx_[a];
94 }
95 for(; i<rawPreBasis.size(); ++i)
96 if (mappedIdx_[i] == invalid)
97 mappedIdx_[i] = numIndices_++;
98 }
99
100 template<class MultiIndex, class PreBasis>
101 void transformIndex(MultiIndex& multiIndex, const PreBasis& preBasis) const
102 {
103 multiIndex = {{ mappedIdx_[multiIndex[0]] }};
104 }
105
106 template<class Prefix, class PreBasis>
107 std::size_t size(const Prefix& prefix, const PreBasis& preBasis) const
108 {
109 if (prefix.size() == 1)
110 return 0;
111 return numIndices_;
112 }
113
114 template<class PreBasis>
115 auto dimension(const PreBasis& preBasis) const
116 {
117 return numIndices_;
118 }
119
121 template<class PreBasis>
122 auto containerDescriptor(const PreBasis& preBasis) const
123 {
124 return Dune::Functions::containerDescriptor(preBasis);
125 }
126
127private:
128 std::vector<std::size_t> mappedIdx_;
129 std::size_t numIndices_;
130};
131
132
133
134template<class RawPreBasisIndicator>
135class PeriodicPreBasisFactory
136{
137public:
138 PeriodicPreBasisFactory()
139 {}
140
141 template<class RPBI, class PIS>
142 PeriodicPreBasisFactory(RPBI&& rawPreBasisIndicator, PIS&& periodicIndexSet) :
143 rawPreBasisIndicator_(std::forward<RPBI>(rawPreBasisIndicator)),
144 periodicIndexSet_(std::forward<PIS>(periodicIndexSet))
145 {}
146
147 template<class GridView,
148 std::enable_if_t<models<Concept::GlobalBasis<GridView>,RawPreBasisIndicator>(), int> = 0>
149 auto operator()(const GridView& gridView) const
150 {
151 const auto& rawPreBasis = rawPreBasisIndicator_.preBasis();
152 auto transformation = PeriodicIndexingTransformation(rawPreBasis, periodicIndexSet_.indexPairSet());
153 return Dune::Functions::Experimental::TransformedIndexPreBasis(std::move(rawPreBasis), std::move(transformation));
154 }
155
156 template<class GridView,
157 std::enable_if_t<models<Concept::PreBasis<GridView>,RawPreBasisIndicator>(), int> = 0>
158 auto operator()(const GridView& gridView) const
159 {
160 const auto& rawPreBasis = rawPreBasisIndicator_;
161 auto transformation = PeriodicIndexingTransformation(rawPreBasis, periodicIndexSet_.indexPairSet());
162 return Dune::Functions::Experimental::TransformedIndexPreBasis(std::move(rawPreBasis), std::move(transformation));
163 }
164
165 template<class GridView,
166 std::enable_if_t<not models<Concept::GlobalBasis<GridView>,RawPreBasisIndicator>(), int> = 0,
167 std::enable_if_t<not models<Concept::PreBasis<GridView>,RawPreBasisIndicator>(), int> = 0>
168 auto operator()(const GridView& gridView) const
169 {
170 auto rawPreBasis = rawPreBasisIndicator_(gridView);
171 rawPreBasis.initializeIndices();
172 auto transformation = PeriodicIndexingTransformation(rawPreBasis, periodicIndexSet_.indexPairSet());
173 return Dune::Functions::Experimental::TransformedIndexPreBasis(std::move(rawPreBasis), std::move(transformation));
174 }
175
176private:
177 RawPreBasisIndicator rawPreBasisIndicator_;
178 PeriodicIndexSet periodicIndexSet_;
179};
180
181} // end namespace BasisFactory::Impl
182
183
184
198template<class RawPreBasisIndicator, class PIS>
200 RawPreBasisIndicator&& rawPreBasisIndicator,
201 PIS&& periodicIndexSet
202 )
203{
204 return Impl::PeriodicPreBasisFactory<std::decay_t<RawPreBasisIndicator>>(
205 std::forward<RawPreBasisIndicator>(rawPreBasisIndicator),
206 std::forward<PIS>(periodicIndexSet));
207}
208
209} // end namespace Experimental
210
211} // end namespace BasisFactory
212
213} // end namespace Dune::Functions
214
215#endif // DUNE_FUFEM_PERIODICBASIS_HH
Container storing identified indices for a periodic basis.
Definition: periodicbasis.hh:37
void unifyIndexPair(std::size_t a, std::size_t b)
Insert a pair of indices.
Definition: periodicbasis.hh:48
A pre-basis transforming multi-indices.
Definition: transformedindexbasis.hh:51
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:199
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
STL namespace.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)