Gyselalib++
 
Loading...
Searching...
No Matches
bernstein.hpp
1#pragma once
2#include <ddc/ddc.hpp>
3
4#include <sll/mapping/cartesian_to_barycentric.hpp>
5#include <sll/math_tools.hpp>
6#include <sll/view.hpp>
7
27template <class X, class Y, class Corner1Tag, class Corner2Tag, class Corner3Tag, std::size_t D>
29{
30public:
33
40 static constexpr std::size_t rank()
41 {
42 return 2;
43 }
44
49 static constexpr std::size_t degree() noexcept
50 {
51 return D;
52 }
53
58 static constexpr std::size_t nbasis()
59 {
60 return (D + 1) * (D + 2) / 2;
61 }
62
68 template <class DDim, class MemorySpace>
69 class Impl
70 {
71 template <class ODDim, class OMemorySpace>
72 friend class Impl;
73
74 private:
76
77 public:
80
82 using discrete_element_type = ddc::DiscreteElement<DDim>;
83
85 using discrete_domain_type = ddc::DiscreteDomain<DDim>;
86
88 using discrete_vector_type = ddc::DiscreteVector<DDim>;
89
96 : m_coord_changer(coord_changer)
97 {
98 }
99
105 template <class OriginMemorySpace>
107 : m_coord_changer(impl.m_coord_changer)
108 {
109 }
110
115 Impl(Impl const& x) = default;
116
121 Impl(Impl&& x) = default;
122
123 ~Impl() = default;
124
131 Impl& operator=(Impl const& x) = default;
132
139 Impl& operator=(Impl&& x) = default;
140
147 ddc::ChunkSpan<double, ddc::DiscreteDomain<DDim>> values,
148 ddc::Coordinate<X, Y> const& x) const;
149 };
150};
151
152template <class X, class Y, class Corner1Tag, class Corner2Tag, class Corner3Tag, std::size_t D>
153template <class DDim, class MemorySpace>
156 ddc::ChunkSpan<double, ddc::DiscreteDomain<DDim>> values,
157 ddc::Coordinate<X, Y> const& x) const
158{
159 const ddc::Coordinate<Corner1Tag, Corner2Tag, Corner3Tag> bary_coords = m_coord_changer(x);
160 const double l1 = ddc::get<Corner1Tag>(bary_coords);
161 const double l2 = ddc::get<Corner2Tag>(bary_coords);
162 const double l3 = ddc::get<Corner3Tag>(bary_coords);
163 assert(values.size() == nbasis());
164
165 ddc::DiscreteElement<DDim> idx(0);
166 for (std::size_t i(0); i < D + 1; ++i) {
167 for (std::size_t j(0); j < D + 1 - i; ++j, ++idx) {
168 const int k = D - i - j;
169 const double multinomial_coefficient
170 = factorial(D) / (factorial(i) * factorial(j) * factorial(k));
171 values(idx) = multinomial_coefficient * ipow(l1, i) * ipow(l2, j) * ipow(l3, k);
172 }
173 }
174}
A class to convert cartesian coordinates to barycentric coordinates on a triangle.
Definition cartesian_to_barycentric.hpp:22
The Impl class holds the implementation of the TriangularBernsteinPolynomialBasis.
Definition bernstein.hpp:70
Impl & operator=(Impl const &x)=default
Copy-assign the class.
ddc::DiscreteVector< DDim > discrete_vector_type
The type of an index step from one element of the basis to another.
Definition bernstein.hpp:88
Impl(Impl const &x)=default
Construct the basis by copy.
Impl(Impl &&x)=default
Construct the basis from an r-value.
void eval_basis(ddc::ChunkSpan< double, ddc::DiscreteDomain< DDim > > values, ddc::Coordinate< X, Y > const &x) const
Evaluate the basis at the given coordinate.
Definition bernstein.hpp:155
Impl & operator=(Impl &&x)=default
Move-assign the class.
Impl(CartesianToBarycentric< X, Y, Corner1Tag, Corner2Tag, Corner3Tag > const &coord_changer)
Construct the basis from the barycentric coordinate mapping.
Definition bernstein.hpp:95
ddc::DiscreteDomain< DDim > discrete_domain_type
The type of the index range of the basis.
Definition bernstein.hpp:85
Impl(Impl< DDim, OriginMemorySpace > const &impl)
Construct the basis by copy.
Definition bernstein.hpp:106
ddc::DiscreteElement< DDim > discrete_element_type
The type of an index of an element of the basis.
Definition bernstein.hpp:82
A class which evaluates the triangular Bernstein polynomials.
Definition bernstein.hpp:29
static constexpr std::size_t rank()
The rank of the system of equations.
Definition bernstein.hpp:40
static constexpr std::size_t nbasis()
The number of basis elements.
Definition bernstein.hpp:58
static constexpr std::size_t degree() noexcept
The degree of the triangular Bernstein polynomials.
Definition bernstein.hpp:49