diff --git a/src/core/lb/particle_coupling.hpp b/src/core/lb/particle_coupling.hpp index 501c820e5a..38d650b4ed 100644 --- a/src/core/lb/particle_coupling.hpp +++ b/src/core/lb/particle_coupling.hpp @@ -105,8 +105,9 @@ class CouplingBookkeeping { CellStructure const &m_cell_structure; /** @brief Check if there is locally a real particle for the given ghost. */ - bool is_ghost_for_local_particle(Particle const &p) const { - return not m_cell_structure.get_local_particle(p.id())->is_ghost(); + bool is_ghost_for_local_particle(Particle const &ghost) const { + auto const p = m_cell_structure.get_local_particle(ghost.id()); + return p != nullptr and not p->is_ghost(); } public: diff --git a/src/core/p3m/P3MFFT.hpp b/src/core/p3m/P3MFFT.hpp index bbdf8e6c0c..39b9d79685 100644 --- a/src/core/p3m/P3MFFT.hpp +++ b/src/core/p3m/P3MFFT.hpp @@ -209,8 +209,7 @@ struct P3MFFTHeffte final : public P3MFFTBackend { Utils::Vector3i const &node_grid) : m_impl(nullptr, comm, global_mesh, rs_local_ld_index, rs_local_ur_index, node_grid), - m_input( - static_cast(Utils::product(m_impl.rs_local_size()))) {} + m_input(static_cast(Utils::product(rs_local_size()))) {} Utils::Vector3i ks_local_ld_index() const override { return m_impl.ks_local_ld_index(); diff --git a/src/core/particle_node.cpp b/src/core/particle_node.cpp index 7cee84fd45..3c0e3e86e4 100644 --- a/src/core/particle_node.cpp +++ b/src/core/particle_node.cpp @@ -504,6 +504,7 @@ void remove_particle(int p_id) { } } mpi_synchronize_max_seen_pid_local(); + get_cell_structure().resort_particles(false); } void make_new_particle(int p_id, Utils::Vector3d const &pos) { diff --git a/src/core/unit_tests/BoxGeometry_test.cpp b/src/core/unit_tests/BoxGeometry_test.cpp index 7ed880fddb..18db6db82f 100644 --- a/src/core/unit_tests/BoxGeometry_test.cpp +++ b/src/core/unit_tests/BoxGeometry_test.cpp @@ -274,6 +274,7 @@ BOOST_AUTO_TEST_CASE(cuboid_minimum_image_non_periodic_axis_test) { auto const a = b + raw; auto const reference = box.get_mi_vector(a, b); + auto const reference_dist2 = box.get_mi_dist2(a, b); // The non-periodic y axis must not fold: component equals the raw // separation. @@ -282,6 +283,7 @@ BOOST_AUTO_TEST_CASE(cuboid_minimum_image_non_periodic_axis_test) { BOOST_CHECK_LT(std::abs(reference[0u]), 0.5 * box_l[0u]); BOOST_CHECK_LT(std::abs(reference[2u]), 0.5 * box_l[2u]); - // And the hoisted fold must agree with the standard box path bitwise. - BOOST_CHECK_EQUAL(fold.dist2(a, b), reference.norm2()); + // And the hoisted fold must agree with the standard box path. + BOOST_CHECK_LT(std::abs(fold.dist2(a, b) - reference.norm2()), 1e-12); + BOOST_CHECK_LT(std::abs(reference.norm2() - reference_dist2), 1e-12); } diff --git a/src/core/unit_tests/p3m_test.cpp b/src/core/unit_tests/p3m_test.cpp index 1c78c78ae5..d2e1335143 100644 --- a/src/core/unit_tests/p3m_test.cpp +++ b/src/core/unit_tests/p3m_test.cpp @@ -35,6 +35,7 @@ #include "EspressoCoreGlobalConfig.hpp" #include "Particle.hpp" +#include "communication.hpp" #include "energy_inline.hpp" #include "integrate.hpp" #include "particle_node.hpp" @@ -152,6 +153,23 @@ template void test_all_p3m_fft_configs() { BOOST_CHECK_CLOSE(energy_k_space, energy_ref, 1e-6); } } + // check FFT properties + auto const &fft = *solver->p3m.fft; + auto const ref_rs_local_size = 12 / ::communicator.node_grid; + BOOST_CHECK_EQUAL(fft.rs_local_size(), ref_rs_local_size); + if (::communicator.size <= 3) { + auto const node_index = ::communicator.calc_node_index(); + auto ref_ks_local_size = 12 / ::communicator.node_grid; + if constexpr (FFTConfig::use_r2c) { + ref_ks_local_size[FFTConfig::r2c_dir] /= 2; + if (node_index[FFTConfig::r2c_dir] == 0) { + ref_ks_local_size[FFTConfig::r2c_dir] += 1; + } + } + BOOST_CHECK_EQUAL(fft.ks_local_size(), ref_ks_local_size); + BOOST_CHECK_EQUAL(fft.ks_local_ur_index() - fft.ks_local_ld_index(), + ref_ks_local_size); + } // deactivate actor solver->detach_system(espresso::system); system.coulomb.impl->solver = std::nullopt;