1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3
4 #ifdef HAVE_CONFIG_H
5 #include "config.h"
6 #endif
7
8 #include <iostream>
9
10 #include <dune/common/filledarray.hh>
11 #include <dune/common/parallel/mpihelper.hh>
12
13 #include <dune/grid/yaspgrid.hh>
14
15 #include <dune/pdelab.hh>
16
17 // Wrapped Qk local basis which can have a zero size on some elements
18 template <class T, int k, int d> struct WrappedBasis {
19 using Basis = Dune::QkStuff::QkLocalBasis<T, T, k, d>;
20
21 Basis basis;
22 bool setZero;
23
WrappedBasisWrappedBasis24 WrappedBasis() : setZero(false) {}
25
sizeWrappedBasis26 unsigned int size() const { return setZero ? 0 : basis.size(); }
27
28 inline void
evaluateFunctionWrappedBasis29 evaluateFunction(const typename Basis::Traits::DomainType &in,
30 std::vector<typename Basis::Traits::RangeType> &out) const {
31 if (setZero)
32 out.clear();
33 else
34 basis.evaluateFunction(in, out);
35 }
36
evaluateJacobianWrappedBasis37 void evaluateJacobian(
38 const typename Basis::Traits::DomainType &in,
39 std::vector<typename Basis::Traits::JacobianType> &out) const {
40 if (setZero)
41 out.clear();
42 else
43 basis.evaluateFunction(in, out);
44 }
45
orderWrappedBasis46 unsigned int order() const { return setZero ? 0 : basis.order(); }
47 };
48
49 // wrapped QkDG local coefficients which can have a zero size on some elements
50 template <int k, int d> struct WrappedCoefficients {
51 using Coefficients = Dune::QkStuff::QkDGLocalCoefficients<k, d>;
52
53 Coefficients coeffs;
54 bool setZero;
55
WrappedCoefficientsWrappedCoefficients56 WrappedCoefficients() : setZero(false) {}
57
sizeWrappedCoefficients58 std::size_t size() const { return setZero ? 0 : coeffs.size(); }
59
localKeyWrappedCoefficients60 const Dune::LocalKey &localKey(std::size_t i) const {
61 if (setZero) {
62 DUNE_THROW(Dune::Exception, "set zero");
63 } else {
64 return coeffs.localKey(i);
65 }
66 }
67 };
68
69 // wrapped Qk local interpolation which can have a zero size on some elements
70 template <class T, int k, int d> struct WrappedInterpolation {
71 using Interpolation = Dune::QkStuff::QkLocalInterpolation<
72 k, d, Dune::QkStuff::QkLocalBasis<T, T, k, d>>;
73
74 Interpolation interpolation;
75 bool setZero;
76
WrappedInterpolationWrappedInterpolation77 WrappedInterpolation() : setZero(false) {}
78
79 template <typename F, typename C>
interpolateWrappedInterpolation80 void interpolate(const F &f, std::vector<C> &out) const {
81 if (setZero)
82 out.clear();
83 else
84 interpolation.interpolate(f, out);
85 }
86 };
87
88 // wrapped Qk local finite element which can have a zero size on some elements
89 template <class T, int k, int d> class WrappedFiniteElement {
90 using Basis = WrappedBasis<T, k, d>;
91 using Coefficients = WrappedCoefficients<k, d>;
92 using Interpolation = WrappedInterpolation<T, k, d>;
93
94 public:
95 typedef Dune::LocalFiniteElementTraits<Basis, Coefficients, Interpolation>
96 Traits;
97
WrappedFiniteElement()98 WrappedFiniteElement()
99 : gt(Dune::GeometryTypes::cube(d))
100 {}
101
localBasis() const102 const typename Traits::LocalBasisType &localBasis() const { return basis; }
103
localCoefficients() const104 const typename Traits::LocalCoefficientsType &localCoefficients() const {
105 return coefficients;
106 }
107
localInterpolation() const108 const typename Traits::LocalInterpolationType &localInterpolation() const {
109 return interpolation;
110 }
111
type() const112 Dune::GeometryType type() const { return gt; }
113
clone() const114 WrappedFiniteElement *clone() const {
115 return new WrappedFiniteElement(*this);
116 }
117
setZero(bool value)118 void setZero(bool value) {
119 basis.setZero = value;
120 coefficients.setZero = value;
121 interpolation.setZero = value;
122 }
123
124 private:
125 Basis basis;
126 Coefficients coefficients;
127 Interpolation interpolation;
128 Dune::GeometryType gt;
129 };
130
131 // wrapped QkDG local finite element map which has no local basis functions on
132 // elements with an even
133 // index
134 template <class GV, class T, int k, int d>
135 class WrappedFiniteElementMap
136 : public Dune::PDELab::LocalFiniteElementMapInterface<
137 Dune::PDELab::LocalFiniteElementMapTraits<
138 WrappedFiniteElement<T, k, d>>,
139 WrappedFiniteElementMap<GV, T, k, d>> {
140
141 public:
142 using Traits =
143 Dune::PDELab::LocalFiniteElementMapTraits<WrappedFiniteElement<T, k, d>>;
144
WrappedFiniteElementMap(const GV & gv_,unsigned int rank_)145 WrappedFiniteElementMap(const GV &gv_, unsigned int rank_)
146 : gv(gv_), rank(rank_) {}
147
fixedSize() const148 bool fixedSize() const { return false; }
149
hasDOFs(int codim) const150 bool hasDOFs(int codim) const { return codim == 0; }
151
size(Dune::GeometryType gt) const152 std::size_t size(Dune::GeometryType gt) const {
153 DUNE_THROW(Dune::PDELab::VariableElementSize,
154 "the fem has variable element size");
155 }
156
maxLocalSize() const157 std::size_t maxLocalSize() const {
158 return Dune::QkStuff::QkSize<k, d>::value;
159 }
160
161 template <class EntityType>
find(const EntityType & e) const162 const typename Traits::FiniteElementType &find(const EntityType &e) const {
163 fe.setZero(gv.indexSet().index(e) % rank != 0);
164 return fe;
165 }
166
167 private:
168 mutable WrappedFiniteElement<T, k, d> fe;
169 GV gv;
170 unsigned int rank;
171 };
172
main(int argc,char ** argv)173 int main(int argc, char **argv) {
174 try {
175 // Maybe initialize Mpi
176 Dune::MPIHelper::instance(argc, argv);
177
178 const int dim = 2;
179
180 Dune::FieldVector<double, dim> L(1.0);
181 Dune::YaspGrid<dim> grid(L, Dune::filledArray<dim, int>(2));
182
183 const int degree = 1;
184 const int blockSize = Dune::QkStuff::QkSize<degree, dim>::value;
185
186 using GV = Dune::YaspGrid<dim>::LeafGridView;
187 using ES = Dune::PDELab::AllEntitySet<GV>;
188 using FEM = WrappedFiniteElementMap<GV, double, degree, dim>;
189 using VBE =
190 Dune::PDELab::ISTL::VectorBackend<Dune::PDELab::ISTL::Blocking::fixed,
191 blockSize>;
192 using GFS =
193 Dune::PDELab::GridFunctionSpace<ES, FEM, Dune::PDELab::NoConstraints,
194 VBE>;
195 using PVBE = Dune::PDELab::ISTL::VectorBackend<>;
196 using POT =
197 Dune::PDELab::ordering::Chunked<Dune::PDELab::EntityBlockedOrderingTag>;
198 using PGFS = Dune::PDELab::PowerGridFunctionSpace<
199 GFS, 2, Dune::PDELab::ISTL::VectorBackend<>, POT>;
200
201 GV gv = grid.leafGridView();
202 FEM fem0(gv, 2);
203 FEM fem1(gv, 3);
204 ES es{gv};
205 auto gfs0 = std::make_shared<GFS>(es, fem0);
206 auto gfs1 = std::make_shared<GFS>(es, fem1);
207
208 {
209 PGFS pgfs(*gfs0, *gfs1, PVBE(), POT(blockSize));
210 pgfs.ordering();
211 }
212
213 {
214 std::array<std::shared_ptr<GFS>,2> containter{gfs0,gfs1};
215 PGFS pgfs(containter, PVBE(), POT(blockSize));
216 pgfs.ordering();
217 }
218
219 return 0;
220 } catch (Dune::Exception &e) {
221 std::cerr << "Dune reported error: " << e << std::endl;
222 return 1;
223 } catch (...) {
224 std::cerr << "Unknown exception thrown!" << std::endl;
225 return 1;
226 }
227 }
228