Reference documentation for deal.II version 9.5.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// Copyright (C) 2000 - 2023 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>
52class DoFHandler;
53template <int dim>
55template <typename number>
57#endif
58
59
78namespace FETools
79{
88 template <int dim, int spacedim = dim>
90 {
91 public:
95 virtual std::unique_ptr<FiniteElement<dim, spacedim>>
96 get(const unsigned int degree) const = 0;
97
103 virtual std::unique_ptr<FiniteElement<dim, spacedim>>
104 get(const Quadrature<1> &quad) const = 0;
105
109 virtual ~FEFactoryBase() override = default;
110 };
111
121 template <class FE>
122 class FEFactory : public FEFactoryBase<FE::dimension, FE::space_dimension>
123 {
124 public:
128 virtual std::unique_ptr<FiniteElement<FE::dimension, FE::space_dimension>>
129 get(const unsigned int degree) const override;
130
135 virtual std::unique_ptr<FiniteElement<FE::dimension, FE::space_dimension>>
136 get(const Quadrature<1> &quad) const override;
137 };
138
154 template <int dim, int spacedim>
155 void
157 std::vector<unsigned int> & renumbering,
158 std::vector<std::vector<unsigned int>> &start_indices);
159
175 template <int dim, int spacedim>
176 void
178 std::vector<types::global_dof_index> &renumbering,
179 std::vector<types::global_dof_index> &block_data,
180 bool return_start_indices = true);
181
195 template <int dim, typename number, int spacedim>
196 void
199 FullMatrix<number> &interpolation_matrix);
200
212 template <int dim, typename number, int spacedim>
213 void
216 FullMatrix<number> &interpolation_matrix);
217
229 template <int dim, typename number, int spacedim>
230 void
233 FullMatrix<number> &difference_matrix);
234
238 template <int dim, typename number, int spacedim>
239 void
242 FullMatrix<number> & matrix);
243
312 template <int dim, int spacedim>
315
354 template <int dim, typename number, int spacedim>
355 void
358 std::vector<std::vector<FullMatrix<number>>> &matrices,
359 const bool isotropic_only = false,
360 const double threshold = 1.e-12);
361
383 template <int dim, typename number, int spacedim>
384 void
388 const unsigned int face_coarse,
389 const unsigned int face_fine,
390 const double threshold = 1.e-12);
391
423 template <int dim, typename number, int spacedim>
424 void
427 std::vector<std::vector<FullMatrix<number>>> &matrices,
428 const bool isotropic_only = false);
429
515 template <int dim, int spacedim>
516 void
519 const Quadrature<dim> & lhs_quadrature,
520 const Quadrature<dim> & rhs_quadrature,
522
530 template <int dim, int spacedim>
531 void
534 const Quadrature<dim> & quadrature,
535 FullMatrix<double> & I_q);
536
550 template <int dim>
551 void
553 const FullMatrix<double> & projection_matrix,
554 const std::vector<Tensor<1, dim>> &vector_of_tensors_at_qp,
555 std::vector<Tensor<1, dim>> & vector_of_tensors_at_nodes);
556
557
558
562 template <int dim>
563 void
565 const FullMatrix<double> & projection_matrix,
566 const std::vector<SymmetricTensor<2, dim>> &vector_of_tensors_at_qp,
567 std::vector<SymmetricTensor<2, dim>> & vector_of_tensors_at_nodes);
568
569
570
580 template <int dim, int spacedim>
581 void
584 const Quadrature<dim - 1> & lhs_quadrature,
585 const Quadrature<dim - 1> & rhs_quadrature,
587 const unsigned int face,
589
590
591
607 template <int dim, int spacedim, typename number>
608 void
610 const FiniteElement<dim, spacedim> &finite_element,
611 const std::vector<Vector<number>> & support_point_values,
612 std::vector<number> & dof_values);
613
614
615
650 template <int dim, int spacedim, class InVector, class OutVector>
651 void
653 const InVector & u1,
654 const DoFHandler<dim, spacedim> &dof2,
655 OutVector & u2);
656
673 template <int dim, int spacedim, class InVector, class OutVector>
674 void
676 const DoFHandler<dim, spacedim> & dof1,
677 const InVector & u1,
678 const DoFHandler<dim, spacedim> & dof2,
680 OutVector & u2);
681
695 template <int dim, class InVector, class OutVector, int spacedim>
696 void
698 const InVector & u1,
700 OutVector & u1_interpolated);
701
714 template <int dim, class InVector, class OutVector, int spacedim>
715 void
717 const DoFHandler<dim, spacedim> & dof1,
719 const InVector & u1,
720 const DoFHandler<dim, spacedim> & dof2,
722 OutVector & u1_interpolated);
723
733 template <int dim, class InVector, class OutVector, int spacedim>
734 void
736 const InVector & z1,
738 OutVector & z1_difference);
739
752 template <int dim, class InVector, class OutVector, int spacedim>
753 void
755 const DoFHandler<dim, spacedim> & dof1,
757 const InVector & z1,
758 const DoFHandler<dim, spacedim> & dof2,
760 OutVector & z1_difference);
761
762
763
772 template <int dim, class InVector, class OutVector, int spacedim>
773 void
775 const InVector & u1,
776 const DoFHandler<dim, spacedim> &dof2,
777 OutVector & u2);
778
839 template <int dim, class InVector, class OutVector, int spacedim>
840 void
842 const InVector & z1,
843 const DoFHandler<dim, spacedim> &dof2,
844 OutVector & z2);
845
858 template <int dim, class InVector, class OutVector, int spacedim>
859 void
861 const DoFHandler<dim, spacedim> & dof1,
862 const InVector & z1,
863 const DoFHandler<dim, spacedim> & dof2,
865 OutVector & z2);
866
882 template <int dim>
883 std::vector<unsigned int>
885
892 template <int dim>
893 std::vector<unsigned int>
895
971 namespace Compositing
972 {
989 template <int dim, int spacedim>
992 const std::vector<const FiniteElement<dim, spacedim> *> &fes,
993 const std::vector<unsigned int> & multiplicities,
994 const bool do_tensor_product = true);
995
1001 template <int dim, int spacedim>
1004 const std::initializer_list<
1005 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1006 &fe_systems);
1007
1011 template <int dim, int spacedim>
1014 const unsigned int N1,
1015 const FiniteElement<dim, spacedim> *fe2 = nullptr,
1016 const unsigned int N2 = 0,
1017 const FiniteElement<dim, spacedim> *fe3 = nullptr,
1018 const unsigned int N3 = 0,
1019 const FiniteElement<dim, spacedim> *fe4 = nullptr,
1020 const unsigned int N4 = 0,
1021 const FiniteElement<dim, spacedim> *fe5 = nullptr,
1022 const unsigned int N5 = 0);
1023
1036 template <int dim, int spacedim>
1037 std::vector<bool>
1039 const std::vector<const FiniteElement<dim, spacedim> *> &fes,
1040 const std::vector<unsigned int> & multiplicities);
1041
1047 template <int dim, int spacedim>
1048 std::vector<bool>
1050 const std::initializer_list<
1051 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1052 &fe_systems);
1053
1068 template <int dim, int spacedim>
1069 std::vector<bool>
1072 const unsigned int N1,
1073 const FiniteElement<dim, spacedim> *fe2 = nullptr,
1074 const unsigned int N2 = 0,
1075 const FiniteElement<dim, spacedim> *fe3 = nullptr,
1076 const unsigned int N3 = 0,
1077 const FiniteElement<dim, spacedim> *fe4 = nullptr,
1078 const unsigned int N4 = 0,
1079 const FiniteElement<dim, spacedim> *fe5 = nullptr,
1080 const unsigned int N5 = 0);
1081
1082
1099 template <int dim, int spacedim>
1100 std::vector<ComponentMask>
1102 const std::vector<const FiniteElement<dim, spacedim> *> &fes,
1103 const std::vector<unsigned int> & multiplicities,
1104 const bool do_tensor_product = true);
1105
1111 template <int dim, int spacedim>
1112 std::vector<ComponentMask>
1114 const std::initializer_list<
1115 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1116 &fe_systems);
1117
1136 template <int dim, int spacedim>
1137 std::vector<ComponentMask>
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 const bool do_tensor_product = true);
1150
1167 template <int dim, int spacedim>
1168 void
1170 std::vector<std::pair<std::pair<unsigned int, unsigned int>,
1171 unsigned int>> &system_to_base_table,
1172 std::vector<std::pair<unsigned int, unsigned int>>
1173 & system_to_component_table,
1174 std::vector<std::pair<std::pair<unsigned int, unsigned int>,
1175 unsigned int>> &component_to_base_table,
1176 const FiniteElement<dim, spacedim> & finite_element,
1177 const bool do_tensor_product = true);
1178
1194 template <int dim, int spacedim>
1195 void
1197 std::vector<std::pair<std::pair<unsigned int, unsigned int>,
1198 unsigned int>> &face_system_to_base_table,
1199 std::vector<std::pair<unsigned int, unsigned int>>
1200 & face_system_to_component_table,
1201 const FiniteElement<dim, spacedim> &finite_element,
1202 const bool do_tensor_product = true,
1203 const unsigned int face_no = 0 /*TODO*/);
1204
1205 } // namespace Compositing
1206
1207
1241 template <int dim, int spacedim = dim>
1242 std::unique_ptr<FiniteElement<dim, spacedim>>
1243 get_fe_by_name(const std::string &name);
1244
1287 template <int dim, int spacedim>
1288 void
1289 add_fe_name(const std::string & name,
1290 const FEFactoryBase<dim, spacedim> *factory);
1291
1302 std::string,
1303 << "Can't re-generate a finite element from the string '"
1304 << arg1 << "'.");
1305
1318 char,
1319 int,
1320 << "The dimension " << arg1
1321 << " in the finite element string must match "
1322 << "the space dimension " << arg2 << '.');
1323
1330
1344
1352 "You are using continuous elements on a grid with "
1353 "hanging nodes but without providing hanging node "
1354 "constraints. Use the respective function with "
1355 "additional AffineConstraints argument(s), instead.");
1368 int,
1369 int,
1370 int,
1371 int,
1372 << "This is a " << arg1 << 'x' << arg2 << " matrix, "
1373 << "but should be a " << arg3 << 'x' << arg4 << " matrix.");
1374
1381 double,
1382 << "Least squares fit leaves a gap of " << arg1);
1383
1390 int,
1391 int,
1392 << arg1 << " must be greater than " << arg2);
1393} // namespace FETools
1394
1395
1396#ifndef DOXYGEN
1397
1398namespace FETools
1399{
1400 template <class FE>
1401 std::unique_ptr<FiniteElement<FE::dimension, FE::space_dimension>>
1402 FEFactory<FE>::get(const unsigned int degree) const
1403 {
1404 return std::make_unique<FE>(degree);
1405 }
1406
1407 namespace Compositing
1408 {
1409 template <int dim, int spacedim>
1410 std::vector<bool>
1412 const std::initializer_list<
1413 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1414 &fe_systems)
1415 {
1416 std::vector<const FiniteElement<dim, spacedim> *> fes;
1417 std::vector<unsigned int> multiplicities;
1418
1419 const auto extract =
1420 [&fes, &multiplicities](
1421 const std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>,
1422 unsigned int> &fe_system) {
1423 fes.push_back(fe_system.first.get());
1424 multiplicities.push_back(fe_system.second);
1425 };
1426
1427 for (const auto &p : fe_systems)
1428 extract(p);
1429
1430 return compute_restriction_is_additive_flags(fes, multiplicities);
1431 }
1432
1433
1434
1435 template <int dim, int spacedim>
1438 const std::initializer_list<
1439 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1440 &fe_systems)
1441 {
1442 std::vector<const FiniteElement<dim, spacedim> *> fes;
1443 std::vector<unsigned int> multiplicities;
1444
1445 const auto extract =
1446 [&fes, &multiplicities](
1447 const std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>,
1448 unsigned int> &fe_system) {
1449 fes.push_back(fe_system.first.get());
1450 multiplicities.push_back(fe_system.second);
1451 };
1452
1453 for (const auto &p : fe_systems)
1454 extract(p);
1455
1456 return multiply_dof_numbers(fes, multiplicities, true);
1457 }
1458
1459
1460
1461 template <int dim, int spacedim>
1462 std::vector<ComponentMask>
1464 const std::initializer_list<
1465 std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>, unsigned int>>
1466 &fe_systems)
1467 {
1468 std::vector<const FiniteElement<dim, spacedim> *> fes;
1469 std::vector<unsigned int> multiplicities;
1470
1471 const auto extract =
1472 [&fes, &multiplicities](
1473 const std::pair<std::unique_ptr<FiniteElement<dim, spacedim>>,
1474 unsigned int> &fe_system) {
1475 fes.push_back(fe_system.first.get());
1476 multiplicities.push_back(fe_system.second);
1477 };
1478
1479 for (const auto &p : fe_systems)
1480 extract(p);
1481
1482 return compute_nonzero_components(fes, multiplicities, true);
1483 }
1484 } // namespace Compositing
1485} // namespace FETools
1486
1487#endif
1488
1492
1493#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_NAMESPACE_OPEN
Definition config.h:472
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:160
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:473
#define DeclException0(Exception0)
Definition exceptions.h:465
static ::ExceptionBase & ExcTriangulationMismatch()
static ::ExceptionBase & ExcInvalidFEName(std::string arg1)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition exceptions.h:579
static ::ExceptionBase & ExcInvalidFEDimension(char arg1, int arg2)
static ::ExceptionBase & ExcLeastSquaresError(double arg1)
#define DeclException2(Exception2, type1, type2, outsequence)
Definition exceptions.h:533
static ::ExceptionBase & ExcFENotPrimitive()
static ::ExceptionBase & ExcHangingNodesNotAllowed()
#define DeclExceptionMsg(Exception, defaulttext)
Definition exceptions.h:488
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:510
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)
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)
constexpr ReturnType< rank, T >::value_type & extract(T &t, const ArrayType &indices)