AMDiS  0.3
The Adaptive Multi-Dimensional Simulation Toolbox
FlatPreBasis.hpp
1 #pragma once
2 
3 #include <dune/common/version.hh>
4 #include <dune/functions/functionspacebases/basistags.hh>
5 #include <dune/functions/functionspacebases/compositebasis.hh>
6 #include <dune/functions/functionspacebases/lagrangebasis.hh>
7 #include <dune/functions/functionspacebases/powerbasis.hh>
8 #include <dune/functions/functionspacebases/flatmultiindex.hh>
9 
10 #include <amdis/Output.hpp>
11 #include <amdis/common/TypeTraits.hpp>
12 #include <amdis/typetree/FiniteElementType.hpp>
13 
14 namespace AMDiS
15 {
16  // Convert the index-merging strategy to FlatLexicographic or FlatInterleaved for
17  // composite or power bases, respectively.
18  template <class PreBasis,
19  class MultiIndex = Dune::Functions::FlatMultiIndex<std::size_t>>
20  struct FlatPreBasis
21  {
22  using type = PreBasis;
23 
24  template <class PB>
25  static type create(PB const& preBasis)
26  {
27  return {preBasis.gridView()};
28  }
29 
30  static PreBasis const& create(PreBasis const& preBasis)
31  {
32  return preBasis;
33  }
34  };
35 
36  template <class PreBasis,
37  class MultiIndex = Dune::Functions::FlatMultiIndex<std::size_t>>
38  using FlatPreBasis_t = typename FlatPreBasis<PreBasis, MultiIndex>::type;
39 
40  template <class PreBasis>
41  auto flatPreBasis(PreBasis const& preBasis)
42  {
43  return FlatPreBasis<PreBasis>::create(preBasis);
44  }
45 
46  // specialization for Lagrange basis that needs an additional `order` parameter.
47 #if DUNE_VERSION_LT(DUNE_FUNCTIONS,2,7)
48  template <class GV, class MI, class MultiIndex>
49  struct FlatPreBasis<Dune::Functions::LagrangePreBasis<GV,-1,MI>, MultiIndex>
50  {
51  using type = Dune::Functions::LagrangePreBasis<GV,-1,MultiIndex>;
52 #else
53  template <class GV, class MI, class R, class MultiIndex>
54  struct FlatPreBasis<Dune::Functions::LagrangePreBasis<GV,-1,MI,R>, MultiIndex>
55  {
56  using type = Dune::Functions::LagrangePreBasis<GV,-1,MultiIndex,R>;
57 #endif
58 
59  template <class PB>
60  static type create(PB const& preBasis)
61  {
62  auto node = preBasis.makeNode();
63  node.bind(*preBasis.gridView().template begin<0>());
64  return {preBasis.gridView(), (unsigned int)(node.finiteElement().localBasis().order())};
65  }
66 
67  static type const& create(type const& preBasis)
68  {
69  return preBasis;
70  }
71  };
72 
73  namespace Impl
74  {
75 #if DUNE_VERSION_LT(DUNE_FUNCTIONS,2,7)
76  // NOTE: dirty hack to get access to protected member variable, due to missing
77  // function in dune-functions-2.6
78  template <class PreBasis>
79  class DerivedPreBasis {
80  public:
81  // specialization for PowerPreBasis
82  template <class PB, class SPB = typename PB::SubPreBasis>
83  static SPB const& subPreBasis(PB const& pb)
84  {
85  return access(pb).subPreBasis_;
86  }
87 
88  // specialization for CompositePreBasis
89  template <std::size_t I, class PB, class SPB = typename PB::template SubPreBasis<I>>
90  static SPB const& subPreBasis(PB const& pb, Dune::index_constant<I>)
91  {
92  return std::get<I>(access(pb).subPreBases_);
93  }
94 
95  template <class T>
96  class Accessor : public T { friend class DerivedPreBasis<PreBasis>; };
97 
98  template <class T>
99  static Accessor<T> const& access(T const& obj) { return static_cast<Accessor<T> const&>(obj); }
100  };
101 
102  template <class PreBasis, class... Index>
103  static auto const& subPreBasis(PreBasis const& preBasis, Index... ii)
104  {
105  return DerivedPreBasis<PreBasis>::subPreBasis(preBasis,ii...);
106  }
107 #else
108  template <class PreBasis, class... Index>
109  static auto const& subPreBasis(PreBasis const& preBasis, Index... ii)
110  {
111  return preBasis.subPreBasis(ii...);
112  }
113 #endif
114  } // end namespace Impl
115 
116 
117  // specialization for composite bases
118  template <class MI, class IMS, class... SPB, class MultiIndex>
119  struct FlatPreBasis<Dune::Functions::CompositePreBasis<MI, IMS, SPB...>, MultiIndex>
120  {
121  using FIMS = Dune::Functions::BasisFactory::FlatLexicographic;
122  using type = Dune::Functions::CompositePreBasis<MultiIndex, FIMS, FlatPreBasis_t<SPB, MultiIndex>...>;
123 
124  template <class PreBasis>
125  static type create(PreBasis const& preBasis)
126  {
127  return create(preBasis, std::index_sequence_for<SPB...>{});
128  }
129 
130  template <class PreBasis, std::size_t... I>
131  static type create(PreBasis const& preBasis, std::index_sequence<I...>)
132  {
133  test_warning(std::is_same_v<IMS,FIMS>, "Basis converted into flat index-merging strategy.");
134  return {FlatPreBasis<SPB, MultiIndex>::create(Impl::subPreBasis(preBasis,Dune::index_constant<I>{}))...};
135  }
136  };
137 
138  // specialization for flat power bases
139  template <class MI, class IMS, class SPB, std::size_t C, class MultiIndex>
140  struct FlatPreBasis<Dune::Functions::PowerPreBasis<MI, IMS, SPB, C>, MultiIndex>
141  {
142  using type = Dune::Functions::PowerPreBasis<MultiIndex, IMS, SPB, C>;
143 
144  template <class PreBasis>
145  static type create(PreBasis const& preBasis)
146  {
147  return {FlatPreBasis<SPB, MultiIndex>::create(Impl::subPreBasis(preBasis))};
148  }
149  };
150 
151  // specialization for blocked power bases
152  template <class MI, class SPB, std::size_t C, class MultiIndex>
153  struct FlatPreBasis<Dune::Functions::PowerPreBasis
154  <MI, Dune::Functions::BasisFactory::BlockedInterleaved, SPB, C>, MultiIndex>
155  {
156  using FIMS = Dune::Functions::BasisFactory::FlatInterleaved;
157  using type = Dune::Functions::PowerPreBasis<MultiIndex, FIMS, FlatPreBasis_t<SPB, MultiIndex>, C>;
158 
159  template <class PreBasis>
160  static type create(PreBasis const& preBasis)
161  {
162  warning("Basis converted into flat index-merging strategy.");
163  return {FlatPreBasis<SPB, MultiIndex>::create(Impl::subPreBasis(preBasis))};
164  }
165  };
166 
167  // specialization for blocked power bases
168  template <class MI, class SPB, std::size_t C, class MultiIndex>
169  struct FlatPreBasis<Dune::Functions::PowerPreBasis
170  <MI, Dune::Functions::BasisFactory::BlockedLexicographic, SPB, C>, MultiIndex>
171  {
172  using FIMS = Dune::Functions::BasisFactory::FlatLexicographic;
173  using type = Dune::Functions::PowerPreBasis<MultiIndex, FIMS, FlatPreBasis_t<SPB, MultiIndex>, C>;
174 
175  template <class PreBasis>
176  static type create(PreBasis const& preBasis)
177  {
178  warning("Basis converted into flat index-merging strategy.");
179  return {FlatPreBasis<SPB, MultiIndex>::create(Impl::subPreBasis(preBasis))};
180  }
181  };
182 
183 } // end namespace AMDiS
constexpr bool MultiIndex
A multi-index type.
Definition: Concepts.hpp:150
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
Definition: FlatPreBasis.hpp:20
void test_warning(bool condition, std::string const &str, Args &&... args)
test for condition and in case of failure print message
Definition: Output.hpp:183