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
4// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_PERIODICBASIS_HH
8#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_PERIODICBASIS_HH
9
10#include <utility>
11#include <type_traits>
12#include <limits>
13#include <set>
14#include <vector>
15
16#include <dune/functions/functionspacebases/concepts.hh>
17#include <dune/functions/functionspacebases/containerdescriptors.hh>
18#include <dune/functions/functionspacebases/transformedindexbasis.hh>
19
20
21namespace Dune::Functions {
22
23namespace BasisFactory {
24
25// The PeriodicBasis class is in the Experimental namespace because we are
26// not completely sure yet whether we like it. We reserve the right to
27// modify it without advance warning. Use at your own risk!
28
29namespace Experimental {
30
31
41{
42 using IndexPairSet = std::set<std::pair<std::size_t,std::size_t>>;
43public:
44
52 void unifyIndexPair(std::size_t a, std::size_t b)
53 {
54 if (a>b)
55 std::swap(a,b);
56 if (a==b)
57 return;
58 indexPairSet_.insert(std::make_pair(a,b));
59 }
60
61 const auto& indexPairSet() const
62 {
63 return indexPairSet_;
64 }
65
66private:
67 IndexPairSet indexPairSet_;
68};
69
70
71
72namespace Impl {
73
74// An index transformation for a TransformedIndexPreBasis
75// implementing periodic functions by merging indices.
76// Currently only flat indices are supported.
77class PeriodicIndexingTransformation
78{
79public:
80
81 static constexpr std::size_t minIndexSize = 1;
82 static constexpr std::size_t maxIndexSize = 1;
83
84 template<class RawPreBasis, class IndexPairSet>
85 PeriodicIndexingTransformation(const RawPreBasis& rawPreBasis, const IndexPairSet& indexPairSet)
86 {
87 static_assert(RawPreBasis::maxMultiIndexSize==1, "PeriodicIndexingTransformation is only implemented for flat multi-indices");
88 std::size_t invalid = {std::numeric_limits<std::size_t>::max()};
89 mappedIdx_.resize(rawPreBasis.size(), invalid);
90 numIndices_ = 0;
91 std::size_t i = 0;
92 for(const auto& [a, b] : indexPairSet)
93 {
94 for(; i<=a; ++i)
95 if (mappedIdx_[i] == invalid)
96 mappedIdx_[i] = numIndices_++;
97 mappedIdx_[b] = mappedIdx_[a];
98 }
99 for(; i<rawPreBasis.size(); ++i)
100 if (mappedIdx_[i] == invalid)
101 mappedIdx_[i] = numIndices_++;
102 }
103
104 template<class MultiIndex, class PreBasis>
105 void transformIndex(MultiIndex& multiIndex, const PreBasis& preBasis) const
106 {
107 multiIndex = {{ mappedIdx_[multiIndex[0]] }};
108 }
109
110 template<class Prefix, class PreBasis>
111 std::size_t size(const Prefix& prefix, const PreBasis& preBasis) const
112 {
113 if (prefix.size() == 1)
114 return 0;
115 return numIndices_;
116 }
117
118 template<class PreBasis>
119 auto dimension(const PreBasis& preBasis) const
120 {
121 return numIndices_;
122 }
123
125 template<class PreBasis>
126 auto containerDescriptor(const PreBasis& preBasis) const
127 {
128 return Dune::Functions::containerDescriptor(preBasis);
129 }
130
131private:
132 std::vector<std::size_t> mappedIdx_;
133 std::size_t numIndices_;
134};
135
136
137
138template<class RawPreBasisIndicator>
139class PeriodicPreBasisFactory
140{
141public:
142 PeriodicPreBasisFactory()
143 {}
144
145 template<class RPBI, class PIS>
146 PeriodicPreBasisFactory(RPBI&& rawPreBasisIndicator, PIS&& periodicIndexSet) :
147 rawPreBasisIndicator_(std::forward<RPBI>(rawPreBasisIndicator)),
148 periodicIndexSet_(std::forward<PIS>(periodicIndexSet))
149 {}
150
151 template<class GridView,
152 std::enable_if_t<models<Concept::GlobalBasis<GridView>,RawPreBasisIndicator>(), int> = 0>
153 auto operator()(const GridView& gridView) const
154 {
155 const auto& rawPreBasis = rawPreBasisIndicator_.preBasis();
156 auto transformation = PeriodicIndexingTransformation(rawPreBasis, periodicIndexSet_.indexPairSet());
157 return Dune::Functions::Experimental::TransformedIndexPreBasis(std::move(rawPreBasis), std::move(transformation));
158 }
159
160 template<class GridView,
161 std::enable_if_t<models<Concept::PreBasis<GridView>,RawPreBasisIndicator>(), int> = 0>
162 auto operator()(const GridView& gridView) const
163 {
164 const auto& rawPreBasis = rawPreBasisIndicator_;
165 auto transformation = PeriodicIndexingTransformation(rawPreBasis, periodicIndexSet_.indexPairSet());
166 return Dune::Functions::Experimental::TransformedIndexPreBasis(std::move(rawPreBasis), std::move(transformation));
167 }
168
169 template<class GridView,
170 std::enable_if_t<not models<Concept::GlobalBasis<GridView>,RawPreBasisIndicator>(), int> = 0,
171 std::enable_if_t<not models<Concept::PreBasis<GridView>,RawPreBasisIndicator>(), int> = 0>
172 auto operator()(const GridView& gridView) const
173 {
174 auto rawPreBasis = rawPreBasisIndicator_(gridView);
175 rawPreBasis.initializeIndices();
176 auto transformation = PeriodicIndexingTransformation(rawPreBasis, periodicIndexSet_.indexPairSet());
177 return Dune::Functions::Experimental::TransformedIndexPreBasis(std::move(rawPreBasis), std::move(transformation));
178 }
179
180private:
181 RawPreBasisIndicator rawPreBasisIndicator_;
182 PeriodicIndexSet periodicIndexSet_;
183};
184
185} // end namespace BasisFactory::Impl
186
187
188
202template<class RawPreBasisIndicator, class PIS>
204 RawPreBasisIndicator&& rawPreBasisIndicator,
205 PIS&& periodicIndexSet
206 )
207{
208 return Impl::PeriodicPreBasisFactory<std::decay_t<RawPreBasisIndicator>>(
209 std::forward<RawPreBasisIndicator>(rawPreBasisIndicator),
210 std::forward<PIS>(periodicIndexSet));
211}
212
213} // end namespace Experimental
214
215} // end namespace BasisFactory
216
217} // end namespace Dune::Functions
218
219#endif // DUNE_FUFEM_PERIODICBASIS_HH
Container storing identified indices for a periodic basis.
Definition: periodicbasis.hh:41
void unifyIndexPair(std::size_t a, std::size_t b)
Insert a pair of indices.
Definition: periodicbasis.hh:52
A pre-basis transforming multi-indices.
Definition: transformedindexbasis.hh:55
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:203
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 (Nov 13, 23:29, 2024)