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