From efe700301fd38d138ba39eb7fa63a2176ecc55bc Mon Sep 17 00:00:00 2001 From: Menno Fraters Date: Sat, 15 Jun 2024 20:54:29 -0400 Subject: [PATCH 1/2] Emplace infrastructure for multiple particle worlds --- include/aspect/particle/world.h | 2 +- source/particle/world.cc | 140 ++++++++++++++++++-------------- source/simulator/core.cc | 2 +- 3 files changed, 81 insertions(+), 63 deletions(-) diff --git a/include/aspect/particle/world.h b/include/aspect/particle/world.h index 94da0ba1efd..9b255fa2864 100644 --- a/include/aspect/particle/world.h +++ b/include/aspect/particle/world.h @@ -347,7 +347,7 @@ namespace aspect */ virtual void - parse_parameters (ParameterHandler &prm); + parse_parameters (ParameterHandler &prm, const unsigned int world_index); private: struct ParticleLoadBalancing diff --git a/source/particle/world.cc b/source/particle/world.cc index 8765fe6e3ef..3221c60d102 100644 --- a/source/particle/world.cc +++ b/source/particle/world.cc @@ -1177,65 +1177,76 @@ namespace aspect void World::declare_parameters (ParameterHandler &prm) { - prm.enter_subsection("Particles"); - { - prm.declare_entry ("Load balancing strategy", "repartition", - Patterns::MultipleSelection ("none|remove particles|add particles|" - "remove and add particles|repartition"), - "Strategy that is used to balance the computational " - "load across processors for adaptive meshes."); - prm.declare_entry ("Minimum particles per cell", "0", - Patterns::Integer (0), - "Lower limit for particle number per cell. This limit is " - "useful for adaptive meshes to prevent fine cells from being empty " - "of particles. It will be checked and enforced after mesh " - "refinement and after particle movement. " - "If there are " - "\\texttt{n\\_number\\_of\\_particles} $<$ \\texttt{min\\_particles\\_per\\_cell} " - "particles in one cell then " - "\\texttt{min\\_particles\\_per\\_cell} - \\texttt{n\\_number\\_of\\_particles} " - "particles are generated and randomly placed in " - "this cell. If the particles carry properties the " - "individual property plugins control how the " - "properties of the new particles are initialized."); - prm.declare_entry ("Maximum particles per cell", "100", - Patterns::Integer (0), - "Upper limit for particle number per cell. This limit is " - "useful for adaptive meshes to prevent coarse cells from slowing down " - "the whole model. It will be checked and enforced after mesh " - "refinement, after MPI transfer of particles and after particle " - "movement. If there are " - "\\texttt{n\\_number\\_of\\_particles} $>$ \\texttt{max\\_particles\\_per\\_cell} " - "particles in one cell then " - "\\texttt{n\\_number\\_of\\_particles} - \\texttt{max\\_particles\\_per\\_cell} " - "particles in this cell are randomly chosen and destroyed."); - prm.declare_entry ("Particle weight", "10", - Patterns::Integer (0), - "Weight that is associated with the computational load of " - "a single particle. The sum of particle weights will be added " - "to the sum of cell weights to determine the partitioning of " - "the mesh if the `repartition' particle load balancing strategy " - "is selected. The optimal weight depends on the used " - "integrator and particle properties. In general for a more " - "expensive integrator and more expensive properties a larger " - "particle weight is recommended. Before adding the weights " - "of particles, each cell already carries a weight of 1000 to " - "account for the cost of field-based computations."); - prm.declare_entry ("Update ghost particles", "false", - Patterns::Bool (), - "Some particle interpolation algorithms require knowledge " - "about particles in neighboring cells. To allow this, " - "particles in ghost cells need to be exchanged between the " - "processes neighboring this cell. This parameter determines " - "whether this transport is happening."); - - Generator::declare_parameters(prm); - Integrator::declare_parameters(prm); - Interpolator::declare_parameters(prm); - - Property::Manager::declare_parameters(prm); - } - prm.leave_subsection (); + constexpr unsigned int number_of_particle_worlds = 1; + for (unsigned int world_index = 0; world_index < number_of_particle_worlds; ++world_index) + { + if (world_index == 0) + { + prm.enter_subsection("Particles"); + } + else + { + prm.enter_subsection("Particles " + std::to_string(world_index)); + } + { + prm.declare_entry ("Load balancing strategy", "repartition", + Patterns::MultipleSelection ("none|remove particles|add particles|" + "remove and add particles|repartition"), + "Strategy that is used to balance the computational " + "load across processors for adaptive meshes."); + prm.declare_entry ("Minimum particles per cell", "0", + Patterns::Integer (0), + "Lower limit for particle number per cell. This limit is " + "useful for adaptive meshes to prevent fine cells from being empty " + "of particles. It will be checked and enforced after mesh " + "refinement and after particle movement. " + "If there are " + "\\texttt{n\\_number\\_of\\_particles} $<$ \\texttt{min\\_particles\\_per\\_cell} " + "particles in one cell then " + "\\texttt{min\\_particles\\_per\\_cell} - \\texttt{n\\_number\\_of\\_particles} " + "particles are generated and randomly placed in " + "this cell. If the particles carry properties the " + "individual property plugins control how the " + "properties of the new particles are initialized."); + prm.declare_entry ("Maximum particles per cell", "100", + Patterns::Integer (0), + "Upper limit for particle number per cell. This limit is " + "useful for adaptive meshes to prevent coarse cells from slowing down " + "the whole model. It will be checked and enforced after mesh " + "refinement, after MPI transfer of particles and after particle " + "movement. If there are " + "\\texttt{n\\_number\\_of\\_particles} $>$ \\texttt{max\\_particles\\_per\\_cell} " + "particles in one cell then " + "\\texttt{n\\_number\\_of\\_particles} - \\texttt{max\\_particles\\_per\\_cell} " + "particles in this cell are randomly chosen and destroyed."); + prm.declare_entry ("Particle weight", "10", + Patterns::Integer (0), + "Weight that is associated with the computational load of " + "a single particle. The sum of particle weights will be added " + "to the sum of cell weights to determine the partitioning of " + "the mesh if the `repartition' particle load balancing strategy " + "is selected. The optimal weight depends on the used " + "integrator and particle properties. In general for a more " + "expensive integrator and more expensive properties a larger " + "particle weight is recommended. Before adding the weights " + "of particles, each cell already carries a weight of 1000 to " + "account for the cost of field-based computations."); + prm.declare_entry ("Update ghost particles", "false", + Patterns::Bool (), + "Some particle interpolation algorithms require knowledge " + "about particles in neighboring cells. To allow this, " + "particles in ghost cells need to be exchanged between the " + "processes neighboring this cell. This parameter determines " + "whether this transport is happening."); + + Generator::declare_parameters(prm); + Integrator::declare_parameters(prm); + Interpolator::declare_parameters(prm); + + Property::Manager::declare_parameters(prm); + } + prm.leave_subsection (); + } } @@ -1243,7 +1254,7 @@ namespace aspect template void - World::parse_parameters (ParameterHandler &prm) + World::parse_parameters (ParameterHandler &prm, const unsigned int world_index) { // First do some error checking. The current algorithm does not find // the cells around particles, if the particles moved more than one @@ -1260,7 +1271,14 @@ namespace aspect "diameter in one time step and therefore skip the layer " "of ghost cells around the local subdomain.")); - prm.enter_subsection("Particles"); + if (world_index == 0) + { + prm.enter_subsection("Particles"); + } + else + { + prm.enter_subsection("Particles " + std::to_string(world_index)); + } { min_particles_per_cell = prm.get_integer("Minimum particles per cell"); max_particles_per_cell = prm.get_integer("Maximum particles per cell"); diff --git a/source/simulator/core.cc b/source/simulator/core.cc index d9af44c7436..138f456293a 100644 --- a/source/simulator/core.cc +++ b/source/simulator/core.cc @@ -452,7 +452,7 @@ namespace aspect if (SimulatorAccess *sim = dynamic_cast*>(particle_world.get())) sim->initialize_simulator (*this); - particle_world->parse_parameters(prm); + particle_world->parse_parameters(prm,0); particle_world->initialize(); } From 0b87a1586b7c4c6ad39e8595d5984439f6c09be0 Mon Sep 17 00:00:00 2001 From: Menno Fraters Date: Sun, 16 Jun 2024 11:02:50 +0000 Subject: [PATCH 2/2] Apply suggestions from code review Rene Co-authored-by: Rene Gassmoeller --- source/particle/world.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/particle/world.cc b/source/particle/world.cc index 3221c60d102..965901f3df5 100644 --- a/source/particle/world.cc +++ b/source/particle/world.cc @@ -1186,7 +1186,7 @@ namespace aspect } else { - prm.enter_subsection("Particles " + std::to_string(world_index)); + prm.enter_subsection("Particles " + std::to_string(world_index+1)); } { prm.declare_entry ("Load balancing strategy", "repartition", @@ -1277,7 +1277,7 @@ namespace aspect } else { - prm.enter_subsection("Particles " + std::to_string(world_index)); + prm.enter_subsection("Particles " + std::to_string(world_index+1)); } { min_particles_per_cell = prm.get_integer("Minimum particles per cell");