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
280 template <typename ObstacleContainer>
281 void
282 get_obstacles_in_cell(const dealii::TriaIterator<dealii::CellAccessor<dim>> &cell,
283 ObstacleContainer &particles);
284
296 void
298
304 void
306
315 void
317
336 void
337 insert_global_particles(const std::vector<dealii::Point<dim, number>> &obstacle_locations,
338 const std::vector<std::vector<number>> &obstacle_properties);
339
345 void
347
353 std::ranges::subrange<ParticleIterator<dim, number>>
355
361 std::ranges::subrange<MeltPoolDG::ParticleIterator<dim, number>>
362 ghost_particle_range() const;
363
371 typename std::ranges::subrange<ParticleIterator<dim, number>>
372 particles_in_cell(typename dealii::Triangulation<dim>::active_cell_iterator cell) const;
373
395 boost::container::small_vector<DEMParticleAccessor<dim, number>, 3 * dim>
397 const number relative_tolerance);
398
407 void
408 compress();
409
416 void
418
439 void
441
456 void
458
464 void
466
475 template <class Archive>
476 void
477 serialize(Archive &ar, const unsigned int version);
478
484 void
485 deserialize();
486
491 unsigned int
492 n_global_particles() const;
493
498 unsigned int
500
506 unsigned int
507 n_ghost_particles() const;
508
512 MPI_Comm
513 get_mpi_communicator() const;
514
523 void
524 subscribe(std::function<void(CellListParticleHandler &, const NotifyEvent)> callback);
525
526 private:
528 dealii::Particles::ParticleHandler<dim> obstacle_handler;
529
531 mutable dealii::Particles::PropertyPool<dim> ghost_particles_property_pool;
532
534 MPI_Comm mpi_communicator = MPI_COMM_WORLD;
535
538 std::unordered_map<dealii::types::particle_index, dealii::Particles::ParticleIterator<dim>>
540
545 boost::signals2::signal<void(CellListParticleHandler &, const NotifyEvent &)> notify_signal;
546
547 struct
548 {
553 std::vector<std::vector<dealii::Particles::ParticleIterator<dim>>> locally_owned_particles;
554
560 std::vector<std::vector<typename dealii::Particles::PropertyPool<dim>::Handle>>
562
564 int cell_level = 0;
565
569
587
589 {
597 void
599 {
600 particles_to_send.clear();
601 particles_to_send.resize(dealii::Utilities::MPI::n_mpi_processes(mpi_communicator));
603 n_particles_to_receive.resize(dealii::Utilities::MPI::n_mpi_processes(mpi_communicator), 0);
606 dealii::Utilities::MPI::n_mpi_processes(mpi_communicator), 0);
607 }
608
609 // index is the rank to whom to send the corresponding particles. Must be sorted with
610 // respect to global particle id.
611 std::vector<std::vector<dealii::Particles::ParticleIterator<dim>>> particles_to_send;
612
613 // index is the rank from which to receive the corresponding particles
614 std::vector<unsigned int> n_particles_to_receive;
615
616 // index is the rank from which to receive the corresponding particles. The value is the
617 // first handle of the ghost particles received from that rank in the global property pool.
618 std::vector<unsigned int> rank_ghost_particle_start_handle;
619
622 std::vector<std::vector<typename dealii::Particles::PropertyPool<dim>::Handle>>
625
629
633 void
635
646 dealii::TriaIterator<dealii::CellAccessor<dim>>
647 find_particle_cache_cell(const dealii::TriaIterator<dealii::CellAccessor<dim>> &cell) const;
648
665 template <typename ObstacleContainer>
666 void
667 find_relevant_particles(const dealii::TriaIterator<dealii::CellAccessor<dim>> &cell,
668 ObstacleContainer &particles);
669
673 number
675
681 void
682 notify(const NotifyEvent &event);
683 };
684
685 template <int dim, typename number, typename ObstacleType>
686 template <class Archive>
687 void
689 const unsigned int version)
690 {
691 obstacle_handler.serialize(ar, version);
692 }
693
694 template <int dim, typename number, typename ObstacleType>
695 template <typename ObstacleContainer>
696 void
698 const dealii::TriaIterator<dealii::CellAccessor<dim>> &cell,
699 ObstacleContainer &particles)
700 {
701 std::size_t current_size = particles.size();
702
703 // Find all relevant particles for the given cell and add them to the provided container.
704 find_relevant_particles(find_particle_cache_cell(cell), particles);
705
706 // Remove duplicates from the container while ensuring that the particles which were already
707 // present before the function call are not removed.
708 auto old_end = particles.begin() + current_size;
709 auto write_ptr = old_end;
710 for (auto read_ptr = old_end; read_ptr != particles.end(); ++read_ptr)
711 {
712 auto found_it = std::find_if(particles.begin(), old_end, [&read_ptr](const auto &particle) {
713 return particle.id() == read_ptr->id();
714 });
715 if (found_it == old_end)
716 {
717 if (write_ptr->id() != read_ptr->id())
718 *write_ptr = std::move(*read_ptr);
719 ++write_ptr;
720 }
721 }
722 particles.erase(write_ptr, particles.end());
723 }
724
725 template <int dim, typename number, typename ObstacleType>
726 template <typename ObstacleContainer>
727 void
729 const dealii::TriaIterator<dealii::CellAccessor<dim>> &cell,
730 ObstacleContainer &particles)
731 {
732 Assert(cell->level() == cell_particle_cache.cell_level,
733 dealii::ExcMessage(
734 "The function only supports searching for particles in cells on the same level as the "
735 "level on which particles are cached."));
736
737 const auto push_back_particles_from_cell = [&](const auto &current_cell) {
738 for (dealii::Particles::ParticleIterator<dim> &particle :
739 cell_particle_cache.locally_owned_particles[current_cell->index()])
740 {
741 Assert(particle.state() == dealii::IteratorState::valid, dealii::ExcInternalError());
742 particles.emplace_back(*particle);
743 }
744
745 for (const typename dealii::Particles::PropertyPool<dim>::Handle particle_handle :
746 cell_particle_cache.ghost_particles[current_cell->index()])
747 {
748 Assert(particle_handle < ghost_particles_property_pool.n_registered_slots(),
749 dealii::ExcInternalError());
750 particles.emplace_back(ghost_particles_property_pool, particle_handle);
751 }
752 };
753
754 // Adjacent cells
755 for (const dealii::TriaIterator<dealii::CellAccessor<dim>> &current_cell :
756 triangulation_level_cache.adjacent_cells.get_adjacent_cells(cell))
757 {
758 push_back_particles_from_cell(current_cell);
759 }
760
761 // Current cell
762 push_back_particles_from_cell(cell);
763 }
764} // 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:32
Interface for a general preconditioner.
Definition boundary_condition_functions.hpp:17
Definition obstacle_data_structure.hpp:589
std::vector< std::vector< dealii::Particles::ParticleIterator< dim > > > particles_to_send
Definition obstacle_data_structure.hpp:611
void reset(MPI_Comm mpi_communicator)
Definition obstacle_data_structure.hpp:598
std::vector< unsigned int > n_particles_to_receive
Definition obstacle_data_structure.hpp:614
std::vector< unsigned int > rank_ghost_particle_start_handle
Definition obstacle_data_structure.hpp:618
std::vector< std::vector< typename dealii::Particles::PropertyPool< dim >::Handle > > rank_to_ghost_handle
Definition obstacle_data_structure.hpp:623
Definition obstacle_data_structure.hpp:571
LevelAdjacentCellsCache< dim > adjacent_cells
Definition obstacle_data_structure.hpp:582
LevelCommunicationPattern< dim > communication_pattern
Definition obstacle_data_structure.hpp:578
int level
The level of the triangulation that is used to cache the particles.
Definition obstacle_data_structure.hpp:585
TriangulationLevelCache(const dealii::Triangulation< dim > &triangulation)
Definition obstacle_data_structure.hpp:572
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:455
int cell_level
The level of the cells on which the particles are cached.
Definition obstacle_data_structure.hpp:564
MPI_Comm mpi_communicator
MPI communicator used for synchronizing obstacle data across all ranks.
Definition obstacle_data_structure.hpp:534
std::ranges::subrange< ParticleIterator< dim, number > > locally_owned_particle_range() const
Definition obstacle_data_structure.cpp:839
dealii::Particles::PropertyPool< dim > ghost_particles_property_pool
Property pool containing the properties of the ghost particles.
Definition obstacle_data_structure.hpp:531
void prepare_for_coarsening_and_refinement()
Definition obstacle_data_structure.cpp:782
void notify(const NotifyEvent &event)
Definition obstacle_data_structure.cpp:750
std::ranges::subrange< ParticleIterator< dim, number > > particles_in_cell(typename dealii::Triangulation< dim >::active_cell_iterator cell) const
Definition obstacle_data_structure.cpp:858
std::vector< std::vector< dealii::Particles::ParticleIterator< dim > > > locally_owned_particles
Definition obstacle_data_structure.hpp:553
void get_obstacles_in_cell(const dealii::TriaIterator< dealii::CellAccessor< dim > > &cell, ObstacleContainer &particles)
Definition obstacle_data_structure.hpp:697
unsigned int n_ghost_particles() const
Definition obstacle_data_structure.cpp:832
number global_max_particle_radius
The maximum radius of all particles in the global domain.
Definition obstacle_data_structure.hpp:567
std::ranges::subrange< MeltPoolDG::ParticleIterator< dim, number > > ghost_particle_range() const
Definition obstacle_data_structure.cpp:848
void serialize(Archive &ar, const unsigned int version)
Definition obstacle_data_structure.hpp:688
void deregister_property_pool() const
Definition obstacle_data_structure.cpp:198
MPI_Comm get_mpi_communicator() const
Definition obstacle_data_structure.cpp:825
void find_relevant_particles(const dealii::TriaIterator< dealii::CellAccessor< dim > > &cell, ObstacleContainer &particles)
Definition obstacle_data_structure.hpp:728
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:247
~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:545
dealii::TriaIterator< dealii::CellAccessor< dim > > find_particle_cache_cell(const dealii::TriaIterator< dealii::CellAccessor< dim > > &cell) const
Definition obstacle_data_structure.cpp:905
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:211
unsigned int n_global_particles() const
Definition obstacle_data_structure.cpp:811
struct MeltPoolDG::CellListParticleHandler::@6 cell_particle_cache
void subscribe(std::function< void(CellListParticleHandler &, const NotifyEvent)> callback)
Definition obstacle_data_structure.cpp:741
void prepare_for_serialization()
Definition obstacle_data_structure.cpp:775
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:868
dealii::Particles::ParticleHandler< dim > obstacle_handler
Handler managing the locally owned obstacles in the domain.
Definition obstacle_data_structure.hpp:528
void deserialize()
Definition obstacle_data_structure.cpp:768
NeighborListUpdateTracker< dim, number, ObstacleType > neighbor_list_update_tracker
Definition obstacle_data_structure.hpp:628
std::vector< std::vector< typename dealii::Particles::PropertyPool< dim >::Handle > > ghost_particles
Definition obstacle_data_structure.hpp:561
void unpack_after_coarsening_and_refinement()
Definition obstacle_data_structure.cpp:789
number compute_max_particle_radius() const
Definition obstacle_data_structure.cpp:232
NotifyEvent
Definition obstacle_data_structure.hpp:217
void register_particle_output(Postprocessor< dim, number > &postprocessor) const
Definition obstacle_data_structure.cpp:798
void auto_update_particle_cache()
Definition obstacle_data_structure.cpp:757
void update_ghost_particle_properties()
Definition obstacle_data_structure.cpp:340
std::unordered_map< dealii::types::particle_index, dealii::Particles::ParticleIterator< dim > > particle_id_to_iterator_cache
Definition obstacle_data_structure.hpp:539
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:818
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