deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
polynomials_wedge.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2020 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13
14#include <deal.II/base/config.h>
15
18#include <deal.II/base/mpi.h>
20#include <deal.II/base/point.h>
25#include <deal.II/base/table.h>
26#include <deal.II/base/tensor.h>
28
29#include <Kokkos_Macros.hpp>
30
31#include <algorithm>
32#include <cmath>
33#include <cstdlib>
34#include <memory>
35#include <string>
36#include <vector>
37
39
40
41
42template <int dim>
44 const unsigned int degree,
45 const std::vector<Point<dim>> &support_points)
46 : ScalarPolynomialsVandermondeBase<dim>(degree, support_points.size())
47{
48 AssertDimension(dim, 3);
49
50 const unsigned int n_dofs = (degree + 1) * (degree + 1) * (degree + 2) / 2;
51 AssertDimension(n_dofs, support_points.size());
52
53 this->reinit(support_points);
54}
55
56
57
58template <int dim>
60 const unsigned int degree)
62 internal::get_wedge_support_points<dim>(
63 degree))
64{
66 degree == 1 || degree == 2,
68 "This constructor only works for linear and quadratic elements."));
69}
70
71
72
73template <int dim>
74double
76 dim>::evaluate_orthogonal_basis_function_by_degree(const unsigned int i,
77 const unsigned int j,
78 const unsigned int k,
79 const Point<dim> &p) const
80{
81 AssertIndexRange(i + j, this->degree() + 1);
82 AssertIndexRange(k, this->degree() + 1);
83
84 const double x = p[0];
85 const double y = p[1];
86 const double z = p[2];
87
88 // the basis function looks like
89 // P_i^{0,0}(2x/(1-y)-1) * (1-y)^i * P_j^{2*i+1,0}(2*y-1) * P_k^{0,0}(2z-1)
90 // separate it into
91 // P_i^{0,0}(2x/(1-y)-1) * (1-y)^i
92 // P_j^{2*i+1,0}(2*y-1)
93 // P_k^{0,0}(2z-1)
94 // the first is a homogenized Jacobi polynomial
95 // define s = 1 - y so the first term can be written as
96 // Q_i^{0,0}(x,s) = P_i^{0,0}(2 * x/s - 1) * s^i
97 const double s = 1 - y;
98
99 const double Qi =
100 Polynomials::jacobi_polynomial_homogenized_value<double>(i, 0, 0, x, s);
101
102 const double Pj =
103 Polynomials::jacobi_polynomial_value<double>(j, 2 * i + 1, 0, y, true);
104
105 const double Pk =
106 Polynomials::jacobi_polynomial_value<double>(k, 0, 0, z, true);
107
108 const double phi = Qi * Pj * Pk;
109
110 if (std::fabs(phi) < 1e-14)
111 return 0.0;
112
113 return phi;
114}
115
116
117
118template <int dim>
119double
121 const unsigned int i,
122 const Point<dim> &p) const
123{
124 AssertIndexRange(i, this->n());
125
126 // find corresponding entry to i
127 // it holds 0 <= j + k <= degree
128 // 0 <= l <= degree
129 for (unsigned int j = 0, counter = 0; j < this->degree() + 1; ++j)
130 for (unsigned int k = 0; k < this->degree() + 1 - j; ++k)
131 for (unsigned int l = 0; l < this->degree() + 1; ++l, ++counter)
132 if (counter == i)
133 return evaluate_orthogonal_basis_function_by_degree(j, k, l, p);
134
136 return 0;
137}
138
139
140
141template <int dim>
145 const unsigned int j,
146 const unsigned int k,
147 const Point<dim> &p) const
148{
149 AssertIndexRange(i + j, this->degree() + 1);
150 AssertIndexRange(k, this->degree() + 1);
151
152 Tensor<1, dim> grad;
153
154 const double x = p[0];
155 const double y = p[1];
156 const double z = p[2];
157
158 // the basis function looks like
159 // P_i^{0,0}(2x/(1-y)-1) * (1-y)^i * P_j^{2*i+1,0}(2*y-1) * P_k^{0,0}(2z-1)
160 // separate it into
161 // P_i^{0,0}(2x/(1-y)-1) * (1-y)^i
162 // and
163 // P_j^{2*i+1,0}(2*y-1)
164 // the first is a homogenized Jacobi polynomial
165 // define s = 1 - y so the first term can be written as
166 // Q_i^{0,0}(x,s) = P_i^{0,0}(2 * x/s - 1) * s^i
167
168 // to get the derivatives just use the product rule with all terms
169 const double s = 1 - y;
170 const double ds_dy = -1.0;
171
172 const double Qi =
173 Polynomials::jacobi_polynomial_homogenized_value<double>(i, 0, 0, x, s);
174 const double Pj =
175 Polynomials::jacobi_polynomial_value<double>(j, 2 * i + 1, 0, y, true);
176 const double Pk =
177 Polynomials::jacobi_polynomial_value<double>(k, 0, 0, z, true);
178
179 const auto dQi_dx =
180 Polynomials::jacobi_polynomial_homogenized_derivative<double>(
181 1, 0, i, 0, 0, x, s);
182
183 const auto dQi_ds =
184 Polynomials::jacobi_polynomial_homogenized_derivative<double>(
185 0, 1, i, 0, 0, x, s);
186
187 const auto dPj_dy =
188 Polynomials::jacobi_polynomial_derivative<double>(j, 2 * i + 1, 0, y, true);
189
190 const double dPk_dz =
191 Polynomials::jacobi_polynomial_derivative<double>(k, 0, 0, z, true);
192
193 grad[0] = dQi_dx * Pj * Pk;
194 if constexpr (dim > 1)
195 grad[1] = dQi_ds * ds_dy * Pj * Pk + Qi * dPj_dy * Pk;
196 if constexpr (dim > 2)
197 grad[2] = Qi * Pj * dPk_dz;
198
199 for (unsigned int d = 0; d < dim; ++d)
200 if (std::fabs(grad[d]) < 1e-14)
201 grad[d] = 0.0;
202
203 return grad;
204}
205
206
207
208template <int dim>
211 const unsigned int i,
212 const Point<dim> &p) const
213{
214 AssertIndexRange(i, this->n());
215
216 // find corresponding entry to i
217 // it holds 0 <= j + k <= degree
218 // 0 <= l <= degree
219 for (unsigned int j = 0, counter = 0; j < this->degree() + 1; ++j)
220 for (unsigned int k = 0; k < this->degree() + 1 - j; ++k)
221 for (unsigned int l = 0; l < this->degree() + 1; ++l, ++counter)
222 if (counter == i)
223 if (counter == i)
224 return evaluate_orthogonal_basis_derivative_by_degree(j, k, l, p);
225
227 return Tensor<1, dim>();
228}
229
230
231
232template <int dim>
233std::string
235{
236 return "ScalarLagrangePolynomialWedge";
237}
238
239
240
241template <int dim>
242std::unique_ptr<ScalarPolynomialsBase<dim>>
244{
245 return std::make_unique<ScalarLagrangePolynomialWedge<dim>>(*this);
246}
247
248
249
253
Definition point.h:111
std::string name() const override
Tensor< 1, dim > evaluate_orthogonal_basis_derivative(const unsigned int i, const Point< dim > &p) const override
virtual std::unique_ptr< ScalarPolynomialsBase< dim > > clone() const override
double evaluate_orthogonal_basis_function(const unsigned int i, const Point< dim > &p) const override
ScalarLagrangePolynomialWedge(const unsigned int degree, const std::vector< Point< dim > > &support_points)
Tensor< 1, dim > evaluate_orthogonal_basis_derivative_by_degree(const unsigned int i, const unsigned int j, const unsigned int k, const Point< dim > &p) const override
virtual unsigned int degree() const
void reinit(const std::vector< Point< dim > > &support_points)
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_ASSERT_UNREACHABLE()
static ::ExceptionBase & ExcNotImplemented()
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
#define AssertThrow(cond, exc)
std::size_t size
Definition mpi.cc:733