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
cell_weights.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) 2018 - 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
13
15
17
18#include <limits>
19
21
22
23namespace parallel
24{
25 // ---------- selection of weighting functions ----------
26
27 template <int dim, int spacedim>
30 {
31 return [factor](const typename DoFHandler<dim, spacedim>::cell_iterator &,
32 const FiniteElement<dim, spacedim> &) -> unsigned int {
33 return factor;
34 };
35 }
36
37
38
39 template <int dim, int spacedim>
42 const std::pair<float, float> &coefficients)
43 {
44 return [coefficients](
46 const FiniteElement<dim, spacedim> &future_fe) -> unsigned int {
47 const float result =
48 std::trunc(coefficients.first *
49 std::pow(future_fe.n_dofs_per_cell(), coefficients.second));
50
51 Assert(result >= 0. &&
52 result <=
53 static_cast<float>(std::numeric_limits<unsigned int>::max()),
55 "Cannot cast determined weight for this cell to unsigned int!"));
56
57 return static_cast<unsigned int>(result);
58 };
59 }
60
61
62
63 template <int dim, int spacedim>
66 const std::vector<std::pair<float, float>> &coefficients)
67 {
68 return [coefficients](
70 const FiniteElement<dim, spacedim> &future_fe) -> unsigned int {
71 float result = 0;
72 for (const auto &pair : coefficients)
73 result +=
74 pair.first * std::pow(future_fe.n_dofs_per_cell(), pair.second);
75 result = std::trunc(result);
76
77 Assert(result >= 0. &&
78 result <=
79 static_cast<float>(std::numeric_limits<unsigned int>::max()),
81 "Cannot cast determined weight for this cell to unsigned int!"));
82
83 return static_cast<unsigned int>(result);
84 };
85 }
86
87
88
89 // ---------- precompute weights ----------
90
91 template <int dim, int spacedim>
92 std::vector<unsigned int>
94 const hp::FECollection<dim, spacedim> &fe_collection,
95 const WeightingFunction &weighting_function)
96 {
97 std::vector<unsigned int> precomputed_weights;
98 precomputed_weights.reserve(fe_collection.size());
99
100 const typename DoFHandler<dim, spacedim>::cell_iterator dummy;
101 for (const auto &fe : fe_collection)
102 precomputed_weights.push_back(weighting_function(dummy, fe));
103
104 return precomputed_weights;
105 }
106
107
108
109 // ---------- handle connection ----------
110
111 template <int dim, int spacedim>
113 const DoFHandler<dim, spacedim> &dof_handler,
114 const WeightingFunction &weighting_function)
115 {
116 reinit(dof_handler, weighting_function);
117 }
118
119
120
121 template <int dim, int spacedim>
123 const DoFHandler<dim, spacedim> &dof_handler,
124 const std::vector<unsigned int> &precomputed_weights)
125 {
126 reinit(dof_handler, precomputed_weights);
127 }
128
129
130
131 template <int dim, int spacedim>
133 {
134 connection.disconnect();
135 }
136
137
138
139 template <int dim, int spacedim>
140 void
142 const DoFHandler<dim, spacedim> &dof_handler,
143 const WeightingFunction &weighting_function)
144 {
145 connection.disconnect();
146
147 connection = dof_handler.get_triangulation().signals.weight.connect(
148 make_weighting_callback(dof_handler, weighting_function));
149 }
150
151
152
153 template <int dim, int spacedim>
154 void
156 const DoFHandler<dim, spacedim> &dof_handler,
157 const std::vector<unsigned int> &precomputed_weights)
158 {
159 connection.disconnect();
160
161 connection = dof_handler.get_triangulation().signals.weight.connect(
162 make_weighting_callback(dof_handler, precomputed_weights));
163 }
164
165
166
167 // ---------- handle callback functions ----------
168
169 template <int dim, int spacedim>
170 std::function<unsigned int(
171 const typename ::Triangulation<dim, spacedim>::cell_iterator &cell,
172 const CellStatus status)>
174 const DoFHandler<dim, spacedim> &dof_handler,
175 const WeightingFunction &weighting_function)
176 {
178 dynamic_cast<const parallel::TriangulationBase<dim, spacedim> *>(
179 &(dof_handler.get_triangulation()));
180
181 Assert(
182 tria != nullptr,
184 "parallel::CellWeights requires a parallel::TriangulationBase object."));
185
186 return [&dof_handler, tria, weighting_function](
187 const typename ::Triangulation<dim, spacedim>::cell_iterator
188 &cell,
189 const CellStatus status) -> unsigned int {
191 cell, status, dof_handler, *tria, weighting_function);
192 };
193 }
194
195
196
197 template <int dim, int spacedim>
198 unsigned int
200 const typename ::Triangulation<dim, spacedim>::cell_iterator &cell_,
201 const CellStatus status,
202 const DoFHandler<dim, spacedim> &dof_handler,
204 const WeightingFunction &weighting_function)
205 {
206 // Check if we are still working with the correct combination of
207 // Triangulation and DoFHandler.
208 Assert(&triangulation == &(dof_handler.get_triangulation()),
210 "Triangulation associated with the DoFHandler has changed!"));
211
212 // Skip if the DoFHandler has not been initialized yet.
213 if (dof_handler.get_fe_collection().empty())
214 return 0;
215
216 // Convert cell type from Triangulation to DoFHandler to be able
217 // to access the information about the degrees of freedom.
218 const typename DoFHandler<dim, spacedim>::cell_iterator cell(*cell_,
219 &dof_handler);
220
221 // Determine which FiniteElement object will be present on this cell after
222 // refinement and will thus specify the number of degrees of freedom.
224 switch (status)
225 {
229 fe_index = cell->future_fe_index();
230 break;
231
233 if constexpr (running_in_debug_mode())
234 {
235 for (const auto &child : cell->child_iterators())
236 Assert(child->is_active() && child->coarsen_flag_set(),
238 }
239
240 fe_index = ::internal::hp::DoFHandlerImplementation::
241 dominated_future_fe_on_children<dim, spacedim>(cell);
242 break;
243
244 default:
246 break;
247 }
248
249 // Return the cell weight determined by the function of choice.
250 return weighting_function(cell, dof_handler.get_fe(fe_index));
251 }
252
253
254
255 template <int dim, int spacedim>
256 std::function<unsigned int(
257 const typename ::Triangulation<dim, spacedim>::cell_iterator &cell,
258 const CellStatus status)>
260 const DoFHandler<dim, spacedim> &dof_handler,
261 const std::vector<unsigned int> &precomputed_weights)
262 {
263 // create callback function
265 dynamic_cast<const parallel::TriangulationBase<dim, spacedim> *>(
266 &(dof_handler.get_triangulation()));
267
268 Assert(
269 tria != nullptr,
271 "parallel::CellWeights requires a parallel::TriangulationBase object."));
272
273 // capture the weights by copy
274 return [&dof_handler, tria, precomputed_weights](
275 const typename ::Triangulation<dim, spacedim>::cell_iterator
276 &cell,
277 const CellStatus status) -> unsigned int {
279 cell, status, dof_handler, *tria, precomputed_weights);
280 };
281 }
282
283
284
285 template <int dim, int spacedim>
286 unsigned int
288 const typename ::Triangulation<dim, spacedim>::cell_iterator &cell_,
289 const CellStatus status,
290 const DoFHandler<dim, spacedim> &dof_handler,
292 const std::vector<unsigned int> &precomputed_weights)
293 {
294 // Check if we are still working with the correct combination of
295 // Triangulation and DoFHandler.
296 Assert(&triangulation == &(dof_handler.get_triangulation()),
298 "Triangulation associated with the DoFHandler has changed!"));
299 (void)triangulation;
300
301 // Skip if the DoFHandler has not been initialized yet.
302 if (dof_handler.get_fe_collection().size() == 0)
303 return 0;
304
305 // Convert cell type from Triangulation to DoFHandler to be able
306 // to access the information about the degrees of freedom.
307 const typename DoFHandler<dim, spacedim>::cell_iterator cell(*cell_,
308 &dof_handler);
309
310 // Determine which FiniteElement object will be present on this cell after
311 // refinement and will thus specify the number of degrees of freedom.
313 switch (status)
314 {
318 fe_index = cell->future_fe_index();
319 break;
320
322 if constexpr (running_in_debug_mode())
323 {
324 for (const auto &child : cell->child_iterators())
325 Assert(child->is_active() && child->coarsen_flag_set(),
327 }
328
329 fe_index = ::internal::hp::DoFHandlerImplementation::
330 dominated_future_fe_on_children<dim, spacedim>(cell);
331 break;
332
333 default:
335 break;
336 }
337
338 // Return the precomputed weight.
339 return precomputed_weights[fe_index];
340 }
341} // namespace parallel
342
343
344// explicit instantiations
345#include "distributed/cell_weights.inst"
346
CellStatus
Definition cell_status.h:29
@ cell_will_be_refined
@ children_will_be_coarsened
const hp::FECollection< dim, spacedim > & get_fe_collection() const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
const Triangulation< dim, spacedim > & get_triangulation() const
Signals signals
Definition tria.h:2588
unsigned int size() const
Definition collection.h:314
bool empty() const
Definition collection.h:323
static unsigned int weighting_callback(const typename ::Triangulation< dim, spacedim >::cell_iterator &cell, const CellStatus status, const DoFHandler< dim, spacedim > &dof_handler, const parallel::TriangulationBase< dim, spacedim > &triangulation, const WeightingFunction &weighting_function)
static WeightingFunction constant_weighting(const unsigned int factor=1)
std::function< unsigned int(const typename DoFHandler< dim, spacedim >::cell_iterator &, const FiniteElement< dim, spacedim > &)> WeightingFunction
static WeightingFunction ndofs_weighting(const std::pair< float, float > &coefficients)
void reinit(const DoFHandler< dim, spacedim > &dof_handler, const WeightingFunction &weighting_function)
static std::function< unsigned int(const typename ::Triangulation< dim, spacedim >::cell_iterator &cell, const CellStatus status)> make_weighting_callback(const DoFHandler< dim, spacedim > &dof_handler, const WeightingFunction &weighting_function)
static std::vector< unsigned int > precompute_weights(const hp::FECollection< dim, spacedim > &fe_collection, const WeightingFunction &weighting_function)
#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 DEAL_II_ASSERT_UNREACHABLE()
#define Assert(cond, exc)
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcInconsistentCoarseningFlags()
typename ActiveSelector::cell_iterator cell_iterator
constexpr types::fe_index invalid_fe_index
Definition types.h:250
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)
unsigned short int fe_index
Definition types.h:70