Reference documentation for deal.II version 9.4.0
\(\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\}}\)
particle_handler.h
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2017 - 2022 by the deal.II authors
4//
5// This file is part of the deal.II library.
6//
7// The deal.II library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.md at
12// the top level directory of deal.II.
13//
14// ---------------------------------------------------------------------
15
16#ifndef dealii_particles_particle_handler_h
17#define dealii_particles_particle_handler_h
18
19#include <deal.II/base/config.h>
20
24#include <deal.II/base/mpi.h>
27
29
30#include <deal.II/fe/mapping.h>
31
33
38
39#include <boost/range/iterator_range.hpp>
40#include <boost/serialization/map.hpp>
41
43
44namespace Particles
45{
65 template <int dim, int spacedim = dim>
67 {
68 public:
73
77 using particle_iterator_range = boost::iterator_range<particle_iterator>;
78
84
89
100 const unsigned int n_properties = 0);
101
105 virtual ~ParticleHandler();
106
112 void
115 const unsigned int n_properties = 0);
116
137 void
138 copy_from(const ParticleHandler<dim, spacedim> &particle_handler);
139
143 void
144 clear();
145
151 void
153
168 void
169 reserve(const std::size_t n_particles);
170
179 void
181
186 begin() const;
187
192 begin();
193
198 end() const;
199
204 end();
205
210 begin_ghost() const;
211
216 begin_ghost();
217
222 end_ghost() const;
223
228 end_ghost();
229
236 const;
237
249
261 const;
262
268 void
269 remove_particle(const particle_iterator &particle);
270
276 void
277 remove_particles(const std::vector<particle_iterator> &particles);
278
287 const Particle<dim, spacedim> &particle,
289
307 const Point<spacedim> & position,
308 const Point<dim> & reference_position,
311 const ArrayView<const double> &properties = {});
312
319 void
321 const std::multimap<
324
334 void
335 insert_particles(const std::vector<Point<spacedim>> &positions);
336
397 std::map<unsigned int, IndexSet>
399 const std::vector<Point<spacedim>> &positions,
400 const std::vector<std::vector<BoundingBox<spacedim>>>
401 & global_bounding_boxes,
402 const std::vector<std::vector<double>> & properties = {},
403 const std::vector<types::particle_index> &ids = {});
404
435 std::map<unsigned int, IndexSet>
437 const std::vector<Particle<dim, spacedim>> &particles,
438 const std::vector<std::vector<BoundingBox<spacedim>>>
439 &global_bounding_boxes);
440
484 template <class VectorType>
485 typename std::enable_if<
486 std::is_convertible<VectorType *, Function<spacedim> *>::value ==
487 false>::type
488 set_particle_positions(const VectorType &input_vector,
489 const bool displace_particles = true);
490
511 void
512 set_particle_positions(const std::vector<Point<spacedim>> &new_positions,
513 const bool displace_particles = true);
514
515
534 void
536 const bool displace_particles = true);
537
565 template <class VectorType>
566 void
567 get_particle_positions(VectorType &output_vector,
568 const bool add_to_output_vector = false);
569
584 void
585 get_particle_positions(std::vector<Point<spacedim>> &positions,
586 const bool add_to_output_vector = false);
587
614 void
616 const std::function<std::size_t()> &size_callback,
617 const std::function<void *(const particle_iterator &, void *)>
619 const std::function<const void *(const particle_iterator &, const void *)>
621
631 n_global_particles() const;
632
641
648
656
676 locally_relevant_ids() const;
677
696
700 unsigned int
702
718
723 PropertyPool<dim, spacedim> &
724 get_property_pool() const;
725
740 void
742
748 void
749 exchange_ghost_particles(const bool enable_ghost_cache = false);
750
758 void
760
770 void
772
791 void
793
805 void
807
816 void
817 deserialize();
818
829 DEAL_II_DEPRECATED_EARLY
830 void
832
843 DEAL_II_DEPRECATED_EARLY
844 void
845 register_load_callback_function(const bool serialization);
846
851 template <class Archive>
852 void
853 serialize(Archive &ar, const unsigned int version);
854
867 struct Signals
868 {
882 boost::signals2::signal<void(
883 const typename Particles::ParticleIterator<dim, spacedim> &particle,
885 &cell)>
887 };
888
894
895 private:
904 const void *& data,
906
915
925 void
927
934
940
949 std::unique_ptr<PropertyPool<dim, spacedim>> property_pool;
950
955
961 const typename particle_container::iterator owned_particles_end;
962
968 std::vector<typename particle_container::iterator> cells_to_particle_cache;
969
975
981
991
997
1009 std::function<std::size_t()> size_callback;
1010
1021 std::function<void *(const particle_iterator &, void *)> store_callback;
1022
1033 std::function<const void *(const particle_iterator &, const void *)>
1035
1042 unsigned int handle;
1043
1053 std::unique_ptr<GridTools::Cache<dim, spacedim>> triangulation_cache;
1054
1055#ifdef DEAL_II_WITH_MPI
1079 void
1081 const std::map<types::subdomain_id, std::vector<particle_iterator>>
1082 &particles_to_send,
1083 const std::map<
1085 std::vector<
1087 &new_cells_for_particles = std::map<
1089 std::vector<
1091 const bool enable_cache = false);
1092
1104 void
1106 const std::map<types::subdomain_id, std::vector<particle_iterator>>
1107 &particles_to_send);
1108
1109#endif
1110
1118
1123 void
1125
1130 std::vector<boost::signals2::connection> tria_listeners;
1131
1140 void
1142
1148 void
1150
1158 void
1159 notify_ready_to_unpack(const bool serialization);
1160
1166 std::vector<char>
1169 const typename Triangulation<dim, spacedim>::CellStatus status) const;
1170
1175 void
1178 const typename Triangulation<dim, spacedim>::CellStatus status,
1179 const boost::iterator_range<std::vector<char>::const_iterator>
1180 &data_range);
1181
1186 typename particle_container::iterator
1188
1193 typename particle_container::iterator
1195
1200 typename particle_container::iterator
1202
1207 typename particle_container::iterator
1209 };
1210
1211
1212
1213 /* ---------------------- inline and template functions ------------------
1214 */
1215
1216 template <int dim, int spacedim>
1219 {
1220 return (const_cast<ParticleHandler<dim, spacedim> *>(this))->begin();
1221 }
1222
1223
1224
1225 template <int dim, int spacedim>
1228 {
1229 return particle_iterator(particle_container_owned_begin(),
1230 *property_pool,
1231 0);
1232 }
1233
1234
1235
1236 template <int dim, int spacedim>
1239 {
1240 return (const_cast<ParticleHandler<dim, spacedim> *>(this))->end();
1241 }
1242
1243
1244
1245 template <int dim, int spacedim>
1248 {
1249 return particle_iterator(particle_container_owned_end(), *property_pool, 0);
1250 }
1251
1252
1253
1254 template <int dim, int spacedim>
1257 {
1258 return (const_cast<ParticleHandler<dim, spacedim> *>(this))->begin_ghost();
1259 }
1260
1261
1262
1263 template <int dim, int spacedim>
1266 {
1267 return particle_iterator(particle_container_ghost_begin(),
1268 *property_pool,
1269 0);
1270 }
1271
1272
1273
1274 template <int dim, int spacedim>
1277 {
1278 return (const_cast<ParticleHandler<dim, spacedim> *>(this))->end_ghost();
1279 }
1280
1281
1282
1283 template <int dim, int spacedim>
1286 {
1287 return particle_iterator(particle_container_ghost_end(), *property_pool, 0);
1288 }
1289
1290
1291
1292 template <int dim, int spacedim>
1295 {
1296 // We should always have at least the three anchor entries in the list of
1297 // particles
1298 Assert(!particles.empty(), ExcInternalError());
1299 typename particle_container::iterator begin =
1300 const_cast<particle_container &>(particles).begin();
1301 return ++begin;
1302 }
1303
1304
1305
1306 template <int dim, int spacedim>
1309 {
1310 Assert(!particles.empty(), ExcInternalError());
1311 return owned_particles_end;
1312 }
1313
1314
1315
1316 template <int dim, int spacedim>
1319 {
1320 Assert(!particles.empty(), ExcInternalError());
1321 typename particle_container::iterator begin = owned_particles_end;
1322 return ++begin;
1323 }
1324
1325
1326
1327 template <int dim, int spacedim>
1330 {
1331 Assert(!particles.empty(), ExcInternalError());
1332 typename particle_container::iterator end =
1333 const_cast<particle_container &>(particles).end();
1334 return --end;
1335 }
1336
1337
1338
1339 template <int dim, int spacedim>
1340 template <class Archive>
1341 inline void
1342 ParticleHandler<dim, spacedim>::serialize(Archive &ar, const unsigned int)
1343 {
1344 // Note that we do not serialize the particle data itself. Instead we
1345 // use the serialization functionality of the triangulation class, because
1346 // this guarantees that data is immediately shipped to new processes if
1347 // the domain is distributed differently after resuming from a checkpoint.
1348 ar //&particles
1349 &global_number_of_particles &global_max_particles_per_cell
1350 & next_free_particle_index;
1351 }
1352
1353
1354
1355 template <int dim, int spacedim>
1356 template <class VectorType>
1357 inline typename std::enable_if<
1358 std::is_convertible<VectorType *, Function<spacedim> *>::value ==
1359 false>::type
1361 const VectorType &input_vector,
1362 const bool displace_particles)
1363 {
1364 AssertDimension(input_vector.size(),
1365 get_next_free_particle_index() * spacedim);
1366 for (auto &p : *this)
1367 {
1368 auto new_point(displace_particles ? p.get_location() :
1369 Point<spacedim>());
1370 const auto id = p.get_id();
1371 for (unsigned int i = 0; i < spacedim; ++i)
1372 new_point[i] += input_vector[id * spacedim + i];
1373 p.set_location(new_point);
1374 }
1375 sort_particles_into_subdomains_and_cells();
1376 }
1377
1378
1379
1380 template <int dim, int spacedim>
1381 template <class VectorType>
1382 inline void
1384 VectorType &output_vector,
1385 const bool add_to_output_vector)
1386 {
1387 AssertDimension(output_vector.size(),
1388 get_next_free_particle_index() * spacedim);
1389 for (const auto &p : *this)
1390 {
1391 auto point = p.get_location();
1392 const auto id = p.get_id();
1393 if (add_to_output_vector)
1394 for (unsigned int i = 0; i < spacedim; ++i)
1395 output_vector[id * spacedim + i] += point[i];
1396 else
1397 for (unsigned int i = 0; i < spacedim; ++i)
1398 output_vector[id * spacedim + i] = point[i];
1399 }
1400 if (add_to_output_vector)
1401 output_vector.compress(VectorOperation::add);
1402 else
1403 output_vector.compress(VectorOperation::insert);
1404 }
1405
1406
1407
1408 template <int dim, int spacedim>
1409 inline IndexSet
1411 {
1412 return this->locally_owned_particle_ids();
1413 }
1414
1415} // namespace Particles
1416
1418
1419#endif
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
IndexSet locally_relevant_ids() 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::function< std::size_t()> size_callback
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
void unpack_callback(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const typename Triangulation< dim, spacedim >::CellStatus status, const boost::iterator_range< std::vector< char >::const_iterator > &data_range)
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
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
std::enable_if< std::is_convertible< VectorType *, Function< spacedim > * >::value==false >::type set_particle_positions(const VectorType &input_vector, const bool displace_particles=true)
types::particle_index get_next_free_particle_index() const
particle_container particles
std::vector< char > pack_callback(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const typename Triangulation< dim, spacedim >::CellStatus status) const
IndexSet locally_owned_particle_ids() const
#define DEAL_II_DEPRECATED
Definition: config.h:164
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:442
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:443
#define Assert(cond, exc)
Definition: exceptions.h:1473
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1667
static ::ExceptionBase & ExcInternalError()
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
Definition: utilities.cc:190
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
unsigned int particle_index
Definition: property_pool.h:65
boost::signals2::signal< void(const typename Particles::ParticleIterator< dim, spacedim > &particle, const typename Triangulation< dim, spacedim >::active_cell_iterator &cell)> particle_lost
const ::Triangulation< dim, spacedim > & tria