deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+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
fe_trace.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2014 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#include <deal.II/base/config.h>
14
17
20#include <deal.II/fe/fe_q.h>
21#include <deal.II/fe/fe_tools.h>
22#include <deal.II/fe/fe_trace.h>
23
24#include <fstream>
25#include <iostream>
26#include <memory>
27#include <sstream>
28
30
31
32
33template <int dim, int spacedim>
34FE_TraceQ<dim, spacedim>::FE_TraceQ(const unsigned int degree)
35 : FE_PolyFace<TensorProductPolynomials<dim - 1>, dim, spacedim>(
37 Polynomials::generate_complete_Lagrange_basis(
38 QGaussLobatto<1>(degree + 1).get_points())),
39 FiniteElementData<dim>(get_dpo_vector(degree),
40 1,
41 degree,
42 FiniteElementData<dim>::L2),
43 std::vector<bool>(1, true))
44 , fe_q(degree)
45{
46 Assert(degree > 0,
47 ExcMessage("FE_Trace can only be used for polynomial degrees "
48 "greater than zero"));
49 this->poly_space.set_numbering(
50 FETools::hierarchic_to_lexicographic_numbering<dim - 1>(degree));
51
52 // Initialize face support points
53 AssertDimension(this->n_unique_faces(), fe_q.n_unique_faces());
54 for (unsigned int face_no = 0; face_no < this->n_unique_faces(); ++face_no)
55 this->unit_face_support_points[face_no] =
56 fe_q.get_unit_face_support_points(face_no);
57
58 // initialize unit support points (this makes it possible to assign initial
59 // values to FE_TraceQ). Note that we simply take the points of fe_q but
60 // skip the last ones which are associated with the interior of FE_Q.
61 this->unit_support_points.resize(this->n_dofs_per_cell());
62 for (unsigned int i = 0; i < this->n_dofs_per_cell(); ++i)
63 this->unit_support_points[i] = fe_q.get_unit_support_points()[i];
64
65 // Initialize constraint matrices
66 this->interface_constraints = fe_q.constraints();
67}
68
69
70
71template <int dim, int spacedim>
72std::unique_ptr<FiniteElement<dim, spacedim>>
74{
75 return std::make_unique<FE_TraceQ<dim, spacedim>>(this->degree);
76}
77
78
79
80template <int dim, int spacedim>
81std::string
83{
84 // note that the FETools::get_fe_by_name function depends on the
85 // particular format of the string this function returns, so they have to be
86 // kept in synch
87
88 std::ostringstream namebuf;
89 namebuf << "FE_TraceQ<" << Utilities::dim_string(dim, spacedim) << ">("
90 << this->degree << ")";
91
92 return namebuf.str();
93}
94
95
96
97template <int dim, int spacedim>
98bool
100 const unsigned int shape_index,
101 const unsigned int face_index) const
102{
103 AssertIndexRange(shape_index, this->n_dofs_per_cell());
105
106 // FE_TraceQ shares the numbering of elemental degrees of freedom with FE_Q
107 // except for the missing interior ones (quad dofs in 2d and hex dofs in
108 // 3d). Therefore, it is safe to ask fe_q for the corresponding
109 // information. The assertion 'shape_index < this->n_dofs_per_cell()' will
110 // make sure that we only access the trace dofs.
111 return fe_q.has_support_on_face(shape_index, face_index);
112}
113
114
115
116template <int dim, int spacedim>
117std::pair<Table<2, bool>, std::vector<unsigned int>>
119{
120 Table<2, bool> constant_modes(1, this->n_dofs_per_cell());
121 for (unsigned int i = 0; i < this->n_dofs_per_cell(); ++i)
122 constant_modes(0, i) = true;
123 return std::pair<Table<2, bool>, std::vector<unsigned int>>(
124 constant_modes, std::vector<unsigned int>(1, 0));
125}
126
127template <int dim, int spacedim>
128void
131 const std::vector<Vector<double>> &support_point_values,
132 std::vector<double> &nodal_values) const
133{
134 AssertDimension(support_point_values.size(),
135 this->get_unit_support_points().size());
136 AssertDimension(support_point_values.size(), nodal_values.size());
137 AssertDimension(this->n_dofs_per_cell(), nodal_values.size());
138
139 for (unsigned int i = 0; i < this->n_dofs_per_cell(); ++i)
140 {
141 AssertDimension(support_point_values[i].size(), 1);
142
143 nodal_values[i] = support_point_values[i](0);
144 }
145}
146
147
148template <int dim, int spacedim>
149std::vector<unsigned int>
151{
152 // This constructs FE_TraceQ in exactly the same way as FE_Q except for the
153 // interior degrees of freedom that are not present here (line in 1d, quad
154 // in 2d, hex in 3d).
155 AssertThrow(deg > 0, ExcMessage("FE_TraceQ needs to be of degree > 0."));
156 std::vector<unsigned int> dpo(dim + 1, 1U);
157 dpo[dim] = 0;
158 dpo[0] = 1;
159 for (unsigned int i = 1; i < dim; ++i)
160 dpo[i] = dpo[i - 1] * (deg - 1);
161 return dpo;
162}
163
164
165
166template <int dim, int spacedim>
167bool
169{
170 return fe_q.hp_constraints_are_implemented();
171}
172
173
174template <int dim, int spacedim>
177 const FiniteElement<dim, spacedim> &fe_other,
178 const unsigned int codim) const
179{
180 Assert(codim <= dim, ExcImpossibleInDim(dim));
181 (void)codim;
182
183 // vertex/line/face/cell domination
184 // --------------------------------
185 if (const FE_TraceQ<dim, spacedim> *fe_traceq_other =
186 dynamic_cast<const FE_TraceQ<dim, spacedim> *>(&fe_other))
187 {
188 if (this->degree < fe_traceq_other->degree)
190 else if (this->degree == fe_traceq_other->degree)
192 else
194 }
195 else if (const FE_Nothing<dim> *fe_nothing =
196 dynamic_cast<const FE_Nothing<dim> *>(&fe_other))
197 {
198 if (fe_nothing->is_dominating())
200 else
201 // the FE_Nothing has no degrees of freedom and it is typically used
202 // in a context where we don't require any continuity along the
203 // interface
205 }
206
209}
210
211
212
213template <int dim, int spacedim>
214void
216 const FiniteElement<dim, spacedim> &source_fe,
217 FullMatrix<double> &interpolation_matrix,
218 const unsigned int face_no) const
219{
220 get_subface_interpolation_matrix(source_fe,
222 interpolation_matrix,
223 face_no);
224}
225
226
227
228template <int dim, int spacedim>
229void
231 const FiniteElement<dim, spacedim> &x_source_fe,
232 const unsigned int subface,
233 FullMatrix<double> &interpolation_matrix,
234 const unsigned int face_no) const
235{
236 // this is the code from FE_FaceQ
237 Assert(interpolation_matrix.n() == this->n_dofs_per_face(face_no),
238 ExcDimensionMismatch(interpolation_matrix.n(),
239 this->n_dofs_per_face(face_no)));
240 Assert(interpolation_matrix.m() == x_source_fe.n_dofs_per_face(face_no),
241 ExcDimensionMismatch(interpolation_matrix.m(),
242 x_source_fe.n_dofs_per_face(face_no)));
243
244 // see if source is a FaceQ element
245 if (const FE_TraceQ<dim, spacedim> *source_fe =
246 dynamic_cast<const FE_TraceQ<dim, spacedim> *>(&x_source_fe))
247 {
248 fe_q.get_subface_interpolation_matrix(source_fe->fe_q,
249 subface,
250 interpolation_matrix,
251 face_no);
252 }
253 else if (dynamic_cast<const FE_Nothing<dim> *>(&x_source_fe) != nullptr)
254 {
255 // nothing to do here, the FE_Nothing has no degrees of freedom anyway
256 }
257 else
259 false,
260 (typename FiniteElement<dim,
261 spacedim>::ExcInterpolationNotImplemented()));
262}
263
264
265
266template <int spacedim>
267FE_TraceQ<1, spacedim>::FE_TraceQ(const unsigned int degree)
268 : FE_FaceQ<1, spacedim>(degree)
269{}
270
271
272
273template <int spacedim>
274std::string
276{
277 // note that the FETools::get_fe_by_name function depends on the
278 // particular format of the string this function returns, so they have to be
279 // kept in synch
280 std::ostringstream namebuf;
281 namebuf << "FE_TraceQ<" << Utilities::dim_string(1, spacedim) << ">("
282 << this->degree << ")";
283
284 return namebuf.str();
285}
286
287
288
289// explicit instantiations
290#include "fe/fe_trace.inst"
291
292
PolynomialType poly_space
FE_Q< dim, spacedim > fe_q
Definition fe_trace.h:138
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
Definition fe_trace.cc:73
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const override
Definition fe_trace.cc:99
virtual std::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const override
Definition fe_trace.cc:118
virtual bool hp_constraints_are_implemented() const override
Definition fe_trace.cc:168
virtual FiniteElementDomination::Domination compare_for_domination(const FiniteElement< dim, spacedim > &fe_other, const unsigned int codim=0) const override final
Definition fe_trace.cc:176
virtual void convert_generalized_support_point_values_to_dof_values(const std::vector< Vector< double > > &support_point_values, std::vector< double > &nodal_values) const override
Definition fe_trace.cc:130
virtual void get_subface_interpolation_matrix(const FiniteElement< dim, spacedim > &source, const unsigned int subface, FullMatrix< double > &matrix, const unsigned int face_no=0) const override
Definition fe_trace.cc:230
virtual std::string get_name() const override
Definition fe_trace.cc:82
static std::vector< unsigned int > get_dpo_vector(const unsigned int deg)
Definition fe_trace.cc:150
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix, const unsigned int face_no=0) const override
Definition fe_trace.cc:215
FE_TraceQ(unsigned int p)
Definition fe_trace.cc:34
const unsigned int degree
Definition fe_data.h:450
unsigned int n_dofs_per_cell() const
unsigned int n_dofs_per_face(unsigned int face_no=0, unsigned int child=0) const
unsigned int n_unique_faces() const
std::vector< std::vector< Point< dim - 1 > > > unit_face_support_points
Definition fe.h:2592
std::vector< Point< dim > > unit_support_points
Definition fe.h:2585
FullMatrix< double > interface_constraints
Definition fe.h:2573
size_type n() const
size_type m() const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_NOT_IMPLEMENTED()
#define Assert(cond, exc)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::size_t size
Definition mpi.cc:733
std::string dim_string(const int dim, const int spacedim)
Definition utilities.cc:547
constexpr unsigned int invalid_unsigned_int
Definition types.h:228
STL namespace.