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
dof_accessor_get.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) 1998 - 2026 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
16
17#include <deal.II/fe/fe.h>
18
20
32#include <deal.II/lac/vector.h>
33
34#include <complex>
35#include <vector>
36
38
39
40template <int dim, int spacedim, bool lda>
41template <typename Number>
42void
44 const ReadVector<Number> &values,
45 Vector<Number> &interpolated_values,
46 const types::fe_index fe_index_) const
47{
48 return this->get_interpolated_dof_values(
49 values,
50 make_array_view(interpolated_values.begin(), interpolated_values.end()),
51 fe_index_);
52}
53
54template <int dim, int spacedim, bool lda>
55template <typename Number>
56void
58 const ReadVector<Number> &values,
59 ArrayView<Number> interpolated_values,
60 const types::fe_index fe_index_) const
61{
62 const types::fe_index fe_index =
63 (this->dof_handler->hp_capability_enabled == false &&
64 fe_index_ == numbers::invalid_fe_index) ?
66 fe_index_;
67
68 if (this->is_active())
69 // If this cell is active: simply return the exact values on this
70 // cell unless the finite element we need to interpolate to is different
71 // than the one we have on the current cell
72 {
73 if ((this->dof_handler->hp_capability_enabled == false) ||
74 // for hp-DoFHandlers, we need to require that on
75 // active cells, you either don't specify an fe_index,
76 // or that you specify the correct one
77 (fe_index == this->active_fe_index()) ||
78 (fe_index == numbers::invalid_fe_index))
79 this->get_dof_values(values,
80 interpolated_values.begin(),
81 interpolated_values.end());
82 else
83 {
84 // well, here we need to first get the values from the current
85 // cell and then interpolate it to the element requested. this
86 // can clearly only happen for DoFHandler objects in hp-mode
87 const unsigned int dofs_per_cell = this->get_fe().n_dofs_per_cell();
88 if (dofs_per_cell == 0)
89 {
90 std::fill(interpolated_values.begin(),
91 interpolated_values.end(),
92 Number(0.0));
93 }
94 else
95 {
96 Vector<Number> dof_values(dofs_per_cell),
97 tmp(interpolated_values.size());
98 this->get_dof_values(values, dof_values);
99
100 FullMatrix<double> interpolation(
101 this->dof_handler->get_fe(fe_index).n_dofs_per_cell(),
102 this->get_fe().n_dofs_per_cell());
103 this->dof_handler->get_fe(fe_index).get_interpolation_matrix(
104 this->get_fe(), interpolation);
105 interpolation.vmult(tmp, dof_values);
106 std::copy(tmp.begin(), tmp.end(), interpolated_values.begin());
107 }
108 }
109 }
110 else
111 // The cell is not active; we need to obtain data them from
112 // children recursively.
113 {
114 // we are on a non-active cell. these do not have any finite
115 // element associated with them in the hp-context (in the non-hp-
116 // context, we can simply assume that the FE space to which we
117 // want to interpolate is the same as for all elements in the
118 // mesh). consequently, we cannot interpolate from children's FE
119 // space to this cell's (unknown) FE space unless an explicit
120 // fe_index is given
121 Assert((this->dof_handler->hp_capability_enabled == false) ||
122 (fe_index != numbers::invalid_fe_index),
124 "You cannot call this function on non-active cells "
125 "of DoFHandler objects unless you provide an explicit "
126 "finite element index because they do not have naturally "
127 "associated finite element spaces associated: degrees "
128 "of freedom are only distributed on active cells for which "
129 "the active FE index has been set."));
130
132 this->get_dof_handler().get_fe(fe_index);
133 const unsigned int dofs_per_cell = fe.n_dofs_per_cell();
134
135 Assert(this->dof_handler != nullptr,
136 typename BaseClass::ExcInvalidObject());
137 Assert(interpolated_values.size() == dofs_per_cell,
138 typename BaseClass::ExcVectorDoesNotMatch());
139 Assert(values.size() == this->dof_handler->n_dofs(),
140 typename BaseClass::ExcVectorDoesNotMatch());
141
142
143 // see if the finite element we have on the current cell has any
144 // degrees of freedom to begin with; if not (e.g., when
145 // interpolating FE_Nothing), then simply skip all of the
146 // following since the output vector would be of size zero
147 // anyway (and in fact is of size zero, see the assertion above)
148 if (fe.n_dofs_per_cell() > 0)
149 {
150 Vector<Number> tmp1(dofs_per_cell);
151 Vector<Number> tmp2(dofs_per_cell);
152 std::fill(interpolated_values.begin(),
153 interpolated_values.end(),
154 Number(0.0));
155
156 // later on we will have to push the values interpolated from the
157 // child to the mother cell into the output vector. unfortunately,
158 // there are two types of elements: ones where you add up the
159 // contributions from the different child cells, and ones where you
160 // overwrite.
161 //
162 // an example for the first is piecewise constant (and discontinuous)
163 // elements, where we build the value on the coarse cell by averaging
164 // the values from the cell (i.e. by adding up a fraction of the
165 // values of their values)
166 //
167 // an example for the latter are the usual continuous elements. the
168 // value on a vertex of a coarse cell must there be the same,
169 // irrespective of the adjacent cell we are presently on. so we always
170 // overwrite. in fact, we must, since we cannot know in advance how
171 // many neighbors there will be, so there is no way to compute the
172 // average with fixed factors
173 //
174 // so we have to find out to which type this element belongs. the
175 // difficulty is: the finite element may be a composed one, so we can
176 // only hope to do this for each shape function individually. in fact,
177 // there are even weird finite elements (for example the
178 // Raviart-Thomas element) which have shape functions that are
179 // additive (interior ones) and others that are overwriting (face
180 // degrees of freedom that need to be continuous across the face).
181 for (unsigned int child = 0; child < this->n_children(); ++child)
182 {
183 // get the values from the present child, if necessary by
184 // interpolation itself either from its own children or
185 // by interpolating from the finite element on an active
186 // child to the finite element space requested here
187 this->child(child)->get_interpolated_dof_values(values,
188 tmp1,
189 fe_index);
190 // interpolate these to the mother cell
191 fe.get_restriction_matrix(child, this->refinement_case())
192 .vmult(tmp2, tmp1);
193
194 // and add up or set them in the output vector
195 for (unsigned int i = 0; i < dofs_per_cell; ++i)
196 if (fe.restriction_is_additive(i))
197 interpolated_values[i] += tmp2(i);
198 else if (tmp2(i) != Number())
199 interpolated_values[i] = tmp2(i);
200 }
201 }
202 }
203}
204
205
206// --------------------------------------------------------------------------
207// explicit instantiations
208#include "dofs/dof_accessor_get.inst"
209
ArrayView< std::remove_reference_t< typename std::iterator_traits< Iterator >::reference >, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
iterator begin() const
Definition array_view.h:755
iterator end() const
Definition array_view.h:764
std::size_t size() const
Definition array_view.h:737
void get_interpolated_dof_values(const ReadVector< Number > &values, ArrayView< Number > interpolated_values, const types::fe_index fe_index=numbers::invalid_fe_index) const
unsigned int n_dofs_per_cell() const
virtual const FullMatrix< double > & get_restriction_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
bool restriction_is_additive(const unsigned int index) const
void vmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
iterator end()
iterator begin()
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define Assert(cond, exc)
static ::ExceptionBase & ExcMessage(std::string arg1)
constexpr types::fe_index invalid_fe_index
Definition types.h:250
unsigned short int fe_index
Definition types.h:70