deal.II version 9.7.0
\(\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
fe_tools.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2000 - 2025 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_fe_tools_H
16#define dealii_fe_tools_H
17
18
19
20#include <deal.II/base/config.h>
21
26#include <deal.II/base/tensor.h>
27
29
31
33
34#include <memory>
35#include <string>
36#include <vector>
37
38
40
41// Forward declarations
42#ifndef DOXYGEN
43template <typename number>
44class FullMatrix;
45template <int dim>
46class Quadrature;
47template <int dim, int spacedim>
48class FiniteElement;
49template <int dim, int spacedim>
51class DoFHandler;
52template <int dim>
54template <typename number>
56#endif
57
58
63
64
77namespace FETools
78{
87 template <int dim, int spacedim = dim>
89 {
90 public:
94 virtual std::unique_ptr<FiniteElement<dim, spacedim>>
95 get(const unsigned int degree) const = 0;
96
101
102 virtual std::unique_ptr<FiniteElement<dim, spacedim>>
103 get(const Quadrature<1> &quad) const = 0;
104
108 virtual ~FEFactoryBase() override = default;
109 };
110
120 template <class FE>
121 class FEFactory : public FEFactoryBase<FE::dimension, FE::space_dimension>
122 {
123 public:
127 virtual std::unique_ptr<FiniteElement<FE::dimension, FE::space_dimension>>
128 get(const unsigned int degree) const override;
129
134 virtual std::unique_ptr<FiniteElement<FE::dimension, FE::space_dimension>>
135 get(const Quadrature<1> &quad) const override;
136 };
137
153 template <int dim, int spacedim>
154 void
156 std::vector<unsigned int> &renumbering,
157 std::vector<std::vector<unsigned int>> &start_indices);
158
174 template <int dim, int spacedim>
175 void
177 std::vector<types::global_dof_index> &renumbering,
178 std::vector<types::global_dof_index> &block_data,
179 bool return_start_indices = true);
180
194 template <int dim, typename number, int spacedim>
195 void
198 FullMatrix<number> &interpolation_matrix);
199
211 template <int dim, typename number, int spacedim>
212 void
215 FullMatrix<number> &interpolation_matrix);
216
228 template <int dim, typename number, int spacedim>
229 void
232 FullMatrix<number> &difference_matrix);
233
237 template <int dim, typename number, int spacedim>
238 void
241 FullMatrix<number> &matrix);
242
311 template <int dim, int spacedim>
314
353 template <int dim, typename number, int spacedim>
354 void
357 std::vector<std::vector<FullMatrix<number>>> &matrices,
358 const bool isotropic_only = false,
359 const double threshold = 1.e-12);
360
382 template <int dim, typename number, int spacedim>
383 void
385 const ArrayView<FullMatrix<number>> &matrices,
386 const unsigned int face_coarse,
387 const unsigned int face_fine,
388 const double threshold = 1.e-12);
389
421 template <int dim, typename number, int spacedim>
422 void
425 std::vector<std::vector<FullMatrix<number>>> &matrices,
426 const bool isotropic_only = false);
427
513 template <int dim, int spacedim>
514 void
517 const Quadrature<dim> &lhs_quadrature,
518 const Quadrature<dim> &rhs_quadrature,
520
528 template <int dim, int spacedim>
529 void
532 const Quadrature<dim> &quadrature,
533 FullMatrix<double> &I_q);
534
548 template <int dim>
549 void
551 const FullMatrix<double> &projection_matrix,
552 const std::vector<Tensor<1, dim>> &vector_of_tensors_at_qp,
553 std::vector<Tensor<1, dim>> &vector_of_tensors_at_nodes);
554
555
556
560 template <int dim>
561 void
563 const FullMatrix<double> &projection_matrix,
564 const std::vector<SymmetricTensor<2, dim>> &vector_of_tensors_at_qp,
565 std::vector<SymmetricTensor<2, dim>> &vector_of_tensors_at_nodes);
566
567
568
578 template <int dim, int spacedim>
579 void
582 const Quadrature<dim - 1> &lhs_quadrature,
583 const Quadrature<dim - 1> &rhs_quadrature,
585 const unsigned int face,
587
620 template <int dim, int spacedim = dim>
623
639 template <int dim, int spacedim, typename number>
640 void
642 const FiniteElement<dim, spacedim> &finite_element,
643 const std::vector<Vector<number>> &support_point_values,
644 std::vector<number> &dof_values);
645
646
647
685 template <int dim, int spacedim, class InVector, class OutVector>
686 void
688 const InVector &u1,
689 const DoFHandler<dim, spacedim> &dof2,
690 OutVector &u2);
691
711 template <int dim, int spacedim, class InVector, class OutVector>
712 void
714 const DoFHandler<dim, spacedim> &dof1,
715 const InVector &u1,
716 const DoFHandler<dim, spacedim> &dof2,
718 OutVector &u2);
719
733 template <int dim, class InVector, class OutVector, int spacedim>
734 void
736 const InVector &u1,
738 OutVector &u1_interpolated);
739
752 template <int dim, class InVector, class OutVector, int spacedim>
753 void
755 const DoFHandler<dim, spacedim> &dof1,
757 const InVector &u1,
758 const DoFHandler<dim, spacedim> &dof2,
760 OutVector &u1_interpolated);
761
771 template <int dim, class InVector, class OutVector, int spacedim>
772 void
774 const InVector &z1,
776 OutVector &z1_difference);
777
790 template <int dim, class InVector, class OutVector, int spacedim>
791 void
793 const DoFHandler<dim, spacedim> &dof1,
795 const InVector &z1,
796 const DoFHandler<dim, spacedim> &dof2,
798 OutVector &z1_difference);
799
800
801
810 template <int dim, class InVector, class OutVector, int spacedim>
811 void
813 const InVector &u1,
814 const DoFHandler<dim, spacedim> &dof2,
815 OutVector &u2);
816
873 template <int dim, class InVector, class OutVector, int spacedim>
874 void
876 const InVector &z1,
877 const DoFHandler<dim, spacedim> &dof2,
878 OutVector &z2);
879
892 template <int dim, class InVector, class OutVector, int spacedim>
893 void
895 const DoFHandler<dim, spacedim> &dof1,
896 const InVector &z1,
897 const DoFHandler<dim, spacedim> &dof2,
899 OutVector &z2);
900
916 template <int dim>
917 std::vector<unsigned int>
919
926 template <int dim>
927 std::vector<unsigned int>
929
951 template <int dim>
952 std::pair<std::vector<unsigned int>, std::vector<unsigned int>>
953 cell_to_face_patch(const unsigned int &degree,
954 const unsigned int &direction,
955 const bool &cell_hierarchical_numbering,
956 const bool &is_continuous);
957
1033 namespace Compositing
1034 {
1051 template <int dim, int spacedim>
1054 const std::vector<const FiniteElement<dim, spacedim> *> &fes,
1055 const std::vector<unsigned int> &multiplicities,
1056 const bool do_tensor_product = true);
1057
1063 template <int dim, int spacedim>
1066 const std::initializer_list<
1067 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1068 &fe_systems);
1069
1076 template <int dim, int spacedim>
1079 const unsigned int N1,
1080 const FiniteElement<dim, spacedim> *fe2 = nullptr,
1081 const unsigned int N2 = 0,
1082 const FiniteElement<dim, spacedim> *fe3 = nullptr,
1083 const unsigned int N3 = 0,
1084 const FiniteElement<dim, spacedim> *fe4 = nullptr,
1085 const unsigned int N4 = 0,
1086 const FiniteElement<dim, spacedim> *fe5 = nullptr,
1087 const unsigned int N5 = 0);
1088
1101 template <int dim, int spacedim>
1102 std::vector<bool>
1104 const std::vector<const FiniteElement<dim, spacedim> *> &fes,
1105 const std::vector<unsigned int> &multiplicities);
1106
1112 template <int dim, int spacedim>
1113 std::vector<bool>
1115 const std::initializer_list<
1116 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1117 &fe_systems);
1118
1136 template <int dim, int spacedim>
1137 DEAL_II_DEPRECATED std::vector<bool>
1140 const unsigned int N1,
1141 const FiniteElement<dim, spacedim> *fe2 = nullptr,
1142 const unsigned int N2 = 0,
1143 const FiniteElement<dim, spacedim> *fe3 = nullptr,
1144 const unsigned int N3 = 0,
1145 const FiniteElement<dim, spacedim> *fe4 = nullptr,
1146 const unsigned int N4 = 0,
1147 const FiniteElement<dim, spacedim> *fe5 = nullptr,
1148 const unsigned int N5 = 0);
1149
1150
1167 template <int dim, int spacedim>
1168 std::vector<ComponentMask>
1170 const std::vector<const FiniteElement<dim, spacedim> *> &fes,
1171 const std::vector<unsigned int> &multiplicities,
1172 const bool do_tensor_product = true);
1173
1179 template <int dim, int spacedim>
1180 std::vector<ComponentMask>
1182 const std::initializer_list<
1183 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1184 &fe_systems);
1185
1207 template <int dim, int spacedim>
1208 DEAL_II_DEPRECATED std::vector<ComponentMask>
1211 const unsigned int N1,
1212 const FiniteElement<dim, spacedim> *fe2 = nullptr,
1213 const unsigned int N2 = 0,
1214 const FiniteElement<dim, spacedim> *fe3 = nullptr,
1215 const unsigned int N3 = 0,
1216 const FiniteElement<dim, spacedim> *fe4 = nullptr,
1217 const unsigned int N4 = 0,
1218 const FiniteElement<dim, spacedim> *fe5 = nullptr,
1219 const unsigned int N5 = 0,
1220 const bool do_tensor_product = true);
1221
1238 template <int dim, int spacedim>
1239 void
1241 std::vector<std::pair<std::pair<unsigned int, unsigned int>,
1242 unsigned int>> &system_to_base_table,
1243 std::vector<std::pair<unsigned int, unsigned int>>
1244 &system_to_component_table,
1245 std::vector<std::pair<std::pair<unsigned int, unsigned int>,
1246 unsigned int>> &component_to_base_table,
1247 const FiniteElement<dim, spacedim> &finite_element,
1248 const bool do_tensor_product = true);
1249
1265 template <int dim, int spacedim>
1266 void
1268 std::vector<std::pair<std::pair<unsigned int, unsigned int>,
1269 unsigned int>> &face_system_to_base_table,
1270 std::vector<std::pair<unsigned int, unsigned int>>
1271 &face_system_to_component_table,
1272 const FiniteElement<dim, spacedim> &finite_element,
1273 const bool do_tensor_product = true,
1274 const unsigned int face_no = 0 /*TODO*/);
1275
1276 } // namespace Compositing
1277
1278
1312 template <int dim, int spacedim = dim>
1313 std::unique_ptr<FiniteElement<dim, spacedim>>
1314 get_fe_by_name(const std::string &name);
1315
1358 template <int dim, int spacedim>
1359 void
1360 add_fe_name(const std::string &name,
1361 const FEFactoryBase<dim, spacedim> *factory);
1362
1373 std::string,
1374 << "Can't re-generate a finite element from the string '"
1375 << arg1 << "'.");
1376
1389 char,
1390 int,
1391 << "The dimension " << arg1
1392 << " in the finite element string must match "
1393 << "the space dimension " << arg2 << '.');
1394
1401
1415
1423 "You are using continuous elements on a grid with "
1424 "hanging nodes but without providing hanging node "
1425 "constraints. Use the respective function with "
1426 "additional AffineConstraints argument(s), instead.");
1439 int,
1440 int,
1441 int,
1442 int,
1443 << "This is a " << arg1 << 'x' << arg2 << " matrix, "
1444 << "but should be a " << arg3 << 'x' << arg4 << " matrix.");
1445
1452 double,
1453 << "Least squares fit leaves a gap of " << arg1);
1454
1461 int,
1462 int,
1463 << arg1 << " must be greater than " << arg2);
1464} // namespace FETools
1465
1466
1467#ifndef DOXYGEN
1468
1469namespace FETools
1470{
1471 template <class FE>
1472 std::unique_ptr<FiniteElement<FE::dimension, FE::space_dimension>>
1473 FEFactory<FE>::get(const unsigned int degree) const
1474 {
1475 return std::make_unique<FE>(degree);
1476 }
1477
1478 namespace Compositing
1479 {
1480 template <int dim, int spacedim>
1481 std::vector<bool>
1483 const std::initializer_list<
1484 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1485 &fe_systems)
1486 {
1487 std::vector<const FiniteElement<dim, spacedim> *> fes;
1488 std::vector<unsigned int> multiplicities;
1489
1490 const auto extract =
1491 [&fes, &multiplicities](
1492 const std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>,
1493 unsigned int> &fe_system) {
1494 fes.push_back(fe_system.first.get());
1495 multiplicities.push_back(fe_system.second);
1496 };
1497
1498 for (const auto &p : fe_systems)
1499 extract(p);
1500
1501 return compute_restriction_is_additive_flags(fes, multiplicities);
1502 }
1503
1504
1505
1506 template <int dim, int spacedim>
1507 FiniteElementData<dim>
1509 const std::initializer_list<
1510 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1511 &fe_systems)
1512 {
1513 std::vector<const FiniteElement<dim, spacedim> *> fes;
1514 std::vector<unsigned int> multiplicities;
1515
1516 const auto extract =
1517 [&fes, &multiplicities](
1518 const std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>,
1519 unsigned int> &fe_system) {
1520 fes.push_back(fe_system.first.get());
1521 multiplicities.push_back(fe_system.second);
1522 };
1523
1524 for (const auto &p : fe_systems)
1525 extract(p);
1526
1527 return multiply_dof_numbers(fes, multiplicities, true);
1528 }
1529
1530
1531
1532 template <int dim, int spacedim>
1533 std::vector<ComponentMask>
1535 const std::initializer_list<
1536 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1537 &fe_systems)
1538 {
1539 std::vector<const FiniteElement<dim, spacedim> *> fes;
1540 std::vector<unsigned int> multiplicities;
1541
1542 const auto extract =
1543 [&fes, &multiplicities](
1544 const std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>,
1545 unsigned int> &fe_system) {
1546 fes.push_back(fe_system.first.get());
1547 multiplicities.push_back(fe_system.second);
1548 };
1549
1550 for (const auto &p : fe_systems)
1551 extract(p);
1552
1553 return compute_nonzero_components(fes, multiplicities, true);
1554 }
1555 } // namespace Compositing
1556} // namespace FETools
1557
1558#endif
1559
1561
1563
1564#endif /* dealii_fe_tools_H */
virtual ~FEFactoryBase() override=default
virtual std::unique_ptr< FiniteElement< dim, spacedim > > get(const Quadrature< 1 > &quad) const =0
virtual std::unique_ptr< FiniteElement< dim, spacedim > > get(const unsigned int degree) const =0
virtual std::unique_ptr< FiniteElement< FE::dimension, FE::space_dimension > > get(const Quadrature< 1 > &quad) const override
virtual std::unique_ptr< FiniteElement< FE::dimension, FE::space_dimension > > get(const unsigned int degree) const override
#define DEAL_II_DEPRECATED
Definition config.h:286
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:40
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:248
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:41
#define DeclException0(Exception0)
static ::ExceptionBase & ExcTriangulationMismatch()
static ::ExceptionBase & ExcInvalidFEName(std::string arg1)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
static ::ExceptionBase & ExcInvalidFEDimension(char arg1, int arg2)
static ::ExceptionBase & ExcLeastSquaresError(double arg1)
#define DeclException2(Exception2, type1, type2, outsequence)
static ::ExceptionBase & ExcFENotPrimitive()
static ::ExceptionBase & ExcHangingNodesNotAllowed()
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcInvalidFE()
static ::ExceptionBase & ExcGridNotRefinedAtLeastOnce()
static ::ExceptionBase & ExcMatrixDimensionMismatch(int arg1, int arg2, int arg3, int arg4)
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcNotGreaterThan(int arg1, int arg2)
typename ActiveSelector::active_cell_iterator active_cell_iterator
void build_face_tables(std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > &face_system_to_base_table, std::vector< std::pair< unsigned int, unsigned int > > &face_system_to_component_table, const FiniteElement< dim, spacedim > &finite_element, const bool do_tensor_product=true, const unsigned int face_no=0)
std::vector< ComponentMask > compute_nonzero_components(const std::vector< const FiniteElement< dim, spacedim > * > &fes, const std::vector< unsigned int > &multiplicities, const bool do_tensor_product=true)
std::vector< bool > compute_restriction_is_additive_flags(const std::vector< const FiniteElement< dim, spacedim > * > &fes, const std::vector< unsigned int > &multiplicities)
void build_cell_tables(std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > &system_to_base_table, std::vector< std::pair< unsigned int, unsigned int > > &system_to_component_table, std::vector< std::pair< std::pair< unsigned int, unsigned int >, unsigned int > > &component_to_base_table, const FiniteElement< dim, spacedim > &finite_element, const bool do_tensor_product=true)
FiniteElementData< dim > multiply_dof_numbers(const std::vector< const FiniteElement< dim, spacedim > * > &fes, const std::vector< unsigned int > &multiplicities, const bool do_tensor_product=true)
void interpolation_difference(const DoFHandler< dim, spacedim > &dof1, const InVector &z1, const FiniteElement< dim, spacedim > &fe2, OutVector &z1_difference)
void compute_projection_from_quadrature_points(const FullMatrix< double > &projection_matrix, const std::vector< Tensor< 1, dim > > &vector_of_tensors_at_qp, std::vector< Tensor< 1, dim > > &vector_of_tensors_at_nodes)
void project_dg(const DoFHandler< dim, spacedim > &dof1, const InVector &u1, const DoFHandler< dim, spacedim > &dof2, OutVector &u2)
void get_back_interpolation_matrix(const FiniteElement< dim, spacedim > &fe1, const FiniteElement< dim, spacedim > &fe2, FullMatrix< number > &interpolation_matrix)
void get_projection_matrix(const FiniteElement< dim, spacedim > &fe1, const FiniteElement< dim, spacedim > &fe2, FullMatrix< number > &matrix)
void compute_component_wise(const FiniteElement< dim, spacedim > &fe, std::vector< unsigned int > &renumbering, std::vector< std::vector< unsigned int > > &start_indices)
void add_fe_name(const std::string &name, const FEFactoryBase< dim, spacedim > *factory)
std::vector< unsigned int > hierarchic_to_lexicographic_numbering(unsigned int degree)
void convert_generalized_support_point_values_to_dof_values(const FiniteElement< dim, spacedim > &finite_element, const std::vector< Vector< number > > &support_point_values, std::vector< number > &dof_values)
void compute_interpolation_to_quadrature_points_matrix(const FiniteElement< dim, spacedim > &fe, const Quadrature< dim > &quadrature, FullMatrix< double > &I_q)
Quadrature< dim > compute_nodal_quadrature(const FiniteElement< dim, spacedim > &fe)
Compute the nodal quadrature rule associated with an element.
std::unique_ptr< FiniteElement< dim, spacedim > > get_fe_by_name(const std::string &name)
void compute_projection_from_quadrature_points_matrix(const FiniteElement< dim, spacedim > &fe, const Quadrature< dim > &lhs_quadrature, const Quadrature< dim > &rhs_quadrature, FullMatrix< double > &X)
void get_interpolation_matrix(const FiniteElement< dim, spacedim > &fe1, const FiniteElement< dim, spacedim > &fe2, FullMatrix< number > &interpolation_matrix)
void extrapolate(const DoFHandler< dim, spacedim > &dof1, const InVector &z1, const DoFHandler< dim, spacedim > &dof2, OutVector &z2)
void compute_embedding_matrices(const FiniteElement< dim, spacedim > &fe, std::vector< std::vector< FullMatrix< number > > > &matrices, const bool isotropic_only=false, const double threshold=1.e-12)
void compute_face_embedding_matrices(const FiniteElement< dim, spacedim > &fe, const ArrayView< FullMatrix< number > > &matrices, const unsigned int face_coarse, const unsigned int face_fine, const double threshold=1.e-12)
void interpolate(const DoFHandler< dim, spacedim > &dof1, const InVector &u1, const DoFHandler< dim, spacedim > &dof2, OutVector &u2)
void compute_block_renumbering(const FiniteElement< dim, spacedim > &fe, std::vector< types::global_dof_index > &renumbering, std::vector< types::global_dof_index > &block_data, bool return_start_indices=true)
std::vector< unsigned int > lexicographic_to_hierarchic_numbering(unsigned int degree)
void compute_projection_from_face_quadrature_points_matrix(const FiniteElement< dim, spacedim > &fe, const Quadrature< dim - 1 > &lhs_quadrature, const Quadrature< dim - 1 > &rhs_quadrature, const typename DoFHandler< dim, spacedim >::active_cell_iterator &cell, const unsigned int face, FullMatrix< double > &X)
FullMatrix< double > compute_node_matrix(const FiniteElement< dim, spacedim > &fe)
void get_interpolation_difference_matrix(const FiniteElement< dim, spacedim > &fe1, const FiniteElement< dim, spacedim > &fe2, FullMatrix< number > &difference_matrix)
void back_interpolate(const DoFHandler< dim, spacedim > &dof1, const InVector &u1, const FiniteElement< dim, spacedim > &fe2, OutVector &u1_interpolated)
void compute_projection_matrices(const FiniteElement< dim, spacedim > &fe, std::vector< std::vector< FullMatrix< number > > > &matrices, const bool isotropic_only=false)
std::pair< std::vector< unsigned int >, std::vector< unsigned int > > cell_to_face_patch(const unsigned int &degree, const unsigned int &direction, const bool &cell_hierarchical_numbering, const bool &is_continuous)
constexpr ReturnType< rank, T >::value_type & extract(T &t, const ArrayType &indices)