7#ifndef DUNE_FUNCTIONS_ANALYTICFUNCTIONS_MONOMIALSET_HH
8#define DUNE_FUNCTIONS_ANALYTICFUNCTIONS_MONOMIALSET_HH
12#include <dune/common/fvector.hh>
13#include <dune/common/fmatrix.hh>
14#include <dune/common/math.hh>
15#include <dune/common/rangeutilities.hh>
19namespace Dune::Functions {
24 template<
int maxDegree,
class DomainFieldType,
class RangeType>
25 void computePowers(
const DomainFieldType& x, RangeType& y)
27 if constexpr(maxDegree >= 0)
30 for(
auto k : Dune::range(maxDegree))
62 template<
class RangeFieldType,
int dimension,
int maxDegree>
65 static constexpr int dim = dimension;
66 static constexpr int size = Dune::binomial(maxDegree + dim, dim);
67 static_assert(1 <= dim && dim <= 3,
"MonomialSet is specialized for dimensions 1,2,3 only.");
80 static constexpr std::array<std::array<std::size_t,dim>,size>
exponents();
91 template<
class DomainFieldType>
92 constexpr Dune::FieldVector<RangeFieldType,size>
operator()(
const Dune::FieldVector<DomainFieldType,dim>& x)
const;
109 template<
class DomainFieldType>
110 constexpr Dune::FieldMatrix<RangeFieldType,size, dim>
operator()(
const Dune::FieldVector<DomainFieldType,dim>& x)
const;
127 template<
class DomainFieldType>
128 constexpr std::array<FieldMatrix<RangeFieldType,dim, dim>, size>
operator()(
const Dune::FieldVector<DomainFieldType,dim>& x)
const;
155 template<
class RangeFieldType,
int maxDegree>
156 struct MonomialSet<RangeFieldType, 1, maxDegree>
158 static constexpr int dim = 1;
159 static constexpr int size = maxDegree+1;
163 auto p = std::array<std::array<std::size_t,1>,size>{};
164 for(
auto k : Dune::range(size))
169 template<
class DomainFieldType>
170 constexpr auto operator()(
const Dune::FieldVector<DomainFieldType,1>& x)
const
172 auto y = Dune::FieldVector<RangeFieldType,size>{};
173 Impl::computePowers<maxDegree>(x[0], y);
179 template<
class DomainFieldType>
180 constexpr auto operator()(
const Dune::FieldVector<DomainFieldType,1>& x)
const
182 auto xPowers = Dune::FieldVector<RangeFieldType,size>{};
183 Impl::computePowers<maxDegree-1>(x[0], xPowers);
185 auto y = Dune::FieldMatrix<RangeFieldType,size,1>{};
186 for(
auto degree : Dune::range(1, maxDegree+1))
187 y[degree][0] = degree*xPowers[degree-1];
193 template<
class DomainFieldType>
194 constexpr auto operator()(
const Dune::FieldVector<DomainFieldType,1>& x)
const
196 auto xPowers = std::array<RangeFieldType,maxDegree+1>{};
197 Impl::computePowers<maxDegree-2>(x[0],xPowers);
199 auto y = std::array<Dune::FieldMatrix<RangeFieldType,1,1>,size>{};
200 for(
auto degree : Dune::range(maxDegree+1))
202 y[degree][0][0] = degree*(degree-1)*xPowers[degree-2];
208 constexpr friend auto derivative(
const Derivative& d)
215 constexpr friend auto derivative(
const MonomialSet& m)
224 template<
class RangeFieldType,
int maxDegree>
225 struct MonomialSet<RangeFieldType, 2, maxDegree>
227 static constexpr int dim = 2;
228 static constexpr int size = (maxDegree+1)*(maxDegree+2)/2;
232 auto p = std::array<std::array<std::size_t,2>,size>{};
233 std::size_t index = 0;
234 for(
auto degree : Dune::range(maxDegree+1))
236 for(
auto k : Dune::range(degree+1))
238 p[index][0] = degree-k;
246 template<
class DomainFieldType>
247 constexpr auto operator()(
const Dune::FieldVector<DomainFieldType,2>& x)
const
249 auto xPowers = std::array<Dune::FieldVector<RangeFieldType,size>,dim>{};
250 for(
auto j : Dune::range(dim))
251 Impl::computePowers<maxDegree>(x[j], xPowers[j]);
253 auto y = Dune::FieldVector<RangeFieldType,size>{};
254 std::size_t index = 0;
255 for(
auto degree : Dune::range(maxDegree+1))
257 for(
auto k : Dune::range(degree+1))
259 y[index] = xPowers[0][degree-k]*xPowers[1][k];
268 template<
class DomainFieldType>
269 constexpr auto operator()(
const Dune::FieldVector<DomainFieldType,2>& x)
const
271 auto xPowers = std::array<Dune::FieldVector<RangeFieldType,size>,dim>{};
272 for(
auto j : Dune::range(dim))
273 Impl::computePowers<maxDegree-1>(x[j], xPowers[j]);
275 auto y = Dune::FieldMatrix<RangeFieldType,size,2>{};
276 std::size_t index = 0;
277 for(
auto degree : Dune::range(maxDegree+1))
279 for(
auto k : Dune::range(degree+1))
282 y[index][0] = (degree-k)*xPowers[0][degree-k-1]*xPowers[1][k];
284 y[index][1] = k*xPowers[0][degree-k]*xPowers[1][k-1];
293 template<
class DomainFieldType>
294 constexpr auto operator()(
const Dune::FieldVector<DomainFieldType,2>& x)
const
296 auto xPowers = std::array<std::array<RangeFieldType,maxDegree+1>,dim>{};
297 for(
auto j : Dune::range(dim))
298 Impl::computePowers<maxDegree-2>(x[j], xPowers[j]);
300 auto y = std::array<Dune::FieldMatrix<RangeFieldType,2,2>,size>{};
301 std::size_t index = 0;
302 for(
auto degree : Dune::range(maxDegree+1))
304 for(
auto k : Dune::range(degree+1))
307 y[index][0][0] = (degree-k-1)*(degree-k)*xPowers[0][degree-k-2]*xPowers[1][k];
308 if (k > 0 and degree-k > 0){
309 auto mixed = k*(degree-k)*xPowers[0][degree-k-1]*xPowers[1][k-1];
310 y[index][0][1]= mixed;
311 y[index][1][0]= mixed;
314 y[index][1][1] = k*(k-1)*xPowers[0][degree-k]*xPowers[1][k-2];
324 constexpr friend auto derivative(
const Derivative & d)
331 constexpr friend auto derivative(
const MonomialSet& m)
340 template<
class RangeFieldType,
int maxDegree>
341 struct MonomialSet<RangeFieldType, 3, maxDegree>
343 static constexpr int dim = 3;
344 static constexpr int size = Dune::binomial(maxDegree + dim, dim);
348 auto p = std::array<std::array<std::size_t,3>,size>{};
349 std::size_t index = 0;
350 for(
auto degree : Dune::range(maxDegree+1))
352 for(
auto k : Dune::range(degree+1))
354 for (
auto l : Dune::range(degree-k+1))
356 p[index][0] = degree-k-l;
367 template<
class DomainFieldType>
368 constexpr auto operator()(
const Dune::FieldVector<DomainFieldType,3>& x)
const
370 auto xPowers = std::array<std::array<RangeFieldType,maxDegree+1>,dim>{};
371 for(
auto j : Dune::range(dim))
372 Impl::computePowers<maxDegree>(x[j], xPowers[j]);
374 auto y = Dune::FieldVector<RangeFieldType,size>{};
375 std::size_t index = 0;
376 for(
auto degree : Dune::range(maxDegree+1))
378 for(
auto k : Dune::range(degree+1))
380 for (
auto l : Dune::range(degree-k+1))
382 y[index] = xPowers[0][degree-k-l]*xPowers[1][l]*xPowers[2][k];
392 template<
class DomainFieldType>
393 constexpr auto operator()(
const Dune::FieldVector<DomainFieldType,3>& x)
const
395 auto xPowers = std::array<std::array<RangeFieldType,maxDegree+1>,dim>{};
396 for(
auto j : Dune::range(dim))
399 for(
auto k : Dune::range(maxDegree))
400 xPowers[j][k+1] = xPowers[j][k]*x[j];
403 auto y = Dune::FieldMatrix<RangeFieldType,size,3>{};
404 std::size_t index = 0;
405 for(
auto degree : Dune::range(maxDegree+1))
407 for(
auto k : Dune::range(degree+1))
409 for (
auto l : Dune::range(degree-k+1))
412 y[index][0] = (degree-k-l)*xPowers[0][degree-k-l-1]*xPowers[1][l]*xPowers[2][k];
414 y[index][1] = l*xPowers[0][degree-k-l]*xPowers[1][l-1]*xPowers[2][k];
416 y[index][2] = k*xPowers[0][degree-k-l]*xPowers[1][l]*xPowers[2][k-1];
426 template<
class DomainFieldType>
427 constexpr auto operator()(
const Dune::FieldVector<DomainFieldType,3>& x)
const
429 auto xPowers = std::array<std::array<RangeFieldType,maxDegree+1>,dim>{};
430 for(
auto j : Dune::range(dim))
431 Impl::computePowers<maxDegree>(x[j], xPowers[j]);
433 auto y = std::array<Dune::FieldMatrix<RangeFieldType,3,3>,size>{};
434 std::size_t index = 0;
435 for(
auto degree : Dune::range(maxDegree+1))
437 for(
auto k : Dune::range(degree+1))
439 for (
auto l : Dune::range(degree-k+1))
442 if (degree-k-l-1 > 0)
443 y[index][0][0] = (degree-k-l)*(degree-k-l-1)*xPowers[0][degree-k-l-2]*xPowers[1][l]*xPowers[2][k];
445 if (degree-k-l > 0 and l > 0){
446 y[index][0][1] = (degree-k-l)*l*xPowers[0][degree-k-l-1]*xPowers[1][l-1]*xPowers[2][k];
447 y[index][1][0] = y[index][0][1];
451 y[index][1][1] = l*(l-1)*xPowers[0][degree-k-l]*xPowers[1][l-2]*xPowers[2][k];
453 if (k > 0 and degree-k-l > 0)
455 y[index][0][2] = (degree-k-l)*k*xPowers[0][degree-k-l-1]*xPowers[1][l]*xPowers[2][k-1];
456 y[index][2][0] = y[index][0][2];
461 y[index][1][2] = l*k*xPowers[0][degree-k-l]*xPowers[1][l-1]*xPowers[2][k-1];
462 y[index][2][1] = y[index][1][2];
466 y[index][2][2] = (k-1)*k*xPowers[0][degree-k-l]*xPowers[1][l]*xPowers[2][k-2];
476 constexpr friend auto derivative(
const Derivative & d)
483 constexpr friend auto derivative(
const MonomialSet& m)
Set of all second order derivatives of monomials up to degree maxDegree as vector of matrix valued fu...
Definition: monomialset.hh:117
constexpr std::array< FieldMatrix< RangeFieldType, dim, dim >, size > operator()(const Dune::FieldVector< DomainFieldType, dim > &x) const
Return array of Matrices of monomial derivatives.
Set of all first order derivatives of monomials up to degree maxDegree as vector of vector valued fun...
Definition: monomialset.hh:99
constexpr Dune::FieldMatrix< RangeFieldType, size, dim > operator()(const Dune::FieldVector< DomainFieldType, dim > &x) const
Return array of arrays of monomial derivatives.
constexpr friend auto derivative(const Derivative &d)
Construct the Hessian object from a Derivative.
Definition: monomialset.hh:135
Function, which evaluates all monomials up to degree maxDegree in a given coordinate.
Definition: monomialset.hh:64
constexpr Dune::FieldVector< RangeFieldType, size > operator()(const Dune::FieldVector< DomainFieldType, dim > &x) const
Return array of monomial evaluations.
static constexpr std::array< std::array< std::size_t, dim >, size > exponents()
Return array of monomial exponents with shape size x dim
constexpr friend auto derivative(const MonomialSet &m)
Construct the Derivative object from a MonomialSet.
Definition: monomialset.hh:145