16 #include <deal.II/particles/particle_handler.h> 18 #include <deal.II/base/std_cxx14/memory.h> 19 #include <deal.II/grid/grid_tools.h> 20 #include <deal.II/grid/grid_tools_cache.h> 24 DEAL_II_NAMESPACE_OPEN
26 #ifdef DEAL_II_WITH_P4EST 30 template <
int dim,
int spacedim>
36 global_number_of_particles(0),
37 global_max_particles_per_cell(0),
38 next_free_particle_index(0),
43 data_offset(
numbers::invalid_unsigned_int)
48 template <
int dim,
int spacedim>
51 const unsigned int n_properties)
53 triangulation(&triangulation, typeid(*this).name()),
54 mapping(&mapping, typeid(*this).name()),
57 global_number_of_particles(0),
58 global_max_particles_per_cell(0),
59 next_free_particle_index(0),
64 data_offset(
numbers::invalid_unsigned_int)
69 template <
int dim,
int spacedim>
75 template <
int dim,
int spacedim>
79 const unsigned int n_properties)
81 triangulation = &tria;
85 property_pool = std_cxx14::make_unique<PropertyPool>(n_properties);
90 template <
int dim,
int spacedim>
95 global_number_of_particles = 0;
96 next_free_particle_index = 0;
97 global_max_particles_per_cell = 0;
102 template <
int dim,
int spacedim>
111 template <
int dim,
int spacedim>
117 unsigned int local_max_particles_per_cell = 0;
118 unsigned int current_particles_per_cell = 0;
123 locally_highest_index = std::max(locally_highest_index,particle->get_id());
125 if (particle->get_surrounding_cell(*triangulation) != current_cell)
127 current_particles_per_cell = 0;
128 current_cell = particle->get_surrounding_cell(*triangulation);
131 ++current_particles_per_cell;
132 local_max_particles_per_cell = std::max(local_max_particles_per_cell,
133 current_particles_per_cell);
136 global_number_of_particles = ::Utilities::MPI::sum (particles.size(), triangulation->get_communicator());
137 next_free_particle_index = ::Utilities::MPI::max (locally_highest_index, triangulation->get_communicator()) + 1;
138 global_max_particles_per_cell = ::Utilities::MPI::max(local_max_particles_per_cell,triangulation->get_communicator());
144 template <
int dim,
int spacedim>
153 template <
int dim,
int spacedim>
162 template <
int dim,
int spacedim>
171 template <
int dim,
int spacedim>
180 template <
int dim,
int spacedim>
189 template <
int dim,
int spacedim>
198 template <
int dim,
int spacedim>
207 template <
int dim,
int spacedim>
216 template <
int dim,
int spacedim>
225 template <
int dim,
int spacedim>
229 const internal::LevelInd level_index = std::make_pair<int, int> (cell->level(),cell->index());
231 if (cell->is_ghost())
233 const auto particles_in_cell = ghost_particles.equal_range(level_index);
234 return boost::make_iterator_range(
particle_iterator(ghost_particles,particles_in_cell.first),
238 const auto particles_in_cell = particles.equal_range(level_index);
239 return boost::make_iterator_range(
particle_iterator(particles,particles_in_cell.first),
245 template <
int dim,
int spacedim>
249 particles.erase(particle->particle);
254 template <
int dim,
int spacedim>
259 typename std::multimap<internal::LevelInd, Particle<dim,spacedim> >::iterator it =
260 particles.insert(std::make_pair(internal::LevelInd(cell->level(),cell->index()),particle));
263 particle_it->set_property_pool(*property_pool);
274 template <
int dim,
int spacedim>
279 for (
auto particle = new_particles.begin(); particle != new_particles.end(); ++particle)
280 particles.insert(particles.end(),
281 std::make_pair(internal::LevelInd(particle->first->level(),particle->first->index()),
284 update_cached_numbers();
289 template <
int dim,
int spacedim>
293 update_cached_numbers();
302 #ifdef DEAL_II_WITH_MPI 304 const int ierr = MPI_Scan(&particles_to_add_locally, &local_start_index, 1,
305 PARTICLE_INDEX_MPI_TYPE, MPI_SUM,
306 triangulation->get_communicator());
308 local_start_index -= particles_to_add_locally;
311 local_start_index += local_next_particle_index;
316 auto &cells = std::get<0>(point_locations);
317 auto &local_positions = std::get<1>(point_locations);
318 auto &index_map = std::get<2>(point_locations);
320 if (cells.size() == 0)
323 auto hint = particles.find(std::make_pair(cells[0]->level(),cells[0]->index()));
324 for (
unsigned int i=0; i<cells.size(); ++i)
326 internal::LevelInd current_cell(cells[i]->level(),cells[i]->index());
327 for (
unsigned int p=0; p<local_positions[i].size(); ++p)
329 hint = particles.insert(hint,
330 std::make_pair(current_cell,
332 local_positions[i][p],
333 local_start_index+index_map[i][p])));
337 update_cached_numbers();
342 template <
int dim,
int spacedim>
346 return global_number_of_particles;
351 template <
int dim,
int spacedim>
355 return global_max_particles_per_cell;
360 template <
int dim,
int spacedim>
364 return particles.size();
369 template <
int dim,
int spacedim>
373 return property_pool->n_properties_per_slot();
378 template <
int dim,
int spacedim>
382 const internal::LevelInd found_cell = std::make_pair<int, int> (cell->level(),cell->index());
384 if (cell->is_locally_owned())
385 return particles.count(found_cell);
386 else if (cell->is_ghost())
387 return ghost_particles.count(found_cell);
388 else if (cell->is_artificial())
396 template <
int dim,
int spacedim>
400 return next_free_particle_index;
405 template <
int dim,
int spacedim>
409 return *property_pool;
427 compare_particle_association(
const unsigned int a,
428 const unsigned int b,
432 const double scalar_product_a = center_directions[a] * particle_direction;
433 const double scalar_product_b = center_directions[b] * particle_direction;
438 return (scalar_product_a > scalar_product_b);
444 template <
int dim,
int spacedim>
456 std::vector<particle_iterator> particles_out_of_cell;
457 particles_out_of_cell.reserve(n_locally_owned_particles());
466 const Point<dim> p_unit = mapping->transform_real_to_unit_cell(cell, it->get_location());
469 it->set_reference_location(p_unit);
474 particles_out_of_cell.push_back(it);
480 particles_out_of_cell.push_back(it);
490 std::vector<std::pair<internal::LevelInd, Particle<dim,spacedim> > > sorted_particles;
491 std::map<types::subdomain_id, std::vector<particle_iterator> > moved_particles;
492 std::map<types::subdomain_id, std::vector<typename Triangulation<dim,spacedim>::active_cell_iterator> > moved_cells;
499 typedef typename std::vector<particle_iterator>::size_type vector_size;
500 sorted_particles.reserve(static_cast<vector_size> (particles_out_of_cell.size()*1.25));
502 const std::set<types::subdomain_id> ghost_owners = triangulation->ghost_owners();
504 for (
auto ghost_domain_id = ghost_owners.begin(); ghost_domain_id != ghost_owners.end(); ++ghost_domain_id)
505 moved_particles[*ghost_domain_id].reserve(static_cast<vector_size> (particles_out_of_cell.size()*0.25));
506 for (
auto ghost_domain_id = ghost_owners.begin(); ghost_domain_id != ghost_owners.end(); ++ghost_domain_id)
507 moved_cells[*ghost_domain_id].reserve(static_cast<vector_size> (particles_out_of_cell.size()*0.25));
511 const std::vector<std::set<typename Triangulation<dim,spacedim>::active_cell_iterator> >
515 const std::vector<std::vector<Tensor<1,spacedim> > >
518 std::vector<unsigned int> neighbor_permutation;
521 typename std::vector<particle_iterator>::iterator it = particles_out_of_cell.begin(),
522 end_particle = particles_out_of_cell.end();
524 for (; it!=end_particle; ++it)
528 bool found_cell =
false;
534 const unsigned int closest_vertex = GridTools::find_closest_vertex_of_cell<dim,spacedim>(current_cell,(*it)->get_location());
535 Tensor<1,spacedim> vertex_to_particle = (*it)->get_location() - current_cell->vertex(closest_vertex);
536 vertex_to_particle /= vertex_to_particle.
norm();
538 const unsigned int closest_vertex_index = current_cell->vertex_index(closest_vertex);
539 const unsigned int n_neighbor_cells = vertex_to_cells[closest_vertex_index].size();
541 neighbor_permutation.resize(n_neighbor_cells);
542 for (
unsigned int i=0; i<n_neighbor_cells; ++i)
543 neighbor_permutation[i] = i;
545 std::sort(neighbor_permutation.begin(),
546 neighbor_permutation.end(),
547 std::bind(&compare_particle_association<spacedim>,
548 std::placeholders::_1,
549 std::placeholders::_2,
550 std::cref(vertex_to_particle),
551 std::cref(vertex_to_cell_centers[closest_vertex_index])));
555 for (
unsigned int i=0; i<n_neighbor_cells; ++i)
559 typename std::set<typename Triangulation<dim,spacedim>::active_cell_iterator>::const_iterator
560 cell = vertex_to_cells[closest_vertex_index].begin();
562 std::advance(cell,neighbor_permutation[i]);
563 const Point<dim> p_unit = mapping->transform_real_to_unit_cell(*cell,
564 (*it)->get_location());
567 current_cell = *cell;
568 current_reference_position = p_unit;
584 const std::pair<const typename Triangulation<dim,spacedim>::active_cell_iterator,
586 GridTools::find_active_cell_around_point<> (*mapping,
588 (*it)->get_location());
589 current_cell = current_cell_and_position.first;
590 current_reference_position = current_cell_and_position.second;
592 catch (GridTools::ExcPointNotFound<spacedim> &)
601 (*it)->set_reference_location(current_reference_position);
605 if (current_cell->is_locally_owned())
607 sorted_particles.push_back(std::make_pair(internal::LevelInd(current_cell->level(),current_cell->index()),
608 (*it)->particle->second));
612 moved_particles[current_cell->subdomain_id()].push_back(*it);
613 moved_cells[current_cell->subdomain_id()].push_back(current_cell);
620 std::multimap<internal::LevelInd,Particle <dim,spacedim> > sorted_particles_map;
623 #ifdef DEAL_II_WITH_MPI 625 send_recv_particles(moved_particles,sorted_particles_map,moved_cells);
628 sorted_particles_map.insert(sorted_particles.begin(),sorted_particles.end());
630 for (
unsigned int i=0; i<particles_out_of_cell.size(); ++i)
631 remove_particle(particles_out_of_cell[i]);
633 particles.insert(sorted_particles_map.begin(),sorted_particles_map.end());
634 update_cached_numbers();
639 template <
int dim,
int spacedim>
647 #ifdef DEAL_II_WITH_MPI 649 ghost_particles.clear();
651 std::map<types::subdomain_id, std::vector<particle_iterator> > ghost_particles_by_domain;
653 const std::set<types::subdomain_id> ghost_owners = triangulation->ghost_owners();
654 for (
auto ghost_domain_id = ghost_owners.begin(); ghost_domain_id != ghost_owners.end(); ++ghost_domain_id)
655 ghost_particles_by_domain[*ghost_domain_id].reserve(
static_cast<typename std::vector<particle_iterator>::size_type
> (particles.size()*0.25));
657 std::vector<std::set<unsigned int> > vertex_to_neighbor_subdomain(triangulation->n_vertices());
660 cell = triangulation->begin_active(),
661 endc = triangulation->end();
662 for (; cell != endc; ++cell)
664 if (cell->is_ghost())
665 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
666 vertex_to_neighbor_subdomain[cell->vertex_index(v)].insert(cell->subdomain_id());
669 cell = triangulation->begin_active();
670 for (; cell != endc; ++cell)
672 if (!cell->is_ghost())
674 std::set<unsigned int> cell_to_neighbor_subdomain;
675 for (
unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
677 cell_to_neighbor_subdomain.insert(vertex_to_neighbor_subdomain[cell->vertex_index(v)].begin(),
678 vertex_to_neighbor_subdomain[cell->vertex_index(v)].end());
681 if (cell_to_neighbor_subdomain.size() > 0)
685 for (std::set<types::subdomain_id>::const_iterator domain=cell_to_neighbor_subdomain.begin();
686 domain != cell_to_neighbor_subdomain.end(); ++domain)
688 for (
typename particle_iterator_range::iterator particle = particle_range.begin(); particle != particle_range.end(); ++particle)
689 ghost_particles_by_domain[*domain].push_back(particle);
695 send_recv_particles(ghost_particles_by_domain,
702 #ifdef DEAL_II_WITH_MPI 703 template <
int dim,
int spacedim>
710 const std::set<types::subdomain_id> ghost_owners = triangulation->ghost_owners();
711 const std::vector<types::subdomain_id> neighbors (ghost_owners.begin(),
713 const unsigned int n_neighbors = neighbors.size();
715 if (send_cells.size() != 0)
723 for (
auto send_particles = particles_to_send.begin(); send_particles != particles_to_send.end(); ++send_particles)
724 Assert(ghost_owners.find(send_particles->first) != ghost_owners.end(),
727 unsigned int n_send_particles = 0;
728 for (
auto send_particles = particles_to_send.begin(); send_particles != particles_to_send.end(); ++send_particles)
729 n_send_particles += send_particles->second.size();
735 std::vector<unsigned int> n_send_data(n_neighbors,0);
736 std::vector<unsigned int> send_offsets(n_neighbors,0);
737 std::vector<char> send_data;
742 if (n_send_particles > 0)
745 const unsigned int particle_size = begin()->serialized_size_in_bytes() + cellid_size + (size_callback ? size_callback() : 0);
746 send_data.resize(n_send_particles * particle_size);
747 void *data =
static_cast<void *
> (&send_data.front());
750 for (
unsigned int i = 0; i<n_neighbors; ++i)
752 send_offsets[i] =
reinterpret_cast<std::size_t
> (data) - reinterpret_cast<std::size_t> (&send_data.front());
754 for (
unsigned int j=0; j<particles_to_send.at(neighbors[i]).size(); ++j)
758 if (send_cells.size() == 0)
759 cell = particles_to_send.at(neighbors[i])[j]->get_surrounding_cell(*triangulation);
761 cell = send_cells.at(neighbors[i])[j];
764 memcpy(data, &cellid, cellid_size);
765 data =
static_cast<char *
>(data) + cellid_size;
767 particles_to_send.at(neighbors[i])[j]->write_data(data);
769 data = store_callback(particles_to_send.at(neighbors[i])[j],data);
771 n_send_data[i] =
reinterpret_cast<std::size_t
> (data) - send_offsets[i] - reinterpret_cast<std::size_t> (&send_data.front());
776 std::vector<unsigned int> n_recv_data(n_neighbors);
777 std::vector<unsigned int> recv_offsets(n_neighbors);
781 std::vector<MPI_Request> n_requests(2*n_neighbors);
782 for (
unsigned int i=0; i<n_neighbors; ++i)
784 const int ierr = MPI_Irecv(&(n_recv_data[i]), 1, MPI_INT, neighbors[i],
785 0, triangulation->get_communicator(), &(n_requests[2*i]));
788 for (
unsigned int i=0; i<n_neighbors; ++i)
790 const int ierr = MPI_Isend(&(n_send_data[i]), 1, MPI_INT, neighbors[i],
791 0, triangulation->get_communicator(), &(n_requests[2*i+1]));
794 const int ierr = MPI_Waitall(2*n_neighbors,&n_requests[0],MPI_STATUSES_IGNORE);
799 unsigned int total_recv_data = 0;
800 for (
unsigned int neighbor_id=0; neighbor_id<n_neighbors; ++neighbor_id)
802 recv_offsets[neighbor_id] = total_recv_data;
803 total_recv_data += n_recv_data[neighbor_id];
807 std::vector<char> recv_data(total_recv_data);
811 std::vector<MPI_Request> requests(2*n_neighbors);
812 unsigned int send_ops = 0;
813 unsigned int recv_ops = 0;
815 for (
unsigned int i=0; i<n_neighbors; ++i)
816 if (n_recv_data[i] > 0)
818 const int ierr = MPI_Irecv(&(recv_data[recv_offsets[i]]), n_recv_data[i], MPI_CHAR,
819 neighbors[i], 1, triangulation->get_communicator(),
820 &(requests[send_ops]));
825 for (
unsigned int i=0; i<n_neighbors; ++i)
826 if (n_send_data[i] > 0)
828 const int ierr = MPI_Isend(&(send_data[send_offsets[i]]), n_send_data[i], MPI_CHAR,
829 neighbors[i], 1, triangulation->get_communicator(),
830 &(requests[send_ops+recv_ops]));
834 const int ierr = MPI_Waitall(send_ops+recv_ops,&requests[0],MPI_STATUSES_IGNORE);
839 const void *recv_data_it =
static_cast<const void *
> (recv_data.data());
841 while (reinterpret_cast<std::size_t> (recv_data_it) -
reinterpret_cast<std::size_t
> (recv_data.data()) < total_recv_data)
844 memcpy(&binary_cellid, recv_data_it, cellid_size);
845 const CellId id(binary_cellid);
846 recv_data_it =
static_cast<const char *
> (recv_data_it) + cellid_size;
850 typename std::multimap<internal::LevelInd,Particle <dim,spacedim> >::iterator recv_particle =
851 received_particles.insert(std::make_pair(internal::LevelInd(cell->level(),cell->index()),
855 recv_data_it = load_callback(
particle_iterator(received_particles,recv_particle),
859 AssertThrow(recv_data_it == recv_data.data() + recv_data.size(),
860 ExcMessage(
"The amount of data that was read into new particles " 861 "does not match the amount of data sent around."));
867 template <
int dim,
int spacedim>
871 void *)> &store_callb,
873 const void *)> &load_callb)
875 size_callback = size_callb;
876 store_callback = store_callb;
877 load_callback = load_callb;
882 template <
int dim,
int spacedim>
891 update_cached_numbers();
893 if (global_max_particles_per_cell > 0)
895 const std::function<void(const typename Triangulation<dim,spacedim>::cell_iterator &,
899 std::placeholders::_1,
900 std::placeholders::_2,
901 std::placeholders::_3);
906 const std::size_t size_per_particle = (particles.size() > 0)
908 begin()->serialized_size_in_bytes()
911 + property_pool->n_properties_per_slot() *
sizeof(double);
918 const std::size_t transfer_size_per_cell =
sizeof (
unsigned int) +
919 (size_per_particle * global_max_particles_per_cell) *
925 data_offset = non_const_triangulation->
register_data_attach(transfer_size_per_cell,callback_function);
931 template <
int dim,
int spacedim>
946 if (serialization && (global_max_particles_per_cell > 0))
948 const std::function<void(const typename Triangulation<dim,spacedim>::cell_iterator &,
952 std::placeholders::_1,
953 std::placeholders::_2,
954 std::placeholders::_3);
959 const std::size_t size_per_particle = (particles.size() > 0)
961 begin()->serialized_size_in_bytes()
964 + property_pool->n_properties_per_slot() *
sizeof(double);
969 const std::size_t transfer_size_per_cell =
sizeof (
unsigned int) +
970 (size_per_particle * global_max_particles_per_cell);
971 data_offset = non_const_triangulation->
register_data_attach(transfer_size_per_cell,callback_function);
977 const std::function<void(const typename Triangulation<dim,spacedim>::cell_iterator &,
979 const void *) > callback_function
982 std::placeholders::_1,
983 std::placeholders::_2,
984 std::placeholders::_3);
991 update_cached_numbers();
997 template <
int dim,
int spacedim>
1003 unsigned int n_particles(0);
1009 const boost::iterator_range<particle_iterator> particle_range
1010 = particles_in_cell(cell);
1011 n_particles = std::distance(particle_range.begin(),particle_range.end());
1013 unsigned int *ndata =
static_cast<unsigned int *
> (data);
1014 *ndata = n_particles;
1015 data =
static_cast<void *
> (ndata + 1);
1018 particle != particle_range.end(); ++particle)
1020 particle->write_data(data);
1027 for (
unsigned int child_index = 0; child_index < GeometryInfo<dim>::max_children_per_cell; ++child_index)
1030 n_particles += n_particles_in_cell(child);
1033 unsigned int *ndata =
static_cast<unsigned int *
> (data);
1034 *ndata = n_particles;
1036 data =
static_cast<void *
> (ndata + 1);
1038 for (
unsigned int child_index = 0; child_index < GeometryInfo<dim>::max_children_per_cell; ++child_index)
1041 const boost::iterator_range<particle_iterator> particle_range
1042 = particles_in_cell(child);
1045 particle != particle_range.end(); ++particle)
1047 particle->write_data(data);
1056 template <
int dim,
int spacedim>
1062 const unsigned int *n_particles_in_cell_ptr =
static_cast<const unsigned int *
> (data);
1063 const void *pdata =
reinterpret_cast<const void *
> (n_particles_in_cell_ptr + 1);
1065 if (*n_particles_in_cell_ptr == 0)
1072 typename std::multimap<internal::LevelInd,Particle<dim,spacedim> >::iterator position_hint = particles.end();
1073 for (
unsigned int i = 0; i < *n_particles_in_cell_ptr; ++i)
1079 #ifdef DEAL_II_WITH_CXX14 1080 position_hint = particles.emplace_hint(position_hint,
1081 std::make_pair(cell->level(),cell->index()),
1084 position_hint = particles.insert(position_hint,
1085 std::make_pair(std::make_pair(cell->level(),cell->index()),
1094 typename std::multimap<internal::LevelInd,Particle<dim,spacedim> >::iterator position_hint = particles.end();
1095 for (
unsigned int i = 0; i < *n_particles_in_cell_ptr; ++i)
1101 #ifdef DEAL_II_WITH_CXX14 1102 position_hint = particles.emplace_hint(position_hint,
1103 std::make_pair(cell->level(),cell->index()),
1106 position_hint = particles.insert(position_hint,
1107 std::make_pair(std::make_pair(cell->level(),cell->index()),
1110 const Point<dim> p_unit = mapping->transform_real_to_unit_cell(cell, position_hint->second.get_location());
1111 position_hint->second.set_reference_location(p_unit);
1118 for (
unsigned int child_index=0; child_index<GeometryInfo<dim>::max_children_per_cell; ++child_index)
1121 position_hints[child_index] = particles.upper_bound(std::make_pair(child->level(),child->index()));
1124 for (
unsigned int i = 0; i < *n_particles_in_cell_ptr; ++i)
1128 for (
unsigned int child_index = 0; child_index < GeometryInfo<dim>::max_children_per_cell; ++child_index)
1134 const Point<dim> p_unit = mapping->transform_real_to_unit_cell(child,
1138 p.set_reference_location(p_unit);
1143 #ifdef DEAL_II_WITH_CXX14 1144 position_hints[child_index] = particles.emplace_hint(position_hints[child_index],
1145 std::make_pair(child->level(),child->index()),
1148 position_hints[child_index] = particles.insert(position_hints[child_index],
1149 std::make_pair(std::make_pair(child->level(),child->index()),
1152 ++position_hints[child_index];
1166 DEAL_II_NAMESPACE_CLOSE
1168 DEAL_II_NAMESPACE_OPEN
1170 #ifdef DEAL_II_WITH_P4EST 1171 #include "particle_handler.inst" 1174 DEAL_II_NAMESPACE_CLOSE
types::particle_index n_global_particles() const
void sort_particles_into_subdomains_and_cells()
static const unsigned int invalid_unsigned_int
types::particle_index n_locally_owned_particles() const
unsigned int particle_index
void remove_particle(const particle_iterator &particle)
void initialize(const parallel::distributed::Triangulation< dim, spacedim > &tria, const Mapping< dim, spacedim > &mapping, const unsigned int n_properties=0)
types::particle_index n_global_max_particles_per_cell() const
particle_iterator insert_particle(const Particle< dim, spacedim > &particle, const typename Triangulation< dim, spacedim >::active_cell_iterator &cell)
void send_recv_particles(const std::map< types::subdomain_id, std::vector< particle_iterator > > &particles_to_send, std::multimap< internal::LevelInd, Particle< dim, spacedim > > &received_particles, 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 > >())
void update_cached_numbers()
const ArrayView< double > get_properties()
#define AssertThrow(cond, exc)
numbers::NumberTraits< Number >::real_type norm() const
unsigned int register_data_attach(const std::size_t size, const std::function< void(const cell_iterator &, const CellStatus, void *)> &pack_callback)
void register_load_callback_function(const bool serialization)
void store_particles(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const typename Triangulation< dim, spacedim >::CellStatus status, void *data) const
static ::ExceptionBase & ExcMessage(std::string arg1)
particle_iterator begin_ghost() const
unsigned int n_properties_per_particle() const
#define Assert(cond, exc)
particle_iterator_range particles_in_cell(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell)
void insert_particles(const std::multimap< typename Triangulation< dim, spacedim >::active_cell_iterator, Particle< dim, spacedim > > &particles)
Abstract base class for mapping classes.
void notify_ready_to_unpack(const unsigned int handle, const std::function< void(const cell_iterator &, const CellStatus, const void *)> &unpack_callback)
particle_iterator begin() const
void exchange_ghost_particles()
unsigned int subdomain_id
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
const types::subdomain_id artificial_subdomain_id
void load_particles(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const typename Triangulation< dim, spacedim >::CellStatus status, const void *data)
types::particle_index get_next_free_particle_index() const
bool has_properties() const
#define AssertThrowMPI(error_code)
std::array< unsigned int, 4 > binary_type
PropertyPool & get_property_pool() const
void register_store_callback_function(const bool serialization)
static ::ExceptionBase & ExcNotImplemented()
boost::iterator_range< particle_iterator > particle_iterator_range
particle_iterator end_ghost() const
particle_iterator end() const
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)
unsigned int n_particles_in_cell(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell) const
static ::ExceptionBase & ExcInternalError()