Reference documentation for deal.II version 9.3.3
\(\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\}}\)
fe_tools.h
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2000 - 2020 by the deal.II authors
4//
5// This file is part of the deal.II library.
6//
7// The deal.II library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.md at
12// the top level directory of deal.II.
13//
14// ---------------------------------------------------------------------
15
16#ifndef dealii_fe_tools_H
17#define dealii_fe_tools_H
18
19
20
21#include <deal.II/base/config.h>
22
27#include <deal.II/base/tensor.h>
28
30
32
34
35#include <memory>
36#include <string>
37#include <vector>
38
39
41
42// Forward declarations
43#ifndef DOXYGEN
44template <typename number>
45class FullMatrix;
46template <int dim>
47class Quadrature;
48template <int dim, int spacedim>
49class FiniteElement;
50template <int dim, int spacedim>
51class DoFHandler;
52template <int dim>
54template <typename number>
56#endif
57
58
61
62
75namespace FETools
76{
85 template <int dim, int spacedim = dim>
87 {
88 public:
92 virtual std::unique_ptr<FiniteElement<dim, spacedim>>
93 get(const unsigned int degree) const = 0;
94
100 virtual std::unique_ptr<FiniteElement<dim, spacedim>>
101 get(const Quadrature<1> &quad) const = 0;
102
106 virtual ~FEFactoryBase() override = default;
107 };
108
118 template <class FE>
119 class FEFactory : public FEFactoryBase<FE::dimension, FE::space_dimension>
120 {
121 public:
125 virtual std::unique_ptr<FiniteElement<FE::dimension, FE::space_dimension>>
126 get(const unsigned int degree) const override;
127
132 virtual std::unique_ptr<FiniteElement<FE::dimension, FE::space_dimension>>
133 get(const Quadrature<1> &quad) const override;
134 };
135
151 template <int dim, int spacedim>
152 void
154 std::vector<unsigned int> & renumbering,
155 std::vector<std::vector<unsigned int>> &start_indices);
156
172 template <int dim, int spacedim>
173 void
175 std::vector<types::global_dof_index> &renumbering,
176 std::vector<types::global_dof_index> &block_data,
177 bool return_start_indices = true);
178
192 template <int dim, typename number, int spacedim>
193 void
196 FullMatrix<number> &interpolation_matrix);
197
209 template <int dim, typename number, int spacedim>
210 void
213 FullMatrix<number> &interpolation_matrix);
214
226 template <int dim, typename number, int spacedim>
227 void
230 FullMatrix<number> &difference_matrix);
231
235 template <int dim, typename number, int spacedim>
236 void
240
309 template <int dim, int spacedim>
312
351 template <int dim, typename number, int spacedim>
352 void
355 std::vector<std::vector<FullMatrix<number>>> &matrices,
356 const bool isotropic_only = false,
357 const double threshold = 1.e-12);
358
380 template <int dim, typename number, int spacedim>
381 void
385 const unsigned int face_coarse,
386 const unsigned int face_fine,
387 const double threshold = 1.e-12);
388
420 template <int dim, typename number, int spacedim>
421 void
424 std::vector<std::vector<FullMatrix<number>>> &matrices,
425 const bool isotropic_only = false);
426
512 template <int dim, int spacedim>
513 void
516 const Quadrature<dim> & lhs_quadrature,
517 const Quadrature<dim> & rhs_quadrature,
519
527 template <int dim, int spacedim>
528 void
531 const Quadrature<dim> & quadrature,
532 FullMatrix<double> & I_q);
533
547 template <int dim>
548 void
550 const FullMatrix<double> & projection_matrix,
551 const std::vector<Tensor<1, dim>> &vector_of_tensors_at_qp,
552 std::vector<Tensor<1, dim>> & vector_of_tensors_at_nodes);
553
554
555
559 template <int dim>
560 void
562 const FullMatrix<double> & projection_matrix,
563 const std::vector<SymmetricTensor<2, dim>> &vector_of_tensors_at_qp,
564 std::vector<SymmetricTensor<2, dim>> & vector_of_tensors_at_nodes);
565
566
567
577 template <int dim, int spacedim>
578 void
581 const Quadrature<dim - 1> & lhs_quadrature,
582 const Quadrature<dim - 1> & rhs_quadrature,
584 const unsigned int face,
586
587
588
604 template <int dim, int spacedim, typename number>
605 void
607 const FiniteElement<dim, spacedim> &finite_element,
608 const std::vector<Vector<number>> & support_point_values,
609 std::vector<number> & dof_values);
610
611
612
614
647 template <int dim, int spacedim, class InVector, class OutVector>
648 void
650 const InVector & u1,
651 const DoFHandler<dim, spacedim> &dof2,
652 OutVector & u2);
653
670 template <int dim, int spacedim, class InVector, class OutVector>
671 void
673 const DoFHandler<dim, spacedim> & dof1,
674 const InVector & u1,
675 const DoFHandler<dim, spacedim> & dof2,
677 OutVector & u2);
678
692 template <int dim, class InVector, class OutVector, int spacedim>
693 void
695 const InVector & u1,
697 OutVector & u1_interpolated);
698
711 template <int dim, class InVector, class OutVector, int spacedim>
712 void
714 const DoFHandler<dim, spacedim> & dof1,
716 const InVector & u1,
717 const DoFHandler<dim, spacedim> & dof2,
719 OutVector & u1_interpolated);
720
730 template <int dim, class InVector, class OutVector, int spacedim>
731 void
733 const InVector & z1,
735 OutVector & z1_difference);
736
749 template <int dim, class InVector, class OutVector, int spacedim>
750 void
752 const DoFHandler<dim, spacedim> & dof1,
754 const InVector & z1,
755 const DoFHandler<dim, spacedim> & dof2,
757 OutVector & z1_difference);
758
759
760
769 template <int dim, class InVector, class OutVector, int spacedim>
770 void
772 const InVector & u1,
773 const DoFHandler<dim, spacedim> &dof2,
774 OutVector & u2);
775
836 template <int dim, class InVector, class OutVector, int spacedim>
837 void
839 const InVector & z1,
840 const DoFHandler<dim, spacedim> &dof2,
841 OutVector & z2);
842
855 template <int dim, class InVector, class OutVector, int spacedim>
856 void
858 const DoFHandler<dim, spacedim> & dof1,
859 const InVector & z1,
860 const DoFHandler<dim, spacedim> & dof2,
862 OutVector & z2);
863
865
879 template <int dim>
880 std::vector<unsigned int>
882
890 template <int dim>
893 std::vector<unsigned int> &h2l);
894
902 template <int dim>
905 std::vector<unsigned int> & h2l);
906
911 template <int dim>
912 DEAL_II_DEPRECATED std::vector<unsigned int>
914
921 template <int dim>
922 std::vector<unsigned int>
924
929 template <int dim>
932 std::vector<unsigned int> & l2h);
933
938 template <int dim>
939 DEAL_II_DEPRECATED std::vector<unsigned int>
941
942
1016 namespace Compositing
1017 {
1034 template <int dim, int spacedim>
1037 const std::vector<const FiniteElement<dim, spacedim> *> &fes,
1038 const std::vector<unsigned int> & multiplicities,
1039 const bool do_tensor_product = true);
1040
1046 template <int dim, int spacedim>
1049 const std::initializer_list<
1050 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1051 &fe_systems);
1052
1056 template <int dim, int spacedim>
1059 const unsigned int N1,
1060 const FiniteElement<dim, spacedim> *fe2 = nullptr,
1061 const unsigned int N2 = 0,
1062 const FiniteElement<dim, spacedim> *fe3 = nullptr,
1063 const unsigned int N3 = 0,
1064 const FiniteElement<dim, spacedim> *fe4 = nullptr,
1065 const unsigned int N4 = 0,
1066 const FiniteElement<dim, spacedim> *fe5 = nullptr,
1067 const unsigned int N5 = 0);
1068
1081 template <int dim, int spacedim>
1082 std::vector<bool>
1084 const std::vector<const FiniteElement<dim, spacedim> *> &fes,
1085 const std::vector<unsigned int> & multiplicities);
1086
1092 template <int dim, int spacedim>
1093 std::vector<bool>
1095 const std::initializer_list<
1096 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1097 &fe_systems);
1098
1113 template <int dim, int spacedim>
1114 std::vector<bool>
1117 const unsigned int N1,
1118 const FiniteElement<dim, spacedim> *fe2 = nullptr,
1119 const unsigned int N2 = 0,
1120 const FiniteElement<dim, spacedim> *fe3 = nullptr,
1121 const unsigned int N3 = 0,
1122 const FiniteElement<dim, spacedim> *fe4 = nullptr,
1123 const unsigned int N4 = 0,
1124 const FiniteElement<dim, spacedim> *fe5 = nullptr,
1125 const unsigned int N5 = 0);
1126
1127
1144 template <int dim, int spacedim>
1145 std::vector<ComponentMask>
1147 const std::vector<const FiniteElement<dim, spacedim> *> &fes,
1148 const std::vector<unsigned int> & multiplicities,
1149 const bool do_tensor_product = true);
1150
1156 template <int dim, int spacedim>
1157 std::vector<ComponentMask>
1159 const std::initializer_list<
1160 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1161 &fe_systems);
1162
1181 template <int dim, int spacedim>
1182 std::vector<ComponentMask>
1185 const unsigned int N1,
1186 const FiniteElement<dim, spacedim> *fe2 = nullptr,
1187 const unsigned int N2 = 0,
1188 const FiniteElement<dim, spacedim> *fe3 = nullptr,
1189 const unsigned int N3 = 0,
1190 const FiniteElement<dim, spacedim> *fe4 = nullptr,
1191 const unsigned int N4 = 0,
1192 const FiniteElement<dim, spacedim> *fe5 = nullptr,
1193 const unsigned int N5 = 0,
1194 const bool do_tensor_product = true);
1195
1212 template <int dim, int spacedim>
1213 void
1215 std::vector<std::pair<std::pair<unsigned int, unsigned int>,
1216 unsigned int>> &system_to_base_table,
1217 std::vector<std::pair<unsigned int, unsigned int>>
1218 & system_to_component_table,
1219 std::vector<std::pair<std::pair<unsigned int, unsigned int>,
1220 unsigned int>> &component_to_base_table,
1221 const FiniteElement<dim, spacedim> & finite_element,
1222 const bool do_tensor_product = true);
1223
1239 template <int dim, int spacedim>
1240 void
1242 std::vector<std::pair<std::pair<unsigned int, unsigned int>,
1243 unsigned int>> &face_system_to_base_table,
1244 std::vector<std::pair<unsigned int, unsigned int>>
1245 & face_system_to_component_table,
1246 const FiniteElement<dim, spacedim> &finite_element,
1247 const bool do_tensor_product = true,
1248 const unsigned int face_no = 0 /*TODO*/);
1249
1250 } // namespace Compositing
1251
1252
1286 template <int dim, int spacedim = dim>
1287 std::unique_ptr<FiniteElement<dim, spacedim>>
1288 get_fe_by_name(const std::string &name);
1289
1332 template <int dim, int spacedim>
1333 void
1334 add_fe_name(const std::string & name,
1335 const FEFactoryBase<dim, spacedim> *factory);
1336
1347 std::string,
1348 << "Can't re-generate a finite element from the string '"
1349 << arg1 << "'.");
1350
1363 char,
1364 int,
1365 << "The dimension " << arg1
1366 << " in the finite element string must match "
1367 << "the space dimension " << arg2 << ".");
1368
1375
1389
1397 "You are using continuous elements on a grid with "
1398 "hanging nodes but without providing hanging node "
1399 "constraints. Use the respective function with "
1400 "additional AffineConstraints argument(s), instead.");
1413 int,
1414 int,
1415 int,
1416 int,
1417 << "This is a " << arg1 << "x" << arg2 << " matrix, "
1418 << "but should be a " << arg3 << "x" << arg4 << " matrix.");
1419
1426 double,
1427 << "Least squares fit leaves a gap of " << arg1);
1428
1435 int,
1436 int,
1437 << arg1 << " must be greater than " << arg2);
1438} // namespace FETools
1439
1440
1441#ifndef DOXYGEN
1442
1443namespace FETools
1444{
1445 template <class FE>
1446 std::unique_ptr<FiniteElement<FE::dimension, FE::space_dimension>>
1447 FEFactory<FE>::get(const unsigned int degree) const
1448 {
1449 return std::make_unique<FE>(degree);
1450 }
1451
1452 namespace Compositing
1453 {
1454 template <int dim, int spacedim>
1455 std::vector<bool>
1457 const std::initializer_list<
1458 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1459 &fe_systems)
1460 {
1461 std::vector<const FiniteElement<dim, spacedim> *> fes;
1462 std::vector<unsigned int> multiplicities;
1463
1464 const auto extract =
1465 [&fes, &multiplicities](
1466 const std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>,
1467 unsigned int> &fe_system) {
1468 fes.push_back(fe_system.first.get());
1469 multiplicities.push_back(fe_system.second);
1470 };
1471
1472 for (const auto &p : fe_systems)
1473 extract(p);
1474
1475 return compute_restriction_is_additive_flags(fes, multiplicities);
1476 }
1477
1478
1479
1480 template <int dim, int spacedim>
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 multiply_dof_numbers(fes, multiplicities, true);
1502 }
1503
1504
1505
1506 template <int dim, int spacedim>
1507 std::vector<ComponentMask>
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 compute_nonzero_components(fes, multiplicities, true);
1528 }
1529 } // namespace Compositing
1530} // namespace FETools
1531
1532#endif
1533
1537
1538#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:162
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:402
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:403
#define DeclException0(Exception0)
Definition: exceptions.h:470
static ::ExceptionBase & ExcTriangulationMismatch()
static ::ExceptionBase & ExcInvalidFEName(std::string arg1)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:584
static ::ExceptionBase & ExcInvalidFEDimension(char arg1, int arg2)
static ::ExceptionBase & ExcLeastSquaresError(double arg1)
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:538
static ::ExceptionBase & ExcFENotPrimitive()
static ::ExceptionBase & ExcHangingNodesNotAllowed()
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:493
static ::ExceptionBase & ExcInvalidFE()
static ::ExceptionBase & ExcGridNotRefinedAtLeastOnce()
static ::ExceptionBase & ExcMatrixDimensionMismatch(int arg1, int arg2, int arg3, int arg4)
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:515
static ::ExceptionBase & ExcNotGreaterThan(int arg1, int arg2)
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)
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, FullMatrix< number >(&matrices)[GeometryInfo< dim >::max_children_per_face], 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)
@ matrix
Contents is actually a matrix.
constexpr ReturnType< rank, T >::value_type & extract(T &t, const ArrayType &indices)