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
fe_q_iso_q1.cc
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2013 - 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
18
19#include <deal.II/fe/fe_dgq.h>
22#include <deal.II/fe/fe_tools.h>
23
24#include <deal.II/lac/vector.h>
25
26#include <memory>
27#include <sstream>
28#include <vector>
29
31
32
33
34template <int dim, int spacedim>
35FE_Q_iso_Q1<dim, spacedim>::FE_Q_iso_Q1(const unsigned int subdivisions)
36 : FE_Q_Base<dim, spacedim>(
37 TensorProductPolynomials<dim, Polynomials::PiecewisePolynomial<double>>(
38 Polynomials::generate_complete_Lagrange_basis_on_subdivisions(
39 subdivisions,
40 1)),
41 FiniteElementData<dim>(this->get_dpo_vector(subdivisions),
42 1,
43 subdivisions,
44 FiniteElementData<dim>::H1),
45 std::vector<bool>(1, false))
46{
47 Assert(subdivisions > 0,
48 ExcMessage("This element can only be used with a positive number of "
49 "subelements"));
50
51 const QTrapezoid<1> trapez;
52 const QIterated<1> points(trapez, subdivisions);
53
54 this->initialize(points.get_points());
55
56 {
57 const std::vector<unsigned int> R =
58 FETools::lexicographic_to_hierarchic_numbering<dim>(subdivisions);
59
61 this->n_dofs_per_cell());
62
63 {
64 this->local_dof_sparsity_pattern.fill(false);
65
66 const unsigned int N = Utilities::pow(points.size(), dim);
67 const int N1d = points.size();
68 for (unsigned int i = 0; i < N; ++i)
69 for (unsigned int j = 0; j < N; ++j)
70 {
71 // compute l1 distance:
72 int distance = 0;
73
74 int xi = i;
75 int xj = j;
76 for (unsigned int d = 0; d < dim; ++d)
77 {
78 int current_distance = std::abs((xi % N1d) - (xj % N1d));
79 xi /= N1d;
80 xj /= N1d;
81 distance = std::max(distance, current_distance);
82 if (distance > 1)
83 break;
84 }
85
86 if (distance <= 1)
87 this->local_dof_sparsity_pattern(R[i], R[j]) = true;
88 }
89 }
90 }
91}
92
93
94
95template <int dim, int spacedim>
97 const std::vector<Point<1>> &support_points)
98 : FE_Q_Base<dim, spacedim>(
99 TensorProductPolynomials<dim, Polynomials::PiecewisePolynomial<double>>(
100 Polynomials::generate_complete_linear_basis_on_subdivisions(
101 support_points)),
102 FiniteElementData<dim>(this->get_dpo_vector(support_points.size() - 1),
103 1,
104 support_points.size() - 1,
105 FiniteElementData<dim>::H1),
106 std::vector<bool>(1, false))
107{
108 Assert(support_points.size() > 1,
109 ExcMessage("This element can only be used with a positive number of "
110 "subelements"));
111
112 this->initialize(support_points);
113}
114
115
116
117template <int dim, int spacedim>
118std::string
120{
121 // note that the FETools::get_fe_by_name function depends on the
122 // particular format of the string this function returns, so they have to be
123 // kept in sync
124
125 std::ostringstream namebuf;
126 namebuf << "FE_Q_iso_Q1<" << Utilities::dim_string(dim, spacedim) << ">("
127 << this->degree << ")";
128 return namebuf.str();
129}
130
131
132
133template <int dim, int spacedim>
134void
137 const std::vector<Vector<double>> &support_point_values,
138 std::vector<double> &nodal_values) const
139{
140 AssertDimension(support_point_values.size(),
141 this->get_unit_support_points().size());
142 AssertDimension(support_point_values.size(), nodal_values.size());
143 AssertDimension(this->n_dofs_per_cell(), nodal_values.size());
144
145 for (unsigned int i = 0; i < this->n_dofs_per_cell(); ++i)
146 {
147 AssertDimension(support_point_values[i].size(), 1);
148
149 nodal_values[i] = support_point_values[i](0);
150 }
151}
152
153
154
155template <int dim, int spacedim>
156std::unique_ptr<FiniteElement<dim, spacedim>>
158{
159 return std::make_unique<FE_Q_iso_Q1<dim, spacedim>>(*this);
160}
161
162
163
164template <int dim, int spacedim>
167 const FiniteElement<dim, spacedim> &fe_other,
168 const unsigned int codim) const
169{
170 Assert(codim <= dim, ExcImpossibleInDim(dim));
171 (void)codim;
172
173 // vertex/line/face domination
174 // (if fe_other is derived from FE_DGQ)
175 // ------------------------------------
176 if (codim > 0)
177 if (dynamic_cast<const FE_DGQ<dim, spacedim> *>(&fe_other) != nullptr)
178 // there are no requirements between continuous and discontinuous elements
180
181 // vertex/line/face domination
182 // (if fe_other is not derived from FE_DGQ)
183 // & cell domination
184 // ----------------------------------------
185 if (const FE_Q_iso_Q1<dim, spacedim> *fe_q_iso_q1_other =
186 dynamic_cast<const FE_Q_iso_Q1<dim, spacedim> *>(&fe_other))
187 {
188 // different behavior as in FE_Q: as FE_Q_iso_Q1(2) is not a subspace of
189 // FE_Q_iso_Q1(3), need that the element degrees are multiples of each
190 // other
191 if (this->degree < fe_q_iso_q1_other->degree &&
192 fe_q_iso_q1_other->degree % this->degree == 0)
194 else if (this->degree == fe_q_iso_q1_other->degree)
196 else if (this->degree > fe_q_iso_q1_other->degree &&
197 this->degree % fe_q_iso_q1_other->degree == 0)
199 else
201 }
202 else if (const FE_Nothing<dim> *fe_nothing =
203 dynamic_cast<const FE_Nothing<dim> *>(&fe_other))
204 {
205 if (fe_nothing->is_dominating())
207 else
208 // the FE_Nothing has no degrees of freedom and it is typically used
209 // in a context where we don't require any continuity along the
210 // interface
212 }
213
216}
217
218
219
220// explicit instantiations
221#include "fe_q_iso_q1.inst"
222
void initialize(const std::vector< Point< 1 > > &support_points_1d)
virtual FiniteElementDomination::Domination compare_for_domination(const FiniteElement< dim, spacedim > &fe_other, const unsigned int codim=0) const override final
virtual std::string get_name() const override
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
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
FE_Q_iso_Q1(const unsigned int n_subdivisions)
unsigned int n_dofs_per_cell() const
Table< 2, bool > local_dof_sparsity_pattern
Definition fe.h:2649
Definition point.h:111
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
#define Assert(cond, exc)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define DEAL_II_NOT_IMPLEMENTED()
std::size_t size
Definition mpi.cc:734
std::string dim_string(const int dim, const int spacedim)
Definition utilities.cc:555
constexpr T pow(const T base, const int iexp)
Definition utilities.h:966
STL namespace.
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)