Reference documentation for deal.II version GIT relicensing-1062-gc06da148b8 2024-07-15 19:20:02+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
particle_handler.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2017 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_particles_particle_handler_h
16#define dealii_particles_particle_handler_h
17
18#include <deal.II/base/config.h>
19
25
27
28#include <deal.II/fe/mapping.h>
29
31
36
37#include <boost/range/iterator_range.hpp>
38#include <boost/serialization/map.hpp>
39
41
42namespace Particles
43{
61 template <int dim, int spacedim = dim>
63 {
64 public:
69
73 using particle_iterator_range = boost::iterator_range<particle_iterator>;
74
80
85
96 const unsigned int n_properties = 0);
97
101 virtual ~ParticleHandler();
102
108 void
111 const unsigned int n_properties = 0);
112
133 void
134 copy_from(const ParticleHandler<dim, spacedim> &particle_handler);
135
139 void
140 clear();
141
147 void
149
164 void
165 reserve(const std::size_t n_particles);
166
175 void
177
182 begin() const;
183
188 begin();
189
194 end() const;
195
200 end();
201
206 begin_ghost() const;
207
212 begin_ghost();
213
218 end_ghost() const;
219
224 end_ghost();
225
232 const;
233
245
257 const;
258
264 void
265 remove_particle(const particle_iterator &particle);
266
272 void
273 remove_particles(const std::vector<particle_iterator> &particles);
274
283 const Particle<dim, spacedim> &particle,
285
303 const Point<spacedim> &position,
304 const Point<dim> &reference_position,
305 const types::particle_index particle_index,
307 const ArrayView<const double> &properties = {});
308
315 void
317 const std::multimap<
320
330 void
331 insert_particles(const std::vector<Point<spacedim>> &positions);
332
393 std::map<unsigned int, IndexSet>
395 const std::vector<Point<spacedim>> &positions,
396 const std::vector<std::vector<BoundingBox<spacedim>>>
397 &global_bounding_boxes,
398 const std::vector<std::vector<double>> &properties = {},
399 const std::vector<types::particle_index> &ids = {});
400
431 std::map<unsigned int, IndexSet>
433 const std::vector<Particle<dim, spacedim>> &particles,
434 const std::vector<std::vector<BoundingBox<spacedim>>>
435 &global_bounding_boxes);
436
480 template <typename VectorType>
481 std::enable_if_t<
482 std::is_convertible_v<VectorType *, Function<spacedim> *> == false>
483 set_particle_positions(const VectorType &input_vector,
484 const bool displace_particles = true);
485
506 void
507 set_particle_positions(const std::vector<Point<spacedim>> &new_positions,
508 const bool displace_particles = true);
509
510
529 void
531 const bool displace_particles = true);
532
560 template <typename VectorType>
561 void
562 get_particle_positions(VectorType &output_vector,
563 const bool add_to_output_vector = false);
564
579 void
580 get_particle_positions(std::vector<Point<spacedim>> &positions,
581 const bool add_to_output_vector = false);
582
609 void
611 const std::function<std::size_t()> &size_callback,
612 const std::function<void *(const particle_iterator &, void *)>
614 const std::function<const void *(const particle_iterator &, const void *)>
616
626 n_global_particles() const;
627
636
643
651
670
674 unsigned int
676
692
697 PropertyPool<dim, spacedim> &
698 get_property_pool() const;
699
714 void
716
722 void
723 exchange_ghost_particles(const bool enable_ghost_cache = false);
724
732 void
734
744 void
746
765 void
767
779 void
781
790 void
791 deserialize();
792
804 void
806
818 void
819 register_load_callback_function(const bool serialization);
820
825 template <class Archive>
826 void
827 serialize(Archive &ar, const unsigned int version);
828
841 struct Signals
842 {
856 boost::signals2::signal<void(
857 const typename Particles::ParticleIterator<dim, spacedim> &particle,
859 &cell)>
861 };
862
868
869 private:
878 const void *&data,
880
889
899 void
901
908
914
923 std::unique_ptr<PropertyPool<dim, spacedim>> property_pool;
924
929
935 const typename particle_container::iterator owned_particles_end;
936
942 std::vector<typename particle_container::iterator> cells_to_particle_cache;
943
949
955
965
971
983 std::function<std::size_t()> size_callback;
984
995 std::function<void *(const particle_iterator &, void *)> store_callback;
996
1007 std::function<const void *(const particle_iterator &, const void *)>
1009
1016 unsigned int handle;
1017
1021 const double tolerance_inside_cell = 1e-12;
1022
1032 std::unique_ptr<GridTools::Cache<dim, spacedim>> triangulation_cache;
1033
1034#ifdef DEAL_II_WITH_MPI
1058 void
1060 const std::map<types::subdomain_id, std::vector<particle_iterator>>
1061 &particles_to_send,
1062 const std::map<
1064 std::vector<
1066 &new_cells_for_particles = std::map<
1068 std::vector<
1070 const bool enable_cache = false);
1071
1083 void
1085 const std::map<types::subdomain_id, std::vector<particle_iterator>>
1086 &particles_to_send);
1087
1088#endif
1089
1097
1102 void
1104
1109 std::vector<boost::signals2::connection> tria_listeners;
1110
1119 void
1121
1127 void
1129
1137 void
1138 notify_ready_to_unpack(const bool serialization);
1139
1145 std::vector<char>
1148 const CellStatus status) const;
1149
1154 void
1157 const CellStatus status,
1158 const boost::iterator_range<std::vector<char>::const_iterator>
1159 &data_range);
1160
1165 typename particle_container::iterator
1167
1172 typename particle_container::iterator
1174
1179 typename particle_container::iterator
1181
1186 typename particle_container::iterator
1188 };
1189
1190
1191
1192 /* ---------------------- inline and template functions ------------------
1193 */
1194
1195 template <int dim, int spacedim>
1198 {
1199 return (const_cast<ParticleHandler<dim, spacedim> *>(this))->begin();
1200 }
1201
1202
1203
1204 template <int dim, int spacedim>
1207 {
1208 return particle_iterator(particle_container_owned_begin(),
1209 *property_pool,
1210 0);
1211 }
1212
1213
1214
1215 template <int dim, int spacedim>
1218 {
1219 return (const_cast<ParticleHandler<dim, spacedim> *>(this))->end();
1220 }
1221
1222
1223
1224 template <int dim, int spacedim>
1227 {
1228 return particle_iterator(particle_container_owned_end(), *property_pool, 0);
1229 }
1230
1231
1232
1233 template <int dim, int spacedim>
1236 {
1237 return (const_cast<ParticleHandler<dim, spacedim> *>(this))->begin_ghost();
1238 }
1239
1240
1241
1242 template <int dim, int spacedim>
1245 {
1246 return particle_iterator(particle_container_ghost_begin(),
1247 *property_pool,
1248 0);
1249 }
1250
1251
1252
1253 template <int dim, int spacedim>
1256 {
1257 return (const_cast<ParticleHandler<dim, spacedim> *>(this))->end_ghost();
1258 }
1259
1260
1261
1262 template <int dim, int spacedim>
1265 {
1266 return particle_iterator(particle_container_ghost_end(), *property_pool, 0);
1267 }
1268
1269
1270
1271 template <int dim, int spacedim>
1274 {
1275 // We should always have at least the three anchor entries in the list of
1276 // particles
1277 Assert(!particles.empty(), ExcInternalError());
1278 typename particle_container::iterator begin =
1279 const_cast<particle_container &>(particles).begin();
1280 return ++begin;
1281 }
1282
1283
1284
1285 template <int dim, int spacedim>
1288 {
1289 Assert(!particles.empty(), ExcInternalError());
1290 return owned_particles_end;
1291 }
1292
1293
1294
1295 template <int dim, int spacedim>
1298 {
1299 Assert(!particles.empty(), ExcInternalError());
1300 typename particle_container::iterator begin = owned_particles_end;
1301 return ++begin;
1302 }
1303
1304
1305
1306 template <int dim, int spacedim>
1309 {
1310 Assert(!particles.empty(), ExcInternalError());
1311 typename particle_container::iterator end =
1312 const_cast<particle_container &>(particles).end();
1313 return --end;
1314 }
1315
1316
1317
1318 template <int dim, int spacedim>
1319 template <class Archive>
1320 inline void
1321 ParticleHandler<dim, spacedim>::serialize(Archive &ar, const unsigned int)
1322 {
1323 // Note that we do not serialize the particle data itself. Instead we
1324 // use the serialization functionality of the triangulation class, because
1325 // this guarantees that data is immediately shipped to new processes if
1326 // the domain is distributed differently after resuming from a checkpoint.
1327 ar //&particles
1328 &global_number_of_particles &global_max_particles_per_cell
1329 &next_free_particle_index;
1330 }
1331
1332
1333
1334 template <int dim, int spacedim>
1335 template <typename VectorType>
1336 inline std::enable_if_t<
1337 std::is_convertible_v<VectorType *, Function<spacedim> *> == false>
1339 const VectorType &input_vector,
1340 const bool displace_particles)
1341 {
1342 AssertDimension(input_vector.size(),
1343 get_next_free_particle_index() * spacedim);
1344 for (auto &p : *this)
1345 {
1346 Point<spacedim> &position = p.get_location();
1347 const auto id = p.get_id();
1348
1349 if (displace_particles)
1350 for (unsigned int i = 0; i < spacedim; ++i)
1351 position[i] += input_vector[id * spacedim + i];
1352 else
1353 for (unsigned int i = 0; i < spacedim; ++i)
1354 position[i] = input_vector[id * spacedim + i];
1355 }
1356 sort_particles_into_subdomains_and_cells();
1357 }
1358
1359
1360
1361 template <int dim, int spacedim>
1362 template <typename VectorType>
1363 inline void
1365 VectorType &output_vector,
1366 const bool add_to_output_vector)
1367 {
1368 AssertDimension(output_vector.size(),
1369 get_next_free_particle_index() * spacedim);
1370 for (const auto &p : *this)
1371 {
1372 auto point = p.get_location();
1373 const auto id = p.get_id();
1374 if (add_to_output_vector)
1375 for (unsigned int i = 0; i < spacedim; ++i)
1376 output_vector[id * spacedim + i] += point[i];
1377 else
1378 for (unsigned int i = 0; i < spacedim; ++i)
1379 output_vector[id * spacedim + i] = point[i];
1380 }
1381 if (add_to_output_vector)
1382 output_vector.compress(VectorOperation::add);
1383 else
1384 output_vector.compress(VectorOperation::insert);
1385 }
1386
1387} // namespace Particles
1388
1390
1391#endif
CellStatus
Definition cell_status.h:31
Abstract base class for mapping classes.
Definition mapping.h:318
std::list< ParticlesInCell > particle_container
std::function< void *(const particle_iterator &, void *)> store_callback
void register_additional_store_load_functions(const std::function< std::size_t()> &size_callback, const std::function< void *(const particle_iterator &, void *)> &store_callback, const std::function< const void *(const particle_iterator &, const void *)> &load_callback)
void exchange_ghost_particles(const bool enable_ghost_cache=false)
types::particle_index n_global_particles() const
particle_iterator end_ghost() const
unsigned int global_max_particles_per_cell
internal::GhostParticlePartitioner< dim, spacedim > ghost_particles_cache
particle_container::iterator particle_container_ghost_begin() const
unsigned int n_properties_per_particle() const
types::particle_index global_number_of_particles
void get_particle_positions(VectorType &output_vector, const bool add_to_output_vector=false)
particle_container::iterator particle_container_owned_end() const
particle_container::iterator particle_container_ghost_end() const
boost::iterator_range< particle_iterator > particle_iterator_range
void send_recv_particles(const std::map< types::subdomain_id, std::vector< particle_iterator > > &particles_to_send, const std::map< types::subdomain_id, std::vector< typename Triangulation< dim, spacedim >::active_cell_iterator > > &new_cells_for_particles=std::map< types::subdomain_id, std::vector< typename Triangulation< dim, spacedim >::active_cell_iterator > >(), const bool enable_cache=false)
ParticleIterator< dim, spacedim > particle_iterator
void send_recv_particles_properties_and_location(const std::map< types::subdomain_id, std::vector< particle_iterator > > &particles_to_send)
types::particle_index number_of_locally_owned_particles
particle_iterator begin_ghost() const
PropertyPool< dim, spacedim > & get_property_pool() const
void initialize(const Triangulation< dim, spacedim > &tria, const Mapping< dim, spacedim > &mapping, const unsigned int n_properties=0)
void serialize(Archive &ar, const unsigned int version)
std::unique_ptr< PropertyPool< dim, spacedim > > property_pool
types::particle_index get_max_local_particle_index() const
void reserve(const std::size_t n_particles)
particle_iterator begin() const
std::map< unsigned int, IndexSet > insert_global_particles(const std::vector< Point< spacedim > > &positions, const std::vector< std::vector< BoundingBox< spacedim > > > &global_bounding_boxes, const std::vector< std::vector< double > > &properties={}, const std::vector< types::particle_index > &ids={})
void notify_ready_to_unpack(const bool serialization)
void register_load_callback_function(const bool serialization)
std::enable_if_t< std::is_convertible_v< VectorType *, Function< spacedim > * >==false > set_particle_positions(const VectorType &input_vector, const bool displace_particles=true)
std::function< std::size_t()> size_callback
std::vector< char > pack_callback(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const CellStatus status) const
void insert_particles(const std::multimap< typename Triangulation< dim, spacedim >::active_cell_iterator, Particle< dim, spacedim > > &particles)
types::particle_index next_free_particle_index
const particle_container::iterator owned_particles_end
particle_iterator end() const
void remove_particle(const particle_iterator &particle)
types::particle_index n_locally_owned_particles() const
void reset_particle_container(particle_container &particles)
types::particle_index n_particles_in_cell(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell) const
typename ParticleAccessor< dim, spacedim >::particle_container particle_container
particle_iterator_range particles_in_cell(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell)
SmartPointer< const Triangulation< dim, spacedim >, ParticleHandler< dim, spacedim > > triangulation
particle_iterator insert_particle(const Particle< dim, spacedim > &particle, const typename Triangulation< dim, spacedim >::active_cell_iterator &cell)
void remove_particles(const std::vector< particle_iterator > &particles)
types::particle_index n_global_max_particles_per_cell() const
std::vector< boost::signals2::connection > tria_listeners
particle_container::iterator particle_container_owned_begin() const
void unpack_callback(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const CellStatus status, const boost::iterator_range< std::vector< char >::const_iterator > &data_range)
std::vector< typename particle_container::iterator > cells_to_particle_cache
void copy_from(const ParticleHandler< dim, spacedim > &particle_handler)
std::function< const void *(const particle_iterator &, const void *)> load_callback
SmartPointer< const Mapping< dim, spacedim >, ParticleHandler< dim, spacedim > > mapping
std::unique_ptr< GridTools::Cache< dim, spacedim > > triangulation_cache
types::particle_index get_next_free_particle_index() const
IndexSet locally_owned_particle_ids() const
Definition point.h:111
#define DEAL_II_DEPRECATED
Definition config.h:207
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:502
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:503
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
boost::signals2::signal< void(const typename Particles::ParticleIterator< dim, spacedim > &particle, const typename Triangulation< dim, spacedim >::active_cell_iterator &cell)> particle_lost