diff --git a/src/core/lb/LBWalberla.cpp b/src/core/lb/LBWalberla.cpp index 22ed37a43e..5b0c9a7ac9 100644 --- a/src/core/lb/LBWalberla.cpp +++ b/src/core/lb/LBWalberla.cpp @@ -59,7 +59,7 @@ void LBWalberla::propagate() { lb_fluid->integrate(); } void LBWalberla::ghost_communication() { lb_fluid->ghost_communication(); } void LBWalberla::ghost_communication_pdf() { - lb_fluid->ghost_communication_vel(); + lb_fluid->ghost_communication_pdf(); } void LBWalberla::ghost_communication_vel() { diff --git a/src/core/unit_tests/lb_particle_coupling_test.cpp b/src/core/unit_tests/lb_particle_coupling_test.cpp index 0bce69c3e2..d35a6ce10c 100644 --- a/src/core/unit_tests/lb_particle_coupling_test.cpp +++ b/src/core/unit_tests/lb_particle_coupling_test.cpp @@ -521,6 +521,61 @@ BOOST_DATA_TEST_CASE_F(CleanupActorLB, coupling_particle_lattice_ia, } } +BOOST_FIXTURE_TEST_CASE(ghost_communication_pdf_flushes_density, + CleanupActorLB) { + auto &lb = espresso::system->lb; + auto const &lattice = espresso::lb_fluid->get_lattice(); + auto const &grid = params.grid_dimensions; + auto const gl = static_cast(lattice.get_ghost_layers()); + + // distinct, node-dependent density (differs from the initial params.density) + auto fold = [](Utils::Vector3i n) { + for (auto i = 0u; i < 3u; ++i) { + if (n[i] < 0) + n[i] += grid[i]; + else if (n[i] >= grid[i]) + n[i] -= grid[i]; + } + return n; + }; + auto node_density = [&fold](Utils::Vector3i const &node) { + auto const f = fold(node); + return 2. + 1e-3 * static_cast(f[0] + 17 * f[1] + 311 * f[2]); + }; + + // Write a distinct density on every locally-owned node. This sets ONLY the + // GhostComm::PDF pending flag; GhostComm::VEL stays clear. + for (auto x = -gl; x < grid[0] + gl; ++x) { + for (auto y = -gl; y < grid[1] + gl; ++y) { + for (auto z = -gl; z < grid[2] + gl; ++z) { + auto const node = Utils::Vector3i{x, y, z}; + if (lattice.node_in_local_domain(node)) { + BOOST_REQUIRE( + espresso::lb_fluid->set_node_density(node, node_density(node))); + } + } + } + } + + // synchronize the PDF ghost layer through the core wrapper + lb.ghost_communication_pdf(); + + // read local halo and check the PDF ghost layer was correctly updated + for (auto x = -gl; x < grid[0] + gl; ++x) { + for (auto y = -gl; y < grid[1] + gl; ++y) { + for (auto z = -gl; z < grid[2] + gl; ++z) { + auto const node = Utils::Vector3i{x, y, z}; + if (lattice.node_in_local_halo(node) and + not lattice.node_in_local_domain(node)) { + auto const res = espresso::lb_fluid->get_node_density(node, true); + BOOST_REQUIRE(res); + BOOST_CHECK_CLOSE(*res, node_density(node), 1e-9); + } + } + } + } +} + BOOST_FIXTURE_TEST_CASE(runtime_exceptions, CleanupActorLB) { boost::mpi::communicator world; auto &lb = espresso::system->lb;