Reference documentation for deal.II version Git 52b85b2253 2021-11-28 10:49:58 +0100
\(\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 - 2021 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 
23 #include <deal.II/base/function.h>
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 
44 namespace Particles
45 {
65  template <int dim, int spacedim = dim>
66  class ParticleHandler : public Subscriptor
67  {
68  public:
73 
77  using particle_iterator_range = boost::iterator_range<particle_iterator>;
78 
82  using particle_container =
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
152  clear_particles();
153 
168  void
169  reserve(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 *)>
620  &load_callback);
621 
631  n_global_particles() const;
632 
641 
648 
656 
676  locally_relevant_ids() const;
677 
694  IndexSet
696 
700  unsigned int
702 
718 
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 
893  mutable Signals signals;
894 
895  private:
904  const void *& data,
906 
914  const typename Triangulation<dim, spacedim>::cell_iterator &cell);
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
1056 
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>
1167  pack_callback(
1168  const typename Triangulation<dim, spacedim>::cell_iterator &cell,
1169  const typename Triangulation<dim, spacedim>::CellStatus status) const;
1170 
1175  void
1177  const typename Triangulation<dim, spacedim>::cell_iterator &cell,
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  {
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  {
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
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  }
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
types::particle_index n_global_particles() const
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1655
types::particle_index n_locally_owned_particles() const
void get_particle_positions(VectorType &output_vector, const bool add_to_output_vector=false)
void remove_particle(const particle_iterator &particle)
PropertyPool< dim, spacedim > & get_property_pool() const
void copy_from(const ParticleHandler< dim, spacedim > &particle_handler)
typename ParticleAccessor< dim, spacedim >::particle_container particle_container
void exchange_ghost_particles(const bool enable_ghost_cache=false)
types::particle_index number_of_locally_owned_particles
IndexSet locally_relevant_ids() const
types::particle_index n_global_max_particles_per_cell() const
std::function< const void *(const particle_iterator &, const void *)> load_callback
particle_iterator insert_particle(const Particle< dim, spacedim > &particle, const typename Triangulation< dim, spacedim >::active_cell_iterator &cell)
void notify_ready_to_unpack(const bool serialization)
const ::Triangulation< dim, spacedim > & tria
types::particle_index n_particles_in_cell(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell) const
IndexSet locally_owned_particle_ids() const
std::vector< boost::signals2::connection > tria_listeners
types::particle_index get_max_local_particle_index() const
std::unique_ptr< PropertyPool< dim, spacedim > > property_pool
types::particle_index next_free_particle_index
boost::signals2::signal< void(const typename Particles::ParticleIterator< dim, spacedim > &particle, const typename Triangulation< dim, spacedim >::active_cell_iterator &cell)> particle_lost
SmartPointer< const Triangulation< dim, spacedim >, ParticleHandler< dim, spacedim > > triangulation
particle_container::iterator particle_container_ghost_begin() const
void remove_particles(const std::vector< particle_iterator > &particles)
unsigned int global_max_particles_per_cell
particle_container particles
void initialize(const Triangulation< dim, spacedim > &tria, const Mapping< dim, spacedim > &mapping, const unsigned int n_properties=0)
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)
unsigned int particle_index
Definition: property_pool.h:65
void register_load_callback_function(const bool serialization)
void insert_particles(const std::multimap< typename Triangulation< dim, spacedim >::active_cell_iterator, Particle< dim, spacedim >> &particles)
particle_iterator begin_ghost() const
void send_recv_particles_properties_and_location(const std::map< types::subdomain_id, std::vector< particle_iterator >> &particles_to_send)
unsigned int n_properties_per_particle() const
types::particle_index global_number_of_particles
void reserve(std::size_t n_particles)
#define Assert(cond, exc)
Definition: exceptions.h:1461
std::list< ParticlesInCell > particle_container
particle_iterator_range particles_in_cell(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell)
std::function< std::size_t()> size_callback
Abstract base class for mapping classes.
Definition: mapping.h:310
std::enable_if< std::is_convertible< VectorType *, Function< spacedim > * >::value==false >::type set_particle_positions(const VectorType &input_vector, const bool displace_particles=true)
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:401
particle_iterator begin() const
const particle_container::iterator owned_particles_end
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
Definition: utilities.cc:185
std::unique_ptr< GridTools::Cache< dim, spacedim > > triangulation_cache
types::particle_index get_next_free_particle_index() const
boost::iterator_range< particle_iterator > particle_iterator_range
ParticleIterator< dim, spacedim > particle_iterator
void serialize(Archive &ar, const unsigned int version)
std::vector< typename particle_container::iterator > cells_to_particle_cache
std::function< void *(const particle_iterator &, void *)> store_callback
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:400
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)
std::vector< char > pack_callback(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const typename Triangulation< dim, spacedim >::CellStatus status) const
particle_container::iterator particle_container_owned_end() const
particle_container::iterator particle_container_owned_begin() const
SmartPointer< const Mapping< dim, spacedim >, ParticleHandler< dim, spacedim > > mapping
particle_container::iterator particle_container_ghost_end() const
#define DEAL_II_DEPRECATED
Definition: config.h:160
internal::GhostParticlePartitioner< dim, spacedim > ghost_particles_cache
particle_iterator end_ghost() const
particle_iterator end() const
void reset_particle_container(particle_container &particles)
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)
static ::ExceptionBase & ExcInternalError()
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={})