deal.II version GIT relicensing-6842-g793a97d2aa 2026-10-02 14:00: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.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) 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#include <deal.II/base/config.h>
14
16
17#ifdef DEAL_II_TRILINOS_WITH_TPETRA
20#endif
21
23
24#include <vector>
25
26
28
29
30namespace Particles
31{
32 namespace Utilities
33 {
34 template <int dim, int spacedim, typename number>
35 void
37 const DoFHandler<dim, spacedim> &space_dh,
38 const Particles::ParticleHandler<dim, spacedim> &particle_handler,
39 SparsityPatternBase &sparsity,
40 const AffineConstraints<number> &constraints,
41 const ComponentMask &space_comps)
42 {
43 if (particle_handler.n_locally_owned_particles() == 0)
44 return; // nothing to do here
45
46 const auto &fe = space_dh.get_fe();
47 const auto max_particles_per_cell =
48 particle_handler.n_global_max_particles_per_cell();
49
50 // Take care of components
51 const ComponentMask comps =
52 (space_comps.size() == 0 ? ComponentMask(fe.n_components(), true) :
53 space_comps);
54 AssertDimension(comps.size(), fe.n_components());
55
56 const auto n_comps = comps.n_selected_components();
57
58 // Global to local indices
59 std::vector<unsigned int> space_gtl(fe.n_components(),
61 for (unsigned int i = 0, j = 0; i < space_gtl.size(); ++i)
62 if (comps[i])
63 space_gtl[i] = j++;
64
65 // [TODO]: when the add_entries_local_to_global below will implement
66 // the version with the dof_mask, this should be uncommented.
67 // // Construct a dof_mask, used to distribute entries to the sparsity
68 // Table<2, bool> dof_mask(max_particles_per_cell * n_comps,
69 // fe.n_dofs_per_cell());
70 // dof_mask.fill(false);
71 // for (unsigned int i = 0; i < space_fe.n_dofs_per_cell(); ++i)
72 // {
73 // const auto comp_i = space_fe.system_to_component_index(i).first;
74 // if (space_gtl[comp_i] != numbers::invalid_unsigned_int)
75 // for (unsigned int j = 0; j < max_particles_per_cell; ++j)
76 // dof_mask(i, j * n_comps + space_gtl[comp_i]) = true;
77 // }
78
79 std::vector<types::global_dof_index> dof_indices(fe.n_dofs_per_cell());
80 std::vector<types::particle_index> particle_indices(
81 max_particles_per_cell * n_comps);
82
83 auto particle = particle_handler.begin();
84 while (particle != particle_handler.end())
85 {
86 const auto &cell = particle->get_surrounding_cell();
87 const auto dh_cell =
88 typename DoFHandler<dim, spacedim>::cell_iterator(*cell, &space_dh);
89 dh_cell->get_dof_indices(dof_indices);
90 const auto pic = particle_handler.particles_in_cell(cell);
91 const auto n_particles = particle_handler.n_particles_in_cell(cell);
92 particle_indices.resize(n_particles * n_comps);
93 Assert(pic.begin() == particle, ExcInternalError());
94 for (; particle != pic.end(); ++particle)
95 {
96 const auto p_id = particle->get_id();
97 for (unsigned int j = 0; j < fe.n_dofs_per_cell(); ++j)
98 {
99 const auto comp_j =
100 space_gtl[fe.system_to_component_index(j).first];
101 if (comp_j != numbers::invalid_unsigned_int)
102 constraints.add_entries_local_to_global(
103 {p_id * n_comps + comp_j}, {dof_indices[j]}, sparsity);
104 }
105 }
106 // [TODO]: when this works, use this:
107 // constraints.add_entries_local_to_global(particle_indices,
108 // dof_indices,
109 // sparsity,
110 // dof_mask);
111 }
112 }
113
114
115
116 template <int dim, int spacedim, typename MatrixType>
117 void
119 const DoFHandler<dim, spacedim> &space_dh,
120 const Particles::ParticleHandler<dim, spacedim> &particle_handler,
121 MatrixType &matrix,
123 const ComponentMask &space_comps)
124 {
125 if (particle_handler.n_locally_owned_particles() == 0)
126 {
127 matrix.compress(VectorOperation::add);
128 return; // nothing else to do here
129 }
130
131 AssertDimension(matrix.n(), space_dh.n_dofs());
132
133 const auto &fe = space_dh.get_fe();
134 const auto max_particles_per_cell =
135 particle_handler.n_global_max_particles_per_cell();
136
137 // Take care of components
138 const ComponentMask comps =
139 (space_comps.size() == 0 ? ComponentMask(fe.n_components(), true) :
140 space_comps);
141 AssertDimension(comps.size(), fe.n_components());
142 const auto n_comps = comps.n_selected_components();
143
144 AssertDimension(matrix.m(),
145 particle_handler.n_global_particles() * n_comps);
146
147
148 // Global to local indices
149 std::vector<unsigned int> space_gtl(fe.n_components(),
151 for (unsigned int i = 0, j = 0; i < space_gtl.size(); ++i)
152 if (comps[i])
153 space_gtl[i] = j++;
154
155 // [TODO]: when the add_entries_local_to_global below will implement
156 // the version with the dof_mask, this should be uncommented.
157 // // Construct a dof_mask, used to distribute entries to the sparsity
158 // Table<2, bool> dof_mask(max_particles_per_cell * n_comps,
159 // fe.n_dofs_per_cell());
160 // dof_mask.fill(false);
161 // for (unsigned int i = 0; i < space_fe.n_dofs_per_cell(); ++i)
162 // {
163 // const auto comp_i = space_fe.system_to_component_index(i).first;
164 // if (space_gtl[comp_i] != numbers::invalid_unsigned_int)
165 // for (unsigned int j = 0; j < max_particles_per_cell; ++j)
166 // dof_mask(i, j * n_comps + space_gtl[comp_i]) = true;
167 // }
168
169 std::vector<types::global_dof_index> dof_indices(fe.n_dofs_per_cell());
170 std::vector<types::particle_index> particle_indices(
171 max_particles_per_cell * n_comps);
172
174 max_particles_per_cell * n_comps, fe.n_dofs_per_cell());
175
176 auto particle = particle_handler.begin();
177 while (particle != particle_handler.end())
178 {
179 const auto &cell = particle->get_surrounding_cell();
180 const auto &dh_cell =
181 typename DoFHandler<dim, spacedim>::cell_iterator(*cell, &space_dh);
182 dh_cell->get_dof_indices(dof_indices);
183 const auto pic = particle_handler.particles_in_cell(cell);
184 const auto n_particles = particle_handler.n_particles_in_cell(cell);
185 particle_indices.resize(n_particles * n_comps);
186 local_matrix.reinit({n_particles * n_comps, fe.n_dofs_per_cell()});
187 Assert(pic.begin() == particle, ExcInternalError());
188 for (unsigned int i = 0; particle != pic.end(); ++particle, ++i)
189 {
190 const auto &reference_location =
191 particle->get_reference_location();
192
193 for (unsigned int d = 0; d < n_comps; ++d)
194 particle_indices[i * n_comps + d] =
195 particle->get_id() * n_comps + d;
196
197 for (unsigned int j = 0; j < fe.n_dofs_per_cell(); ++j)
198 {
199 const auto comp_j =
200 space_gtl[fe.system_to_component_index(j).first];
201 if (comp_j != numbers::invalid_unsigned_int)
202 local_matrix(i * n_comps + comp_j, j) =
203 fe.shape_value(j, reference_location);
204 }
205 }
206 constraints.distribute_local_to_global(local_matrix,
207 particle_indices,
208 dof_indices,
209 matrix);
210 }
211 matrix.compress(VectorOperation::add);
212 }
213
214#include "particles/utilities.inst"
215
216 } // namespace Utilities
217} // namespace Particles
void distribute_local_to_global(const InVector &local_vector, const std::vector< size_type > &local_dof_indices, OutVector &global_vector) const
void add_entries_local_to_global(const std::vector< size_type > &local_dof_indices, SparsityPatternBase &sparsity_pattern, const bool keep_constrained_entries=true, const Table< 2, bool > &dof_mask=Table< 2, bool >()) const
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
types::particle_index n_global_particles() const
particle_iterator begin() const
particle_iterator end() const
types::particle_index n_locally_owned_particles() const
types::particle_index n_particles_in_cell(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell) const
particle_iterator_range particles_in_cell(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell)
types::particle_index n_global_max_particles_per_cell() const
#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
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
constexpr unsigned int invalid_unsigned_int
Definition types.h:228