3#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_PERIODICBASIS_HH
4#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_PERIODICBASIS_HH
12#include <dune/functions/functionspacebases/concepts.hh>
13#include <dune/functions/functionspacebases/transformedindexbasis.hh>
16namespace Dune::Functions {
18namespace BasisFactory {
24namespace Experimental {
37 using IndexPairSet = std::set<std::pair<std::size_t,std::size_t>>;
53 indexPairSet_.insert(std::make_pair(a,b));
56 const auto& indexPairSet()
const
62 IndexPairSet indexPairSet_;
72class PeriodicIndexingTransformation
76 static constexpr std::size_t minIndexSize = 1;
77 static constexpr std::size_t maxIndexSize = 1;
79 template<
class RawPreBasis,
class IndexPairSet>
80 PeriodicIndexingTransformation(
const RawPreBasis& rawPreBasis,
const IndexPairSet& indexPairSet)
82 static_assert(RawPreBasis::maxMultiIndexSize==1,
"PeriodicIndexingTransformation is only implemented for flat multi-indices");
84 mappedIdx_.resize(rawPreBasis.size(), invalid);
87 for(
const auto& [a, b] : indexPairSet)
90 if (mappedIdx_[i] == invalid)
91 mappedIdx_[i] = numIndices_++;
92 mappedIdx_[b] = mappedIdx_[a];
94 for(; i<rawPreBasis.size(); ++i)
95 if (mappedIdx_[i] == invalid)
96 mappedIdx_[i] = numIndices_++;
99 template<
class MultiIndex,
class PreBasis>
100 void transformIndex(MultiIndex& multiIndex,
const PreBasis& preBasis)
const
102 multiIndex = {{ mappedIdx_[multiIndex[0]] }};
105 template<
class Prefix,
class PreBasis>
106 std::size_t size(
const Prefix& prefix,
const PreBasis& preBasis)
const
108 if (prefix.size() == 1)
113 template<
class PreBasis>
114 auto dimension(
const PreBasis& preBasis)
const
120 std::vector<std::size_t> mappedIdx_;
121 std::size_t numIndices_;
126template<
class RawPreBasisIndicator>
127class PeriodicPreBasisFactory
130 PeriodicPreBasisFactory()
133 template<
class RPBI,
class PIS>
134 PeriodicPreBasisFactory(RPBI&& rawPreBasisIndicator, PIS&& periodicIndexSet) :
135 rawPreBasisIndicator_(
std::forward<RPBI>(rawPreBasisIndicator)),
136 periodicIndexSet_(
std::forward<PIS>(periodicIndexSet))
139 template<
class GridView,
140 std::enable_if_t<models<Concept::GlobalBasis<GridView>,RawPreBasisIndicator>(),
int> = 0>
141 auto operator()(
const GridView& gridView)
const
143 const auto& rawPreBasis = rawPreBasisIndicator_.preBasis();
144 auto transformation = PeriodicIndexingTransformation(rawPreBasis, periodicIndexSet_.indexPairSet());
148 template<
class GridView,
149 std::enable_if_t<models<Concept::PreBasis<GridView>,RawPreBasisIndicator>(),
int> = 0>
150 auto operator()(
const GridView& gridView)
const
152 const auto& rawPreBasis = rawPreBasisIndicator_;
153 auto transformation = PeriodicIndexingTransformation(rawPreBasis, periodicIndexSet_.indexPairSet());
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
162 auto rawPreBasis = rawPreBasisIndicator_(gridView);
163 rawPreBasis.initializeIndices();
164 auto transformation = PeriodicIndexingTransformation(rawPreBasis, periodicIndexSet_.indexPairSet());
169 RawPreBasisIndicator rawPreBasisIndicator_;
170 PeriodicIndexSet periodicIndexSet_;
190template<
class RawPreBasisIndicator,
class PIS>
192 RawPreBasisIndicator&& rawPreBasisIndicator,
193 PIS&& periodicIndexSet
196 return Impl::PeriodicPreBasisFactory<std::decay_t<RawPreBasisIndicator>>(
197 std::forward<RawPreBasisIndicator>(rawPreBasisIndicator),
198 std::forward<PIS>(periodicIndexSet));
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
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