]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add first particle handler test. Simplify update
authorRene Gassmoeller <rene.gassmoeller@mailbox.org>
Fri, 13 Oct 2017 21:52:43 +0000 (15:52 -0600)
committerRene Gassmoeller <rene.gassmoeller@mailbox.org>
Thu, 9 Nov 2017 16:47:22 +0000 (09:47 -0700)
include/deal.II/particles/particle_handler.h
source/particles/particle_handler.cc
tests/particles/particle_02.cc
tests/particles/particle_03.cc
tests/particles/particle_handler_01.cc [new file with mode: 0644]
tests/particles/particle_handler_01.output [new file with mode: 0644]
tests/particles/particle_iterator_01.cc

index 098ceeea3763416eccf5a51d8f831af64d7d0bb8..094e3b879814077edb5d852b22e2c7b7e8b600bc 100644 (file)
@@ -97,6 +97,16 @@ namespace Particles
      */
     void clear_particles();
 
+    /**
+     * Updates all internally cached numbers. Note that all functions that
+     * modify internal data structures and act on multiple particles will
+     * call this function automatically (e.g. insert_particles), while
+     * functions that act on single particles will not call this function
+     * (e.g. insert_particle). This is done because the update is
+     * expensive compared to single operations.
+     */
+    void update_cache();
+
     /**
      * Return an iterator to the first particle.
      */
@@ -352,32 +362,6 @@ namespace Particles
      */
     unsigned int data_offset;
 
-    /**
-     * Calculates the number of particles in the global model domain.
-     */
-    void
-    update_n_global_particles();
-
-    /**
-     * Calculates and stores the number of particles in the cell that
-     * contains the most particles in the global model (stored in the
-     * member variable global_max_particles_per_cell). This variable is a
-     * state variable, because it is needed to serialize and deserialize
-     * the particle data correctly in parallel (it determines the size of
-     * the data chunks per cell that are stored and read). Before accessing
-     * the variable this function has to be called, unless the state was
-     * read from another source (e.g. after resuming from a checkpoint).
-     */
-    void
-    update_global_max_particles_per_cell();
-
-    /**
-     * Calculates the next free particle index in the global model domain.
-     * This equals one plus the highest particle index currently active.
-     */
-    void
-    update_next_free_particle_index();
-
     /**
      * Transfer particles that have crossed subdomain boundaries to other
      * processors.
index 99a9f72267e4d5c83a7849bd6a4cd0c1700f5abb..13839888cc55b8f5e745bfc5f995187f24424f78 100644 (file)
@@ -103,6 +103,36 @@ namespace Particles
 
 
 
+  template <int dim,int spacedim>
+  void
+  ParticleHandler<dim,spacedim>::update_cache()
+  {
+
+    types::particle_index locally_highest_index = 0;
+    unsigned int local_max_particles_per_cell = 0;
+    unsigned int current_particles_per_cell = 0;
+    typename Triangulation<dim,spacedim>::active_cell_iterator current_cell;
+
+    for (particle_iterator particle = begin(); particle != end(); ++particle)
+      {
+        locally_highest_index = std::max(locally_highest_index,particle->get_id());
+
+        if (particle->get_surrounding_cell(*triangulation) != current_cell)
+          current_particles_per_cell = 0;
+
+        ++current_particles_per_cell;
+        local_max_particles_per_cell = std::max(local_max_particles_per_cell,
+                                                current_particles_per_cell);
+      }
+
+    global_number_of_particles = dealii::Utilities::MPI::sum (particles.size(), triangulation->get_communicator());
+    next_free_particle_index = dealii::Utilities::MPI::max (locally_highest_index, triangulation->get_communicator()) + 1;
+    global_max_particles_per_cell = dealii::Utilities::MPI::max(local_max_particles_per_cell,triangulation->get_communicator());
+  }
+
+
+
+
   template <int dim,int spacedim>
   typename ParticleHandler<dim,spacedim>::particle_iterator
   ParticleHandler<dim,spacedim>::begin() const
@@ -202,6 +232,7 @@ namespace Particles
   ParticleHandler<dim,spacedim>::insert_particles(const std::multimap<types::LevelInd, Particle<dim,spacedim> > &new_particles)
   {
     particles.insert(new_particles.begin(),new_particles.end());
+    update_cache();
   }
 
 
@@ -233,15 +264,6 @@ namespace Particles
 
 
 
-  template <int dim,int spacedim>
-  void
-  ParticleHandler<dim,spacedim>::update_n_global_particles()
-  {
-    global_number_of_particles = dealii::Utilities::MPI::sum (particles.size(), triangulation->get_communicator());
-  }
-
-
-
   template <int dim,int spacedim>
   unsigned int
   ParticleHandler<dim,spacedim>::n_particles_in_cell(const typename Triangulation<dim,spacedim>::active_cell_iterator &cell) const
@@ -260,37 +282,6 @@ namespace Particles
 
 
 
-  template <int dim,int spacedim>
-  void
-  ParticleHandler<dim,spacedim>::update_next_free_particle_index()
-  {
-    types::particle_index locally_highest_index = 0;
-    for (particle_iterator particle = begin(); particle != end(); ++particle)
-      locally_highest_index = std::max(locally_highest_index,particle->get_id());
-
-    next_free_particle_index = dealii::Utilities::MPI::max (locally_highest_index, triangulation->get_communicator()) + 1;
-  }
-
-
-
-  template <int dim,int spacedim>
-  void
-  ParticleHandler<dim,spacedim>::update_global_max_particles_per_cell()
-  {
-    unsigned int local_max_particles_per_cell(0);
-    typename Triangulation<dim,spacedim>::active_cell_iterator cell = triangulation->begin_active();
-    for (; cell!=triangulation->end(); ++cell)
-      if (cell->is_locally_owned())
-        {
-          local_max_particles_per_cell = std::max(local_max_particles_per_cell,
-                                                  n_particles_in_cell(cell));
-        }
-
-    global_max_particles_per_cell = dealii::Utilities::MPI::max(local_max_particles_per_cell,triangulation->get_communicator());
-  }
-
-
-
   template <int dim, int spacedim>
   PropertyPool &
   ParticleHandler<dim,spacedim>::get_property_pool () const
@@ -535,6 +526,7 @@ namespace Particles
       remove_particle(particles_out_of_cell[i]);
 
     particles.insert(sorted_particles_map.begin(),sorted_particles_map.end());
+    update_cache();
   }
 
 
@@ -764,7 +756,7 @@ namespace Particles
 
     // Only save and load particles if there are any, we might get here for
     // example if somebody created a ParticleHandler but generated 0 particles.
-    update_global_max_particles_per_cell();
+    update_cache();
 
     if (global_max_particles_per_cell > 0)
       {
@@ -864,7 +856,7 @@ namespace Particles
         // Reset offset and update global number of particles. The number
         // can change because of discarded or newly generated particles
         data_offset = numbers::invalid_unsigned_int;
-        update_n_global_particles();
+        update_cache();
       }
   }
 
index e4601726a4ef34d36e9ba2a90d2f7382b7a45889..922d9bb7be75347fb6d2422590d2bd48e33a1a3a 100644 (file)
@@ -33,7 +33,7 @@ void test ()
     reference_position(0) = 0.2;
     reference_position(1) = 0.4;
 
-    const Particles::types::particle_index index(7);
+    const types::particle_index index(7);
 
     Particles::Particle<2> particle(position,reference_position,index);
 
index aaa6a882bf06c20741133bf07da660c48df186a5..86d768686641add1c5c05037b2e49875b6905886 100644 (file)
@@ -37,7 +37,7 @@ void test ()
     reference_position(0) = 0.2;
     reference_position(1) = 0.4;
 
-    const Particles::types::particle_index index(7);
+    const types::particle_index index(7);
 
     std::vector<double> properties = {0.15,0.45,0.75};
 
diff --git a/tests/particles/particle_handler_01.cc b/tests/particles/particle_handler_01.cc
new file mode 100644 (file)
index 0000000..2455732
--- /dev/null
@@ -0,0 +1,90 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2017 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+
+// check the creation and destruction of particle within the particle handler class.
+
+#include "../tests.h"
+#include <deal.II/particles/particle_handler.h>
+
+#include <deal.II/distributed/tria.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/fe/mapping_q.h>
+
+template <int dim, int spacedim>
+void test ()
+{
+  {
+    parallel::distributed::Triangulation<dim,spacedim> tr(MPI_COMM_WORLD);
+
+    GridGenerator::hyper_cube(tr);
+    MappingQ<dim,spacedim> mapping(1);
+
+    Particles::ParticleHandler<dim,spacedim> particle_handler(tr,mapping);
+
+    Particles::Particle<dim,spacedim> particle;
+
+    Point<spacedim> position;
+    position(0) = 0.3;
+    if (spacedim>1)
+      position(1) = 0.5;
+    if (spacedim>2)
+      position(2) = 0.7;
+
+    Point<dim> reference_position;
+    reference_position(0) = 0.2;
+    if (dim>1)
+      reference_position(1) = 0.4;
+    if (dim>2)
+      reference_position(1) = 0.6;
+
+    particle.set_location(position);
+    particle.set_reference_location(reference_position);
+    deallog << "Particle location: " << particle.get_location() << std::endl;
+
+
+    std::pair<typename parallel::distributed::Triangulation<dim, spacedim>::active_cell_iterator, Point<dim> > cell_position =
+      GridTools::find_active_cell_around_point(mapping, tr, particle.get_location());
+
+    particle_handler.insert_particle(particle,cell_position.first);
+    particle_handler.update_cache();
+
+    deallog << "Particle number: " << particle_handler.n_global_particles() << std::endl;
+
+    for (auto particle = particle_handler.begin(); particle != particle_handler.end(); ++particle)
+      {
+        deallog << "Particle location: " << particle->get_location() << std::endl;
+        deallog << "Particle reference location: " << particle->get_reference_location() << std::endl;
+      }
+  }
+
+  deallog << "OK" << std::endl;
+}
+
+
+
+int main (int argc, char *argv[])
+{
+  Utilities::MPI::MPI_InitFinalize mpi_initialization (argc, argv, 1);
+
+  initlog();
+
+  test<2,2>();
+  test<2,3>();
+
+  test<3,3>();
+}
diff --git a/tests/particles/particle_handler_01.output b/tests/particles/particle_handler_01.output
new file mode 100644 (file)
index 0000000..2cf7a27
--- /dev/null
@@ -0,0 +1,16 @@
+
+DEAL::Particle location: 0.300000 0.500000
+DEAL::Particle number: 1
+DEAL::Particle location: 0.300000 0.500000
+DEAL::Particle reference location: 0.200000 0.400000
+DEAL::OK
+DEAL::Particle location: 0.300000 0.500000 0.700000
+DEAL::Particle number: 1
+DEAL::Particle location: 0.300000 0.500000 0.700000
+DEAL::Particle reference location: 0.200000 0.400000
+DEAL::OK
+DEAL::Particle location: 0.300000 0.500000 0.700000
+DEAL::Particle number: 1
+DEAL::Particle location: 0.300000 0.500000 0.700000
+DEAL::Particle reference location: 0.200000 0.600000 0.00000
+DEAL::OK
index 67ccd4597f165e944f3a03196296d4b0cdc82668..2eac94b1c6dd73cc1fc300ee00b641830a73b9be 100644 (file)
@@ -44,7 +44,7 @@ void test ()
     if (dim>1)
       reference_position(1) = 0.4;
 
-    const Particles::types::particle_index index(7);
+    const types::particle_index index(7);
 
     std::vector<double> properties = {0.15,0.45,0.75};
 
@@ -52,9 +52,9 @@ void test ()
     particle.set_property_pool(pool);
     particle.set_properties(ArrayView<double>(&properties[0],properties.size()));
 
-    std::multimap<Particles::types::LevelInd,Particles::Particle<dim> > map;
+    std::multimap<types::LevelInd,Particles::Particle<dim> > map;
 
-    Particles::types::LevelInd level_index = std::make_pair(0,0);
+    types::LevelInd level_index = std::make_pair(0,0);
     map.insert(std::make_pair(level_index,particle));
 
     particle.get_properties()[0] = 0.05;

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.