22#include <boost/container/small_vector.hpp>
38 template <std::
size_t dim>
43 std::array<unsigned int, dim> &)
52 std::array<unsigned int, 1> &indices)
61 std::array<unsigned int, 2> &indices)
71 std::array<unsigned int, 3> &indices)
82template <
int dim,
typename PolynomialType>
86 std::array<unsigned int, dim> &indices)
const
88 Assert(i < Utilities::fixed_power<dim>(polynomials.size()),
90 internal::compute_tensor_index(index_map[i],
102 std::array<unsigned int, 0> &)
const
104 constexpr int dim = 0;
110template <
int dim,
typename PolynomialType>
113 std::ostream &out)
const
115 std::array<unsigned int, dim>
ix;
116 for (
unsigned int i = 0; i < this->n(); ++i)
118 compute_index(i,
ix);
120 for (
unsigned int d = 0; d < dim; ++d)
131 std::ostream &)
const
133 constexpr int dim = 0;
139template <
int dim,
typename PolynomialType>
142 const std::vector<unsigned int> &renumber)
144 Assert(renumber.size() == index_map.size(),
147 index_map = renumber;
148 for (
unsigned int i = 0; i < index_map.size(); ++i)
149 index_map_inverse[index_map[i]] = i;
157 const std::vector<unsigned int> &)
159 constexpr int dim = 0;
165template <
int dim,
typename PolynomialType>
168 const unsigned int i,
173 std::array<unsigned int, dim> indices;
174 compute_index(i, indices);
177 for (
unsigned int d = 0; d < dim; ++d)
178 value *= polynomials[indices[d]].value(p(d));
191 constexpr int dim = 0;
199template <
int dim,
typename PolynomialType>
202 const unsigned int i,
205 std::array<unsigned int, dim> indices;
206 compute_index(i, indices);
214 std::vector<double> tmp(2);
215 for (
unsigned int d = 0; d < dim; ++d)
217 polynomials[indices[d]].value(p(d), tmp);
224 for (
unsigned int d = 0; d < dim; ++d)
227 for (
unsigned int x = 0;
x < dim; ++
x)
242 constexpr int dim = 0;
250template <
int dim,
typename PolynomialType>
253 const unsigned int i,
256 std::array<unsigned int, dim> indices;
257 compute_index(i, indices);
261 std::vector<double> tmp(3);
262 for (
unsigned int d = 0; d < dim; ++d)
264 polynomials[indices[d]].value(p(d), tmp);
272 for (
unsigned int d1 = 0;
d1 < dim; ++
d1)
273 for (
unsigned int d2 = 0;
d2 < dim; ++
d2)
276 for (
unsigned int x = 0;
x < dim; ++
x)
278 unsigned int derivative = 0;
306template <
int dim,
typename PolynomialType>
310 std::vector<double> & values,
317 Assert(values.size() ==
this->n() || values.size() == 0,
353 const unsigned int n_polynomials = polynomials.
size();
354 boost::container::small_vector<ndarray<double, dim, 5>, 20>
values_1d(
357 for (
unsigned int i = 0; i < n_polynomials; ++i)
358 for (
unsigned int d = 0; d < dim; ++d)
359 values_1d[i][d][0] = polynomials[i].value(p(d));
361 for (
unsigned int i = 0; i < n_polynomials; ++i)
362 for (
unsigned d = 0; d < dim; ++d)
363 polynomials[i].value(p(d),
367 unsigned int indices[3];
368 unsigned int ind = 0;
369 for (indices[2] = 0; indices[2] < (dim > 2 ? n_polynomials : 1); ++indices[2])
370 for (indices[1] = 0; indices[1] < (dim > 1 ? n_polynomials : 1);
373 for (indices[0] = 0; indices[0] < n_polynomials; ++indices[0], ++
ind)
375 double value =
values_1d[indices[0]][0][0];
376 for (
unsigned int d = 1; d < dim; ++d)
378 values[index_map_inverse[
ind]] = value;
381 for (indices[0] = 0; indices[0] < n_polynomials; ++indices[0], ++
ind)
383 const unsigned int i = index_map_inverse[
ind];
387 double value =
values_1d[indices[0]][0][0];
388 for (
unsigned int x = 1;
x < dim; ++
x)
394 for (
unsigned int d = 0; d < dim; ++d)
397 for (
unsigned int x = 0;
x < dim; ++
x)
403 for (
unsigned int d1 = 0;
d1 < dim; ++
d1)
404 for (
unsigned int d2 = 0;
d2 < dim; ++
d2)
407 for (
unsigned int x = 0;
x < dim; ++
x)
409 unsigned int derivative = 0;
421 for (
unsigned int d1 = 0;
d1 < dim; ++
d1)
422 for (
unsigned int d2 = 0;
d2 < dim; ++
d2)
423 for (
unsigned int d3 = 0;
d3 < dim; ++
d3)
426 for (
unsigned int x = 0;
x < dim; ++
x)
428 unsigned int derivative = 0;
442 for (
unsigned int d1 = 0;
d1 < dim; ++
d1)
443 for (
unsigned int d2 = 0;
d2 < dim; ++
d2)
444 for (
unsigned int d3 = 0;
d3 < dim; ++
d3)
445 for (
unsigned int d4 = 0;
d4 < dim; ++
d4)
448 for (
unsigned int x = 0;
x < dim; ++
x)
450 unsigned int derivative = 0;
473 std::vector<double> &,
479 constexpr int dim = 0;
485template <
int dim,
typename PolynomialType>
486std::unique_ptr<ScalarPolynomialsBase<dim>>
489 return std::make_unique<TensorProductPolynomials<dim, PolynomialType>>(*this);
494template <
int dim,
typename PolynomialType>
505template <
int dim,
typename PolynomialType>
506std::vector<PolynomialType>
529 ExcMessage(
"The number of polynomials must be larger than zero "
530 "for all coordinate directions."));
539 const unsigned int i,
540 std::array<unsigned int, dim> &indices)
const
544 for (
unsigned int d = 0; d < dim; ++d)
552 internal::compute_tensor_index(i,
553 polynomials[0].
size(),
557 internal::compute_tensor_index(i,
558 polynomials[0].
size(),
559 polynomials[1].
size(),
568 std::array<unsigned int, 0> &)
const
570 constexpr int dim = 0;
581 std::array<unsigned int, dim> indices;
582 compute_index(i, indices);
585 for (
unsigned int d = 0; d < dim; ++d)
586 value *= polynomials[d][indices[d]].value(p(d));
598 constexpr int dim = 0;
611 std::array<unsigned int, dim> indices;
612 compute_index(i, indices);
619 for (
unsigned int d = 0; d < dim; ++d)
620 polynomials[d][indices[d]].value(p(d), 1, v[d].
data());
623 for (
unsigned int d = 0; d < dim; ++d)
626 for (
unsigned int x = 0;
x < dim; ++
x)
640 constexpr int dim = 0;
653 std::array<unsigned int, dim> indices;
654 compute_index(i, indices);
657 for (
unsigned int d = 0; d < dim; ++d)
658 polynomials[d][indices[d]].value(p(d), 2, v[d].
data());
661 for (
unsigned int d1 = 0;
d1 < dim; ++
d1)
662 for (
unsigned int d2 = 0;
d2 < dim; ++
d2)
665 for (
unsigned int x = 0;
x < dim; ++
x)
667 unsigned int derivative = 0;
689 constexpr int dim = 0;
701 std::vector<double> & values,
707 Assert(values.size() ==
this->n() || values.size() == 0,
745 for (
unsigned int d = 0; d < dim; ++d)
750 for (
unsigned int d = 0; d < dim; ++d)
751 for (
unsigned int i = 0; i < polynomials[d].size(); ++i)
752 polynomials[d][i].value(p(d),
756 for (
unsigned int i = 0; i < this->n(); ++i)
762 std::array<unsigned int, dim> indices;
763 compute_index(i, indices);
768 for (
unsigned int x = 0;
x < dim; ++
x)
769 values[i] *= v(
x, indices[
x])[0];
773 for (
unsigned int d = 0; d < dim; ++d)
776 for (
unsigned int x = 0;
x < dim; ++
x)
777 grads[i][d] *= v(
x, indices[
x])[d ==
x ? 1 : 0];
781 for (
unsigned int d1 = 0;
d1 < dim; ++
d1)
782 for (
unsigned int d2 = 0;
d2 < dim; ++
d2)
785 for (
unsigned int x = 0;
x < dim; ++
x)
787 unsigned int derivative = 0;
798 for (
unsigned int d1 = 0;
d1 < dim; ++
d1)
799 for (
unsigned int d2 = 0;
d2 < dim; ++
d2)
800 for (
unsigned int d3 = 0;
d3 < dim; ++
d3)
803 for (
unsigned int x = 0;
x < dim; ++
x)
805 unsigned int derivative = 0;
814 v(
x, indices[
x])[derivative];
819 for (
unsigned int d1 = 0;
d1 < dim; ++
d1)
820 for (
unsigned int d2 = 0;
d2 < dim; ++
d2)
821 for (
unsigned int d3 = 0;
d3 < dim; ++
d3)
822 for (
unsigned int d4 = 0;
d4 < dim; ++
d4)
825 for (
unsigned int x = 0;
x < dim; ++
x)
827 unsigned int derivative = 0;
838 v(
x, indices[
x])[derivative];
849 std::vector<double> &,
855 constexpr int dim = 0;
867 for (
unsigned int d = 0; d < dim; ++d)
879 constexpr int dim = 0;
888std::unique_ptr<ScalarPolynomialsBase<dim>>
891 return std::make_unique<AnisotropicPolynomials<dim>>(*this);
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
double compute_value(const unsigned int i, const Point< dim > &p) const override
AnisotropicPolynomials(const std::vector< std::vector< Polynomials::Polynomial< double > > > &base_polynomials)
static unsigned int get_n_tensor_pols(const std::vector< std::vector< Polynomials::Polynomial< double > > > &pols)
void compute_index(const unsigned int i, std::array< unsigned int, dim > &indices) const
Tensor< 2, dim > compute_grad_grad(const unsigned int i, const Point< dim > &p) const override
Tensor< 1, dim > compute_grad(const unsigned int i, const Point< dim > &p) const override
virtual std::unique_ptr< ScalarPolynomialsBase< dim > > clone() const override
value_type * data() const noexcept
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
void output_indices(std::ostream &out) const
void compute_index(const unsigned int i, std::array< unsigned int, dim > &indices) const
double compute_value(const unsigned int i, const Point< dim > &p) const override
virtual std::size_t memory_consumption() const override
Tensor< 1, dim > compute_grad(const unsigned int i, const Point< dim > &p) const override
virtual std::unique_ptr< ScalarPolynomialsBase< dim > > clone() const override
std::vector< PolynomialType > get_underlying_polynomials() const
void set_numbering(const std::vector< unsigned int > &renumber)
Tensor< 2, dim > compute_grad_grad(const unsigned int i, const Point< dim > &p) const override
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch2(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
@ update_values
Shape function values.
@ update_3rd_derivatives
Third derivatives of shape functions.
std::enable_if_t< std::is_fundamental< T >::value, std::size_t > memory_consumption(const T &t)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)