deal.II version GIT relicensing-2287-g6548a49e0a 2024-12-20 18:30:00+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
tensor_product_polynomials.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2000 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_tensor_product_polynomials_h
16#define dealii_tensor_product_polynomials_h
17
18
19#include <deal.II/base/config.h>
20
23#include <deal.II/base/point.h>
26#include <deal.II/base/tensor.h>
28
29#include <vector>
30
32
33// Forward declarations for friends
34// TODO: We may be able to modify these classes so they aren't
35// required to be friends
36template <int dim>
38template <int dim>
40
74template <int dim, typename PolynomialType = Polynomials::Polynomial<double>>
76{
77public:
82 static constexpr unsigned int dimension = dim;
83
90 template <class Pol>
91 TensorProductPolynomials(const std::vector<Pol> &pols);
92
96 void
97 output_indices(std::ostream &out) const;
98
103 void
104 set_numbering(const std::vector<unsigned int> &renumber);
105
109 const std::vector<unsigned int> &
111
115 const std::vector<unsigned int> &
117
130 void
131 evaluate(const Point<dim> &unit_point,
132 std::vector<double> &values,
133 std::vector<Tensor<1, dim>> &grads,
134 std::vector<Tensor<2, dim>> &grad_grads,
135 std::vector<Tensor<3, dim>> &third_derivatives,
136 std::vector<Tensor<4, dim>> &fourth_derivatives) const override;
137
150 double
151 compute_value(const unsigned int i, const Point<dim> &p) const override;
152
167 template <int order>
169 compute_derivative(const unsigned int i, const Point<dim> &p) const;
170
174 virtual Tensor<1, dim>
175 compute_1st_derivative(const unsigned int i,
176 const Point<dim> &p) const override;
177
181 virtual Tensor<2, dim>
182 compute_2nd_derivative(const unsigned int i,
183 const Point<dim> &p) const override;
184
188 virtual Tensor<3, dim>
189 compute_3rd_derivative(const unsigned int i,
190 const Point<dim> &p) const override;
191
195 virtual Tensor<4, dim>
196 compute_4th_derivative(const unsigned int i,
197 const Point<dim> &p) const override;
198
212 compute_grad(const unsigned int i, const Point<dim> &p) const override;
213
227 compute_grad_grad(const unsigned int i, const Point<dim> &p) const override;
228
232 std::string
233 name() const override;
234
238 virtual std::unique_ptr<ScalarPolynomialsBase<dim>>
239 clone() const override;
240
244 virtual std::size_t
245 memory_consumption() const override;
246
251 std::vector<PolynomialType>
253
254protected:
258 std::vector<PolynomialType> polynomials;
259
263 std::vector<unsigned int> index_map;
264
268 std::vector<unsigned int> index_map_inverse;
269
276 void
277 compute_index(const unsigned int i,
278 std::array<unsigned int, dim> &indices) const;
279
284 friend class TensorProductPolynomialsBubbles<dim>;
285
290 friend class TensorProductPolynomialsConst<dim>;
291};
292
293
294
320template <int dim>
322{
323public:
340 const std::vector<std::vector<Polynomials::Polynomial<double>>>
341 &base_polynomials);
342
347 void
348 set_numbering(const std::vector<unsigned int> &renumber);
349
353 const std::vector<unsigned int> &
354 get_numbering() const;
355
359 const std::vector<unsigned int> &
360 get_numbering_inverse() const;
361
375 void
376 evaluate(const Point<dim> &unit_point,
377 std::vector<double> &values,
378 std::vector<Tensor<1, dim>> &grads,
379 std::vector<Tensor<2, dim>> &grad_grads,
380 std::vector<Tensor<3, dim>> &third_derivatives,
381 std::vector<Tensor<4, dim>> &fourth_derivatives) const override;
382
395 double
396 compute_value(const unsigned int i, const Point<dim> &p) const override;
397
412 template <int order>
414 compute_derivative(const unsigned int i, const Point<dim> &p) const;
415
419 virtual Tensor<1, dim>
420 compute_1st_derivative(const unsigned int i,
421 const Point<dim> &p) const override;
422
426 virtual Tensor<2, dim>
427 compute_2nd_derivative(const unsigned int i,
428 const Point<dim> &p) const override;
429
433 virtual Tensor<3, dim>
434 compute_3rd_derivative(const unsigned int i,
435 const Point<dim> &p) const override;
436
440 virtual Tensor<4, dim>
441 compute_4th_derivative(const unsigned int i,
442 const Point<dim> &p) const override;
443
457 compute_grad(const unsigned int i, const Point<dim> &p) const override;
458
472 compute_grad_grad(const unsigned int i, const Point<dim> &p) const override;
473
477 std::string
478 name() const override;
479
483 virtual std::unique_ptr<ScalarPolynomialsBase<dim>>
484 clone() const override;
485
486private:
490 const std::vector<std::vector<Polynomials::Polynomial<double>>> polynomials;
491
495 std::vector<unsigned int> index_map;
496
500 std::vector<unsigned int> index_map_inverse;
501
508 void
509 compute_index(const unsigned int i,
510 std::array<unsigned int, dim> &indices) const;
511
515 static unsigned int
517 const std::vector<std::vector<Polynomials::Polynomial<double>>> &pols);
518};
519
522#ifndef DOXYGEN
523
524
525/* ---------------- template and inline functions ---------- */
526
527
528template <int dim, typename PolynomialType>
529template <class Pol>
531 const std::vector<Pol> &pols)
532 : ScalarPolynomialsBase<dim>(1, Utilities::fixed_power<dim>(pols.size()))
533 , polynomials(pols.begin(), pols.end())
534 , index_map(this->n())
535 , index_map_inverse(this->n())
536{
537 // per default set this index map to identity. This map can be changed by
538 // the user through the set_numbering() function
539 for (unsigned int i = 0; i < this->n(); ++i)
540 {
541 index_map[i] = i;
542 index_map_inverse[i] = i;
543 }
544}
545
546
547template <int dim, typename PolynomialType>
548inline const std::vector<unsigned int> &
550{
551 return index_map;
552}
553
554
555template <int dim, typename PolynomialType>
556inline const std::vector<unsigned int> &
558{
559 return index_map_inverse;
560}
561
562
563template <int dim, typename PolynomialType>
564inline std::string
566{
567 return "TensorProductPolynomials";
568}
569
570
571template <int dim, typename PolynomialType>
572template <int order>
575 const unsigned int i,
576 const Point<dim> &p) const
577{
578 std::array<unsigned int, dim> indices;
579 compute_index(i, indices);
580
582 {
583 std::vector<double> tmp(5);
584 for (unsigned int d = 0; d < dim; ++d)
585 {
586 polynomials[indices[d]].value(p[d], tmp);
587 v[d][0] = tmp[0];
588 v[d][1] = tmp[1];
589 v[d][2] = tmp[2];
590 v[d][3] = tmp[3];
591 v[d][4] = tmp[4];
592 }
593 }
594
595 if constexpr (order == 1)
596 {
597 Tensor<1, dim> derivative;
598 for (unsigned int d = 0; d < dim; ++d)
599 {
600 derivative[d] = 1.;
601 for (unsigned int x = 0; x < dim; ++x)
602 {
603 unsigned int x_order = 0;
604 if (d == x)
605 ++x_order;
606
607 derivative[d] *= v[x][x_order];
608 }
609 }
610
611 return derivative;
612 }
613 else if constexpr (order == 2)
614 {
615 Tensor<2, dim> derivative;
616 for (unsigned int d1 = 0; d1 < dim; ++d1)
617 for (unsigned int d2 = 0; d2 < dim; ++d2)
618 {
619 derivative[d1][d2] = 1.;
620 for (unsigned int x = 0; x < dim; ++x)
621 {
622 unsigned int x_order = 0;
623 if (d1 == x)
624 ++x_order;
625 if (d2 == x)
626 ++x_order;
627
628 derivative[d1][d2] *= v[x][x_order];
629 }
630 }
631
632 return derivative;
633 }
634 else if constexpr (order == 3)
635 {
636 Tensor<3, dim> derivative;
637 for (unsigned int d1 = 0; d1 < dim; ++d1)
638 for (unsigned int d2 = 0; d2 < dim; ++d2)
639 for (unsigned int d3 = 0; d3 < dim; ++d3)
640 {
641 derivative[d1][d2][d3] = 1.;
642 for (unsigned int x = 0; x < dim; ++x)
643 {
644 unsigned int x_order = 0;
645 if (d1 == x)
646 ++x_order;
647 if (d2 == x)
648 ++x_order;
649 if (d3 == x)
650 ++x_order;
651
652 derivative[d1][d2][d3] *= v[x][x_order];
653 }
654 }
655
656 return derivative;
657 }
658 else if constexpr (order == 4)
659 {
660 Tensor<4, dim> derivative;
661 for (unsigned int d1 = 0; d1 < dim; ++d1)
662 for (unsigned int d2 = 0; d2 < dim; ++d2)
663 for (unsigned int d3 = 0; d3 < dim; ++d3)
664 for (unsigned int d4 = 0; d4 < dim; ++d4)
665 {
666 derivative[d1][d2][d3][d4] = 1.;
667 for (unsigned int x = 0; x < dim; ++x)
668 {
669 unsigned int x_order = 0;
670 if (d1 == x)
671 ++x_order;
672 if (d2 == x)
673 ++x_order;
674 if (d3 == x)
675 ++x_order;
676 if (d4 == x)
677 ++x_order;
678
679 derivative[d1][d2][d3][d4] *= v[x][x_order];
680 }
681 }
682
683 return derivative;
684 }
685 else
686 {
688 return {};
689 }
690}
691
692
693
694template <>
695template <int order>
698 compute_derivative(const unsigned int, const Point<0> &) const
699{
701
702 return {};
703}
704
705
706
707template <int dim, typename PolynomialType>
708inline Tensor<1, dim>
710 const unsigned int i,
711 const Point<dim> &p) const
712{
713 return compute_derivative<1>(i, p);
714}
715
716
717
718template <int dim, typename PolynomialType>
719inline Tensor<2, dim>
721 const unsigned int i,
722 const Point<dim> &p) const
723{
724 return compute_derivative<2>(i, p);
725}
726
727
728
729template <int dim, typename PolynomialType>
730inline Tensor<3, dim>
732 const unsigned int i,
733 const Point<dim> &p) const
734{
735 return compute_derivative<3>(i, p);
736}
737
738
739
740template <int dim, typename PolynomialType>
741inline Tensor<4, dim>
743 const unsigned int i,
744 const Point<dim> &p) const
745{
746 return compute_derivative<4>(i, p);
747}
748
749
750
751template <int dim>
752template <int order>
755 const Point<dim> &p) const
756{
757 std::array<unsigned int, dim> indices;
758 compute_index(i, indices);
759
760 std::vector<std::vector<double>> v(dim, std::vector<double>(order + 1));
761 for (unsigned int d = 0; d < dim; ++d)
762 polynomials[d][indices[d]].value(p[d], v[d]);
763
764 if constexpr (order == 1)
765 {
766 Tensor<1, dim> derivative;
767 for (unsigned int d = 0; d < dim; ++d)
768 {
769 derivative[d] = 1.;
770 for (unsigned int x = 0; x < dim; ++x)
771 {
772 unsigned int x_order = 0;
773 if (d == x)
774 ++x_order;
775
776 derivative[d] *= v[x][x_order];
777 }
778 }
779
780 return derivative;
781 }
782 else if constexpr (order == 2)
783 {
784 Tensor<2, dim> derivative;
785 for (unsigned int d1 = 0; d1 < dim; ++d1)
786 for (unsigned int d2 = 0; d2 < dim; ++d2)
787 {
788 derivative[d1][d2] = 1.;
789 for (unsigned int x = 0; x < dim; ++x)
790 {
791 unsigned int x_order = 0;
792 if (d1 == x)
793 ++x_order;
794 if (d2 == x)
795 ++x_order;
796
797 derivative[d1][d2] *= v[x][x_order];
798 }
799 }
800
801 return derivative;
802 }
803 else if constexpr (order == 3)
804 {
805 Tensor<3, dim> derivative;
806 for (unsigned int d1 = 0; d1 < dim; ++d1)
807 for (unsigned int d2 = 0; d2 < dim; ++d2)
808 for (unsigned int d3 = 0; d3 < dim; ++d3)
809 {
810 derivative[d1][d2][d3] = 1.;
811 for (unsigned int x = 0; x < dim; ++x)
812 {
813 unsigned int x_order = 0;
814 if (d1 == x)
815 ++x_order;
816 if (d2 == x)
817 ++x_order;
818 if (d3 == x)
819 ++x_order;
820
821 derivative[d1][d2][d3] *= v[x][x_order];
822 }
823 }
824
825 return derivative;
826 }
827 else if constexpr (order == 4)
828 {
829 Tensor<4, dim> derivative;
830 for (unsigned int d1 = 0; d1 < dim; ++d1)
831 for (unsigned int d2 = 0; d2 < dim; ++d2)
832 for (unsigned int d3 = 0; d3 < dim; ++d3)
833 for (unsigned int d4 = 0; d4 < dim; ++d4)
834 {
835 derivative[d1][d2][d3][d4] = 1.;
836 for (unsigned int x = 0; x < dim; ++x)
837 {
838 unsigned int x_order = 0;
839 if (d1 == x)
840 ++x_order;
841 if (d2 == x)
842 ++x_order;
843 if (d3 == x)
844 ++x_order;
845 if (d4 == x)
846 ++x_order;
847
848 derivative[d1][d2][d3][d4] *= v[x][x_order];
849 }
850 }
851
852 return derivative;
853 }
854 else
855 {
857 return {};
858 }
859}
860
861
862
863template <>
864template <int order>
867 const Point<0> &) const
868{
870
871 return {};
872}
873
874
875
876template <int dim>
877inline Tensor<1, dim>
879 const Point<dim> &p) const
880{
881 return compute_derivative<1>(i, p);
882}
883
884
885
886template <int dim>
887inline Tensor<2, dim>
889 const Point<dim> &p) const
890{
891 return compute_derivative<2>(i, p);
892}
893
894
895
896template <int dim>
897inline Tensor<3, dim>
899 const Point<dim> &p) const
900{
901 return compute_derivative<3>(i, p);
902}
903
904
905
906template <int dim>
907inline Tensor<4, dim>
909 const Point<dim> &p) const
910{
911 return compute_derivative<4>(i, p);
912}
913
914
915
916template <int dim>
917inline std::string
919{
920 return "AnisotropicPolynomials";
921}
922
923
924
925#endif // DOXYGEN
927
928#endif
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
void set_numbering(const std::vector< unsigned int > &renumber)
const std::vector< std::vector< Polynomials::Polynomial< double > > > polynomials
virtual Tensor< 1, dim > compute_1st_derivative(const unsigned int i, const Point< dim > &p) const override
static unsigned int get_n_tensor_pols(const std::vector< std::vector< Polynomials::Polynomial< double > > > &pols)
std::vector< unsigned int > index_map
virtual Tensor< 3, dim > compute_3rd_derivative(const unsigned int i, const Point< dim > &p) const override
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
virtual Tensor< 2, dim > compute_2nd_derivative(const unsigned int i, const Point< dim > &p) const override
Tensor< order, dim > compute_derivative(const unsigned int i, const Point< dim > &p) const
const std::vector< unsigned int > & get_numbering() const
std::string name() const override
Tensor< 1, dim > compute_grad(const unsigned int i, const Point< dim > &p) const override
std::vector< unsigned int > index_map_inverse
virtual Tensor< 4, dim > compute_4th_derivative(const unsigned int i, const Point< dim > &p) const override
const std::vector< unsigned int > & get_numbering_inverse() const
virtual std::unique_ptr< ScalarPolynomialsBase< dim > > clone() const override
Definition point.h:111
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
virtual Tensor< 2, dim > compute_2nd_derivative(const unsigned int i, const Point< dim > &p) const override
const std::vector< unsigned int > & get_numbering() const
Tensor< 1, dim > compute_grad(const unsigned int i, const Point< dim > &p) const override
Tensor< order, dim > compute_derivative(const unsigned int i, const Point< dim > &p) const
virtual std::unique_ptr< ScalarPolynomialsBase< dim > > clone() const override
virtual Tensor< 1, dim > compute_1st_derivative(const unsigned int i, const Point< dim > &p) const override
std::vector< unsigned int > index_map
std::vector< unsigned int > index_map_inverse
std::vector< PolynomialType > get_underlying_polynomials() const
virtual Tensor< 3, dim > compute_3rd_derivative(const unsigned int i, const Point< dim > &p) const override
std::vector< PolynomialType > polynomials
void set_numbering(const std::vector< unsigned int > &renumber)
const std::vector< unsigned int > & get_numbering_inverse() const
Tensor< 2, dim > compute_grad_grad(const unsigned int i, const Point< dim > &p) const override
std::string name() const override
static constexpr unsigned int dimension
virtual Tensor< 4, dim > compute_4th_derivative(const unsigned int i, const Point< dim > &p) const override
TensorProductPolynomials(const std::vector< Pol > &pols)
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
static ::ExceptionBase & ExcNotImplemented()
#define AssertThrow(cond, exc)
#define DEAL_II_NOT_IMPLEMENTED()
std::size_t size
Definition mpi.cc:734
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
typename internal::ndarray::HelperArray< T, Ns... >::type ndarray
Definition ndarray.h:107