include/meltpooldg/particles/obstacle_data_structure.hpp Source File

Developer Documentation: include/meltpooldg/particles/obstacle_data_structure.hpp Source File
Developer Documentation
obstacle_data_structure.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <deal.II/base/array_view.h>
4#include <deal.II/base/point.h>
5
6#include <deal.II/grid/filtered_iterator.h>
7#include <deal.II/grid/grid_tools.h>
8#include <deal.II/grid/tria_iterator_selector.h>
9
10#include <deal.II/matrix_free/matrix_free.h>
11
12#include <deal.II/numerics/solution_transfer.h>
13
14#include <deal.II/particles/particle_handler.h>
15#include <deal.II/particles/property_pool.h>
16
20
21#include <boost/container/small_vector.hpp>
22
23#include <functional>
24#include <ranges>
25#include <vector>
26
27namespace MeltPoolDG
28{
30 template <int dim, typename number, typename ObstacleType>
31 struct CellListParticleHandler;
32
33
34 template <int dim, typename number, typename ObstacleType>
36 {
37 public:
46
66 bool
67 update_required() const;
68
81 void
82 reinit_after_update(const number new_skin_thickness = 0,
83 const number new_max_displacement_before_update = 0);
84
85 private:
88 std::vector<dealii::Point<dim, number>> previous_obstacle_locations;
89
92
96
99 };
100
101
208 template <int dim, typename number, typename ObstacleType>
210 {
211 public:
230
238 explicit CellListParticleHandler(const dealii::Triangulation<dim> &triangulation,
239 const dealii::Mapping<dim> &mapping);
240
246
256 void
257 initialize();
258
264 static number
265 minimal_cell_vertex_distance(const number max_particle_radius);
266
288 template <typename ObstacleContainer>
289 void
290 get_obstacles_in_cell(const dealii::TriaIterator<dealii::CellAccessor<dim>> &cell,
291 ObstacleContainer &particles);
292
304 void
306
312 void
314
323 void
325
344 void
345 insert_global_particles(const std::vector<dealii::Point<dim, number>> &obstacle_locations,
346 const std::vector<std::vector<number>> &obstacle_properties);
347
353 void
355
361 std::ranges::subrange<ParticleIterator<dim, number>>
363
369 std::ranges::subrange<MeltPoolDG::ParticleIterator<dim, number>>
370 ghost_particle_range() const;
371
379 typename std::ranges::subrange<ParticleIterator<dim, number>>
380 particles_in_cell(typename dealii::Triangulation<dim>::active_cell_iterator cell) const;
381
403 boost::container::small_vector<DEMParticleAccessor<dim, number>, 3 * dim>
405 const number relative_tolerance);
406
415 void
416 compress();
417
424 void
426
447 void
449
464 void
466
472 void
474
483 template <class Archive>
484 void
485 serialize(Archive &ar, const unsigned int version);
486
492 void
493 deserialize();
494
499 unsigned int
500 n_global_particles() const;
501
506 unsigned int
508
514 unsigned int
515 n_ghost_particles() const;
516
520 MPI_Comm
521 get_mpi_communicator() const;
522
527 const dealii::Triangulation<dim> &
528 get_triangulation() const;
529
538 void
539 subscribe(std::function<void(CellListParticleHandler &, const NotifyEvent)> callback);
540
541 private:
543 dealii::Particles::ParticleHandler<dim> obstacle_handler;
544
546 mutable dealii::Particles::PropertyPool<dim> ghost_particles_property_pool;
547
549 MPI_Comm mpi_communicator = MPI_COMM_WORLD;
550
553 std::unordered_map<dealii::types::particle_index, dealii::Particles::ParticleIterator<dim>>
555
560 boost::signals2::signal<void(CellListParticleHandler &, const NotifyEvent &)> notify_signal;
561
562 struct
563 {
568 std::vector<std::vector<dealii::Particles::ParticleIterator<dim>>> locally_owned_particles;
569
575 std::vector<std::vector<typename dealii::Particles::PropertyPool<dim>::Handle>>
577
579 int cell_level = 0;
580
584
602
604 {
612 void
614 {
615 particles_to_send.clear();
616 particles_to_send.resize(dealii::Utilities::MPI::n_mpi_processes(mpi_communicator));
618 n_particles_to_receive.resize(dealii::Utilities::MPI::n_mpi_processes(mpi_communicator), 0);
621 dealii::Utilities::MPI::n_mpi_processes(mpi_communicator), 0);
622 }
623
624 // index is the rank to whom to send the corresponding particles. Must be sorted with
625 // respect to global particle id.
626 std::vector<std::vector<dealii::Particles::ParticleIterator<dim>>> particles_to_send;
627
628 // index is the rank from which to receive the corresponding particles
629 std::vector<unsigned int> n_particles_to_receive;
630
631 // index is the rank from which to receive the corresponding particles. The value is the
632 // first handle of the ghost particles received from that rank in the global property pool.
633 std::vector<unsigned int> rank_ghost_particle_start_handle;
634
637 std::vector<std::vector<typename dealii::Particles::PropertyPool<dim>::Handle>>
640
644
648 void
650
661 dealii::TriaIterator<dealii::CellAccessor<dim>>
662 find_particle_cache_cell(const dealii::TriaIterator<dealii::CellAccessor<dim>> &cell) const;
663
680 template <typename ObstacleContainer>
681 void
682 find_relevant_particles(const dealii::TriaIterator<dealii::CellAccessor<dim>> &cell,
683 ObstacleContainer &particles);
684
688 number
690
696 void
697 notify(const NotifyEvent &event);
698 };
699
700 template <int dim, typename number, typename ObstacleType>
701 template <class Archive>
702 void
704 const unsigned int version)
705 {
706 obstacle_handler.serialize(ar, version);
707 }
708
709 template <int dim, typename number, typename ObstacleType>
710 template <typename ObstacleContainer>
711 void
713 const dealii::TriaIterator<dealii::CellAccessor<dim>> &cell,
714 ObstacleContainer &particles)
715 {
716 std::size_t current_size = particles.size();
717
718 // Find all relevant particles for the given cell and add them to the provided container.
719 find_relevant_particles(find_particle_cache_cell(cell), particles);
720
721 // Remove duplicates from the container while ensuring that the particles which were already
722 // present before the function call are not removed.
723 auto old_end = particles.begin() + current_size;
724 auto write_ptr = old_end;
725 for (auto read_ptr = old_end; read_ptr != particles.end(); ++read_ptr)
726 {
727 auto found_it = std::find_if(particles.begin(), old_end, [&read_ptr](const auto &particle) {
728 return particle.id() == read_ptr->id();
729 });
730 if (found_it == old_end)
731 {
732 if (write_ptr->id() != read_ptr->id())
733 *write_ptr = std::move(*read_ptr);
734 ++write_ptr;
735 }
736 }
737 particles.erase(write_ptr, particles.end());
738 }
739
740 template <int dim, typename number, typename ObstacleType>
741 template <typename ObstacleContainer>
742 void
744 const dealii::TriaIterator<dealii::CellAccessor<dim>> &cell,
745 ObstacleContainer &particles)
746 {
747 Assert(cell->level() == cell_particle_cache.cell_level,
748 dealii::ExcMessage(
749 "The function only supports searching for particles in cells on the same level as the "
750 "level on which particles are cached."));
751
752 const auto push_back_particles_from_cell = [&](const auto &current_cell) {
753 for (dealii::Particles::ParticleIterator<dim> &particle :
754 cell_particle_cache.locally_owned_particles[current_cell->index()])
755 {
756 Assert(particle.state() == dealii::IteratorState::valid, dealii::ExcInternalError());
757 particles.emplace_back(*particle);
758 }
759
760 for (const typename dealii::Particles::PropertyPool<dim>::Handle particle_handle :
761 cell_particle_cache.ghost_particles[current_cell->index()])
762 {
763 Assert(particle_handle < ghost_particles_property_pool.n_registered_slots(),
764 dealii::ExcInternalError());
765 particles.emplace_back(ghost_particles_property_pool, particle_handle);
766 }
767 };
768
769 // Adjacent cells
770 for (const dealii::TriaIterator<dealii::CellAccessor<dim>> &current_cell :
771 triangulation_level_cache.adjacent_cells.get_adjacent_cells(cell))
772 {
773 push_back_particles_from_cell(current_cell);
774 }
775
776 // Current cell
777 push_back_particles_from_cell(cell);
778 }
779} // namespace MeltPoolDG
Definition particle_accessor.hpp:20
Definition triangulation_utils.hpp:43
Computes and stores the MPI communication pattern for a given level of a distributed triangulation.
Definition triangulation_utils.hpp:159
Definition postprocessor.hpp:33
Interface for a general preconditioner.
Definition boundary_condition_functions.hpp:17
Definition obstacle_data_structure.hpp:604
std::vector< std::vector< dealii::Particles::ParticleIterator< dim > > > particles_to_send
Definition obstacle_data_structure.hpp:626
void reset(MPI_Comm mpi_communicator)
Definition obstacle_data_structure.hpp:613
std::vector< unsigned int > n_particles_to_receive
Definition obstacle_data_structure.hpp:629
std::vector< unsigned int > rank_ghost_particle_start_handle
Definition obstacle_data_structure.hpp:633
std::vector< std::vector< typename dealii::Particles::PropertyPool< dim >::Handle > > rank_to_ghost_handle
Definition obstacle_data_structure.hpp:638
Definition obstacle_data_structure.hpp:586
LevelAdjacentCellsCache< dim > adjacent_cells
Definition obstacle_data_structure.hpp:597
LevelCommunicationPattern< dim > communication_pattern
Definition obstacle_data_structure.hpp:593
int level
The level of the triangulation that is used to cache the particles.
Definition obstacle_data_structure.hpp:600
TriangulationLevelCache(const dealii::Triangulation< dim > &triangulation)
Definition obstacle_data_structure.hpp:587
Forward declaration of the CellListParticleHandler class template.
Definition obstacle_data_structure.hpp:210
void sort_particles_into_subdomains_and_cells()
Definition obstacle_data_structure.cpp:482
int cell_level
The level of the cells on which the particles are cached.
Definition obstacle_data_structure.hpp:579
MPI_Comm mpi_communicator
MPI communicator used for synchronizing obstacle data across all ranks.
Definition obstacle_data_structure.hpp:549
std::ranges::subrange< ParticleIterator< dim, number > > locally_owned_particle_range() const
Definition obstacle_data_structure.cpp:882
dealii::Particles::PropertyPool< dim > ghost_particles_property_pool
Property pool containing the properties of the ghost particles.
Definition obstacle_data_structure.hpp:546
void prepare_for_coarsening_and_refinement()
Definition obstacle_data_structure.cpp:818
void notify(const NotifyEvent &event)
Definition obstacle_data_structure.cpp:786
std::ranges::subrange< ParticleIterator< dim, number > > particles_in_cell(typename dealii::Triangulation< dim >::active_cell_iterator cell) const
Definition obstacle_data_structure.cpp:901
std::vector< std::vector< dealii::Particles::ParticleIterator< dim > > > locally_owned_particles
Definition obstacle_data_structure.hpp:568
void get_obstacles_in_cell(const dealii::TriaIterator< dealii::CellAccessor< dim > > &cell, ObstacleContainer &particles)
Definition obstacle_data_structure.hpp:712
unsigned int n_ghost_particles() const
Definition obstacle_data_structure.cpp:875
number global_max_particle_radius
The maximum radius of all particles in the global domain.
Definition obstacle_data_structure.hpp:582
std::ranges::subrange< MeltPoolDG::ParticleIterator< dim, number > > ghost_particle_range() const
Definition obstacle_data_structure.cpp:891
void serialize(Archive &ar, const unsigned int version)
Definition obstacle_data_structure.hpp:703
void deregister_property_pool() const
Definition obstacle_data_structure.cpp:225
MPI_Comm get_mpi_communicator() const
Definition obstacle_data_structure.cpp:861
void find_relevant_particles(const dealii::TriaIterator< dealii::CellAccessor< dim > > &cell, ObstacleContainer &particles)
Definition obstacle_data_structure.hpp:743
struct MeltPoolDG::CellListParticleHandler::@7 cell_particle_cache
void initialize()
Reinitializes the internal data structure by synchronizing obstacle data across all MPI processes.
Definition obstacle_data_structure.cpp:120
void compress()
Definition obstacle_data_structure.cpp:274
~CellListParticleHandler()
Destructor. Explicitly deregisters all particles from the global obstacle property pool.
struct MeltPoolDG::CellListParticleHandler::TriangulationLevelCache triangulation_level_cache
boost::signals2::signal< void(CellListParticleHandler &, const NotifyEvent &)> notify_signal
Definition obstacle_data_structure.hpp:560
dealii::TriaIterator< dealii::CellAccessor< dim > > find_particle_cache_cell(const dealii::TriaIterator< dealii::CellAccessor< dim > > &cell) const
Definition obstacle_data_structure.cpp:948
struct MeltPoolDG::CellListParticleHandler::GhostParticleUpdateCache ghost_particle_update_cache
void insert_global_particles(const std::vector< dealii::Point< dim, number > > &obstacle_locations, const std::vector< std::vector< number > > &obstacle_properties)
Definition obstacle_data_structure.cpp:238
unsigned int n_global_particles() const
Definition obstacle_data_structure.cpp:847
const dealii::Triangulation< dim > & get_triangulation() const
Definition obstacle_data_structure.cpp:868
void subscribe(std::function< void(CellListParticleHandler &, const NotifyEvent)> callback)
Definition obstacle_data_structure.cpp:777
void prepare_for_serialization()
Definition obstacle_data_structure.cpp:811
boost::container::small_vector< DEMParticleAccessor< dim, number >, 3 *dim > find_particles_in_neighborhood(const DEMParticleAccessor< dim, number > &particle, const number relative_tolerance)
Definition obstacle_data_structure.cpp:911
dealii::Particles::ParticleHandler< dim > obstacle_handler
Handler managing the locally owned obstacles in the domain.
Definition obstacle_data_structure.hpp:543
void deserialize()
Definition obstacle_data_structure.cpp:804
NeighborListUpdateTracker< dim, number, ObstacleType > neighbor_list_update_tracker
Definition obstacle_data_structure.hpp:643
std::vector< std::vector< typename dealii::Particles::PropertyPool< dim >::Handle > > ghost_particles
Definition obstacle_data_structure.hpp:576
void unpack_after_coarsening_and_refinement()
Definition obstacle_data_structure.cpp:825
number compute_max_particle_radius() const
Definition obstacle_data_structure.cpp:259
NotifyEvent
Definition obstacle_data_structure.hpp:217
static number minimal_cell_vertex_distance(const number max_particle_radius)
Definition obstacle_data_structure.cpp:214
void register_particle_output(Postprocessor< dim, number > &postprocessor) const
Definition obstacle_data_structure.cpp:834
void auto_update_particle_cache()
Definition obstacle_data_structure.cpp:793
void update_ghost_particle_properties()
Definition obstacle_data_structure.cpp:367
std::unordered_map< dealii::types::particle_index, dealii::Particles::ParticleIterator< dim > > particle_id_to_iterator_cache
Definition obstacle_data_structure.hpp:554
void broadcast_global_particles() const
Broadcasts obstacle properties of all locally owned particles to all MPI processes.
unsigned int n_locally_owned_particles() const
Definition obstacle_data_structure.cpp:854
Definition obstacle_data_structure.hpp:36
number skin_thickness
Definition obstacle_data_structure.hpp:95
number max_displacement_before_update
The maximum allowed displacement of any particle before an update is required.
Definition obstacle_data_structure.hpp:98
const CellListParticleHandler< dim, number, ObstacleType > & obstacle_data_structure
The obstacle data structure that is being monitored for updates.
Definition obstacle_data_structure.hpp:91
void reinit_after_update(const number new_skin_thickness=0, const number new_max_displacement_before_update=0)
Definition obstacle_data_structure.cpp:81
bool update_required() const
Definition obstacle_data_structure.cpp:16
std::vector< dealii::Point< dim, number > > previous_obstacle_locations
Definition obstacle_data_structure.hpp:88