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
utilities.h
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) 2020 - 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#ifndef dealii_particles_utilities_h
14#define dealii_particles_utilities_h
15
16#include <deal.II/base/config.h>
17
19#include <deal.II/base/point.h>
21
23
25#include <deal.II/fe/fe.h>
26
28
31
33
35
37
38
39
40namespace Particles
41{
46 namespace Utilities
47 {
92 template <int dim, int spacedim, typename number = double>
93 void
95 const DoFHandler<dim, spacedim> &space_dh,
96 const Particles::ParticleHandler<dim, spacedim> &particle_handler,
97 SparsityPatternBase &sparsity,
98 const AffineConstraints<number> &constraints =
100 const ComponentMask &space_comps = {});
101
145 template <int dim, int spacedim, typename MatrixType>
146 void
148 const DoFHandler<dim, spacedim> &space_dh,
149 const Particles::ParticleHandler<dim, spacedim> &particle_handler,
150 MatrixType &matrix,
153 const ComponentMask &space_comps = {});
154
187 template <int dim,
188 int spacedim,
189 typename InputVectorType,
190 typename OutputVectorType>
191 void
193 const DoFHandler<dim, spacedim> &field_dh,
194 const Particles::ParticleHandler<dim, spacedim> &particle_handler,
195 const InputVectorType &field_vector,
196 OutputVectorType &interpolated_field,
197 const ComponentMask &field_comps = {})
198 {
199 if (particle_handler.n_locally_owned_particles() == 0)
200 {
201 interpolated_field.compress(VectorOperation::add);
202 return; // nothing else to do here
203 }
204
205 const auto &fe = field_dh.get_fe();
206 auto particle = particle_handler.begin();
207
208 // Take care of components
209 const ComponentMask comps =
210 (field_comps.size() == 0 ? ComponentMask(fe.n_components(), true) :
211 field_comps);
212 AssertDimension(comps.size(), fe.n_components());
213 const auto n_comps = comps.n_selected_components();
214
215 AssertDimension(field_vector.size(), field_dh.n_dofs());
216 AssertDimension(interpolated_field.size(),
217 particle_handler.get_next_free_particle_index() *
218 n_comps);
219
220 // Global to local indices
221 std::vector<unsigned int> space_gtl(fe.n_components(),
223 for (unsigned int i = 0, j = 0; i < space_gtl.size(); ++i)
224 if (comps[i])
225 space_gtl[i] = j++;
226
227 std::vector<types::global_dof_index> dof_indices(fe.n_dofs_per_cell());
228
229 while (particle != particle_handler.end())
230 {
231 const auto &cell = particle->get_surrounding_cell();
232 const auto &dh_cell =
233 typename DoFHandler<dim, spacedim>::cell_iterator(*cell, &field_dh);
234 dh_cell->get_dof_indices(dof_indices);
235 const auto pic = particle_handler.particles_in_cell(cell);
236
237 Assert(pic.begin() == particle, ExcInternalError());
238 for (unsigned int i = 0; particle != pic.end(); ++particle, ++i)
239 {
240 const Point<dim> reference_location =
241 particle->get_reference_location();
242
243 const auto id = particle->get_id();
244
245 for (unsigned int j = 0; j < fe.n_dofs_per_cell(); ++j)
246 {
247 const auto comp_j =
248 space_gtl[fe.system_to_component_index(j).first];
249 if (comp_j != numbers::invalid_unsigned_int)
250 interpolated_field[id * n_comps + comp_j] +=
251 fe.shape_value(j, reference_location) *
252 field_vector(dof_indices[j]);
253 }
254 }
255 }
256 interpolated_field.compress(VectorOperation::add);
257 }
258
259
307 template <int n_components,
308 int dim,
309 int spacedim,
310 typename InputVectorType,
311 typename OutputVectorType>
312 void
314 const DoFHandler<dim, spacedim> &field_dh,
315 const Particles::ParticleHandler<dim, spacedim> &particle_handler,
316 const InputVectorType &field_vector,
317 OutputVectorType &interpolated_field,
318 const ComponentMask &field_comps = {},
319 const Mapping<dim, spacedim> &mapping =
320 (ReferenceCells::get_hypercube<dim>()
321#ifndef _MSC_VER
322 .template get_default_linear_mapping<spacedim>()
323#else
324 .ReferenceCell<dim>::get_default_linear_mapping<spacedim>()
325#endif
326 ))
327 {
328 if (particle_handler.n_locally_owned_particles() == 0)
329 {
330 // This is a collective operation that must be matched by the
331 // compress() at the end of the function on all other processes. The
332 // values are written with operator=, hence we use insert here.
333 interpolated_field.compress(VectorOperation::insert);
334 return; // nothing else to do here
335 }
336
337 const auto &fe = field_dh.get_fe();
338 auto particle = particle_handler.begin();
339
340 // Take care of components
341 const ComponentMask comps =
342 (field_comps.size() == 0 ? ComponentMask(n_components, true) :
343 field_comps);
344 AssertDimension(comps.size(), n_components);
345 const auto n_selected_comps = comps.n_selected_components();
346
347 AssertDimension(field_vector.size(), field_dh.n_dofs());
348 AssertDimension(interpolated_field.size(),
349 particle_handler.get_next_free_particle_index() *
350 n_selected_comps);
351
352 std::vector<types::global_dof_index> dof_indices(fe.n_dofs_per_cell());
353
354 // Generate an evaluator that will be used to interpolate the fields at
355 // the particle location.
357 fe,
359 std::vector<Point<dim>> particle_reference_locations;
360 std::vector<types::particle_index> particle_indices;
361 Vector<double> local_dof_values(fe.dofs_per_cell);
362
363 while (particle != particle_handler.end())
364 {
365 const auto &cell = particle->get_surrounding_cell();
366 const auto &dh_cell =
367 typename DoFHandler<dim, spacedim>::cell_iterator(*cell, &field_dh);
368 dh_cell->get_dof_indices(dof_indices);
369 dh_cell->get_dof_values(field_vector, local_dof_values);
370
371 const auto pic = particle_handler.particles_in_cell(cell);
372 Assert(pic.begin() == particle, ExcInternalError());
373
374 // Gather the reference location and ids of all particles
375 particle_reference_locations.clear();
376 particle_indices.clear();
377 for (const auto &p : pic)
378 {
379 particle_reference_locations.emplace_back(
380 p.get_reference_location());
381 particle_indices.emplace_back(p.get_id());
382 }
383
384 evaluator.reinit(cell, particle_reference_locations);
385 evaluator.evaluate(make_array_view(local_dof_values),
387 for (unsigned int particle_index = 0; particle != pic.end();
388 ++particle, ++particle_index)
389 {
390 const types::particle_index global_particle_id =
391 particle_indices[particle_index];
392
393 if constexpr (n_components == 1)
394 {
395 // The single component may be deselected by the mask, in
396 // which case there is nothing to write (and the output
397 // vector has no entry for this particle).
398 if (comps[0])
399 interpolated_field[global_particle_id] =
400 evaluator.get_value(particle_index);
401 }
402 else
403 {
404 unsigned int j_comp = 0;
405 for (unsigned int j = 0; j < n_components; ++j)
406 {
407 if (comps[j])
408 {
409 interpolated_field[global_particle_id *
410 n_selected_comps +
411 j_comp] =
412 evaluator.get_value(particle_index)[j];
413 j_comp++;
414 }
415 }
416 }
417 }
418 }
419
420 // The entries are written using operator=, possibly for particles whose
421 // global id is owned by another process. Ship those values to their
422 // owner and finalize the vector. This is collective and matches the
423 // compress() in the early-return branch above.
424 interpolated_field.compress(VectorOperation::insert);
425 }
426
427 } // namespace Utilities
428} // namespace Particles
430
431#endif
ArrayView< std::remove_reference_t< typename std::iterator_traits< Iterator >::reference >, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
unsigned int size() const
unsigned int n_selected_components(const unsigned int overall_number_of_components=numbers::invalid_unsigned_int) const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
types::global_dof_index n_dofs() const
Abstract base class for mapping classes.
Definition mapping.h:318
particle_iterator begin() const
particle_iterator end() const
types::particle_index n_locally_owned_particles() const
particle_iterator_range particles_in_cell(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell)
types::particle_index get_next_free_particle_index() const
Definition point.h:111
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
typename ActiveSelector::cell_iterator cell_iterator
@ update_values
Shape function values.
void create_interpolation_matrix(const DoFHandler< dim, spacedim > &space_dh, const Particles::ParticleHandler< dim, spacedim > &particle_handler, MatrixType &matrix, const AffineConstraints< typename MatrixType::value_type > &constraints=AffineConstraints< typename MatrixType::value_type >(), const ComponentMask &space_comps={})
Definition utilities.cc:118
void create_interpolation_sparsity_pattern(const DoFHandler< dim, spacedim > &space_dh, const Particles::ParticleHandler< dim, spacedim > &particle_handler, SparsityPatternBase &sparsity, const AffineConstraints< number > &constraints=AffineConstraints< number >(), const ComponentMask &space_comps={})
Definition utilities.cc:36
void interpolate_field_on_particles(const DoFHandler< dim, spacedim > &field_dh, const Particles::ParticleHandler< dim, spacedim > &particle_handler, const InputVectorType &field_vector, OutputVectorType &interpolated_field, const ComponentMask &field_comps={})
Definition utilities.h:192
constexpr unsigned int invalid_unsigned_int
Definition types.h:228
unsigned int particle_index