for (const auto &p_unit : reference_locations)
{
if (numbers::is_finite(p_unit[0]) &&
- GeometryInfo<dim>::is_inside_unit_cell(p_unit))
+ GeometryInfo<dim>::is_inside_unit_cell(p_unit,
+ tolerance_inside_cell))
particle->set_reference_location(p_unit);
else
particles_out_of_cell.push_back(particle);
real_locations,
reference_locations);
- if (GeometryInfo<dim>::is_inside_unit_cell(
- reference_locations[0]))
+ if (GeometryInfo<dim>::is_inside_unit_cell(reference_locations[0],
+ tolerance_inside_cell))
{
current_cell = *cell;
found_cell = true;
cell, real_locations, reference_locations);
if (GeometryInfo<dim>::is_inside_unit_cell(
- reference_locations[0]))
+ reference_locations[0], tolerance_inside_cell))
{
current_cell = cell;
found_cell = true;
const Point<dim> p_unit =
mapping->transform_real_to_unit_cell(
child, particle->get_location());
- if (GeometryInfo<dim>::is_inside_unit_cell(p_unit,
- 1e-12))
+ if (GeometryInfo<dim>::is_inside_unit_cell(
+ p_unit, tolerance_inside_cell))
{
found_new_cell = true;
particle->set_reference_location(p_unit);
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2021 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.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+// Test if sort_particles_into_subdomains_and_cells() works for a particle
+// located at a vertex.
+
+#include <deal.II/distributed/tria.h>
+
+#include <deal.II/fe/mapping_q.h>
+
+#include <deal.II/grid/filtered_iterator.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/grid_out.h>
+#include <deal.II/grid/grid_tools.h>
+
+#include <deal.II/particles/particle_handler.h>
+
+#include "../tests.h"
+
+template <int dim, int spacedim>
+void
+test()
+{
+ parallel::distributed::Triangulation<dim, spacedim> tr(MPI_COMM_WORLD);
+
+ GridGenerator::subdivided_hyper_cube(tr, 20, 0, 4);
+
+ MappingQ<dim, spacedim> mapping(3);
+
+ // both processes create a particle handler with a particle in a
+ // position that is in a ghost cell to the other process
+ Particles::ParticleHandler<dim, spacedim> particle_handler(tr, mapping);
+
+ particle_handler.signals.particle_lost.connect(
+ [](const typename Particles::ParticleIterator<dim> &particle,
+ const typename Triangulation<dim>::active_cell_iterator &cell) {
+ AssertThrow(false, ExcMessage("Particle lost."));
+ });
+
+ std::vector<Point<spacedim>> position(1);
+
+ if (Utilities::MPI::this_mpi_process(tr.get_communicator()) == 0)
+ for (unsigned int i = 0; i < dim; ++i)
+ position[0][i] = 2;
+
+ auto my_bounding_box = GridTools::compute_mesh_predicate_bounding_box(
+ tr, IteratorFilters::LocallyOwnedCell());
+
+ auto global_bounding_boxes =
+ Utilities::MPI::all_gather(MPI_COMM_WORLD, my_bounding_box);
+
+ particle_handler.insert_global_particles(position, global_bounding_boxes);
+
+ // Reverse the refinement and check again
+ for (auto cell = tr.begin_active(); cell != tr.end(); ++cell)
+ {
+ if (cell->is_locally_owned())
+ if (cell->center().distance(position[0]) <= 1)
+ cell->set_refine_flag();
+ }
+
+ particle_handler.prepare_for_coarsening_and_refinement();
+ tr.prepare_coarsening_and_refinement();
+ tr.execute_coarsening_and_refinement();
+ particle_handler.unpack_after_coarsening_and_refinement();
+ particle_handler.sort_particles_into_subdomains_and_cells();
+
+ deallog << "OK" << std::endl;
+}
+
+
+
+int
+main(int argc, char *argv[])
+{
+ Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
+
+ MPILogInitAll all;
+
+ test<2, 2>();
+}