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_set.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) 2013 - 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 <iomanip>
35#include <limits>
36#include <vector>
37
39
40template <typename Number>
42 Number,
43 Number,
44 << "Called set_dof_values_by_interpolation(), but"
45 << " the element to be set, value " << std::setprecision(16)
46 << arg1 << ", does not match with the non-zero value "
47 << std::setprecision(16) << arg2 << " already set before.");
48
49namespace internal
50{
51#ifdef DEBUG
57 template <typename Number>
58 std::enable_if_t<!std::is_unsigned_v<Number>,
60 get_abs(const Number a)
61 {
62 return std::abs(a);
63 }
64
65 template <typename Number>
66 std::enable_if_t<std::is_unsigned_v<Number>, Number>
67 get_abs(const Number a)
68 {
69 return a;
70 }
71
72
77 template <typename T>
79 decltype(std::declval<const T>().set_ghost_state(std::declval<bool>()));
80
81 template <typename T>
82 constexpr bool has_set_ghost_state =
83 is_supported_operation<set_ghost_state_t, T>;
84
85 template <
86 typename VectorType,
87 std::enable_if_t<has_set_ghost_state<VectorType>, VectorType> * = nullptr>
88 void
89 set_ghost_state(VectorType &vector, const bool ghosted)
90 {
91 vector.set_ghost_state(ghosted);
92 }
93
94 template <
95 typename VectorType,
96 std::enable_if_t<!has_set_ghost_state<VectorType>, VectorType> * = nullptr>
97 void
98 set_ghost_state(VectorType &, const bool)
99 {
100 // serial vector: nothing to do
101 }
102#endif
103
104
109 template <int dim,
110 int spacedim,
111 bool lda,
112 class OutputVector,
113 typename number>
114 void
116 const Vector<number> &local_values,
117 OutputVector &values,
118 const bool perform_check)
119 {
120 (void)perform_check;
121
122 if constexpr (running_in_debug_mode())
123 {
124 using VectorNumber = typename OutputVector::value_type;
125 constexpr bool is_dealii_vector =
126 std::is_same_v<OutputVector, Vector<VectorNumber>> ||
127 std::is_same_v<OutputVector, BlockVector<VectorNumber>> ||
128 std::is_same_v<OutputVector,
130 std::is_same_v<OutputVector,
132 if (perform_check && is_dealii_vector)
133 {
134 const bool old_ghost_state = values.has_ghost_elements();
135 set_ghost_state(values, true);
136
137 boost::container::small_vector<number, 200> local_values_old(
138 cell.get_fe().n_dofs_per_cell());
139 cell.get_dof_values(values,
140 local_values_old.begin(),
141 local_values_old.end());
142
143 for (unsigned int i = 0; i < cell.get_fe().n_dofs_per_cell(); ++i)
144 {
145 // a check consistent with the one in
146 // Utilities::MPI::Partitioner::import_from_ghosted_array_finish()
147 Assert(
148 local_values_old[i] == number() ||
149 get_abs(local_values_old[i] - local_values[i]) <=
150 get_abs(local_values_old[i] + local_values[i]) * 100000. *
151 std::numeric_limits<typename numbers::NumberTraits<
152 number>::real_type>::epsilon(),
153 ExcNonMatchingElementsSetDofValuesByInterpolation<number>(
154 local_values[i], local_values_old[i]));
155 }
156
157 set_ghost_state(values, old_ghost_state);
158 }
159 }
160
161 cell.set_dof_values(local_values, values);
162 }
163
164
165 template <int dim,
166 int spacedim,
167 bool lda,
168 class OutputVector,
169 typename number>
170 void
173 const Vector<number> &local_values,
174 OutputVector &values,
175 const types::fe_index fe_index_,
176 const std::function<void(const DoFCellAccessor<dim, spacedim, lda> &cell,
177 const Vector<number> &local_values,
178 OutputVector &values)> &processor)
179 {
180 const types::fe_index fe_index =
181 (cell.get_dof_handler().has_hp_capabilities() == false &&
182 fe_index_ == numbers::invalid_fe_index) ?
184 fe_index_;
185
186 if (cell.is_active() && !cell.is_artificial())
187 {
188 if ((cell.get_dof_handler().has_hp_capabilities() == false) ||
189 // for hp-DoFHandlers, we need to require that on
190 // active cells, you either don't specify an fe_index,
191 // or that you specify the correct one
192 (fe_index == cell.active_fe_index()) ||
193 (fe_index == numbers::invalid_fe_index))
194 // simply set the values on this cell
195 processor(cell, local_values, values);
196 else
197 {
198 Assert(local_values.size() ==
199 cell.get_dof_handler().get_fe(fe_index).n_dofs_per_cell(),
200 ExcMessage("Incorrect size of local_values vector."));
201
202 FullMatrix<double> interpolation(
203 cell.get_fe().n_dofs_per_cell(),
204 cell.get_dof_handler().get_fe(fe_index).n_dofs_per_cell());
205
206 cell.get_fe().get_interpolation_matrix(
207 cell.get_dof_handler().get_fe(fe_index), interpolation);
208
209 // do the interpolation to the target space. for historical
210 // reasons, matrices are set to size 0x0 internally even if
211 // we reinit as 4x0, so we have to treat this case specially
212 Vector<number> tmp(cell.get_fe().n_dofs_per_cell());
213 if ((tmp.size() > 0) && (local_values.size() > 0))
214 interpolation.vmult(tmp, local_values);
215
216 // now set the dof values in the global vector
217 processor(cell, tmp, values);
218 }
219 }
220 else
221 // otherwise distribute them to the children
222 {
223 Assert((cell.get_dof_handler().has_hp_capabilities() == false) ||
224 (fe_index != numbers::invalid_fe_index),
226 "You cannot call this function on non-active cells "
227 "of DoFHandler objects unless you provide an explicit "
228 "finite element index because they do not have naturally "
229 "associated finite element spaces associated: degrees "
230 "of freedom are only distributed on active cells for which "
231 "the active FE index has been set."));
232
234 cell.get_dof_handler().get_fe(fe_index);
235 const unsigned int dofs_per_cell = fe.n_dofs_per_cell();
236
237 Assert(local_values.size() == dofs_per_cell,
239 ExcVectorDoesNotMatch()));
240 Assert(values.size() == cell.get_dof_handler().n_dofs(),
242 ExcVectorDoesNotMatch()));
243
244 Vector<number> tmp(dofs_per_cell);
245
246 for (unsigned int child = 0; child < cell.n_children(); ++child)
247 {
248 if (tmp.size() > 0)
249 fe.get_prolongation_matrix(child, cell.refinement_case())
250 .vmult(tmp, local_values);
252 *cell.child(child), tmp, values, fe_index, processor);
253 }
254 }
255 }
256
257} // namespace internal
258
259
260
261template <int dim, int spacedim, bool lda>
262template <class OutputVector, typename number>
263void
265 const Vector<number> &local_values,
266 OutputVector &values,
267 const types::fe_index fe_index_,
268 const bool perform_check) const
269{
270 internal::process_by_interpolation<dim, spacedim, lda, OutputVector, number>(
271 *this,
272 local_values,
273 values,
274 fe_index_,
275 [perform_check](const DoFCellAccessor<dim, spacedim, lda> &cell,
276 const Vector<number> &local_values,
277 OutputVector &values) {
278 internal::set_dof_values(cell, local_values, values, perform_check);
279 });
280}
281
282
283template <int dim, int spacedim, bool lda>
284template <class OutputVector, typename number>
285void
288 const Vector<number> &local_values,
289 OutputVector &values,
290 const types::fe_index fe_index_) const
291{
292 internal::process_by_interpolation<dim, spacedim, lda, OutputVector, number>(
293 *this,
294 local_values,
295 values,
296 fe_index_,
298 const Vector<number> &local_values,
299 OutputVector &values) {
300 std::vector<types::global_dof_index> dof_indices(
301 cell.get_fe().n_dofs_per_cell());
302 cell.get_dof_indices(dof_indices);
304 dof_indices,
305 values);
306 });
307}
308
309
310// --------------------------------------------------------------------------
311// explicit instantiations
312#include "dofs/dof_accessor_set.inst"
313
void distribute_local_to_global(const InVector &local_vector, const std::vector< size_type > &local_dof_indices, OutVector &global_vector) const
const DoFHandler< dim, spacedim > & get_dof_handler() const
void get_dof_values(const InputVector &values, Vector< number > &local_values) const
const FiniteElement< dimension_, space_dimension_ > & get_fe() const
TriaIterator< DoFCellAccessor< dimension_, space_dimension_, level_dof_access > > child(const unsigned int i) const
void distribute_local_to_global_by_interpolation(const Vector< number > &local_values, OutputVector &values, const types::fe_index fe_index=numbers::invalid_fe_index) const
void set_dof_values(const Vector< number > &local_values, OutputVector &values) const
void set_dof_values_by_interpolation(const Vector< number > &local_values, OutputVector &values, const types::fe_index fe_index=numbers::invalid_fe_index, const bool perform_check=false) const
void get_dof_indices(std::vector< types::global_dof_index > &dof_indices) const
types::fe_index active_fe_index() const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
bool has_hp_capabilities() const
types::global_dof_index n_dofs() const
unsigned int n_dofs_per_cell() const
virtual const FullMatrix< double > & get_prolongation_matrix(const unsigned int child, const RefinementCase< dim > &refinement_case=RefinementCase< dim >::isotropic_refinement) const
void vmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
virtual size_type size() const override
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
constexpr bool running_in_debug_mode()
Definition config.h:76
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define Assert(cond, exc)
#define DeclException2(Exception2, type1, type2, outsequence)
static ::ExceptionBase & ExcNonMatchingElementsSetDofValuesByInterpolation(Number arg1, Number arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
decltype(std::declval< const T >().set_ghost_state(std::declval< bool >())) set_ghost_state_t
constexpr bool has_set_ghost_state
std::enable_if_t<!std::is_unsigned_v< Number >, typename numbers::NumberTraits< Number >::real_type > get_abs(const Number a)
void set_ghost_state(VectorType &vector, const bool ghosted)
void set_dof_values(const DoFCellAccessor< dim, spacedim, lda > &cell, const Vector< number > &local_values, OutputVector &values, const bool perform_check)
void process_by_interpolation(const DoFCellAccessor< dim, spacedim, lda > &cell, const Vector< number > &local_values, OutputVector &values, const types::fe_index fe_index_, const std::function< void(const DoFCellAccessor< dim, spacedim, lda > &cell, const Vector< number > &local_values, OutputVector &values)> &processor)
constexpr types::fe_index invalid_fe_index
Definition types.h:250
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
unsigned short int fe_index
Definition types.h:70