From 7a7f82a3a8b245b6bffb208d9ae29eb9cd9b98ea Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Tue, 15 Apr 2025 11:18:54 +0200 Subject: [PATCH 01/19] feat: send specific mesh_id_t in MPI - Before, we only are able to send the whole mesh structure - For performance reasons, we should only send a part of it - So here are the correspondinf functiosn that send only cells[id] of m_subdomain - TODO : delete update_mesh function - TODO : factorize the two functions for cells[id] and subdomain. It is maybe more complex --- include/samurai/mesh.hpp | 87 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index cf8f74e24..cb53cb51b 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -644,6 +644,93 @@ namespace samurai #endif } + // TODO : find a clever way to factorize the two next functions. For new, I have to duplicate the code 2 times. + + // This function is to only send m_subdomain instead of the whole mesh data + template + inline void Mesh_base::update_subdomain_neighbour() + { +#ifdef SAMURAI_WITH_MPI + // send/recv the meshes of the neighbouring subdomains + mpi::communicator world; + std::vector req; + + boost::mpi::packed_oarchive::buffer_type buffer; + boost::mpi::packed_oarchive oa(world, buffer); + oa << derived_cast().subdomain; + + std::transform(m_mpi_neighbourhood.cbegin(), + m_mpi_neighbourhood.cend(), + std::back_inserter(req), + [&](const auto& neighbour) + { + return world.isend(neighbour.rank, neighbour.rank, buffer); + }); + + for (auto& neighbour : m_mpi_neighbourhood) + { + world.recv(neighbour.rank, world.rank(), neighbour.mesh.subdomain); + } + + mpi::wait_all(req.begin(), req.end()); +#endif + } + + // This function is to only send cells[i] instead of the whole mesh + template + inline void Mesh_base::update_meshid_neighbour() + { +#ifdef SAMURAI_WITH_MPI + // send/recv the meshes of the neighbouring subdomains + mpi::communicator world; + std::vector req; + + boost::mpi::packed_oarchive::buffer_type buffer; + boost::mpi::packed_oarchive oa(world, buffer); + oa << derived_cast()[MeshID]; + + std::transform(m_mpi_neighbourhood.cbegin(), + m_mpi_neighbourhood.cend(), + std::back_inserter(req), + [&](const auto& neighbour) + { + return world.isend(neighbour.rank, neighbour.rank, buffer); + }); + + for (auto& neighbour : m_mpi_neighbourhood) + { + world.recv(neighbour.rank, world.rank(), neighbour.mesh[MeshID]); + } + + mpi::wait_all(req.begin(), req.end()); +#endif + } + + // These are helper functions to send a specific cells[i] + template + inline void Mesh_base::update_neighbour_cells() + { + update_meshid_neighbour(); + } + + template + inline void Mesh_base::update_neighbour_cells_and_ghosts() + { + update_meshid_neighbour(); + } + + template + inline void Mesh_base::update_neighbour_all_cells() + { + update_meshid_neighbour(); + } + + template + inline void Mesh_base::update_neighbour_reference() + { + update_meshid_neighbour(); + } + template inline void Mesh_base::construct_subdomain() { From 38a27e961502b71268328c1f1d26f0e40e959a1a Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Tue, 15 Apr 2025 11:24:02 +0200 Subject: [PATCH 02/19] fix: Reduce communication volume - Previously, we send the whole mesh structure - But it is not needed. - Here are the modified sends reduced in size that improve the performance --- include/samurai/mr/mesh.hpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index b847cad98..8b68eeaf7 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -226,7 +226,9 @@ namespace samurai } this->cells()[mesh_id_t::all_cells] = {cell_list, false}; - this->update_mesh_neighbour(); + // this->update_mesh_neighbour(); + this->update_neighbour_cells_and_ghosts(); + this->update_neighbour_reference(); for (auto& neighbour : this->mpi_neighbourhood()) { @@ -339,11 +341,14 @@ namespace samurai this->cells()[mesh_id_t::all_cells][level + 1] = lcl; this->cells()[mesh_id_t::proj_cells][level] = lcl_proj; } - this->update_mesh_neighbour(); + // this->update_mesh_neighbour(); + this->update_neighbour_subdomain(); + this->update_neighbour_all_cells(); } else { this->cells()[mesh_id_t::all_cells] = {cell_list, false}; + // TODO : what to send here ? this->update_mesh_neighbour(); } } From 2210089487fbde8ae95c1cb44816c513dca31c8b Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Tue, 15 Apr 2025 11:45:15 +0200 Subject: [PATCH 03/19] fix: Solve a compilation issue - Add definition - Add template mesh_id_t properly --- include/samurai/mesh.hpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index cb53cb51b..138f9b628 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -133,6 +133,16 @@ namespace samurai cell_t get_cell(std::size_t level, const xt::xexpression& coord) const; void update_mesh_neighbour(); + + void update_neighbour_subdomain(); + template + void update_meshid_neighbour(); + + void update_neighbour_cells(); + void update_neighbour_cells_and_ghosts(); + void update_neighbour_all_cells(); + void update_neighbour_reference(); + void to_stream(std::ostream& os) const; protected: @@ -648,7 +658,7 @@ namespace samurai // This function is to only send m_subdomain instead of the whole mesh data template - inline void Mesh_base::update_subdomain_neighbour() + inline void Mesh_base::update_neighbour_subdomain() { #ifdef SAMURAI_WITH_MPI // send/recv the meshes of the neighbouring subdomains @@ -657,7 +667,7 @@ namespace samurai boost::mpi::packed_oarchive::buffer_type buffer; boost::mpi::packed_oarchive oa(world, buffer); - oa << derived_cast().subdomain; + oa << derived_cast().m_subdomain; std::transform(m_mpi_neighbourhood.cbegin(), m_mpi_neighbourhood.cend(), @@ -669,7 +679,7 @@ namespace samurai for (auto& neighbour : m_mpi_neighbourhood) { - world.recv(neighbour.rank, world.rank(), neighbour.mesh.subdomain); + world.recv(neighbour.rank, world.rank(), neighbour.mesh.m_subdomain); } mpi::wait_all(req.begin(), req.end()); @@ -677,7 +687,8 @@ namespace samurai } // This function is to only send cells[i] instead of the whole mesh - template + template + template ::mesh_id_t MeshID> inline void Mesh_base::update_meshid_neighbour() { #ifdef SAMURAI_WITH_MPI From c9312165eb3811cae0581d34fa00f0ade869162a Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Tue, 15 Apr 2025 12:53:00 +0200 Subject: [PATCH 04/19] fix: use non-const functions - Add non-const to be able to write with operator[] - TODO : is it preferable to use a setter to preserve the [] as const ? --- include/samurai/algorithm.hpp | 2 +- include/samurai/mesh.hpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/samurai/algorithm.hpp b/include/samurai/algorithm.hpp index d07483d53..bd6c21617 100644 --- a/include/samurai/algorithm.hpp +++ b/include/samurai/algorithm.hpp @@ -59,7 +59,7 @@ namespace samurai } template - inline void for_each_level(Mesh& mesh, Func&& f, bool include_empty_levels = false) + inline void for_each_level(const Mesh& mesh, Func&& f, bool include_empty_levels = false) { using mesh_id_t = typename Mesh::mesh_id_t; for_each_level(mesh[mesh_id_t::cells], std::forward(f), include_empty_levels); diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 138f9b628..d53f60feb 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -89,6 +89,7 @@ namespace samurai std::size_t nb_cells(std::size_t level, mesh_id_t mesh_id = mesh_id_t::reference) const; const ca_type& operator[](mesh_id_t mesh_id) const; + ca_type& operator[](mesh_id_t mesh_id); std::size_t max_level() const; std::size_t& max_level(); @@ -413,6 +414,12 @@ namespace samurai return m_cells[mesh_id]; } + template + inline auto Mesh_base::operator[](mesh_id_t mesh_id) -> ca_type& + { + return m_cells[mesh_id]; + } + template inline std::size_t Mesh_base::max_level() const { From 7320a187ce97aca0e046342ffa87451935667c0d Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Tue, 15 Apr 2025 13:31:50 +0200 Subject: [PATCH 05/19] fix: temporary modification, trying to fix const issue --- include/samurai/field.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/samurai/field.hpp b/include/samurai/field.hpp index be02e9162..d8063ce3f 100644 --- a/include/samurai/field.hpp +++ b/include/samurai/field.hpp @@ -1188,14 +1188,14 @@ namespace samurai inline auto ScalarField::begin() -> iterator { using mesh_id_t = typename mesh_t::mesh_id_t; - return iterator(this, this->mesh()[mesh_id_t::cells].begin()); + return iterator(this, std::as_const(this->mesh()[mesh_id_t::cells]).begin()); } template inline auto ScalarField::end() -> iterator { using mesh_id_t = typename mesh_t::mesh_id_t; - return iterator(this, this->mesh()[mesh_id_t::cells].end()); + return iterator(this, std::as_const(this->mesh()[mesh_id_t::cells]).end()); } template From 5d567a6f90bfc46d9c71be585175963f5f4045df Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Tue, 15 Apr 2025 13:38:00 +0200 Subject: [PATCH 06/19] fix: try to debug CI --- include/samurai/field.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/samurai/field.hpp b/include/samurai/field.hpp index d8063ce3f..b4b3de870 100644 --- a/include/samurai/field.hpp +++ b/include/samurai/field.hpp @@ -1188,6 +1188,7 @@ namespace samurai inline auto ScalarField::begin() -> iterator { using mesh_id_t = typename mesh_t::mesh_id_t; + // add comment : the CI is buggy ahahaha return iterator(this, std::as_const(this->mesh()[mesh_id_t::cells]).begin()); } From 9b125a3f4a2f69c637c7fceb0b380f5fe47b2834 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Tue, 22 Apr 2025 10:34:32 +0200 Subject: [PATCH 07/19] feat: reconstruct the cells_and_ghost neighbourhood - Before: we send/recv the neighbourhood cells_and_ghosts - But we can avoid MPI comms by reconstructing it locally - At this point, the advection-2d case works fine --- include/samurai/mr/mesh.hpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 8b68eeaf7..914ed336e 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -227,9 +227,30 @@ namespace samurai this->cells()[mesh_id_t::all_cells] = {cell_list, false}; // this->update_mesh_neighbour(); - this->update_neighbour_cells_and_ghosts(); + + // this->update_neighbour_cells_and_ghosts(); this->update_neighbour_reference(); + // Here we want to reconstruct cells_and_ghosts and reference + for (auto& neighbour : this->mpi_neighbourhood()) + { + // reconstruct cells_and_ghosts + cl_type cell_list_neighbour; + for_each_interval(this->cells()[mesh_id_t::cells], + [&](std::size_t level, const auto& interval, const auto& index_yz) + { + lcl_type& lcl = cell_list_neighbour[level]; + static_nested_loop( + [&](auto stencil) + { + auto index = xt::eval(index_yz + stencil); + lcl[index].add_interval( + {interval.start - config::max_stencil_width, interval.end + config::max_stencil_width}); + }); + }); + neighbour.mesh[mesh_id_t::cells_and_ghosts] = {cell_list, false}; + } + for (auto& neighbour : this->mpi_neighbourhood()) { for (std::size_t level = 0; level <= max_level; ++level) From e3fae999e29816bfc601f1a7de7e4c6fca63d6f4 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Tue, 22 Apr 2025 18:56:03 +0200 Subject: [PATCH 08/19] feat: factorize mesh steps --- include/samurai/mr/mesh.hpp | 143 ++++++++++++++++++++++-------------- 1 file changed, 87 insertions(+), 56 deletions(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 914ed336e..13eeebcad 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -90,6 +90,14 @@ namespace samurai void update_sub_mesh_impl(); + template + void construct_ghost_cells(MeshT& mesh, cl_type& cell_list, std::size_t max_stencil_width); + + template + void construct_mra_cells(MeshT& mesh, cl_type& cell_list); + void construct_periodic_cells(); + void construct_projection_cells(); + template xt::xtensor exists(mesh_id_t type, std::size_t level, interval_t interval, T... index) const; }; @@ -139,6 +147,73 @@ namespace samurai { } + template + template + void MRMesh::construct_ghost_cells(MeshT& mesh, cl_type& cell_list, std::size_t max_stencil_width) + { + for_each_interval( + mesh[mesh_id_t::cells], + [&](std::size_t level, const auto& interval, const auto& index_yz) + { + lcl_type& lcl = cell_list[level]; + static_nested_loop( + [&](auto stencil) + { + auto index = xt::eval(index_yz + stencil); + lcl[index].add_interval({interval.start - config::max_stencil_width, interval.end + config::max_stencil_width}); + }); + }); + mesh[mesh_id_t::cells_and_ghosts] = {cell_list, false}; + } + + template + template + void MRMesh::construct_mra_cells(MeshT& mesh, cl_type& cell_list) + { + mpi::communicator world; + // cppcheck-suppress redundantInitialization + auto max_level = mpi::all_reduce(world, this->cells()[mesh_id_t::cells].max_level(), mpi::maximum()); + // cppcheck-suppress redundantInitialization + auto min_level = mpi::all_reduce(world, this->cells()[mesh_id_t::cells].min_level(), mpi::minimum()); + + for (std::size_t level = max_level; level >= ((min_level == 0) ? 1 : min_level); --level) + { + auto expr = difference(mesh[mesh_id_t::cells_and_ghosts][level], this->get_union()[level]).on(level); // TODO : change this-> + expr( + [&](const auto& interval, const auto& index_yz) + { + lcl_type& lcl = cell_list[level - 1]; + static_nested_loop( + [&](auto stencil) + { + auto new_interval = interval >> 1; + lcl[(index_yz >> 1) + stencil].add_interval( + {new_interval.start - config::prediction_order, new_interval.end + config::prediction_order}); + }); + }); + + auto expr_2 = intersection(mesh[mesh_id_t::cells][level], mesh[mesh_id_t::cells][level]); + + expr_2( + [&](const auto& interval, const auto& index_yz) + { + if (level - 1 > 0) + { + lcl_type& lcl = cell_list[level - 2]; + + static_nested_loop( + [&](auto stencil) + { + auto new_interval = interval >> 2; + lcl[(index_yz >> 2) + stencil].add_interval( + {new_interval.start - config::prediction_order, new_interval.end + config::prediction_order}); + }); + } + }); + } + mesh[mesh_id_t::all_cells] = {cell_list, false}; + } + template inline void MRMesh::update_sub_mesh_impl() { @@ -149,6 +224,7 @@ namespace samurai // cppcheck-suppress redundantInitialization auto min_level = mpi::all_reduce(world, this->cells()[mesh_id_t::cells].min_level(), mpi::minimum()); cl_type cell_list; + std::vector neighbour_cell_list(this->mpi_neighbourhood().size()); #else // cppcheck-suppress redundantInitialization auto max_level = this->cells()[mesh_id_t::cells].max_level(); @@ -170,67 +246,22 @@ namespace samurai // // level 0 |.......|-------|.......| |.......|-------|.......| // - for_each_interval( - this->cells()[mesh_id_t::cells], - [&](std::size_t level, const auto& interval, const auto& index_yz) - { - lcl_type& lcl = cell_list[level]; - static_nested_loop( - [&](auto stencil) - { - auto index = xt::eval(index_yz + stencil); - lcl[index].add_interval({interval.start - config::max_stencil_width, interval.end + config::max_stencil_width}); - }); - }); - this->cells()[mesh_id_t::cells_and_ghosts] = {cell_list, false}; + // + // + + construct_ghost_cells(this->cells(), cell_list, config::max_stencil_width); + // reconstruct ghost cells for neighbourhood + for (int i = 0; i < this->mpi_neighbourhood().size(); i++) + { + auto& neighbour = this->mpi_neighbourhood()[i]; + construct_ghost_cells(neighbour.mesh, neighbour_cell_list[i], config::max_stencil_width); + } // Add cells for the MRA if (this->max_level() != this->min_level()) { - for (std::size_t level = max_level; level >= ((min_level == 0) ? 1 : min_level); --level) - { - auto expr = difference(this->cells()[mesh_id_t::cells_and_ghosts][level], this->get_union()[level]).on(level); - - expr( - [&](const auto& interval, const auto& index_yz) - { - lcl_type& lcl = cell_list[level - 1]; - - static_nested_loop( - [&](auto stencil) - { - auto new_interval = interval >> 1; - lcl[(index_yz >> 1) + stencil].add_interval( - {new_interval.start - config::prediction_order, new_interval.end + config::prediction_order}); - }); - }); - - auto expr_2 = intersection(this->cells()[mesh_id_t::cells][level], this->cells()[mesh_id_t::cells][level]); - - expr_2( - [&](const auto& interval, const auto& index_yz) - { - if (level - 1 > 0) - { - lcl_type& lcl = cell_list[level - 2]; - - static_nested_loop( - [&](auto stencil) - { - auto new_interval = interval >> 2; - lcl[(index_yz >> 2) + stencil].add_interval( - {new_interval.start - config::prediction_order, new_interval.end + config::prediction_order}); - }); - } - }); - } - this->cells()[mesh_id_t::all_cells] = {cell_list, false}; - - // this->update_mesh_neighbour(); - - // this->update_neighbour_cells_and_ghosts(); + construct_mra_cells(this->cells(), cell_list); this->update_neighbour_reference(); - // Here we want to reconstruct cells_and_ghosts and reference for (auto& neighbour : this->mpi_neighbourhood()) { From 7f153e6171b6f3b7f757a23679f339cbb657e912 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 23 Apr 2025 16:01:28 +0200 Subject: [PATCH 09/19] feat: factorize mesh_id construction steps - I suggest decompose the mesh_id steps in subfunctions - This is now easier to reconstruct the subdomain mesh locally !! --- include/samurai/mr/mesh.hpp | 305 ++++++++++++++++++++---------------- 1 file changed, 167 insertions(+), 138 deletions(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 13eeebcad..51f119e40 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -91,12 +91,15 @@ namespace samurai void update_sub_mesh_impl(); template - void construct_ghost_cells(MeshT& mesh, cl_type& cell_list, std::size_t max_stencil_width); - + void construct_ghost_cells(MeshT& mesh, cl_type& cell_list); template void construct_mra_cells(MeshT& mesh, cl_type& cell_list); - void construct_periodic_cells(); - void construct_projection_cells(); + template + void construct_periodic_cells(MeshT& mesh, cl_type& cell_list); + template + void construct_projection_cells(MeshT& mesh, cl_type& cell_list); + template + void construct_neighbour_cells(MeshT& mesh, cl_type& cell_list); template xt::xtensor exists(mesh_id_t type, std::size_t level, interval_t interval, T... index) const; @@ -149,7 +152,7 @@ namespace samurai template template - void MRMesh::construct_ghost_cells(MeshT& mesh, cl_type& cell_list, std::size_t max_stencil_width) + void MRMesh::construct_ghost_cells(MeshT& mesh, cl_type& cell_list) { for_each_interval( mesh[mesh_id_t::cells], @@ -172,13 +175,13 @@ namespace samurai { mpi::communicator world; // cppcheck-suppress redundantInitialization - auto max_level = mpi::all_reduce(world, this->cells()[mesh_id_t::cells].max_level(), mpi::maximum()); + auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); // cppcheck-suppress redundantInitialization - auto min_level = mpi::all_reduce(world, this->cells()[mesh_id_t::cells].min_level(), mpi::minimum()); + auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); for (std::size_t level = max_level; level >= ((min_level == 0) ? 1 : min_level); --level) { - auto expr = difference(mesh[mesh_id_t::cells_and_ghosts][level], this->get_union()[level]).on(level); // TODO : change this-> + auto expr = difference(mesh.cells()[mesh_id_t::cells_and_ghosts][level], mesh.get_union()[level]).on(level); expr( [&](const auto& interval, const auto& index_yz) { @@ -192,7 +195,7 @@ namespace samurai }); }); - auto expr_2 = intersection(mesh[mesh_id_t::cells][level], mesh[mesh_id_t::cells][level]); + auto expr_2 = intersection(mesh.cells()[mesh_id_t::cells][level], mesh.cells()[mesh_id_t::cells][level]); expr_2( [&](const auto& interval, const auto& index_yz) @@ -214,6 +217,147 @@ namespace samurai mesh[mesh_id_t::all_cells] = {cell_list, false}; } + template + template + void MRMesh::construct_periodic_cells(MeshT& mesh, cl_type& cell_list) + { + mpi::communicator world; + + auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); + // cppcheck-suppress redundantInitialization + auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); + + xt::xtensor_fixed> stencil; + xt::xtensor_fixed> min_corner; + xt::xtensor_fixed> max_corner; + + auto& domain = mesh.domain(); + auto min_indices = domain.min_indices(); + auto max_indices = domain.max_indices(); + + for (std::size_t level = mesh.cells()[mesh_id_t::reference].min_level(); level <= mesh.cells()[mesh_id_t::reference].max_level(); + ++level) + { + std::size_t delta_l = domain.level() - level; + lcl_type& lcl = cell_list[level]; + + for (std::size_t d = 0; d < dim; ++d) + { + if (mesh.is_periodic(d)) + { + stencil.fill(0); + stencil[d] = (max_indices[d] - min_indices[d]) >> delta_l; + + min_corner[d] = (min_indices[d] >> delta_l) - config::ghost_width; + max_corner[d] = (min_indices[d] >> delta_l) + config::ghost_width; + for (std::size_t dd = 0; dd < dim; ++dd) + { + if (dd != d) + { + min_corner[dd] = (min_indices[dd] >> delta_l) - config::ghost_width; + max_corner[dd] = (max_indices[dd] >> delta_l) + config::ghost_width; + } + } + + lca_type lca1{ + level, + Box{min_corner, max_corner} + }; + + auto set1 = intersection(mesh.cells()[mesh_id_t::reference][level], lca1); + set1( + [&](const auto& i, const auto& index_yz) + { + lcl[index_yz + xt::view(stencil, xt::range(1, _))].add_interval(i + stencil[0]); + }); + + min_corner[d] = (max_indices[d] >> delta_l) - config::ghost_width; + max_corner[d] = (max_indices[d] >> delta_l) + config::ghost_width; + lca_type lca2{ + level, + Box{min_corner, max_corner} + }; + + auto set2 = intersection(mesh.cells()[mesh_id_t::reference][level], lca2); + set2( + [&](const auto& i, const auto& index_yz) + { + lcl[index_yz - xt::view(stencil, xt::range(1, _))].add_interval(i - stencil[0]); + }); + mesh.cells()[mesh_id_t::all_cells][level] = {lcl}; + } + } + } + } + + template + template + void MRMesh::construct_projection_cells(MeshT& mesh, cl_type& cell_list) + { + mpi::communicator world; + auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); + // cppcheck-suppress redundantInitialization + auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); + + for (std::size_t level = 0; level < max_level; ++level) + { + lcl_type& lcl = cell_list[level + 1]; + lcl_type lcl_proj{level}; + auto expr = intersection(mesh.cells()[mesh_id_t::all_cells][level], mesh.get_union()[level]); + + expr( + [&](const auto& interval, const auto& index_yz) + { + static_nested_loop( + [&](auto s) + { + lcl[(index_yz << 1) + s].add_interval(interval << 1); + }); + lcl_proj[index_yz].add_interval(interval); + }); + mesh.cells()[mesh_id_t::all_cells][level + 1] = lcl; + mesh.cells()[mesh_id_t::proj_cells][level] = lcl_proj; + } + } + + template + template + void MRMesh::construct_neighbour_cells(MeshT& mesh, cl_type& cell_list) + { + mpi::communicator world; + auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); + // cppcheck-suppress redundantInitialization + auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); + + for (auto& neighbour : mesh.mpi_neighbourhood()) + { + for (std::size_t level = 0; level <= max_level; ++level) + { + auto expr = intersection(mesh.subdomain(), neighbour.mesh[mesh_id_t::reference][level]).on(level); + expr( + [&](const auto& interval, const auto& index_yz) + { + lcl_type& lcl = cell_list[level]; + lcl[index_yz].add_interval(interval); + + if (level > neighbour.mesh[mesh_id_t::reference].min_level()) + { + lcl_type& lclm1 = cell_list[level - 1]; + + static_nested_loop( + [&](auto stencil) + { + auto new_interval = interval >> 1; + lclm1[(index_yz >> 1) + stencil].add_interval( + {new_interval.start - config::prediction_order, new_interval.end + config::prediction_order}); + }); + } + }); + } + } + mesh.cells()[mesh_id_t::all_cells] = {cell_list, false}; + } + template inline void MRMesh::update_sub_mesh_impl() { @@ -249,150 +393,35 @@ namespace samurai // // - construct_ghost_cells(this->cells(), cell_list, config::max_stencil_width); + construct_ghost_cells(*this, cell_list); // reconstruct ghost cells for neighbourhood - for (int i = 0; i < this->mpi_neighbourhood().size(); i++) + for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) { auto& neighbour = this->mpi_neighbourhood()[i]; - construct_ghost_cells(neighbour.mesh, neighbour_cell_list[i], config::max_stencil_width); + construct_ghost_cells((neighbour.mesh), neighbour_cell_list[i]); } // Add cells for the MRA if (this->max_level() != this->min_level()) { - construct_mra_cells(this->cells(), cell_list); + construct_mra_cells(*this, cell_list); this->update_neighbour_reference(); - // Here we want to reconstruct cells_and_ghosts and reference - for (auto& neighbour : this->mpi_neighbourhood()) + for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) { - // reconstruct cells_and_ghosts - cl_type cell_list_neighbour; - for_each_interval(this->cells()[mesh_id_t::cells], - [&](std::size_t level, const auto& interval, const auto& index_yz) - { - lcl_type& lcl = cell_list_neighbour[level]; - static_nested_loop( - [&](auto stencil) - { - auto index = xt::eval(index_yz + stencil); - lcl[index].add_interval( - {interval.start - config::max_stencil_width, interval.end + config::max_stencil_width}); - }); - }); - neighbour.mesh[mesh_id_t::cells_and_ghosts] = {cell_list, false}; + auto& neighbour = this->mpi_neighbourhood()[i]; + construct_mra_cells((neighbour.mesh), neighbour_cell_list[i]); } - for (auto& neighbour : this->mpi_neighbourhood()) - { - for (std::size_t level = 0; level <= max_level; ++level) - { - auto expr = intersection(this->subdomain(), neighbour.mesh[mesh_id_t::reference][level]).on(level); - expr( - [&](const auto& interval, const auto& index_yz) - { - lcl_type& lcl = cell_list[level]; - lcl[index_yz].add_interval(interval); - - if (level > neighbour.mesh[mesh_id_t::reference].min_level()) - { - lcl_type& lclm1 = cell_list[level - 1]; - - static_nested_loop( - [&](auto stencil) - { - auto new_interval = interval >> 1; - lclm1[(index_yz >> 1) + stencil].add_interval( - {new_interval.start - config::prediction_order, new_interval.end + config::prediction_order}); - }); - } - }); - } - } + construct_neighbour_cells(*this, cell_list); + // TODO : add reconstruction this->cells()[mesh_id_t::all_cells] = {cell_list, false}; - // add ghosts for periodicity - xt::xtensor_fixed> stencil; - xt::xtensor_fixed> min_corner; - xt::xtensor_fixed> max_corner; - - auto& domain = this->domain(); - auto min_indices = domain.min_indices(); - auto max_indices = domain.max_indices(); - - for (std::size_t level = this->cells()[mesh_id_t::reference].min_level(); - level <= this->cells()[mesh_id_t::reference].max_level(); - ++level) - { - std::size_t delta_l = domain.level() - level; - lcl_type& lcl = cell_list[level]; + construct_periodic_cells(*this, cell_list); + // TODO : add reconstruction - for (std::size_t d = 0; d < dim; ++d) - { - if (this->is_periodic(d)) - { - stencil.fill(0); - stencil[d] = (max_indices[d] - min_indices[d]) >> delta_l; - - min_corner[d] = (min_indices[d] >> delta_l) - config::ghost_width; - max_corner[d] = (min_indices[d] >> delta_l) + config::ghost_width; - for (std::size_t dd = 0; dd < dim; ++dd) - { - if (dd != d) - { - min_corner[dd] = (min_indices[dd] >> delta_l) - config::ghost_width; - max_corner[dd] = (max_indices[dd] >> delta_l) + config::ghost_width; - } - } - - lca_type lca1{ - level, - Box{min_corner, max_corner} - }; - - auto set1 = intersection(this->cells()[mesh_id_t::reference][level], lca1); - set1( - [&](const auto& i, const auto& index_yz) - { - lcl[index_yz + xt::view(stencil, xt::range(1, _))].add_interval(i + stencil[0]); - }); - - min_corner[d] = (max_indices[d] >> delta_l) - config::ghost_width; - max_corner[d] = (max_indices[d] >> delta_l) + config::ghost_width; - lca_type lca2{ - level, - Box{min_corner, max_corner} - }; - - auto set2 = intersection(this->cells()[mesh_id_t::reference][level], lca2); - set2( - [&](const auto& i, const auto& index_yz) - { - lcl[index_yz - xt::view(stencil, xt::range(1, _))].add_interval(i - stencil[0]); - }); - this->cells()[mesh_id_t::all_cells][level] = {lcl}; - } - } - } - - for (std::size_t level = 0; level < max_level; ++level) - { - lcl_type& lcl = cell_list[level + 1]; - lcl_type lcl_proj{level}; - auto expr = intersection(this->cells()[mesh_id_t::all_cells][level], this->get_union()[level]); - - expr( - [&](const auto& interval, const auto& index_yz) - { - static_nested_loop( - [&](auto s) - { - lcl[(index_yz << 1) + s].add_interval(interval << 1); - }); - lcl_proj[index_yz].add_interval(interval); - }); - this->cells()[mesh_id_t::all_cells][level + 1] = lcl; - this->cells()[mesh_id_t::proj_cells][level] = lcl_proj; - } + construct_projection_cells(*this, cell_list); + // TODO : add reconstruction + // // this->update_mesh_neighbour(); this->update_neighbour_subdomain(); this->update_neighbour_all_cells(); From 2f787c4c099c648196dca2dc1473cf30d3dab882 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 23 Apr 2025 16:13:37 +0200 Subject: [PATCH 10/19] fix: correct cppcheck and some stuff --- include/samurai/mr/mesh.hpp | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 51f119e40..517f895ef 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -222,7 +222,7 @@ namespace samurai void MRMesh::construct_periodic_cells(MeshT& mesh, cl_type& cell_list) { mpi::communicator world; - + // cppcheck-suppress redundantInitialization auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); // cppcheck-suppress redundantInitialization auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); @@ -295,6 +295,7 @@ namespace samurai void MRMesh::construct_projection_cells(MeshT& mesh, cl_type& cell_list) { mpi::communicator world; + // cppcheck-suppress redundantInitialization auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); // cppcheck-suppress redundantInitialization auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); @@ -325,6 +326,7 @@ namespace samurai void MRMesh::construct_neighbour_cells(MeshT& mesh, cl_type& cell_list) { mpi::communicator world; + // cppcheck-suppress redundantInitialization auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); // cppcheck-suppress redundantInitialization auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); @@ -413,14 +415,32 @@ namespace samurai } construct_neighbour_cells(*this, cell_list); - // TODO : add reconstruction + for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) + { + auto& neighbour = this->mpi_neighbourhood()[i]; + construct_neighbour_cells(neighbour.mesh, neighbour_cell_list[i]); + } this->cells()[mesh_id_t::all_cells] = {cell_list, false}; - construct_periodic_cells(*this, cell_list); - // TODO : add reconstruction + for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) + { + auto& neighbour = this->mpi_neighbourhood()[i]; + neighbour.mesh.cells()[mesh_id_t::all_cells] = {neighbour_cell_list[i], false}; + } + construct_periodic_cells(*this, cell_list); + for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) + { + auto& neighbour = this->mpi_neighbourhood()[i]; + construct_periodic_cells(neighbour.mesh, neighbour_cell_list[i]); + } construct_projection_cells(*this, cell_list); - // TODO : add reconstruction + for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) + { + auto& neighbour = this->mpi_neighbourhood()[i]; + construct_projection_cells(neighbour.mesh, neighbour_cell_list[i]); + } + // // this->update_mesh_neighbour(); this->update_neighbour_subdomain(); From ceadd7050757b5986ecd6ae247ae148b82be6e9e Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 23 Apr 2025 17:31:22 +0200 Subject: [PATCH 11/19] feat: reconstruct locally the mesh - For each subdomain, we reconstruct cells_and_ghosts_ and reference and prijection. - TODO : there is a segfault for the periodic one. --- include/samurai/mr/mesh.hpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 517f895ef..852250a63 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -407,7 +407,7 @@ namespace samurai if (this->max_level() != this->min_level()) { construct_mra_cells(*this, cell_list); - this->update_neighbour_reference(); + // this->update_neighbour_reference(); for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) { auto& neighbour = this->mpi_neighbourhood()[i]; @@ -428,12 +428,14 @@ namespace samurai neighbour.mesh.cells()[mesh_id_t::all_cells] = {neighbour_cell_list[i], false}; } - construct_periodic_cells(*this, cell_list); - for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) - { - auto& neighbour = this->mpi_neighbourhood()[i]; - construct_periodic_cells(neighbour.mesh, neighbour_cell_list[i]); - } + // For now, this leads to a segfault. + // construct_periodic_cells(*this, cell_list); + // for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) + // { + // auto& neighbour = this->mpi_neighbourhood()[i]; + // construct_periodic_cells(neighbour.mesh, neighbour_cell_list[i]); + // } + construct_projection_cells(*this, cell_list); for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) { @@ -444,7 +446,7 @@ namespace samurai // // this->update_mesh_neighbour(); this->update_neighbour_subdomain(); - this->update_neighbour_all_cells(); + // this->update_neighbour_all_cells(); } else { From 729c57affcabbc4a62cde3969fb2be3a751e9b98 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 23 Apr 2025 17:38:48 +0200 Subject: [PATCH 12/19] fix: remove periodic construction - For now, lets check without periodic --- include/samurai/mr/mesh.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 852250a63..e49ef7819 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -221,6 +221,7 @@ namespace samurai template void MRMesh::construct_periodic_cells(MeshT& mesh, cl_type& cell_list) { + /** mpi::communicator world; // cppcheck-suppress redundantInitialization auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); @@ -288,6 +289,7 @@ namespace samurai } } } + **/ } template From 14ba272494d4bc67d4cb382f4529e79cdc4babd7 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 23 Apr 2025 17:46:24 +0200 Subject: [PATCH 13/19] fix: avoid mpi functions when no MPI --- include/samurai/mr/mesh.hpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index e49ef7819..e96d1ba50 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -173,11 +173,18 @@ namespace samurai template void MRMesh::construct_mra_cells(MeshT& mesh, cl_type& cell_list) { +#ifdef SAMURAI_WITH_MPI mpi::communicator world; // cppcheck-suppress redundantInitialization auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); // cppcheck-suppress redundantInitialization auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); +#else + // cppcheck-suppress redundantInitialization + auto max_level = mesh.cells()[mesh_id_t::cells].max_level(); + // cppcheck-suppress redundantInitialization + auto min_level = mesh.cells()[mesh_id_t::cells].min_level(); +#endif for (std::size_t level = max_level; level >= ((min_level == 0) ? 1 : min_level); --level) { @@ -222,11 +229,20 @@ namespace samurai void MRMesh::construct_periodic_cells(MeshT& mesh, cl_type& cell_list) { /** + +#ifdef SAMURAI_WITH_MPI mpi::communicator world; // cppcheck-suppress redundantInitialization auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); // cppcheck-suppress redundantInitialization auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); +#else + // cppcheck-suppress redundantInitialization + auto max_level = mesh.cells()[mesh_id_t::cells].max_level(); + // cppcheck-suppress redundantInitialization + auto min_level = mesh.cells()[mesh_id_t::cells].min_level(); +#endif + xt::xtensor_fixed> stencil; xt::xtensor_fixed> min_corner; @@ -296,11 +312,18 @@ namespace samurai template void MRMesh::construct_projection_cells(MeshT& mesh, cl_type& cell_list) { +#ifdef SAMURAI_WITH_MPI mpi::communicator world; // cppcheck-suppress redundantInitialization auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); // cppcheck-suppress redundantInitialization auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); +#else + // cppcheck-suppress redundantInitialization + auto max_level = mesh.cells()[mesh_id_t::cells].max_level(); + // cppcheck-suppress redundantInitialization + auto min_level = mesh.cells()[mesh_id_t::cells].min_level(); +#endif for (std::size_t level = 0; level < max_level; ++level) { @@ -327,11 +350,18 @@ namespace samurai template void MRMesh::construct_neighbour_cells(MeshT& mesh, cl_type& cell_list) { +#ifdef SAMURAI_WITH_MPI mpi::communicator world; // cppcheck-suppress redundantInitialization auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); // cppcheck-suppress redundantInitialization auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); +#else + // cppcheck-suppress redundantInitialization + auto max_level = mesh.cells()[mesh_id_t::cells].max_level(); + // cppcheck-suppress redundantInitialization + auto min_level = mesh.cells()[mesh_id_t::cells].min_level(); +#endif for (auto& neighbour : mesh.mpi_neighbourhood()) { From 98e5f70ed753c308621d1311d7a21fc502549b7a Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 23 Apr 2025 17:55:04 +0200 Subject: [PATCH 14/19] fix: add MPI macros --- include/samurai/mr/mesh.hpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index e96d1ba50..40cdb03cc 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -429,52 +429,58 @@ namespace samurai construct_ghost_cells(*this, cell_list); // reconstruct ghost cells for neighbourhood +#ifdef SAMURAI_WITH_MPI for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) { auto& neighbour = this->mpi_neighbourhood()[i]; construct_ghost_cells((neighbour.mesh), neighbour_cell_list[i]); } - +#endif // Add cells for the MRA if (this->max_level() != this->min_level()) { construct_mra_cells(*this, cell_list); // this->update_neighbour_reference(); +#ifdef SAMURAI_WITH_MPI for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) { auto& neighbour = this->mpi_neighbourhood()[i]; construct_mra_cells((neighbour.mesh), neighbour_cell_list[i]); } - +#endif construct_neighbour_cells(*this, cell_list); +#ifdef SAMURAI_WITH_MPI for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) { auto& neighbour = this->mpi_neighbourhood()[i]; construct_neighbour_cells(neighbour.mesh, neighbour_cell_list[i]); } +#endif this->cells()[mesh_id_t::all_cells] = {cell_list, false}; - +#ifdef SAMURAI_WITH_MPI for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) { auto& neighbour = this->mpi_neighbourhood()[i]; neighbour.mesh.cells()[mesh_id_t::all_cells] = {neighbour_cell_list[i], false}; } - +#endif // For now, this leads to a segfault. // construct_periodic_cells(*this, cell_list); +#ifdef SAMURAI_WITH_MPI // for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) // { // auto& neighbour = this->mpi_neighbourhood()[i]; // construct_periodic_cells(neighbour.mesh, neighbour_cell_list[i]); // } - +#endif construct_projection_cells(*this, cell_list); +#ifdef SAMURAI_WITH_MPI for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) { auto& neighbour = this->mpi_neighbourhood()[i]; construct_projection_cells(neighbour.mesh, neighbour_cell_list[i]); } - +#endif // // this->update_mesh_neighbour(); this->update_neighbour_subdomain(); From 865ae6748325527062cd0d7e73badd5d00ad1aa8 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 23 Apr 2025 19:14:59 +0200 Subject: [PATCH 15/19] feat: uncomment periodic part --- include/samurai/mr/mesh.hpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 40cdb03cc..a663495d5 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -228,8 +228,6 @@ namespace samurai template void MRMesh::construct_periodic_cells(MeshT& mesh, cl_type& cell_list) { - /** - #ifdef SAMURAI_WITH_MPI mpi::communicator world; // cppcheck-suppress redundantInitialization @@ -243,7 +241,6 @@ namespace samurai auto min_level = mesh.cells()[mesh_id_t::cells].min_level(); #endif - xt::xtensor_fixed> stencil; xt::xtensor_fixed> min_corner; xt::xtensor_fixed> max_corner; @@ -305,7 +302,6 @@ namespace samurai } } } - **/ } template From 3f63de362ff88b42e8c313dc3df9eff82ff32134 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 23 Apr 2025 19:21:37 +0200 Subject: [PATCH 16/19] fix: add cppcheck-suppress --- include/samurai/mr/mesh.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index a663495d5..4d64a80a7 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -249,6 +249,7 @@ namespace samurai auto min_indices = domain.min_indices(); auto max_indices = domain.max_indices(); + // cppcheck-suppress constStatement for (std::size_t level = mesh.cells()[mesh_id_t::reference].min_level(); level <= mesh.cells()[mesh_id_t::reference].max_level(); ++level) { From e0819a01b15eb487d50f93a4b5a93263cf4f1e8d Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 23 Apr 2025 19:47:38 +0200 Subject: [PATCH 17/19] feat: introduce periodic meshid construction - Now only for the rank mesh - TODO : resolve the issue when launched for the neighbour mesh --- include/samurai/mr/mesh.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 4d64a80a7..d9de2f4b0 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -462,7 +462,7 @@ namespace samurai } #endif // For now, this leads to a segfault. - // construct_periodic_cells(*this, cell_list); + construct_periodic_cells(*this, cell_list); #ifdef SAMURAI_WITH_MPI // for (std::size_t i = 0; i < this->mpi_neighbourhood().size(); i++) // { From 0cb02ce2ce813520b8122874fdba7ab83dbdd84c Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 23 Apr 2025 21:03:31 +0200 Subject: [PATCH 18/19] fix: remove useless code --- include/samurai/mr/mesh.hpp | 53 ++----------------------------------- 1 file changed, 2 insertions(+), 51 deletions(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index d9de2f4b0..6b907316e 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -173,18 +173,10 @@ namespace samurai template void MRMesh::construct_mra_cells(MeshT& mesh, cl_type& cell_list) { -#ifdef SAMURAI_WITH_MPI - mpi::communicator world; - // cppcheck-suppress redundantInitialization - auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); - // cppcheck-suppress redundantInitialization - auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); -#else // cppcheck-suppress redundantInitialization auto max_level = mesh.cells()[mesh_id_t::cells].max_level(); // cppcheck-suppress redundantInitialization auto min_level = mesh.cells()[mesh_id_t::cells].min_level(); -#endif for (std::size_t level = max_level; level >= ((min_level == 0) ? 1 : min_level); --level) { @@ -228,18 +220,10 @@ namespace samurai template void MRMesh::construct_periodic_cells(MeshT& mesh, cl_type& cell_list) { -#ifdef SAMURAI_WITH_MPI - mpi::communicator world; - // cppcheck-suppress redundantInitialization - auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); - // cppcheck-suppress redundantInitialization - auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); -#else // cppcheck-suppress redundantInitialization auto max_level = mesh.cells()[mesh_id_t::cells].max_level(); // cppcheck-suppress redundantInitialization auto min_level = mesh.cells()[mesh_id_t::cells].min_level(); -#endif xt::xtensor_fixed> stencil; xt::xtensor_fixed> min_corner; @@ -250,8 +234,7 @@ namespace samurai auto max_indices = domain.max_indices(); // cppcheck-suppress constStatement - for (std::size_t level = mesh.cells()[mesh_id_t::reference].min_level(); level <= mesh.cells()[mesh_id_t::reference].max_level(); - ++level) + for (std::size_t level = min_level; level <= max_level; ++level) { std::size_t delta_l = domain.level() - level; lcl_type& lcl = cell_list[level]; @@ -309,18 +292,8 @@ namespace samurai template void MRMesh::construct_projection_cells(MeshT& mesh, cl_type& cell_list) { -#ifdef SAMURAI_WITH_MPI - mpi::communicator world; - // cppcheck-suppress redundantInitialization - auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); - // cppcheck-suppress redundantInitialization - auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); -#else // cppcheck-suppress redundantInitialization auto max_level = mesh.cells()[mesh_id_t::cells].max_level(); - // cppcheck-suppress redundantInitialization - auto min_level = mesh.cells()[mesh_id_t::cells].min_level(); -#endif for (std::size_t level = 0; level < max_level; ++level) { @@ -347,18 +320,8 @@ namespace samurai template void MRMesh::construct_neighbour_cells(MeshT& mesh, cl_type& cell_list) { -#ifdef SAMURAI_WITH_MPI - mpi::communicator world; - // cppcheck-suppress redundantInitialization - auto max_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].max_level(), mpi::maximum()); - // cppcheck-suppress redundantInitialization - auto min_level = mpi::all_reduce(world, mesh.cells()[mesh_id_t::cells].min_level(), mpi::minimum()); -#else // cppcheck-suppress redundantInitialization auto max_level = mesh.cells()[mesh_id_t::cells].max_level(); - // cppcheck-suppress redundantInitialization - auto min_level = mesh.cells()[mesh_id_t::cells].min_level(); -#endif for (auto& neighbour : mesh.mpi_neighbourhood()) { @@ -392,21 +355,9 @@ namespace samurai template inline void MRMesh::update_sub_mesh_impl() { -#ifdef SAMURAI_WITH_MPI - mpi::communicator world; - // cppcheck-suppress redundantInitialization - auto max_level = mpi::all_reduce(world, this->cells()[mesh_id_t::cells].max_level(), mpi::maximum()); - // cppcheck-suppress redundantInitialization - auto min_level = mpi::all_reduce(world, this->cells()[mesh_id_t::cells].min_level(), mpi::minimum()); cl_type cell_list; std::vector neighbour_cell_list(this->mpi_neighbourhood().size()); -#else - // cppcheck-suppress redundantInitialization - auto max_level = this->cells()[mesh_id_t::cells].max_level(); - // cppcheck-suppress redundantInitialization - auto min_level = this->cells()[mesh_id_t::cells].min_level(); - cl_type cell_list; -#endif + // Construction of ghost cells // =========================== // From f8295d5ace659443edfc0cdd2aaa00edd8e7430d Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Thu, 24 Apr 2025 10:59:23 +0200 Subject: [PATCH 19/19] fix: add MPI macro --- include/samurai/mr/mesh.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 6b907316e..c4160e06c 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -356,8 +356,9 @@ namespace samurai inline void MRMesh::update_sub_mesh_impl() { cl_type cell_list; +#ifdef SAMURAI_WITH_MPI std::vector neighbour_cell_list(this->mpi_neighbourhood().size()); - +#endif // Construction of ghost cells // =========================== //