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
scalar_polynomials_vandermonde_base.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#include <deal.II/base/config.h>
14
17#include <deal.II/base/mpi.h>
19#include <deal.II/base/point.h>
21
23#include <deal.II/lac/vector.h>
24
25
27
28template <int dim>
30 const unsigned int degree,
31 const unsigned int n_dofs)
32 : ScalarPolynomialsBase<dim>(degree, n_dofs)
33{}
34
35
36
37template <int dim>
38void
40 const std::vector<Point<dim>> &support_points)
41{
43 support_points.size() == this->n(),
45 "The number of DoFs must be equal to the number of support points."));
46
47 // fill VDM Matrix
48 const unsigned int n = support_points.size();
49 FullMatrix<double> VDM(n);
50
51 for (unsigned i = 0; i < n; ++i)
52 for (unsigned j = 0; j < n; ++j)
53 VDM[i][j] = evaluate_orthogonal_basis_function(i, support_points[j]);
54
55 // get the inverse matrix
56 Householder<double> householder(VDM);
57 Vector<double> e(n);
58 Vector<double> x(n);
59
60 // assume e_j are unit vectors
61 // compute (VDM^-1)_ij by using (VDM^-1)_ij = e_i (VDM^-1) e_j
62 // loop over all vectors e_j
63 for (unsigned int j = 0; j < n; ++j)
64 {
65 e = 0.;
66 e[j] = 1.;
67
68 x = 0.;
69 // get x = (VDM^-1) e_j
70 householder.least_squares(x, e);
71
72 for (unsigned int i = 0; i < n; ++i)
73 // (VDM^-1)_ij = e_i (VDM^-1) e_j
74 VDM(i, j) = x[i];
75 }
76
77 vandermonde_matrix_inverse = VDM;
78
79 // clean up small values
80 for (unsigned int i = 0; i < n; ++i)
81 for (unsigned int j = 0; j < n; ++j)
82 if (std::abs(vandermonde_matrix_inverse[i][j]) < 1e-14)
83 vandermonde_matrix_inverse[i][j] = 0.;
84}
85
86
87
88template <int dim>
89double
91 const Point<dim> &p) const
92{
93 AssertIndexRange(i, vandermonde_matrix_inverse.m());
94
95 double result = 0.;
96 for (unsigned int j = 0; j < vandermonde_matrix_inverse.n(); ++j)
97 result += vandermonde_matrix_inverse[i][j] *
98 evaluate_orthogonal_basis_function(j, p);
99
100 if (std::fabs(result) < 1e-14)
101 result = 0.0;
102
103 return result;
104}
105
106
107
108template <int dim>
111 const Point<dim> &p) const
112{
113 AssertIndexRange(i, vandermonde_matrix_inverse.m());
114
115 Tensor<1, dim> grad;
116
117 grad = 0.;
118 for (unsigned int j = 0; j < vandermonde_matrix_inverse.n(); ++j)
119 grad += vandermonde_matrix_inverse[i][j] *
120 evaluate_orthogonal_basis_derivative(j, p);
121
122 if constexpr (dim > 0)
123 for (unsigned int d = 0; d < dim; ++d)
124 if (std::fabs(grad[d]) < 1e-14)
125 grad[d] = 0.0;
126
127 return grad;
128}
129
130
131
132template <int dim>
135 const unsigned int i,
136 const Point<dim> &p) const
137{
138 AssertIndexRange(i, vandermonde_matrix_inverse.m());
139
140 Tensor<2, dim> grad_grad;
141
142 grad_grad = 0.;
143 for (unsigned int j = 0; j < vandermonde_matrix_inverse.n(); ++j)
144 grad_grad += vandermonde_matrix_inverse[i][j] *
145 evaluate_orthogonal_basis_2nd_derivative(j, p);
146
147 if constexpr (dim > 0)
148 for (unsigned int d = 0; d < dim; ++d)
149 for (unsigned int e = 0; e < dim; ++e)
150 if (std::fabs(grad_grad[d][e]) < 1e-14)
151 grad_grad[d][e] = 0.0;
152
153 return grad_grad;
154}
155
156
157
158template <int dim>
159void
161 const Point<dim> &unit_point,
162 std::vector<double> &values,
163 std::vector<Tensor<1, dim>> &grads,
164 std::vector<Tensor<2, dim>> &grad_grads,
165 std::vector<Tensor<3, dim>> &third_derivatives,
166 std::vector<Tensor<4, dim>> &fourth_derivatives) const
167{
168 (void)grad_grads;
169 (void)third_derivatives;
170 (void)fourth_derivatives;
171
172 if (values.size() == this->n())
173 for (unsigned int i = 0; i < this->n(); ++i)
174 values[i] = compute_value(i, unit_point);
175
176 if (grads.size() == this->n())
177 for (unsigned int i = 0; i < this->n(); ++i)
178 grads[i] = compute_grad(i, unit_point);
179}
180
181
182
183template <int dim>
186 const unsigned int i,
187 const Point<dim> &p) const
188{
189 return compute_grad(i, p);
190}
191
192
193
194template <int dim>
197 const unsigned int i,
198 const Point<dim> &p) const
199{
200 return compute_grad_grad(i, p);
201}
202
203
204
205template <int dim>
208 const unsigned int i,
209 const Point<dim> &p) const
210{
211 (void)i;
212 (void)p;
213
215
216 return {};
217}
218
219
220
221template <int dim>
224 const unsigned int i,
225 const Point<dim> &p) const
226{
227 (void)i;
228 (void)p;
229
231
232 return {};
233}
234
235
236
237template <int dim>
241 const unsigned int j,
242 const unsigned int k,
243 const Point<dim> &p) const
244{
245 (void)i;
246 (void)j;
247 (void)k;
248 (void)p;
249
251
252 return {};
253}
254
255
256
257template <int dim>
260 const unsigned int i,
261 const Point<dim> &p) const
262{
263 (void)i;
264 (void)p;
265
267
268 return {};
269}
270
271
272
277
number2 least_squares(Vector< number2 > &dst, const Vector< number2 > &src) const
Definition point.h:111
Tensor< 2, dim > compute_2nd_derivative(const unsigned int i, const Point< dim > &p) const override
Tensor< 1, dim > compute_1st_derivative(const unsigned int i, const Point< dim > &p) const override
virtual Tensor< 2, dim > evaluate_orthogonal_basis_2nd_derivative_by_degree(const unsigned int i, const unsigned int j, const unsigned int k, const Point< dim > &p) const
void evaluate(const Point< dim > &unit_point, std::vector< double > &values, std::vector< Tensor< 1, dim > > &grads, std::vector< Tensor< 2, dim > > &grad_grads, std::vector< Tensor< 3, dim > > &third_derivatives, std::vector< Tensor< 4, dim > > &fourth_derivatives) const override
virtual Tensor< 2, dim > evaluate_orthogonal_basis_2nd_derivative(const unsigned int i, const Point< dim > &p) const
void reinit(const std::vector< Point< dim > > &support_points)
Tensor< 4, dim > compute_4th_derivative(const unsigned int i, const Point< dim > &p) const override
Tensor< 2, dim > compute_grad_grad(const unsigned int i, const Point< dim > &p) const override
ScalarPolynomialsVandermondeBase(const unsigned int degree, const unsigned int n_dofs)
Tensor< 1, dim > compute_grad(const unsigned int i, const Point< dim > &p) const override
Tensor< 3, dim > compute_3rd_derivative(const unsigned int i, const Point< dim > &p) const override
double compute_value(const unsigned int i, const Point< dim > &p) const override
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcNotImplemented()
#define AssertIndexRange(index, range)
#define AssertThrow(cond, exc)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)