From 8a1df9fd2fc1228cd180f772f4f7730ffbe8695f Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Thu, 28 Aug 2025 12:10:35 +0200 Subject: [PATCH 01/60] add mesh_config --- demos/FiniteVolume/heat.cpp | 5 +- include/samurai/arguments.hpp | 7 ++ include/samurai/mesh.hpp | 31 +++++++ include/samurai/mesh_config.hpp | 147 ++++++++++++++++++++++++++++++++ include/samurai/mr/mesh.hpp | 7 ++ 5 files changed, 194 insertions(+), 3 deletions(-) create mode 100644 include/samurai/mesh_config.hpp diff --git a/demos/FiniteVolume/heat.cpp b/demos/FiniteVolume/heat.cpp index 0062ae1dc..e3b361bdf 100644 --- a/demos/FiniteVolume/heat.cpp +++ b/demos/FiniteVolume/heat.cpp @@ -102,8 +102,6 @@ int main(int argc, char* argv[]) app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters"); app.add_option("--dt", dt, "Time step")->capture_default_str()->group("Simulation parameters"); app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_flag("--save-final-state-only", save_final_state_only, "Save final state only")->group("Output"); @@ -127,7 +125,8 @@ int main(int argc, char* argv[]) if (restart_file.empty()) { - mesh = {box, min_level, max_level}; + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + mesh = {config, box}; u.resize(); // Initial solution if (init_sol == "dirac") diff --git a/include/samurai/arguments.hpp b/include/samurai/arguments.hpp index 0b00c62c3..b828e4dd4 100644 --- a/include/samurai/arguments.hpp +++ b/include/samurai/arguments.hpp @@ -8,6 +8,10 @@ namespace samurai { namespace args { + // Mesh arguments + static std::size_t min_level = std::numeric_limits::infinity(); + static std::size_t max_level = std::numeric_limits::infinity(); + static bool timers = false; #ifdef SAMURAI_WITH_MPI static bool dont_redirect_output = false; @@ -24,6 +28,9 @@ namespace samurai inline void read_samurai_arguments(CLI::App& app, int& argc, char**& argv) { + app.add_option("--min-level", args::min_level, "The minimum level of the mesh")->group("SAMURAI"); + app.add_option("--max-level", args::max_level, "The maximum level of the mesh")->group("SAMURAI"); + #ifdef SAMURAI_WITH_MPI app.add_flag("--dont-redirect-output", args::dont_redirect_output, "Redirect the output for all ranks different of 0") ->capture_default_str() diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 1fa2192f7..da617220b 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -11,6 +11,7 @@ #include "cell_array.hpp" #include "cell_list.hpp" #include "domain_builder.hpp" +#include "mesh_config.hpp" #include "static_algorithm.hpp" #include "stencil.hpp" #include "subset/node.hpp" @@ -157,6 +158,7 @@ namespace samurai Mesh_base(const cl_type& cl, const self_type& ref_mesh); Mesh_base(const cl_type& cl, std::size_t min_level, std::size_t max_level); Mesh_base(const ca_type& ca, std::size_t min_level, std::size_t max_level); + Mesh_base(mesh_config& config, const samurai::Box& b, std::size_t start_level); Mesh_base(const samurai::Box& b, std::size_t start_level, std::size_t min_level, @@ -247,6 +249,35 @@ namespace samurai return *static_cast(this); } + template + inline Mesh_base::Mesh_base(mesh_config& config, const samurai::Box& b, std::size_t start_level) + : m_domain{start_level, b, (config.parse_args(), config.approx_box_tol()), config.scaling_factor()} + , m_min_level{config.min_level()} + , m_max_level{config.max_level()} + { + // config.parse_args(); + // m_min_level = config.min_level(); + // m_max_level = config.max_level(); + + assert(m_min_level <= m_max_level); + +#ifdef SAMURAI_WITH_MPI + partition_mesh(start_level, b); + // load_balancing(); +#else + this->m_cells[mesh_id_t::cells][start_level] = {start_level, b, config.approx_box_tol(), config.scaling_factor()}; +#endif + construct_subdomain(); + construct_union(); + update_sub_mesh(); + construct_corners(); + renumbering(); + update_mesh_neighbour(); + + set_origin_point(origin_point()); + set_scaling_factor(config.scaling_factor()); + } + template inline Mesh_base::Mesh_base(const samurai::Box& b, std::size_t start_level, diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp new file mode 100644 index 000000000..22750b7c5 --- /dev/null +++ b/include/samurai/mesh_config.hpp @@ -0,0 +1,147 @@ +// Copyright 2018-2025 the samurai's authors +// SPDX-License-Identifier: BSD-3-Clause + +#pragma once + +#include "arguments.hpp" +#include + +namespace samurai +{ + + template + class mesh_config + { + public: + + static constexpr std::size_t dim = dim_; + + mesh_config() + { + m_periodic.fill(false); + } + + auto& max_stencil_width(std::size_t stencil_width) + { + m_max_stencil_width = stencil_width; + return *this; + } + + auto& max_stencil_width() const + { + return m_max_stencil_width; + } + + auto& graduation_width(std::size_t grad_width) + { + m_graduation_width = grad_width; + return *this; + } + + auto& graduation_width() const + { + return m_graduation_width; + } + + auto& min_level(std::size_t level) + { + m_min_level = level; + return *this; + } + + auto& min_level() const + { + return m_min_level; + } + + auto& max_level(std::size_t level) + { + m_max_level = level; + return *this; + } + + auto& max_level() const + { + return m_max_level; + } + + auto& approx_box_tol(double tol) + { + m_approx_box_tol = tol; + return *this; + } + + auto& approx_box_tol() const + { + return m_approx_box_tol; + } + + auto& scaling_factor(double factor) + { + m_scaling_factor = factor; + return *this; + } + + auto& scaling_factor() const + { + return m_scaling_factor; + } + + auto& periodic(std::array const& periodicity) + { + m_periodic = periodicity; + return *this; + } + + auto& periodic() const + { + return m_periodic; + } + + auto& periodic(std::size_t i) const + { + return m_periodic[i]; + } + + void parse_args() + { + // if (args::max_stencil_width != std::numeric_limits::max()) + // { + // m_max_stencil_width = args::max_stencil_width; + // } + // if (args::graduation_width != std::numeric_limits::max()) + // { + // m_graduation_width = args::graduation_width; + // } + if (args::min_level != std::numeric_limits::max()) + { + m_min_level = args::min_level; + } + if (args::max_level != std::numeric_limits::max()) + { + m_max_level = args::max_level; + } + // if (args::approx_box_tol != std::numeric_limits::infinity()) + // { + // m_approx_box_tol = args::approx_box_tol; + // } + // if (args::scaling_factor != std::numeric_limits::infinity()) + // { + // m_scaling_factor = args::scaling_factor; + // } + } + + private: + + std::size_t m_max_stencil_width = 1; + std::size_t m_graduation_width = 1; + + std::size_t m_min_level; + std::size_t m_max_level; + + double m_approx_box_tol = 0.05; + double m_scaling_factor = 0; + + std::array m_periodic; + }; +} diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 10912c566..d58eba4b4 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -77,6 +77,7 @@ namespace samurai MRMesh(const cl_type& cl, const self_type& ref_mesh); MRMesh(const cl_type& cl, std::size_t min_level, std::size_t max_level); MRMesh(const ca_type& ca, std::size_t min_level, std::size_t max_level); + MRMesh(mesh_config& config, const samurai::Box& b); MRMesh(const samurai::Box& b, std::size_t min_level, std::size_t max_level, @@ -124,6 +125,12 @@ namespace samurai { } + template + inline MRMesh::MRMesh(mesh_config& config, const samurai::Box& b) + : base_type(config, b, (config.parse_args(), config.max_level())) + { + } + template inline MRMesh::MRMesh(const samurai::Box& b, std::size_t min_level, From 5b66ff9ab7f7ee916401160586d95bf52d8ac1e8 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 8 Sep 2025 11:05:30 +0200 Subject: [PATCH 02/60] set default value to non-zero values --- include/samurai/arguments.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/samurai/arguments.hpp b/include/samurai/arguments.hpp index b828e4dd4..55b39c197 100644 --- a/include/samurai/arguments.hpp +++ b/include/samurai/arguments.hpp @@ -9,8 +9,8 @@ namespace samurai namespace args { // Mesh arguments - static std::size_t min_level = std::numeric_limits::infinity(); - static std::size_t max_level = std::numeric_limits::infinity(); + static std::size_t min_level = std::numeric_limits::max(); + static std::size_t max_level = std::numeric_limits::max(); static bool timers = false; #ifdef SAMURAI_WITH_MPI From db4e6b0cde3389b3c4d0e18603429beee4da434f Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 8 Sep 2025 11:05:50 +0200 Subject: [PATCH 03/60] fix config --- demos/FiniteVolume/heat.cpp | 7 ++++--- include/samurai/mesh.hpp | 7 ++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/demos/FiniteVolume/heat.cpp b/demos/FiniteVolume/heat.cpp index e3b361bdf..5b8e4dd59 100644 --- a/demos/FiniteVolume/heat.cpp +++ b/demos/FiniteVolume/heat.cpp @@ -84,8 +84,8 @@ int main(int argc, char* argv[]) std::string restart_file; // Multiresolution parameters - std::size_t min_level = 3; - std::size_t max_level = dim == 1 ? 5 : 6; + std::size_t min_level = 4; + std::size_t max_level = dim == 1 ? 5 : 8; // Output parameters fs::path path = fs::current_path(); @@ -127,6 +127,7 @@ int main(int argc, char* argv[]) { auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); mesh = {config, box}; + // mesh = {box, min_level, max_level}; u.resize(); // Initial solution if (init_sol == "dirac") @@ -174,7 +175,7 @@ int main(int argc, char* argv[]) if (explicit_scheme) { - double dx = mesh.cell_length(max_level); + double dx = mesh.cell_length(mesh.max_level()); dt = cfl * (dx * dx) / (pow(2, dim) * diff_coeff); } diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index da617220b..f5eb1903c 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -255,10 +255,6 @@ namespace samurai , m_min_level{config.min_level()} , m_max_level{config.max_level()} { - // config.parse_args(); - // m_min_level = config.min_level(); - // m_max_level = config.max_level(); - assert(m_min_level <= m_max_level); #ifdef SAMURAI_WITH_MPI @@ -275,7 +271,7 @@ namespace samurai update_mesh_neighbour(); set_origin_point(origin_point()); - set_scaling_factor(config.scaling_factor()); + set_scaling_factor(scaling_factor()); } template @@ -289,6 +285,7 @@ namespace samurai , m_min_level{min_level} , m_max_level{max_level} { + static_assert(false, "Delete min_level and max_level from CLI11 options and use mesh_config object in the constructor"); assert(min_level <= max_level); m_periodic.fill(false); From d3550154addf8e533df9fb44dbf1b3515902b356 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 8 Sep 2025 16:01:39 +0200 Subject: [PATCH 04/60] add graduation_width in mesh_config --- demos/FiniteVolume/heat.cpp | 1 - demos/FiniteVolume/linear_convection.cpp | 7 +- .../linear_convection_obstacle.cpp | 8 +- include/samurai/arguments.hpp | 6 +- include/samurai/mesh.hpp | 245 +++++++++++------- include/samurai/mesh_config.hpp | 29 ++- include/samurai/mr/adapt.hpp | 2 +- 7 files changed, 189 insertions(+), 109 deletions(-) diff --git a/demos/FiniteVolume/heat.cpp b/demos/FiniteVolume/heat.cpp index 5b8e4dd59..fc45a722e 100644 --- a/demos/FiniteVolume/heat.cpp +++ b/demos/FiniteVolume/heat.cpp @@ -127,7 +127,6 @@ int main(int argc, char* argv[]) { auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); mesh = {config, box}; - // mesh = {box, min_level, max_level}; u.resize(); // Initial solution if (init_sol == "dirac") diff --git a/demos/FiniteVolume/linear_convection.cpp b/demos/FiniteVolume/linear_convection.cpp index a7ae59070..80580038f 100644 --- a/demos/FiniteVolume/linear_convection.cpp +++ b/demos/FiniteVolume/linear_convection.cpp @@ -76,8 +76,6 @@ int main(int argc, char* argv[]) app.add_flag("--implicit", implicit_scheme, "Implicit scheme instead of explicit")->group("Simulation parameters"); app.add_option("--dt", dt, "Time step")->capture_default_str()->group("Simulation parameters"); app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_option("--nfiles", nfiles, "Number of output files")->capture_default_str()->group("Output"); @@ -100,7 +98,8 @@ int main(int argc, char* argv[]) if (restart_file.empty()) { - mesh = {box, min_level, max_level, periodic}; + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).periodic(periodic); + mesh = {config, box}; // Initial solution u = samurai::make_scalar_field("u", mesh, @@ -145,7 +144,7 @@ int main(int argc, char* argv[]) if (dt == 0) { - double dx = mesh.cell_length(max_level); + double dx = mesh.cell_length(mesh.max_level()); auto a = xt::abs(velocity); double sum_velocities = xt::sum(xt::abs(velocity))(); dt = cfl * dx / sum_velocities; diff --git a/demos/FiniteVolume/linear_convection_obstacle.cpp b/demos/FiniteVolume/linear_convection_obstacle.cpp index 00a048657..5d807c984 100644 --- a/demos/FiniteVolume/linear_convection_obstacle.cpp +++ b/demos/FiniteVolume/linear_convection_obstacle.cpp @@ -62,8 +62,6 @@ int main(int argc, char* argv[]) app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--dt", dt, "Time step")->capture_default_str()->group("Simulation parameters"); app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_option("--nfiles", nfiles, "Number of output files")->capture_default_str()->group("Output"); @@ -77,7 +75,9 @@ int main(int argc, char* argv[]) samurai::DomainBuilder domain({-1., -1.}, {1., 1.}); domain.remove({0.0, 0.0}, {0.4, 0.4}); - Mesh mesh(domain, min_level, max_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + Mesh mesh = {config, domain}; + // Mesh mesh(domain, min_level, max_level); // Initial solution auto u = samurai::make_scalar_field("u", @@ -117,7 +117,7 @@ int main(int argc, char* argv[]) if (dt == 0) { - double dx = mesh.cell_length(max_level); + double dx = mesh.cell_length(mesh.max_level()); auto a = xt::abs(constant_velocity); double sum_velocities = xt::sum(xt::abs(constant_velocity))(); dt = cfl * dx / sum_velocities; diff --git a/include/samurai/arguments.hpp b/include/samurai/arguments.hpp index 55b39c197..997b59ad5 100644 --- a/include/samurai/arguments.hpp +++ b/include/samurai/arguments.hpp @@ -9,8 +9,9 @@ namespace samurai namespace args { // Mesh arguments - static std::size_t min_level = std::numeric_limits::max(); - static std::size_t max_level = std::numeric_limits::max(); + static std::size_t min_level = std::numeric_limits::max(); + static std::size_t max_level = std::numeric_limits::max(); + static std::size_t graduation_width = std::numeric_limits::max(); static bool timers = false; #ifdef SAMURAI_WITH_MPI @@ -30,6 +31,7 @@ namespace samurai { app.add_option("--min-level", args::min_level, "The minimum level of the mesh")->group("SAMURAI"); app.add_option("--max-level", args::max_level, "The maximum level of the mesh")->group("SAMURAI"); + app.add_option("--graduation-width", args::graduation_width, "The graduation width of the mesh")->group("SAMURAI"); #ifdef SAMURAI_WITH_MPI app.add_flag("--dont-redirect-output", args::dont_redirect_output, "Redirect the output for all ranks different of 0") diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index f5eb1903c..58c96f2dd 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -99,6 +99,8 @@ namespace samurai std::size_t min_level() const; std::size_t& min_level(); + std::size_t graduation_width() const; + auto& origin_point() const; void set_origin_point(const coords_t& origin_point); double scaling_factor() const; @@ -159,25 +161,27 @@ namespace samurai Mesh_base(const cl_type& cl, std::size_t min_level, std::size_t max_level); Mesh_base(const ca_type& ca, std::size_t min_level, std::size_t max_level); Mesh_base(mesh_config& config, const samurai::Box& b, std::size_t start_level); - Mesh_base(const samurai::Box& b, - std::size_t start_level, - std::size_t min_level, - std::size_t max_level, - double approx_box_tol = lca_type::default_approx_box_tol, - double scaling_factor = 0); + + Mesh_base(mesh_config& config, const samurai::DomainBuilder& domain_builder, std::size_t start_level); + + Mesh_base(const samurai::Box&, std::size_t, std::size_t, std::size_t, double, double) + { + std::cerr << "Delete min_level and max_level from CLI11 options and use mesh_config object in the mesh constructor" << std::endl; + exit(EXIT_FAILURE); + } + Mesh_base(const samurai::DomainBuilder& domain_builder, std::size_t start_level, std::size_t min_level, std::size_t max_level, double approx_box_tol = lca_type::default_approx_box_tol, double scaling_factor = 0); - Mesh_base(const samurai::Box& b, - std::size_t start_level, - std::size_t min_level, - std::size_t max_level, - const std::array& periodic, - double approx_box_tol = lca_type::default_approx_box_tol, - double scaling_factor = 0); + + Mesh_base(const samurai::Box&, std::size_t, std::size_t, std::size_t, const std::array&, double, double) + { + std::cerr << "Delete min_level and max_level from CLI11 options and use mesh_config object in the mesh constructor" << std::endl; + exit(EXIT_FAILURE); + } derived_type& derived_cast() & noexcept; const derived_type& derived_cast() const& noexcept; @@ -212,6 +216,8 @@ namespace samurai // std::vector m_neighbouring_ranks; std::vector m_mpi_neighbourhood; + mesh_config m_config; + #ifdef SAMURAI_WITH_MPI friend class boost::serialization::access; @@ -254,9 +260,9 @@ namespace samurai : m_domain{start_level, b, (config.parse_args(), config.approx_box_tol()), config.scaling_factor()} , m_min_level{config.min_level()} , m_max_level{config.max_level()} + , m_periodic{config.periodic()} + , m_config(config) { - assert(m_min_level <= m_max_level); - #ifdef SAMURAI_WITH_MPI partition_mesh(start_level, b); // load_balancing(); @@ -274,61 +280,70 @@ namespace samurai set_scaling_factor(scaling_factor()); } - template - inline Mesh_base::Mesh_base(const samurai::Box& b, - std::size_t start_level, - std::size_t min_level, - std::size_t max_level, - double approx_box_tol, - double scaling_factor_) - : m_domain{start_level, b, approx_box_tol, scaling_factor_} - , m_min_level{min_level} - , m_max_level{max_level} - { - static_assert(false, "Delete min_level and max_level from CLI11 options and use mesh_config object in the constructor"); - assert(min_level <= max_level); - m_periodic.fill(false); - -#ifdef SAMURAI_WITH_MPI - partition_mesh(start_level, b); - // load_balancing(); -#else - this->m_cells[mesh_id_t::cells][start_level] = {start_level, b, approx_box_tol, scaling_factor_}; -#endif - construct_subdomain(); - construct_union(); - update_sub_mesh(); - construct_corners(); - renumbering(); - update_mesh_neighbour(); - - set_origin_point(origin_point()); - set_scaling_factor(scaling_factor()); - } - - template - Mesh_base::Mesh_base(const samurai::DomainBuilder& domain_builder, - [[maybe_unused]] std::size_t start_level, - std::size_t min_level, - std::size_t max_level, - [[maybe_unused]] double approx_box_tol, - double scaling_factor_) - : m_min_level{min_level} - , m_max_level{max_level} + // template + // [[deprecated("Delete min_level and max_level from CLI11 options and use mesh_config object in the constructor")]] inline + // Mesh_base::Mesh_base( + // const samurai::Box& b, + // std::size_t start_level, + // std::size_t min_level, + // std::size_t max_level, + // double approx_box_tol, + // double scaling_factor_) + // : m_domain{start_level, b, approx_box_tol, scaling_factor_} + // , m_min_level{min_level} + // , m_max_level{max_level} + // { + // assert(min_level <= max_level); + // m_periodic.fill(false); + + // #ifdef SAMURAI_WITH_MPI + // partition_mesh(start_level, b); + // // load_balancing(); + // #else + // this->m_cells[mesh_id_t::cells][start_level] = {start_level, b, approx_box_tol, scaling_factor_}; + // #endif + // construct_subdomain(); + // construct_union(); + // update_sub_mesh(); + // construct_corners(); + // renumbering(); + // update_mesh_neighbour(); + + // set_origin_point(origin_point()); + // set_scaling_factor(scaling_factor()); + // } + + template + Mesh_base::Mesh_base(mesh_config& config, + const samurai::DomainBuilder& domain_builder, + [[maybe_unused]] std::size_t start_level) + : m_min_level{(config.parse_args(), config.min_level())} + , m_max_level{config.max_level()} + , m_config(config) { - assert(min_level <= max_level); + if (std::any_of(config.periodic().begin(), + config.periodic().end(), + [](bool b) + { + return b; + })) + { + std::cerr << "Periodicity is not implemented with DomainBuilder." << std::endl; + exit(EXIT_FAILURE); + } m_periodic.fill(false); #ifdef SAMURAI_WITH_MPI std::cerr << "MPI is not implemented with DomainBuilder." << std::endl; - std::exit(1); + std::exit(EXIT_FAILURE); // partition_mesh(start_level, b); // load_balancing(); #else + double scaling_factor_ = config.scaling_factor(); compute_scaling_factor(domain_builder, scaling_factor_); // Build the domain by adding and removing boxes - cl_type domain_cl = construct_initial_mesh(domain_builder, start_level, approx_box_tol, scaling_factor_); + cl_type domain_cl = construct_initial_mesh(domain_builder, start_level, config.approx_box_tol(), scaling_factor_); this->m_cells[mesh_id_t::cells] = {domain_cl, false}; #endif @@ -344,38 +359,76 @@ namespace samurai set_scaling_factor(scaling_factor_); } - template - inline Mesh_base::Mesh_base(const samurai::Box& b, - std::size_t start_level, - std::size_t min_level, - std::size_t max_level, - const std::array& periodic, - double approx_box_tol, - double scaling_factor_) - : m_domain{start_level, b, approx_box_tol, scaling_factor_} - , m_min_level{min_level} - , m_max_level{max_level} - , m_periodic{periodic} - { - assert(min_level <= max_level); - -#ifdef SAMURAI_WITH_MPI - partition_mesh(start_level, b); - // load_balancing(); -#else - this->m_cells[mesh_id_t::cells][start_level] = {start_level, b, approx_box_tol, scaling_factor_}; -#endif - - construct_subdomain(); - construct_union(); - update_sub_mesh(); - construct_corners(); - renumbering(); - update_mesh_neighbour(); - - set_origin_point(origin_point()); - set_scaling_factor(scaling_factor()); - } + // template + // Mesh_base::Mesh_base(const samurai::DomainBuilder& domain_builder, + // [[maybe_unused]] std::size_t start_level, + // std::size_t min_level, + // std::size_t max_level, + // [[maybe_unused]] double approx_box_tol, + // double scaling_factor_) + // : m_min_level{min_level} + // , m_max_level{max_level} + // { + // assert(min_level <= max_level); + // m_periodic.fill(false); + + // #ifdef SAMURAI_WITH_MPI + // std::cerr << "MPI is not implemented with DomainBuilder." << std::endl; + // std::exit(1); + // // partition_mesh(start_level, b); + // // load_balancing(); + // #else + // compute_scaling_factor(domain_builder, scaling_factor_); + + // // Build the domain by adding and removing boxes + // cl_type domain_cl = construct_initial_mesh(domain_builder, start_level, approx_box_tol, scaling_factor_); + + // this->m_cells[mesh_id_t::cells] = {domain_cl, false}; + // #endif + // construct_subdomain(); + // m_domain = m_subdomain; + // construct_union(); + // update_sub_mesh(); + // construct_corners(); + // renumbering(); + // update_mesh_neighbour(); + + // set_origin_point(domain_builder.origin_point()); + // set_scaling_factor(scaling_factor_); + // } + + // template + // inline Mesh_base::Mesh_base(const samurai::Box& b, + // std::size_t start_level, + // std::size_t min_level, + // std::size_t max_level, + // const std::array& periodic, + // double approx_box_tol, + // double scaling_factor_) + // : m_domain{start_level, b, approx_box_tol, scaling_factor_} + // , m_min_level{min_level} + // , m_max_level{max_level} + // , m_periodic{periodic} + // { + // assert(min_level <= max_level); + + // #ifdef SAMURAI_WITH_MPI + // partition_mesh(start_level, b); + // // load_balancing(); + // #else + // this->m_cells[mesh_id_t::cells][start_level] = {start_level, b, approx_box_tol, scaling_factor_}; + // #endif + + // construct_subdomain(); + // construct_union(); + // update_sub_mesh(); + // construct_corners(); + // renumbering(); + // update_mesh_neighbour(); + + // set_origin_point(origin_point()); + // set_scaling_factor(scaling_factor()); + // } template inline Mesh_base::Mesh_base(const cl_type& cl, std::size_t min_level, std::size_t max_level) @@ -440,7 +493,7 @@ namespace samurai , m_max_level(ref_mesh.m_max_level) , m_periodic(ref_mesh.m_periodic) , m_mpi_neighbourhood(ref_mesh.m_mpi_neighbourhood) - + , m_config(ref_mesh.m_config) { m_cells[mesh_id_t::cells] = ca; @@ -462,7 +515,7 @@ namespace samurai , m_max_level(ref_mesh.m_max_level) , m_periodic(ref_mesh.m_periodic) , m_mpi_neighbourhood(ref_mesh.m_mpi_neighbourhood) - + , m_config(ref_mesh.m_config) { m_cells[mesh_id_t::cells] = {cl, false}; @@ -625,6 +678,12 @@ namespace samurai return m_min_level; } + template + inline std::size_t Mesh_base::graduation_width() const + { + return m_config.graduation_width(); + } + template inline auto& Mesh_base::origin_point() const { diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index 22750b7c5..b7d6f9ec3 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -49,6 +49,11 @@ namespace samurai return *this; } + auto& min_level() + { + return m_min_level; + } + auto& min_level() const { return m_min_level; @@ -60,6 +65,11 @@ namespace samurai return *this; } + auto& max_level() + { + return m_max_level; + } + auto& max_level() const { return m_max_level; @@ -93,6 +103,12 @@ namespace samurai return *this; } + auto& periodic(bool periodicity) + { + m_periodic.fill(periodicity); + return *this; + } + auto& periodic() const { return m_periodic; @@ -109,10 +125,10 @@ namespace samurai // { // m_max_stencil_width = args::max_stencil_width; // } - // if (args::graduation_width != std::numeric_limits::max()) - // { - // m_graduation_width = args::graduation_width; - // } + if (args::graduation_width != std::numeric_limits::max()) + { + m_graduation_width = args::graduation_width; + } if (args::min_level != std::numeric_limits::max()) { m_min_level = args::min_level; @@ -129,6 +145,11 @@ namespace samurai // { // m_scaling_factor = args::scaling_factor; // } + if (m_max_level < m_min_level) + { + std::cerr << "Max level must be greater than min level." << std::endl; + exit(EXIT_FAILURE); + } } private: diff --git a/include/samurai/mr/adapt.hpp b/include/samurai/mr/adapt.hpp index 958c14a7f..6b99bff53 100644 --- a/include/samurai/mr/adapt.hpp +++ b/include/samurai/mr/adapt.hpp @@ -384,7 +384,7 @@ namespace samurai mesh.domain(), mesh.mpi_neighbourhood(), mesh.periodicity(), - mesh_t::config::graduation_width, + mesh.graduation_width(), mesh_t::config::max_stencil_width); mesh_t new_mesh{new_ca, mesh}; #ifdef SAMURAI_WITH_MPI From dee8260cc0c50a9a03d2a29baab560391723e6d2 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 8 Sep 2025 16:02:35 +0200 Subject: [PATCH 05/60] add graduation_width in mesh_config --- include/samurai/mr/mesh.hpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index d58eba4b4..020d42d14 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -31,8 +31,8 @@ namespace samurai }; template @@ -41,8 +41,8 @@ namespace samurai static constexpr std::size_t dim = dim_; static constexpr std::size_t max_refinement_level = max_refinement_level_; static constexpr int max_stencil_width = max_stencil_width_; - static constexpr std::size_t graduation_width = graduation_width_; - static constexpr int prediction_order = prediction_order_; + // static constexpr std::size_t graduation_width = graduation_width_; + static constexpr int prediction_order = prediction_order_; // static constexpr int ghost_width = std::max(std::max(2 * // static_cast(graduation_width) - 1, @@ -88,6 +88,7 @@ namespace samurai std::size_t max_level, double approx_box_tol = lca_type::default_approx_box_tol, double scaling_factor = 0); + MRMesh(mesh_config& config, const samurai::DomainBuilder& domain_builder); MRMesh(const samurai::Box& b, std::size_t min_level, std::size_t max_level, @@ -131,6 +132,12 @@ namespace samurai { } + template + inline MRMesh::MRMesh(mesh_config& config, const samurai::DomainBuilder& domain_builder) + : base_type(config, domain_builder, (config.parse_args(), config.max_level())) + { + } + template inline MRMesh::MRMesh(const samurai::Box& b, std::size_t min_level, From 8f68eb39ae3c88c27c6d37342c0ae0ecfc0e8ae7 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 16 Sep 2025 15:44:19 +0200 Subject: [PATCH 06/60] dynamic ghost_width and max_stencil_size (radius) Co-authored-by: Pierre Matalon --- demos/FiniteVolume/advection_1d.cpp | 12 ++-- demos/FiniteVolume/advection_2d.cpp | 7 +- demos/FiniteVolume/advection_2d_user_bc.cpp | 9 ++- demos/FiniteVolume/burgers_mra.cpp | 11 ++-- demos/FiniteVolume/lid_driven_cavity.cpp | 8 +-- demos/FiniteVolume/linear_convection.cpp | 6 +- include/samurai/algorithm/graduation.hpp | 34 +++++----- include/samurai/algorithm/update.hpp | 54 ++++++++------- include/samurai/arguments.hpp | 3 + include/samurai/bc/apply_field_bc.hpp | 26 ++++---- include/samurai/bc/bc.hpp | 55 ++++++++-------- include/samurai/boundary.hpp | 9 ++- include/samurai/field.hpp | 16 +++++ include/samurai/mesh.hpp | 28 ++++++++ include/samurai/mesh_config.hpp | 65 +++++++++++++++---- include/samurai/mr/adapt.hpp | 9 +-- include/samurai/mr/mesh.hpp | 62 +++++++++--------- .../samurai/schemes/fv/explicit_FV_scheme.hpp | 12 ++++ .../schemes/fv/operators/convection_lin.hpp | 4 -- .../fv/operators/convection_nonlin.hpp | 2 - include/samurai/static_algorithm.hpp | 6 ++ 21 files changed, 270 insertions(+), 168 deletions(-) diff --git a/demos/FiniteVolume/advection_1d.cpp b/demos/FiniteVolume/advection_1d.cpp index 3df099cc7..13df511b7 100644 --- a/demos/FiniteVolume/advection_1d.cpp +++ b/demos/FiniteVolume/advection_1d.cpp @@ -91,8 +91,6 @@ int main(int argc, char* argv[]) app.add_option("--Ti", t, "Initial time")->capture_default_str()->group("Simulation parameters"); app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_option("--nfiles", nfiles, "Number of output files")->capture_default_str()->group("Output"); @@ -100,12 +98,16 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box({left_box}, {right_box}); - samurai::MRMesh mesh; + + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).periodic(is_periodic); + samurai::MRMesh mesh = {config, box}; + // samurai::MRMesh mesh; auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { - mesh = {box, min_level, max_level, std::array{is_periodic}}; + // mesh = {box, min_level, max_level, std::array{is_periodic}}; + mesh = {config, box}; init(u); } else @@ -113,7 +115,7 @@ int main(int argc, char* argv[]) samurai::load(restart_file, mesh, u); } - double dt = cfl * mesh.cell_length(max_level); + double dt = cfl * mesh.cell_length(mesh.max_level()); const double dt_save = Tf / static_cast(nfiles); if (!is_periodic) diff --git a/demos/FiniteVolume/advection_2d.cpp b/demos/FiniteVolume/advection_2d.cpp index 7066e7119..51bec0295 100644 --- a/demos/FiniteVolume/advection_2d.cpp +++ b/demos/FiniteVolume/advection_2d.cpp @@ -92,8 +92,6 @@ int main(int argc, char* argv[]) app.add_option("--Ti", t, "Initial time")->capture_default_str()->group("Simulation parameters"); app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_option("--nfiles", nfiles, "Number of output files")->capture_default_str()->group("Output"); @@ -101,12 +99,13 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box(min_corner, max_corner); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); samurai::MRMesh mesh; auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { - mesh = {box, min_level, max_level}; + mesh = {config, box}; init(u); } else @@ -115,7 +114,7 @@ int main(int argc, char* argv[]) } samurai::make_bc>(u, 0.); - double dt = cfl * mesh.cell_length(max_level); + double dt = cfl * mesh.cell_length(mesh.max_level()); const double dt_save = Tf / static_cast(nfiles); auto unp1 = samurai::make_scalar_field("unp1", mesh); diff --git a/demos/FiniteVolume/advection_2d_user_bc.cpp b/demos/FiniteVolume/advection_2d_user_bc.cpp index ac4d5e163..11fefe75d 100644 --- a/demos/FiniteVolume/advection_2d_user_bc.cpp +++ b/demos/FiniteVolume/advection_2d_user_bc.cpp @@ -124,8 +124,6 @@ int main(int argc, char* argv[]) app.add_option("--Ti", t, "Initial time")->capture_default_str()->group("Simulation parameters"); app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_option("--nfiles", nfiles, "Number of output files")->capture_default_str()->group("Output"); @@ -133,12 +131,13 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box(min_corner, max_corner); - samurai::MRMesh mesh; + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + samurai::MRMesh mesh{config, box}; auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { - mesh = {box, min_level, max_level}; + mesh = {config, box}; init(u); } else @@ -147,7 +146,7 @@ int main(int argc, char* argv[]) } samurai::make_bc(u, 0.); - double dt = cfl * mesh.cell_length(max_level); + double dt = cfl * mesh.cell_length(mesh.max_level()); const double dt_save = Tf / static_cast(nfiles); auto unp1 = samurai::make_scalar_field("unp1", mesh); diff --git a/demos/FiniteVolume/burgers_mra.cpp b/demos/FiniteVolume/burgers_mra.cpp index ea6e74dbe..e5b6455e9 100644 --- a/demos/FiniteVolume/burgers_mra.cpp +++ b/demos/FiniteVolume/burgers_mra.cpp @@ -226,7 +226,7 @@ void run_simulation(Field& u, int main(int argc, char* argv[]) { constexpr std::size_t dim = 1; - using Config = samurai::MRConfig; + using Config = samurai::MRConfig; using Box = samurai::Box; auto& app = samurai::initialize("Finite volume example for the Burgers equation in 1d", argc, argv); @@ -256,8 +256,6 @@ int main(int argc, char* argv[]) app.add_option("--init-sol", init_sol, "Initial solution: hat/gaussian")->capture_default_str()->group("Simulation parameters"); app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Ouput"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Ouput"); app.add_option("--nfiles", nfiles, "Number of output files")->capture_default_str()->group("Ouput"); @@ -270,8 +268,11 @@ int main(int argc, char* argv[]) //--------------------// Box box({left_box}, {right_box}); - samurai::MRMesh mesh{box, min_level, max_level}; - samurai::MRMesh max_level_mesh{box, max_level, max_level}; + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_radius(2).graduation_width(2); + samurai::MRMesh mesh{config, box}; + // samurai::MRMesh mesh{box, min_level, max_level}; + auto max_level_config = samurai::mesh_config().min_level(max_level).max_level(max_level).max_stencil_radius(2); + samurai::MRMesh max_level_mesh{max_level_config, box}; auto u = samurai::make_scalar_field("u", mesh); auto unp1 = samurai::make_scalar_field("unp1", mesh); diff --git a/demos/FiniteVolume/lid_driven_cavity.cpp b/demos/FiniteVolume/lid_driven_cavity.cpp index 004cdde63..9c25cdc51 100644 --- a/demos/FiniteVolume/lid_driven_cavity.cpp +++ b/demos/FiniteVolume/lid_driven_cavity.cpp @@ -128,8 +128,6 @@ int main(int argc, char* argv[]) app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--dt", dt, "Time step")->capture_default_str()->group("Simulation parameters"); app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--nfiles", nfiles, "Number of output files")->capture_default_str()->group("Output"); @@ -158,7 +156,8 @@ int main(int argc, char* argv[]) // where v = velocity // p = pressure - auto mesh = Mesh(box, min_level, max_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_radius(2); + auto mesh = Mesh(config, box); // Fields for the Navier-Stokes equations auto velocity = samurai::make_vector_field("velocity", mesh); @@ -235,7 +234,8 @@ int main(int argc, char* argv[]) // d(i)/dt + conv(i) = 0, where conv(i) = v.grad(i). // 2nd mesh - auto mesh2 = Mesh2(box, 1, max_level); + auto config2 = samurai::mesh_config().min_level(1).max_level(mesh.max_level()).max_stencil_size(4).disable_args_parse(); + auto mesh2 = Mesh2(config2, box); // Ink data fields auto ink = samurai::make_scalar_field("ink", mesh2); diff --git a/demos/FiniteVolume/linear_convection.cpp b/demos/FiniteVolume/linear_convection.cpp index 80580038f..41d8a5fe5 100644 --- a/demos/FiniteVolume/linear_convection.cpp +++ b/demos/FiniteVolume/linear_convection.cpp @@ -59,10 +59,6 @@ int main(int argc, char* argv[]) double t = 0.; std::string restart_file; - // Multiresolution parameters - std::size_t min_level = 1; - std::size_t max_level = dim == 1 ? 6 : 4; - // Output parameters fs::path path = fs::current_path(); std::string filename = "linear_convection_" + std::to_string(dim) + "D"; @@ -98,7 +94,7 @@ int main(int argc, char* argv[]) if (restart_file.empty()) { - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).periodic(periodic); + auto config = samurai::mesh_config().min_level(1).max_level(dim == 1 ? 6 : 4).periodic(periodic).max_stencil_radius(3); mesh = {config, box}; // Initial solution u = samurai::make_scalar_field("u", diff --git a/include/samurai/algorithm/graduation.hpp b/include/samurai/algorithm/graduation.hpp index 1827820f1..72860d31d 100644 --- a/include/samurai/algorithm/graduation.hpp +++ b/include/samurai/algorithm/graduation.hpp @@ -321,13 +321,13 @@ namespace samurai template void list_interval_to_refine_for_contiguous_boundary_cells( - const size_t half_stencil_width, + const int max_stencil_radius, const CellArray& ca, const LevelCellArray& domain, const std::array& is_periodic, std::array, CellArray::max_size>& out) { - if (half_stencil_width == 1) + if (max_stencil_radius == 1) { return; } @@ -348,13 +348,13 @@ namespace samurai // Case where the boundary is at level L and the jump is going down to L-1: // We want to have enough contiguous boundary cells to ensure that the stencil at the lower level // won't go outside the domain. - // To ensure half_stencil_width at L-1, we need 2*half_stencil_width at level L. + // To ensure max_stencil_radius at L-1, we need 2*max_stencil_radius at level L. // However, since we project the B.C. in the first outside ghost at level L-1, we can reduce the number of - // contiguous cells by 1 at level L-1. This makes, at level L, 2*(half_stencil_width - 2) contiguous cells. - // (One cell is a real cell, the other is a ghost cell outside of the domain, which makes half_stencil_width - 2 + // contiguous cells by 1 at level L-1. This makes, at level L, 2*(max_stencil_radius - 2) contiguous cells. + // (One cell is a real cell, the other is a ghost cell outside of the domain, which makes max_stencil_radius - 2 // ghosts cells inside the domain). - int n_contiguous_boundary_cells = std::max(int(half_stencil_width), 2 * (int(half_stencil_width) - 2)); + int n_contiguous_boundary_cells = std::max(max_stencil_radius, 2 * (max_stencil_radius - 2)); if (n_contiguous_boundary_cells > 1) { @@ -382,16 +382,16 @@ namespace samurai // 2. Jump level --> level+1 // Case where the boundary is at level L and jump is going up: - // If the number of boundary contiguous cells is >= ceil(half_stencil_width/2), then there is nothing to do, - // since the half stencil at L+1 will not go out of the domain. Here, we just test if half_stencil_width > 2 by + // If the number of boundary contiguous cells is >= ceil(max_stencil_radius/2), then there is nothing to do, + // since the half stencil at L+1 will not go out of the domain. Here, we just test if max_stencil_radius > 2 by // simplicity, but at some point it would be nice to implement the real test. Otherwise, ensuring - // half_stencil_width contiguous cells at level L+1 is enough. - if (half_stencil_width > 2) + // max_stencil_radius contiguous cells at level L+1 is enough. + if (max_stencil_radius > 2) { for (size_t level = max_level - 1; level != min_level - 1; --level) { auto boundaryCells = difference(ca[level], translate(self(domain).on(level), -translation)); - for (size_t i = 1; i != half_stencil_width; ++i) + for (int i = 1; i != max_stencil_radius; ++i) { auto refine_subset = translate( intersection(translate(boundaryCells, -i * translation), ca[level + 1]).on(level), @@ -410,8 +410,8 @@ namespace samurai } template - void list_intervals_to_refine(const size_t grad_width, - const size_t half_stencil_width, + void list_intervals_to_refine(const std::size_t grad_width, + const int max_stencil_radius, const CellArray& ca, const LevelCellArray& domain, [[maybe_unused]] const std::vector>& mpi_neighbourhood, @@ -422,7 +422,7 @@ namespace samurai list_interval_to_refine_for_graduation(grad_width, ca, domain, mpi_neighbourhood, is_periodic, nb_cells_finest_level, out); if (!domain.empty()) { - list_interval_to_refine_for_contiguous_boundary_cells(half_stencil_width, ca, domain, is_periodic, out); + list_interval_to_refine_for_contiguous_boundary_cells(max_stencil_radius, ca, domain, is_periodic, out); } } @@ -486,8 +486,8 @@ namespace samurai const LevelCellArray& domain, [[maybe_unused]] const std::vector>& mpi_neighbourhood, const std::array& is_periodic, - const size_t grad_width = 1, - const size_t half_stencil_width = 1 // half of width of the numerical scheme's stencil. + const size_t grad_width = 1, + const int max_stencil_radius = 1 // half of width of the numerical scheme's stencil. ) { using ca_type = CellArray; @@ -537,7 +537,7 @@ namespace samurai // Then, if the non-graduated is not tagged as keep, we coarsen it ca_add_p.clear(); ca_remove_p.clear(); - list_intervals_to_refine(grad_width, half_stencil_width, ca, domain, mpi_neighbourhood, is_periodic, nb_cells_finest_level, remove_m_all); + list_intervals_to_refine(grad_width, max_stencil_radius, ca, domain, mpi_neighbourhood, is_periodic, nb_cells_finest_level, remove_m_all); add_p_interval.clear(); add_p_inner_stencil.clear(); diff --git a/include/samurai/algorithm/update.hpp b/include/samurai/algorithm/update.hpp index bd9c95823..bb8ef3fbc 100644 --- a/include/samurai/algorithm/update.hpp +++ b/include/samurai/algorithm/update.hpp @@ -102,10 +102,18 @@ namespace samurai { using mesh_id_t = typename Field::mesh_t::mesh_id_t; - assert(layer > 0 && layer <= Field::mesh_t::config::max_stencil_width); + // assert(layer > 0 && layer <= Field::mesh_t::config::max_stencil_width); auto& mesh = field.mesh(); +#ifndef NDEBUG + if (!(layer > 0 && layer <= mesh.max_stencil_radius())) + { + std::cerr << " " << std::endl; + exit(EXIT_FAILURE); + } +#endif + auto domain = self(mesh.domain()).on(proj_level); auto& inner = mesh.get_union()[proj_level]; @@ -125,7 +133,7 @@ namespace samurai // We don't want to fill by projection the ghosts that have been/will be filled by the B.C. in other directions. // This can happen when there is a hole in the domain. - std::size_t n_bc_ghosts = Field::mesh_t::config::max_stencil_width; + int n_bc_ghosts = mesh.max_stencil_radius(); if (!field.get_bc().empty()) { n_bc_ghosts = field.get_bc().front()->stencil_size() / 2; @@ -278,7 +286,7 @@ namespace samurai auto& mesh = field.mesh(); - std::size_t n_bc_ghosts = Field::mesh_t::config::max_stencil_width; + int n_bc_ghosts = mesh.max_stencil_radius(); if (!field.get_bc().empty()) { n_bc_ghosts = field.get_bc().front()->stencil_size() / 2; @@ -432,12 +440,12 @@ namespace samurai // - the B.C. is projected onto the lower ghosts // - those lower ghosts are projected onto the even lower ghosts - std::size_t n_bc_ghosts = Field::mesh_t::config::max_stencil_width; + int n_bc_ghosts = mesh.max_stencil_radius(); if (!field.get_bc().empty()) { - n_bc_ghosts = field.get_bc().front()->stencil_size() / 2; + n_bc_ghosts = static_cast(field.get_bc().front()->stencil_size()) / 2; } - int max_coarse_layer = static_cast(n_bc_ghosts % 2 == 0 ? n_bc_ghosts / 2 : (n_bc_ghosts + 1) / 2); + int max_coarse_layer = n_bc_ghosts % 2 == 0 ? n_bc_ghosts / 2 : (n_bc_ghosts + 1) / 2; for (int layer = 1; layer <= max_coarse_layer; ++layer) { project_bc(level, direction, layer, field); // project from level+1 to level @@ -954,7 +962,6 @@ namespace samurai using field_value_t = typename Field::value_type; #endif using mesh_id_t = typename Field::mesh_t::mesh_id_t; - using config = typename Field::mesh_t::config; using lca_type = typename Field::mesh_t::lca_type; using interval_value_t = typename Field::interval_t::value_t; using box_t = Box; @@ -977,8 +984,8 @@ namespace samurai for (std::size_t d = 0; d < dim; ++d) { - min_corner[d] = (min_indices[d] >> delta_l) - config::ghost_width; - max_corner[d] = (max_indices[d] >> delta_l) + config::ghost_width; + min_corner[d] = (min_indices[d] >> delta_l) - mesh.ghost_width(); + max_corner[d] = (max_indices[d] >> delta_l) + mesh.ghost_width(); shift[d] = 0; } #ifdef SAMURAI_WITH_MPI @@ -997,23 +1004,23 @@ namespace samurai const auto shift_interval = shift[0]; const auto shift_index = xt::view(shift, xt::range(1, _)); - min_corner[d] = (min_indices[d] >> delta_l) - config::ghost_width; + min_corner[d] = (min_indices[d] >> delta_l) - mesh.ghost_width(); max_corner[d] = (min_indices[d] >> delta_l); lca_type lca_min_m(level, box_t(min_corner, max_corner)); - min_corner[d] = (max_indices[d] >> delta_l) - config::ghost_width; + min_corner[d] = (max_indices[d] >> delta_l) - mesh.ghost_width(); max_corner[d] = (max_indices[d] >> delta_l); lca_type lca_max_m(level, box_t(min_corner, max_corner)); min_corner[d] = (min_indices[d] >> delta_l); - max_corner[d] = (min_indices[d] >> delta_l) + config::ghost_width; + max_corner[d] = (min_indices[d] >> delta_l) + mesh.ghost_width(); lca_type lca_min_p(level, box_t(min_corner, max_corner)); min_corner[d] = (max_indices[d] >> delta_l); - max_corner[d] = (max_indices[d] >> delta_l) + config::ghost_width; + max_corner[d] = (max_indices[d] >> delta_l) + mesh.ghost_width(); lca_type lca_max_p(level, box_t(min_corner, max_corner)); @@ -1084,8 +1091,8 @@ namespace samurai #endif // SAMURAI_WITH_MPI /* reset variables for next iterations. */ shift[d] = 0; - min_corner[d] = (min_indices[d] >> delta_l) - config::ghost_width; - max_corner[d] = (max_indices[d] >> delta_l) + config::ghost_width; + min_corner[d] = (min_indices[d] >> delta_l) - mesh.ghost_width(); + max_corner[d] = (max_indices[d] >> delta_l) + mesh.ghost_width(); } } } @@ -1125,7 +1132,6 @@ namespace samurai using tag_value_type = typename Tag::value_type; #endif using mesh_id_t = typename Tag::mesh_t::mesh_id_t; - using config = typename Tag::mesh_t::config; using lca_type = typename Tag::mesh_t::lca_type; using interval_value_t = typename Tag::interval_t::value_t; using box_t = Box; @@ -1147,8 +1153,8 @@ namespace samurai for (std::size_t d = 0; d < dim; ++d) { shift[d] = 0; - min_corner[d] = (min_indices[d] >> delta_l) - config::ghost_width; - max_corner[d] = (max_indices[d] >> delta_l) + config::ghost_width; + min_corner[d] = (min_indices[d] >> delta_l) - mesh.ghost_width(); + max_corner[d] = (max_indices[d] >> delta_l) + mesh.ghost_width(); } #ifdef SAMURAI_WITH_MPI using tag_value_type = typename Tag::value_type; @@ -1167,23 +1173,23 @@ namespace samurai const auto shift_interval = shift[0]; const auto shift_index = xt::view(shift, xt::range(1, _)); - min_corner[d] = (min_indices[d] >> delta_l) - config::ghost_width; + min_corner[d] = (min_indices[d] >> delta_l) - mesh.ghost_width(); max_corner[d] = (min_indices[d] >> delta_l); lca_type lca_min_m(level, box_t(min_corner, max_corner)); - min_corner[d] = (max_indices[d] >> delta_l) - config::ghost_width; + min_corner[d] = (max_indices[d] >> delta_l) - mesh.ghost_width(); max_corner[d] = (max_indices[d] >> delta_l); lca_type lca_max_m(level, box_t(min_corner, max_corner)); min_corner[d] = (min_indices[d] >> delta_l); - max_corner[d] = (min_indices[d] >> delta_l) + config::ghost_width; + max_corner[d] = (min_indices[d] >> delta_l) + mesh.ghost_width(); lca_type lca_min_p(level, box_t(min_corner, max_corner)); min_corner[d] = (max_indices[d] >> delta_l); - max_corner[d] = (max_indices[d] >> delta_l) + config::ghost_width; + max_corner[d] = (max_indices[d] >> delta_l) + mesh.ghost_width(); lca_type lca_max_p(level, box_t(min_corner, max_corner)); @@ -1313,8 +1319,8 @@ namespace samurai #endif // SAMURAI_WITH_MPI /* reset variables for next iterations. */ shift[d] = 0; - min_corner[d] = (min_indices[d] >> delta_l) - config::ghost_width; - max_corner[d] = (max_indices[d] >> delta_l) + config::ghost_width; + min_corner[d] = (min_indices[d] >> delta_l) - mesh.ghost_width(); + max_corner[d] = (max_indices[d] >> delta_l) + mesh.ghost_width(); } } } diff --git a/include/samurai/arguments.hpp b/include/samurai/arguments.hpp index 997b59ad5..c662011a2 100644 --- a/include/samurai/arguments.hpp +++ b/include/samurai/arguments.hpp @@ -12,6 +12,7 @@ namespace samurai static std::size_t min_level = std::numeric_limits::max(); static std::size_t max_level = std::numeric_limits::max(); static std::size_t graduation_width = std::numeric_limits::max(); + static int max_stencil_radius = std::numeric_limits::max(); static bool timers = false; #ifdef SAMURAI_WITH_MPI @@ -32,6 +33,8 @@ namespace samurai app.add_option("--min-level", args::min_level, "The minimum level of the mesh")->group("SAMURAI"); app.add_option("--max-level", args::max_level, "The maximum level of the mesh")->group("SAMURAI"); app.add_option("--graduation-width", args::graduation_width, "The graduation width of the mesh")->group("SAMURAI"); + // app.add_option("--graduation-width", args::graduation_width, "The graduation width of the mesh")->group("SAMURAI"); + app.add_option("--max-stencil-radius", args::max_stencil_radius, "The maximum number of neighbour in each direction")->group("SAMURAI"); #ifdef SAMURAI_WITH_MPI app.add_flag("--dont-redirect-output", args::dont_redirect_output, "Redirect the output for all ranks different of 0") diff --git a/include/samurai/bc/apply_field_bc.hpp b/include/samurai/bc/apply_field_bc.hpp index 37d9689eb..4e634b295 100644 --- a/include/samurai/bc/apply_field_bc.hpp +++ b/include/samurai/bc/apply_field_bc.hpp @@ -366,25 +366,26 @@ namespace samurai template void update_further_ghosts_by_polynomial_extrapolation(std::size_t level, const DirectionVector& direction, Field& field) { - static constexpr std::size_t ghost_width = Field::mesh_t::config::ghost_width; + int ghost_width = field.mesh().ghost_width(); static constexpr std::size_t max_stencil_size_implemented_PE = PolynomialExtrapolation::max_stencil_size_implemented_PE; // 1. We fill the ghosts that are further than those filled by the B.C. (where there are boundary cells) - std::size_t ghost_layers_filled_by_bc = 0; + int ghost_layers_filled_by_bc = 0; for (auto& bc : field.get_bc()) { ghost_layers_filled_by_bc = std::max(ghost_layers_filled_by_bc, bc->stencil_size() / 2); } // We populate the ghosts sequentially from the closest to the farthest. - for (std::size_t ghost_layer = ghost_layers_filled_by_bc + 1; ghost_layer <= ghost_width; ++ghost_layer) + for (int ghost_layer = ghost_layers_filled_by_bc + 1; ghost_layer <= ghost_width; ++ghost_layer) { - std::size_t stencil_s = 2 * ghost_layer; - static_for<2, std::min(max_stencil_size_implemented_PE, 2 * ghost_width) + 1>::apply( - [&](auto integral_constant_i) + int stencil_s = 2 * ghost_layer; + // static_for<2, std::min(max_stencil_size_implemented_PE, 2 * ghost_width) + 1>::apply( + static_for<2, max_stencil_size_implemented_PE + 1>::apply( + [&](auto stencil_size_) { - static constexpr std::size_t stencil_size = integral_constant_i(); + static constexpr int stencil_size = static_cast(stencil_size_()); if constexpr (stencil_size % 2 == 0) // (because PolynomialExtrapolation is only implemented for even stencil_size) { @@ -405,13 +406,14 @@ namespace samurai const std::size_t ghost_layers_filled_by_projection_bc = 1; - for (std::size_t ghost_layer = ghost_layers_filled_by_projection_bc + 1; ghost_layer <= ghost_width; ++ghost_layer) + for (int ghost_layer = ghost_layers_filled_by_projection_bc + 1; ghost_layer <= ghost_width; ++ghost_layer) { - std::size_t stencil_s = 2 * ghost_layer; - static_for<2, std::min(max_stencil_size_implemented_PE, 2 * ghost_width) + 1>::apply( - [&](auto integral_constant_i) + int stencil_s = 2 * ghost_layer; + // static_for<2, std::min(max_stencil_size_implemented_PE, 2 * ghost_width) + 1>::apply( + static_for<2, max_stencil_size_implemented_PE + 1>::apply( + [&](auto stencil_size_) { - static constexpr std::size_t stencil_size = integral_constant_i(); + static constexpr int stencil_size = static_cast(stencil_size_()); if constexpr (stencil_size % 2 == 0) // (because PolynomialExtrapolation is only implemented for even stencil_size) { diff --git a/include/samurai/bc/bc.hpp b/include/samurai/bc/bc.hpp index 7eb9d56f0..97247aeeb 100644 --- a/include/samurai/bc/bc.hpp +++ b/include/samurai/bc/bc.hpp @@ -31,32 +31,31 @@ return line_stencil(); \ } -#define INIT_BC(NAME, STENCIL_SIZE) \ - using base_t = samurai::Bc; \ - using cell_t = typename base_t::cell_t; \ - using value_t = typename base_t::value_t; \ - using direction_t = typename base_t::direction_t; \ - using base_t::base_t; \ - using base_t::dim; \ - using base_t::get_apply_function; \ - using base_t::get_stencil; \ - \ - using stencil_t = samurai::Stencil; \ - using constant_stencil_size_t = std::integral_constant; \ - using stencil_cells_t = std::array; \ - using apply_function_t = std::function&, const value_t&)>; \ - \ - static_assert(STENCIL_SIZE <= base_t::max_stencil_size_implemented, "The stencil size is too large."); \ - static_assert(Field::mesh_t::config::ghost_width >= STENCIL_SIZE / 2, "Not enough ghost layers for this boundary condition."); \ - \ - std::unique_ptr clone() const override \ - { \ - return std::make_unique(*this); \ - } \ - \ - std::size_t stencil_size() const override \ - { \ - return STENCIL_SIZE; \ +#define INIT_BC(NAME, STENCIL_SIZE) \ + using base_t = samurai::Bc; \ + using cell_t = typename base_t::cell_t; \ + using value_t = typename base_t::value_t; \ + using direction_t = typename base_t::direction_t; \ + using base_t::base_t; \ + using base_t::dim; \ + using base_t::get_apply_function; \ + using base_t::get_stencil; \ + \ + using stencil_t = samurai::Stencil; \ + using constant_stencil_size_t = std::integral_constant; \ + using stencil_cells_t = std::array; \ + using apply_function_t = std::function&, const value_t&)>; \ + \ + static_assert(STENCIL_SIZE <= base_t::max_stencil_size_implemented, "The stencil size is too large."); \ + \ + std::unique_ptr clone() const override \ + { \ + return std::make_unique(*this); \ + } \ + \ + int stencil_size() const override \ + { \ + return STENCIL_SIZE; \ } namespace samurai @@ -592,9 +591,9 @@ namespace samurai Bc& operator=(Bc&& bc) noexcept = default; virtual std::unique_ptr clone() const = 0; - virtual std::size_t stencil_size() const = 0; + virtual int stencil_size() const = 0; - static constexpr std::size_t max_stencil_size_implemented = 10; // cppcheck-suppress unusedStructMember + static constexpr int max_stencil_size_implemented = 10; // cppcheck-suppress unusedStructMember APPLY_AND_STENCIL_FUNCTIONS(1) APPLY_AND_STENCIL_FUNCTIONS(2) APPLY_AND_STENCIL_FUNCTIONS(3) diff --git a/include/samurai/boundary.hpp b/include/samurai/boundary.hpp index ac505f65e..8977c27ed 100644 --- a/include/samurai/boundary.hpp +++ b/include/samurai/boundary.hpp @@ -49,7 +49,7 @@ namespace samurai } template - auto domain_boundary_outer_layer(const Mesh& mesh, std::size_t level, std::size_t layer_width) + auto domain_boundary_outer_layer(const Mesh& mesh, std::size_t level, int layer_width) { using lca_t = typename Mesh::lca_type; using lcl_t = typename Mesh::lcl_type; @@ -62,7 +62,7 @@ namespace samurai [&](const auto& direction) { auto inner_boundary = domain_boundary(mesh, level, direction); - for (std::size_t layer = 1; layer <= layer_width; ++layer) + for (int layer = 1; layer <= layer_width; ++layer) { auto outer_layer = difference(translate(inner_boundary, layer * direction), domain); outer_layer( @@ -76,8 +76,7 @@ namespace samurai } template - auto - domain_boundary_outer_layer(const Mesh& mesh, std::size_t level, const DirectionVector& direction, std::size_t layer_width) + auto domain_boundary_outer_layer(const Mesh& mesh, std::size_t level, const DirectionVector& direction, int layer_width) { using lca_t = typename Mesh::lca_type; using lcl_t = typename Mesh::lcl_type; @@ -87,7 +86,7 @@ namespace samurai lcl_t outer_boundary_lcl(level, mesh.origin_point(), mesh.scaling_factor()); auto inner_boundary = domain_boundary(mesh, level, direction); - for (std::size_t layer = 1; layer <= layer_width; ++layer) + for (int layer = 1; layer <= layer_width; ++layer) { auto outer_layer = difference(translate(inner_boundary, layer * direction), domain); outer_layer( diff --git a/include/samurai/field.hpp b/include/samurai/field.hpp index 1f037057f..340b8dc48 100644 --- a/include/samurai/field.hpp +++ b/include/samurai/field.hpp @@ -702,6 +702,14 @@ namespace samurai template inline auto VectorField::attach_bc(const Bc_derived& bc) { + if (bc.stencil_size() > this->mesh().cfg().max_stencil_size()) + { + std::cerr << "The stencil size required by this boundary condition (" << bc.stencil_size() + << ") is larger than the max_stencil_size parameter of the mesh (" << this->mesh().cfg().max_stencil_size() + << ").\nYou can set it with mesh_config.max_stencil_radius(" << bc.stencil_size() / 2 + << ") or mesh_config.max_stencil_size(" << bc.stencil_size() << ")." << std::endl; + exit(EXIT_FAILURE); + } p_bc.push_back(bc.clone()); return p_bc.back().get(); } @@ -1331,6 +1339,14 @@ namespace samurai template inline auto ScalarField::attach_bc(const Bc_derived& bc) { + if (bc.stencil_size() > this->mesh().cfg().max_stencil_size()) + { + std::cerr << "The stencil size required by this boundary condition (" << bc.stencil_size() + << ") is larger than the max_stencil_size parameter of the mesh (" << this->mesh().cfg().max_stencil_size() + << ").\nYou can set it with mesh_config.max_stencil_radius(" << bc.stencil_size() / 2 + << ") or mesh_config.max_stencil_size(" << bc.stencil_size() << ")." << std::endl; + exit(EXIT_FAILURE); + } p_bc.push_back(bc.clone()); return p_bc.back().get(); } diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 58c96f2dd..331201a81 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -100,6 +100,9 @@ namespace samurai std::size_t& min_level(); std::size_t graduation_width() const; + int ghost_width() const; + int max_stencil_radius() const; + auto& cfg() const; auto& origin_point() const; void set_origin_point(const coords_t& origin_point); @@ -107,6 +110,7 @@ namespace samurai void set_scaling_factor(double scaling_factor); void scale_domain(double domain_scaling_factor); double cell_length(std::size_t level) const; + double min_cell_length() const; const lca_type& domain() const; const lca_type& subdomain() const; const ca_type& get_union() const; @@ -684,6 +688,24 @@ namespace samurai return m_config.graduation_width(); } + template + inline int Mesh_base::ghost_width() const + { + return m_config.ghost_width(); + } + + template + inline int Mesh_base::max_stencil_radius() const + { + return m_config.max_stencil_radius(); + } + + template + inline auto& Mesh_base::cfg() const + { + return m_config; + } + template inline auto& Mesh_base::origin_point() const { @@ -732,6 +754,12 @@ namespace samurai return samurai::cell_length(scaling_factor(), level); } + template + inline double Mesh_base::min_cell_length() const + { + return cell_length(max_level()); + } + template inline auto Mesh_base::domain() const -> const lca_type& { diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index b7d6f9ec3..bea749234 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -9,27 +9,53 @@ namespace samurai { - template + template class mesh_config { public: - static constexpr std::size_t dim = dim_; + static constexpr std::size_t dim = dim_; + static constexpr std::size_t prediction_stencil_radius = prediction_stencil_radius_; mesh_config() { m_periodic.fill(false); } - auto& max_stencil_width(std::size_t stencil_width) + auto& max_stencil_radius(int stencil_radius) { - m_max_stencil_width = stencil_width; + m_max_stencil_radius = stencil_radius; return *this; } - auto& max_stencil_width() const + auto& max_stencil_radius() { - return m_max_stencil_width; + return m_max_stencil_radius; + } + + auto& max_stencil_radius() const + { + return m_max_stencil_radius; + } + + auto& max_stencil_size(int stencil_size) + { + m_max_stencil_radius = stencil_size / 2; + if (stencil_size % 2 == 1) + { + m_max_stencil_radius += 1; + } + return *this; + } + + auto max_stencil_size() const + { + return m_max_stencil_radius * 2; + } + + auto ghost_width() const + { + return m_ghost_width; } auto& graduation_width(std::size_t grad_width) @@ -119,12 +145,22 @@ namespace samurai return m_periodic[i]; } + auto& disable_args_parse() + { + m_disable_args_parse = false; + return *this; + } + void parse_args() { - // if (args::max_stencil_width != std::numeric_limits::max()) - // { - // m_max_stencil_width = args::max_stencil_width; - // } + if (m_disable_args_parse) + { + return; + } + if (args::max_stencil_radius != std::numeric_limits::max()) + { + m_max_stencil_radius = args::max_stencil_radius; + } if (args::graduation_width != std::numeric_limits::max()) { m_graduation_width = args::graduation_width; @@ -150,12 +186,15 @@ namespace samurai std::cerr << "Max level must be greater than min level." << std::endl; exit(EXIT_FAILURE); } + + m_ghost_width = std::max(static_cast(m_max_stencil_radius), static_cast(prediction_stencil_radius)); } private: - std::size_t m_max_stencil_width = 1; - std::size_t m_graduation_width = 1; + int m_max_stencil_radius = 1; + std::size_t m_graduation_width = 1; + int m_ghost_width = 1; std::size_t m_min_level; std::size_t m_max_level; @@ -164,5 +203,7 @@ namespace samurai double m_scaling_factor = 0; std::array m_periodic; + + bool m_disable_args_parse = false; }; } diff --git a/include/samurai/mr/adapt.hpp b/include/samurai/mr/adapt.hpp index 6b99bff53..b8af6fd37 100644 --- a/include/samurai/mr/adapt.hpp +++ b/include/samurai/mr/adapt.hpp @@ -220,7 +220,7 @@ namespace samurai { // Since the adaptation process starts at max_level, we just need to flag to `keep` the boundary cells at max_level only. // There will never be boundary cells at lower levels. - auto bdry = domain_boundary_layer(mesh, mesh.max_level(), direction, Mesh::config::max_stencil_width); + auto bdry = domain_boundary_layer(mesh, mesh.max_level(), direction, static_cast(mesh.max_stencil_radius())); for_each_cell(mesh, bdry, [&](auto& cell) @@ -380,12 +380,7 @@ namespace samurai using ca_type = typename mesh_t::ca_type; ca_type new_ca = update_cell_array_from_tag(mesh[mesh_id_t::cells], m_tag); - make_graduation(new_ca, - mesh.domain(), - mesh.mpi_neighbourhood(), - mesh.periodicity(), - mesh.graduation_width(), - mesh_t::config::max_stencil_width); + make_graduation(new_ca, mesh.domain(), mesh.mpi_neighbourhood(), mesh.periodicity(), mesh.graduation_width(), mesh.max_stencil_radius()); mesh_t new_mesh{new_ca, mesh}; #ifdef SAMURAI_WITH_MPI mpi::communicator world; diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 020d42d14..33c640ef7 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -40,7 +40,7 @@ namespace samurai { static constexpr std::size_t dim = dim_; static constexpr std::size_t max_refinement_level = max_refinement_level_; - static constexpr int max_stencil_width = max_stencil_width_; + // static constexpr int max_stencil_width = max_stencil_width_; // static constexpr std::size_t graduation_width = graduation_width_; static constexpr int prediction_order = prediction_order_; @@ -48,9 +48,9 @@ namespace samurai // static_cast(graduation_width) - 1, // static_cast(max_stencil_width)), // static_cast(prediction_order)); - static constexpr int ghost_width = std::max(static_cast(max_stencil_width), static_cast(prediction_order)); - using interval_t = TInterval; - using mesh_id_t = MRMeshId; + // static constexpr int ghost_width = std::max(static_cast(max_stencil_width_), static_cast(prediction_order)); + using interval_t = TInterval; + using mesh_id_t = MRMeshId; }; template @@ -72,6 +72,9 @@ namespace samurai using ca_type = typename base_type::ca_type; using lca_type = typename base_type::lca_type; + using base_type::ghost_width; + using base_type::max_stencil_radius; + MRMesh() = default; MRMesh(const ca_type& ca, const self_type& ref_mesh); MRMesh(const cl_type& cl, const self_type& ref_mesh); @@ -200,18 +203,19 @@ 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}); - }); - }); + 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( + -max_stencil_radius(), + max_stencil_radius() + 1, + [&](auto stencil) + { + auto index = xt::eval(index_yz + stencil); + lcl[index].add_interval({interval.start - max_stencil_radius(), interval.end + max_stencil_radius()}); + }); + }); this->cells()[mesh_id_t::cells_and_ghosts] = {cell_list, false}; // Add cells for the MRA @@ -327,8 +331,8 @@ namespace samurai box_t box; for (std::size_t d = 0; d < dim; ++d) { - box.min_corner()[d] = (neighbor_min_indices[d] >> delta_l) - config::ghost_width; - box.max_corner()[d] = (neighbor_max_indices[d] >> delta_l) + config::ghost_width; + box.min_corner()[d] = (neighbor_min_indices[d] >> delta_l) - ghost_width(); + box.max_corner()[d] = (neighbor_max_indices[d] >> delta_l) + ghost_width(); } neighbourhood_extended_subdomain[neighbor_id][level] = {level, box}; } @@ -343,8 +347,8 @@ namespace samurai for (std::size_t d = 0; d < dim; ++d) { - min_corner[d] = (subdomain_min_indices[d] >> delta_l) - config::ghost_width; - max_corner[d] = (subdomain_max_indices[d] >> delta_l) + config::ghost_width; + min_corner[d] = (subdomain_min_indices[d] >> delta_l) - ghost_width(); + max_corner[d] = (subdomain_max_indices[d] >> delta_l) + ghost_width(); } lca_type lca_extended_subdomain(level, box_t(min_corner, max_corner)); for (std::size_t d = 0; d < dim; ++d) @@ -353,13 +357,13 @@ namespace samurai { shift[d] = (domain_max_indices[d] - domain_min_indices[d]) >> delta_l; - min_corner[d] = (domain_min_indices[d] >> delta_l) - config::ghost_width; - max_corner[d] = (domain_min_indices[d] >> delta_l) + config::ghost_width; + min_corner[d] = (domain_min_indices[d] >> delta_l) - ghost_width(); + max_corner[d] = (domain_min_indices[d] >> delta_l) + ghost_width(); lca_type lca_min(level, box_t(min_corner, max_corner)); - min_corner[d] = (domain_max_indices[d] >> delta_l) - config::ghost_width; - max_corner[d] = (domain_max_indices[d] >> delta_l) + config::ghost_width; + min_corner[d] = (domain_max_indices[d] >> delta_l) - ghost_width(); + max_corner[d] = (domain_max_indices[d] >> delta_l) + ghost_width(); lca_type lca_max(level, box_t(min_corner, max_corner)); @@ -404,8 +408,8 @@ namespace samurai /* reset variables for next iterations. */ shift[d] = 0; - min_corner[d] = (subdomain_min_indices[d] >> delta_l) - config::ghost_width; - max_corner[d] = (subdomain_max_indices[d] >> delta_l) + config::ghost_width; + min_corner[d] = (subdomain_min_indices[d] >> delta_l) - ghost_width(); + max_corner[d] = (subdomain_max_indices[d] >> delta_l) + ghost_width(); } } } @@ -435,7 +439,7 @@ namespace samurai { for (std::size_t level = 0; level <= this->max_level(); ++level) { - auto expr = intersection(nestedExpand(self(this->subdomain()).on(level), config::ghost_width), + auto expr = intersection(nestedExpand(self(this->subdomain()).on(level), ghost_width()), neighbour.mesh[mesh_id_t::reference][level]); expr( [&](const auto& interval, const auto& index_yz) @@ -448,7 +452,7 @@ namespace samurai if (this->is_periodic(d)) { auto domain_shift = get_periodic_shift(this->domain(), level, d); - auto expr_left = intersection(nestedExpand(self(this->subdomain()).on(level), config::ghost_width), + auto expr_left = intersection(nestedExpand(self(this->subdomain()).on(level), ghost_width()), translate(neighbour.mesh[mesh_id_t::reference][level], -domain_shift)); expr_left( [&](const auto& interval, const auto& index_yz) @@ -457,7 +461,7 @@ namespace samurai lcl[index_yz].add_interval(interval); }); - auto expr_right = intersection(nestedExpand(self(this->subdomain()).on(level), config::ghost_width), + auto expr_right = intersection(nestedExpand(self(this->subdomain()).on(level), ghost_width()), translate(neighbour.mesh[mesh_id_t::reference][level], domain_shift)); expr_right( [&](const auto& interval, const auto& index_yz) diff --git a/include/samurai/schemes/fv/explicit_FV_scheme.hpp b/include/samurai/schemes/fv/explicit_FV_scheme.hpp index 5b6b096f3..c61a69662 100644 --- a/include/samurai/schemes/fv/explicit_FV_scheme.hpp +++ b/include/samurai/schemes/fv/explicit_FV_scheme.hpp @@ -75,6 +75,18 @@ namespace samurai virtual void apply(output_field_t& output_field, input_field_t& input_field) { + static constexpr int scheme_stencil_size = static_cast(scheme_t::cfg_t::stencil_size); + int mesh_stencil_size = input_field.mesh().cfg().max_stencil_size(); + + if (scheme_stencil_size > mesh_stencil_size) + { + std::cerr << "The stencil size required by the scheme '" << scheme().name() << "' (" << scheme_stencil_size + << ") is larger than the max_stencil_size parameter of the mesh (" << mesh_stencil_size + << ").\nYou can set it with mesh_config.max_stencil_radius(" << scheme_stencil_size / 2 + << ") or mesh_config.max_stencil_size(" << scheme_stencil_size << ")." << std::endl; + exit(EXIT_FAILURE); + } + for (std::size_t d = 0; d < dim; ++d) { apply(d, output_field, input_field); diff --git a/include/samurai/schemes/fv/operators/convection_lin.hpp b/include/samurai/schemes/fv/operators/convection_lin.hpp index 8a414411f..67f9505ed 100644 --- a/include/samurai/schemes/fv/operators/convection_lin.hpp +++ b/include/samurai/schemes/fv/operators/convection_lin.hpp @@ -89,8 +89,6 @@ namespace samurai template auto make_convection_weno5(const VelocityVector& velocity) { - static_assert(Field::mesh_t::config::ghost_width >= 3, "WENO5 requires at least 3 ghosts."); - static constexpr std::size_t dim = Field::dim; static constexpr bool is_soa = detail::is_soa_v; static constexpr std::size_t stencil_size = 6; @@ -259,8 +257,6 @@ namespace samurai requires IsField auto make_convection_weno5(VelocityField& velocity_field) { - static_assert(Field::mesh_t::config::ghost_width >= 3, "WENO5 requires at least 3 ghosts."); - static constexpr std::size_t dim = Field::dim; static constexpr bool is_soa = detail::is_soa_v; diff --git a/include/samurai/schemes/fv/operators/convection_nonlin.hpp b/include/samurai/schemes/fv/operators/convection_nonlin.hpp index ca93c7a83..bb3c4b880 100644 --- a/include/samurai/schemes/fv/operators/convection_nonlin.hpp +++ b/include/samurai/schemes/fv/operators/convection_nonlin.hpp @@ -84,8 +84,6 @@ namespace samurai { using field_value_t = typename Field::value_type; - static_assert(Field::mesh_t::config::ghost_width >= 3, "WENO5 requires at least 3 ghosts."); - static constexpr std::size_t dim = Field::dim; static constexpr std::size_t stencil_size = 6; diff --git a/include/samurai/static_algorithm.hpp b/include/samurai/static_algorithm.hpp index d91a4f745..c948c1e31 100644 --- a/include/samurai/static_algorithm.hpp +++ b/include/samurai/static_algorithm.hpp @@ -188,6 +188,12 @@ namespace samurai detail::static_nested_loop_impl(start, end, step, std::forward(f), index, std::integral_constant{}); } + template + inline void static_nested_loop(int start, int end, Func&& f) + { + static_nested_loop(start, end, 1, std::forward(f)); + } + /** * constexpr power function */ From 55f3e61b62bc52307af87e8dfcd88d16136dab29 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 16 Sep 2025 16:22:57 +0200 Subject: [PATCH 07/60] fix lid_driven_cavity --- demos/FiniteVolume/lid_driven_cavity.cpp | 6 +++--- include/samurai/mr/mesh.hpp | 2 +- include/samurai/reconstruction.hpp | 14 ++++++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/demos/FiniteVolume/lid_driven_cavity.cpp b/demos/FiniteVolume/lid_driven_cavity.cpp index 9c25cdc51..fa782a7f4 100644 --- a/demos/FiniteVolume/lid_driven_cavity.cpp +++ b/demos/FiniteVolume/lid_driven_cavity.cpp @@ -96,11 +96,11 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Lid-driven cavity", argc, argv); constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; + using Config = samurai::MRConfig; using Mesh = samurai::MRMesh; using mesh_id_t = typename Mesh::mesh_id_t; - using Config2 = samurai::MRConfig; + using Config2 = samurai::MRConfig; using Mesh2 = samurai::MRMesh; static constexpr bool is_soa = false; @@ -234,7 +234,7 @@ int main(int argc, char* argv[]) // d(i)/dt + conv(i) = 0, where conv(i) = v.grad(i). // 2nd mesh - auto config2 = samurai::mesh_config().min_level(1).max_level(mesh.max_level()).max_stencil_size(4).disable_args_parse(); + auto config2 = samurai::mesh_config().min_level(1).max_level(mesh.max_level()).max_stencil_size(6).disable_args_parse(); auto mesh2 = Mesh2(config2, box); // Ink data fields diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 33c640ef7..20752bb69 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -31,7 +31,7 @@ namespace samurai }; template Date: Fri, 19 Sep 2025 14:37:31 +0200 Subject: [PATCH 08/60] fix disable_args_parse --- include/samurai/mesh_config.hpp | 66 +++++++++++++++--------------- include/samurai/samurai_config.hpp | 4 +- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index bea749234..728b7aa73 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -4,6 +4,7 @@ #pragma once #include "arguments.hpp" +#include "samurai_config.hpp" #include namespace samurai @@ -153,38 +154,37 @@ namespace samurai void parse_args() { - if (m_disable_args_parse) + if (!m_disable_args_parse) { - return; - } - if (args::max_stencil_radius != std::numeric_limits::max()) - { - m_max_stencil_radius = args::max_stencil_radius; - } - if (args::graduation_width != std::numeric_limits::max()) - { - m_graduation_width = args::graduation_width; - } - if (args::min_level != std::numeric_limits::max()) - { - m_min_level = args::min_level; - } - if (args::max_level != std::numeric_limits::max()) - { - m_max_level = args::max_level; - } - // if (args::approx_box_tol != std::numeric_limits::infinity()) - // { - // m_approx_box_tol = args::approx_box_tol; - // } - // if (args::scaling_factor != std::numeric_limits::infinity()) - // { - // m_scaling_factor = args::scaling_factor; - // } - if (m_max_level < m_min_level) - { - std::cerr << "Max level must be greater than min level." << std::endl; - exit(EXIT_FAILURE); + if (args::max_stencil_radius != std::numeric_limits::max()) + { + m_max_stencil_radius = args::max_stencil_radius; + } + if (args::graduation_width != std::numeric_limits::max()) + { + m_graduation_width = args::graduation_width; + } + if (args::min_level != std::numeric_limits::max()) + { + m_min_level = args::min_level; + } + if (args::max_level != std::numeric_limits::max()) + { + m_max_level = args::max_level; + } + // if (args::approx_box_tol != std::numeric_limits::infinity()) + // { + // m_approx_box_tol = args::approx_box_tol; + // } + // if (args::scaling_factor != std::numeric_limits::infinity()) + // { + // m_scaling_factor = args::scaling_factor; + // } + if (m_max_level < m_min_level) + { + std::cerr << "Max level must be greater than min level." << std::endl; + exit(EXIT_FAILURE); + } } m_ghost_width = std::max(static_cast(m_max_stencil_radius), static_cast(prediction_stencil_radius)); @@ -193,8 +193,8 @@ namespace samurai private: int m_max_stencil_radius = 1; - std::size_t m_graduation_width = 1; - int m_ghost_width = 1; + std::size_t m_graduation_width = default_config::graduation_width; + int m_ghost_width = default_config::ghost_width; std::size_t m_min_level; std::size_t m_max_level; diff --git a/include/samurai/samurai_config.hpp b/include/samurai/samurai_config.hpp index b4394f61a..73034122b 100644 --- a/include/samurai/samurai_config.hpp +++ b/include/samurai/samurai_config.hpp @@ -16,8 +16,8 @@ namespace samurai namespace default_config { static constexpr std::size_t max_level = 20; - static constexpr std::size_t ghost_width = 1; - static constexpr std::size_t graduation_width = 1; + static constexpr int ghost_width = 1; + static constexpr int graduation_width = 1; static constexpr std::size_t prediction_order = 1; using index_t = signed long long int; From 5d46f16a55e2fd026293151f51e4f566d7894134 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Wed, 24 Sep 2025 13:09:31 +0200 Subject: [PATCH 09/60] update demos --- demos/FiniteVolume/AMR_Burgers_Hat.cpp | 5 ++--- demos/FiniteVolume/burgers.cpp | 8 ++++---- demos/FiniteVolume/burgers_os.cpp | 13 +++++-------- demos/FiniteVolume/heat_heterogeneous.cpp | 7 +++---- demos/FiniteVolume/heat_nonlinear.cpp | 7 +++---- demos/FiniteVolume/level_set.cpp | 9 ++++----- demos/FiniteVolume/level_set_from_scratch.cpp | 9 ++++----- demos/FiniteVolume/nagumo.cpp | 7 +++---- demos/FiniteVolume/scalar_burgers_2d.cpp | 7 +++---- demos/FiniteVolume/stokes_2d.cpp | 7 +++---- demos/highorder/main.cpp | 6 +++--- demos/pablo/bubble_2d.cpp | 4 ++-- demos/tutorial/graduation_case_2.cpp | 4 ++-- 13 files changed, 41 insertions(+), 52 deletions(-) diff --git a/demos/FiniteVolume/AMR_Burgers_Hat.cpp b/demos/FiniteVolume/AMR_Burgers_Hat.cpp index 0a975c4e8..6b65c7fac 100644 --- a/demos/FiniteVolume/AMR_Burgers_Hat.cpp +++ b/demos/FiniteVolume/AMR_Burgers_Hat.cpp @@ -225,8 +225,6 @@ int main(int argc, char* argv[]) app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters"); app.add_option("--start-level", start_level, "Start level of AMR")->capture_default_str()->group("AMR parameters"); - app.add_option("--min-level", min_level, "Minimum level of AMR")->capture_default_str()->group("AMR parameters"); - app.add_option("--max-level", max_level, "Maximum level of AMR")->capture_default_str()->group("AMR parameters"); app.add_option("--with-correction", correction, "Apply flux correction at the interface of two refinement levels") ->capture_default_str() ->group("AMR parameters"); @@ -236,12 +234,13 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box({left_box}, {right_box}); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); samurai::amr::Mesh mesh; auto phi = samurai::make_scalar_field("phi", mesh); if (restart_file.empty()) { - mesh = {box, start_level, min_level, max_level}; + mesh = {box, start_level, config.min_level(), config.max_level()}; init_solution(phi); } else diff --git a/demos/FiniteVolume/burgers.cpp b/demos/FiniteVolume/burgers.cpp index c965fe9eb..4af3649a9 100644 --- a/demos/FiniteVolume/burgers.cpp +++ b/demos/FiniteVolume/burgers.cpp @@ -91,8 +91,6 @@ int main_dim(int argc, char* argv[]) app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters"); app.add_option("--dt", dt, "Time step")->capture_default_str()->group("Simulation parameters"); app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_option("--nfiles", nfiles, "Number of output files")->capture_default_str()->group("Output"); @@ -108,6 +106,8 @@ int main_dim(int argc, char* argv[]) box_corner1.fill(left_box); box_corner2.fill(right_box); Box box(box_corner1, box_corner2); + + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); samurai::MRMesh mesh; auto u = samurai::make_vector_field("u", mesh); @@ -117,7 +117,7 @@ int main_dim(int argc, char* argv[]) if (restart_file.empty()) { - mesh = {box, min_level, max_level}; + mesh = {config, box}; u.resize(); // Initial solution @@ -221,7 +221,7 @@ int main_dim(int argc, char* argv[]) // Time iteration // //--------------------// - double dx = mesh.cell_length(max_level); + double dx = mesh.cell_length(mesh.max_level()); dt = cfl * dx / pow(2, dim); auto MRadaptation = samurai::make_MRAdapt(u); diff --git a/demos/FiniteVolume/burgers_os.cpp b/demos/FiniteVolume/burgers_os.cpp index e9965ec1c..4d3bce296 100644 --- a/demos/FiniteVolume/burgers_os.cpp +++ b/demos/FiniteVolume/burgers_os.cpp @@ -125,8 +125,6 @@ int main(int argc, char* argv[]) app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--dt", dt, "Time step")->capture_default_str()->group("Simulation parameters"); app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_option("--nfiles", nfiles, "Number of output files")->capture_default_str()->group("Output"); @@ -134,8 +132,6 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); - std::cout << " max_level = " << max_level << " min_level = " << min_level << std::endl; - //--------------------// // Problem definition // //--------------------// @@ -151,9 +147,10 @@ int main(int argc, char* argv[]) samurai::LevelCellArray<1> lca_left(max_level, box_left, {-1}, 0.05, 2); samurai::LevelCellArray<1> lca_right(max_level, box_right, {-1}, 0.05, 2); - std::array periodic; - periodic.fill(true); - samurai::MRMesh mesh{box, min_level, max_level, periodic, 0.05, 2}; + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).periodic(true).approx_box_tol(0.05).scaling_factor(2); + std::cout << " max_level = " << config.max_level() << " min_level = " << config.min_level() << std::endl; + + samurai::MRMesh mesh{config, box}; auto u = samurai::make_scalar_field("u", mesh); auto unp1 = samurai::make_scalar_field("unp1", mesh); @@ -187,7 +184,7 @@ int main(int argc, char* argv[]) // Time iteration // //--------------------// - double dx = mesh.cell_length(max_level); + double dx = mesh.cell_length(mesh.max_level()); dt = cfl * dx / velocity(0); while (t != Tf) diff --git a/demos/FiniteVolume/heat_heterogeneous.cpp b/demos/FiniteVolume/heat_heterogeneous.cpp index 8b4823da2..e352e46c9 100644 --- a/demos/FiniteVolume/heat_heterogeneous.cpp +++ b/demos/FiniteVolume/heat_heterogeneous.cpp @@ -74,8 +74,6 @@ int main(int argc, char* argv[]) app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters"); app.add_option("--dt", dt, "Time step")->capture_default_str()->group("Simulation parameters"); app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_flag("--save-final-state-only", save_final_state_only, "Save final state only")->group("Output"); @@ -93,6 +91,7 @@ int main(int argc, char* argv[]) box_corner1.fill(left_box); box_corner2.fill(right_box); Box box(box_corner1, box_corner2); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); samurai::MRMesh mesh; auto u = samurai::make_scalar_field("u", mesh); @@ -100,7 +99,7 @@ int main(int argc, char* argv[]) if (restart_file.empty()) { - mesh = {box, min_level, max_level}; + mesh = {config, box}; u.resize(); // Initial solution: crenel samurai::for_each_cell(mesh, @@ -153,7 +152,7 @@ int main(int argc, char* argv[]) if (explicit_scheme) { double diff_coeff = 4; - double dx = mesh.cell_length(max_level); + double dx = mesh.cell_length(mesh.max_level()); dt = cfl * (dx * dx) / (pow(2, dim) * diff_coeff); } diff --git a/demos/FiniteVolume/heat_nonlinear.cpp b/demos/FiniteVolume/heat_nonlinear.cpp index c9c259e11..e89b1ea7a 100644 --- a/demos/FiniteVolume/heat_nonlinear.cpp +++ b/demos/FiniteVolume/heat_nonlinear.cpp @@ -149,8 +149,6 @@ int main(int argc, char* argv[]) app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters"); app.add_option("--dt", dt, "Time step")->capture_default_str()->group("Simulation parameters"); app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_flag("--save-final-state-only", save_final_state_only, "Save final state only")->group("Output"); @@ -168,12 +166,13 @@ int main(int argc, char* argv[]) box_corner1.fill(left_box); box_corner2.fill(right_box); Box box(box_corner1, box_corner2); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); samurai::MRMesh mesh; auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { - mesh = {box, min_level, max_level}; + mesh = {config, box}; u = samurai::make_scalar_field("u", mesh, [&](const auto& coords) @@ -204,7 +203,7 @@ int main(int argc, char* argv[]) if (explicit_scheme) { double diff_coeff = 1; - double dx = mesh.cell_length(max_level); + double dx = mesh.cell_length(mesh.max_level()); dt = cfl * (dx * dx) / (pow(2, dim) * diff_coeff); } diff --git a/demos/FiniteVolume/level_set.cpp b/demos/FiniteVolume/level_set.cpp index 49d2b7c60..d9c708eb2 100644 --- a/demos/FiniteVolume/level_set.cpp +++ b/demos/FiniteVolume/level_set.cpp @@ -90,7 +90,7 @@ void AMR_criteria(const Field& f, Tag& tag) samurai::for_each_cell(mesh[mesh_id_t::cells], [&](auto cell) { - const double dx = mesh.cell_length(max_level); + const double dx = mesh.cell_length(mesh.max_level()); if (std::abs(f[cell]) < 1.2 * 5 * std::sqrt(2.) * dx) { @@ -281,8 +281,6 @@ int main(int argc, char* argv[]) app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters"); app.add_option("--start-level", start_level, "Start level of AMR")->capture_default_str()->group("AMR parameters"); - app.add_option("--min-level", min_level, "Minimum level of AMR")->capture_default_str()->group("AMR parameters"); - app.add_option("--max-level", max_level, "Maximum level of AMR")->capture_default_str()->group("AMR parameters"); app.add_option("--with-correction", correction, "Apply flux correction at the interface of two refinement levels") ->capture_default_str() ->group("AMR parameters"); @@ -292,12 +290,13 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box(min_corner, max_corner); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); samurai::amr::Mesh mesh; auto phi = samurai::make_scalar_field("phi", mesh); if (restart_file.empty()) { - mesh = {box, start_level, min_level, max_level}; + mesh = {box, start_level, config.min_level(), config.max_level()}; init_level_set(phi); } else @@ -305,7 +304,7 @@ int main(int argc, char* argv[]) samurai::load(restart_file, mesh, phi); } - double dt = cfl * mesh.cell_length(max_level); + double dt = cfl * mesh.cell_length(mesh.max_level()); const double dt_save = Tf / static_cast(nfiles); auto u = init_velocity(mesh); diff --git a/demos/FiniteVolume/level_set_from_scratch.cpp b/demos/FiniteVolume/level_set_from_scratch.cpp index 2000b1adc..7b8c6f1f5 100644 --- a/demos/FiniteVolume/level_set_from_scratch.cpp +++ b/demos/FiniteVolume/level_set_from_scratch.cpp @@ -335,7 +335,7 @@ void AMR_criteria(const Field& f, Tag& tag) samurai::for_each_cell(mesh[SimpleID::cells], [&](auto cell) { - const double dx = mesh.cell_length(max_level); + const double dx = mesh.cell_length(mesh.max_level()); if (std::abs(f[cell]) < 1.2 * 5 * std::sqrt(2.) * dx) { @@ -623,8 +623,6 @@ int main(int argc, char* argv[]) app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters"); app.add_option("--start-level", start_level, "Start level of AMR")->capture_default_str()->group("AMR parameters"); - app.add_option("--min-level", min_level, "Minimum level of AMR")->capture_default_str()->group("AMR parameters"); - app.add_option("--max-level", max_level, "Maximum level of AMR")->capture_default_str()->group("AMR parameters"); app.add_flag("--with-correction", correction, "Apply flux correction at the interface of two refinement levels") ->capture_default_str() ->group("AMR parameters"); @@ -634,13 +632,14 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box(min_corner, max_corner); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); AMRMesh mesh; auto phi = samurai::make_scalar_field("phi", mesh); if (restart_file.empty()) { - mesh = {box, max_level, min_level, max_level}; + mesh = {box, config.max_level(), config.min_level(), config.max_level()}; init_level_set(phi); } else @@ -648,7 +647,7 @@ int main(int argc, char* argv[]) samurai::load(restart_file, mesh, phi); } - double dt = cfl * mesh.cell_length(max_level); + double dt = cfl * mesh.cell_length(mesh.max_level()); const double dt_save = Tf / static_cast(nfiles); // We initialize the level set function diff --git a/demos/FiniteVolume/nagumo.cpp b/demos/FiniteVolume/nagumo.cpp index 5f051d90e..5e71fd265 100644 --- a/demos/FiniteVolume/nagumo.cpp +++ b/demos/FiniteVolume/nagumo.cpp @@ -90,8 +90,6 @@ int main(int argc, char* argv[]) app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters"); app.add_flag("--explicit-reaction", explicit_reaction, "Explicit the reaction term")->capture_default_str()->group("Simulation parameters"); app.add_flag("--explicit-diffusion", explicit_diffusion, "Explicit the diffusion term")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_flag("--save-final-state-only", save_final_state_only, "Save final state only")->group("Output"); @@ -109,7 +107,8 @@ int main(int argc, char* argv[]) box_corner1.fill(left_box); box_corner2.fill(right_box); Box box(box_corner1, box_corner2); - samurai::MRMesh mesh{box, min_level, max_level}; + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + samurai::MRMesh mesh{config, box}; auto u = samurai::make_vector_field("u", mesh); @@ -177,7 +176,7 @@ int main(int argc, char* argv[]) dt = Tf / 100; if (explicit_diffusion) { - double dx = mesh.cell_length(max_level); + double dx = mesh.cell_length(mesh.max_level()); dt = cfl * (dx * dx) / (pow(2, dim) * D); } } diff --git a/demos/FiniteVolume/scalar_burgers_2d.cpp b/demos/FiniteVolume/scalar_burgers_2d.cpp index 7e1c1a324..5a643d1b3 100644 --- a/demos/FiniteVolume/scalar_burgers_2d.cpp +++ b/demos/FiniteVolume/scalar_burgers_2d.cpp @@ -212,8 +212,6 @@ int main(int argc, char* argv[]) app.add_option("--Ti", t, "Initial time")->capture_default_str()->group("Simulation parameters"); app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--with-correction", correction, "Apply flux correction at the interface of two refinement levels") ->capture_default_str() ->group("Multiresolution"); @@ -224,13 +222,14 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box(min_corner, max_corner); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); samurai::MRMesh mesh; auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { - mesh = {box, min_level, max_level}; + mesh = {config, box}; init(u); } else @@ -240,7 +239,7 @@ int main(int argc, char* argv[]) samurai::make_bc>(u, 0.); - double dt = cfl * mesh.cell_length(max_level); + double dt = cfl * mesh.cell_length(mesh.max_level()); const double dt_save = Tf / static_cast(nfiles); auto unp1 = samurai::make_scalar_field("unp1", mesh); diff --git a/demos/FiniteVolume/stokes_2d.cpp b/demos/FiniteVolume/stokes_2d.cpp index 463786eb7..3644aa4cb 100644 --- a/demos/FiniteVolume/stokes_2d.cpp +++ b/demos/FiniteVolume/stokes_2d.cpp @@ -180,8 +180,6 @@ int main(int argc, char* argv[]) ->group("Simulation parameters"); app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--dt", dt, "Time step")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_option("--nfiles", nfiles, "Number of output files")->capture_default_str()->group("Output"); @@ -196,8 +194,9 @@ int main(int argc, char* argv[]) PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); PetscCheck(size == 1, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "This is a uniprocessor example only!"); - auto box = samurai::Box({0, 0}, {1, 1}); - auto mesh = Mesh(box, min_level, max_level); + auto box = samurai::Box({0, 0}, {1, 1}); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto mesh = Mesh(config, box); //--------------------// // Stationary problem // diff --git a/demos/highorder/main.cpp b/demos/highorder/main.cpp index 9c68c95a0..baabb3b5b 100644 --- a/demos/highorder/main.cpp +++ b/demos/highorder/main.cpp @@ -135,8 +135,6 @@ int main(int argc, char* argv[]) app.add_option("--min-corner", min_corner, "The min corner of the box")->capture_default_str()->group("Simulation parameters"); app.add_option("--max-corner", min_corner, "The max corner of the box")->capture_default_str()->group("Simulation parameters"); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--refinement", refinement, "Number of refinement")->capture_default_str()->group("Multiresolution"); app.add_option("--with-correction", correction, "Apply flux correction at the interface of two refinement levels") ->capture_default_str() @@ -150,7 +148,9 @@ int main(int argc, char* argv[]) using mesh_t = samurai::MRMesh; using mesh_id_t = typename mesh_t::mesh_id_t; using cl_type = typename mesh_t::cl_type; - mesh_t init_mesh{box, min_level, max_level}; + + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + mesh_t init_mesh{config, box}; auto adapt_field = samurai::make_scalar_field("adapt_field", init_mesh, diff --git a/demos/pablo/bubble_2d.cpp b/demos/pablo/bubble_2d.cpp index 3d97eb37b..e7c132800 100644 --- a/demos/pablo/bubble_2d.cpp +++ b/demos/pablo/bubble_2d.cpp @@ -259,8 +259,8 @@ int main(int argc, char* argv[]) app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--dt", dt, "Time step")->capture_default_str()->group("Simulation parameters"); app.add_option("--start-level", start_level, "Start level of AMR")->capture_default_str()->group("Adaptation parameters"); - app.add_option("--min-level", min_level, "Minimum level of AMR")->capture_default_str()->group("Adaptation parameters"); - app.add_option("--max-level", max_level, "Maximum level of AMR")->capture_default_str()->group("Adaptation parameters"); + app.add_option("--minimum-level", min_level, "Minimum level of AMR")->capture_default_str()->group("Adaptation parameters"); + app.add_option("--maximum-level", max_level, "Maximum level of AMR")->capture_default_str()->group("Adaptation parameters"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_option("--nfiles", nfiles, "Number of output files")->capture_default_str()->group("Output"); diff --git a/demos/tutorial/graduation_case_2.cpp b/demos/tutorial/graduation_case_2.cpp index 46c24b83e..da336852e 100644 --- a/demos/tutorial/graduation_case_2.cpp +++ b/demos/tutorial/graduation_case_2.cpp @@ -50,8 +50,8 @@ int main(int argc, char* argv[]) fs::path path = fs::current_path(); std::string filename = "graduation_case_2"; - app.add_option("--min-level", min_level, "Minimum level of the mesh generator")->capture_default_str(); - app.add_option("--max-level", max_level, "Maximum level of the mesh generator")->capture_default_str(); + app.add_option("--minimum-level", min_level, "Minimum level of the mesh generator")->capture_default_str(); + app.add_option("--maximum-level", max_level, "Maximum level of the mesh generator")->capture_default_str(); app.add_flag("--with-corner", with_corner, "Make the graduation including the diagonal")->capture_default_str(); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); From 147bc8d7bc97d81bc13f7060bca617264a4183d6 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Wed, 24 Sep 2025 13:47:04 +0200 Subject: [PATCH 10/60] fix cpp-check error --- include/samurai/mesh.hpp | 15 ++++++++++++++- include/samurai/mesh_config.hpp | 4 ++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 331201a81..6f5783b9d 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -168,6 +168,7 @@ namespace samurai Mesh_base(mesh_config& config, const samurai::DomainBuilder& domain_builder, std::size_t start_level); + // cppcheck-suppress uninitMemberVar Mesh_base(const samurai::Box&, std::size_t, std::size_t, std::size_t, double, double) { std::cerr << "Delete min_level and max_level from CLI11 options and use mesh_config object in the mesh constructor" << std::endl; @@ -181,6 +182,7 @@ namespace samurai double approx_box_tol = lca_type::default_approx_box_tol, double scaling_factor = 0); + // cppcheck-suppress uninitMemberVar Mesh_base(const samurai::Box&, std::size_t, std::size_t, std::size_t, const std::array&, double, double) { std::cerr << "Delete min_level and max_level from CLI11 options and use mesh_config object in the mesh constructor" << std::endl; @@ -757,7 +759,18 @@ namespace samurai template inline double Mesh_base::min_cell_length() const { - return cell_length(max_level()); + if (args::finer_level_flux != 0) + { + return cell_length(max_level()); + } + else + { +#ifdef SAMURAI_WITH_MPI + return cell_length(max_level()); +#else + return cell_length(m_cells[mesh_id_t::cells].max_level()); +#endif + } } template diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index 728b7aa73..e10677c37 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -196,8 +196,8 @@ namespace samurai std::size_t m_graduation_width = default_config::graduation_width; int m_ghost_width = default_config::ghost_width; - std::size_t m_min_level; - std::size_t m_max_level; + std::size_t m_min_level = 0; + std::size_t m_max_level = 6; double m_approx_box_tol = 0.05; double m_scaling_factor = 0; From 30d6e639a625221f778e9147069ce62a44caf595 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Wed, 24 Sep 2025 14:32:12 +0200 Subject: [PATCH 11/60] fix errors --- demos/FiniteVolume/burgers.cpp | 4 ++-- include/samurai/algorithm/update.hpp | 2 +- include/samurai/mesh.hpp | 9 ++++++--- include/samurai/mesh_config.hpp | 7 ++++++- include/samurai/uniform_mesh.hpp | 9 +++++++++ 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/demos/FiniteVolume/burgers.cpp b/demos/FiniteVolume/burgers.cpp index 4af3649a9..1cb37e215 100644 --- a/demos/FiniteVolume/burgers.cpp +++ b/demos/FiniteVolume/burgers.cpp @@ -52,7 +52,7 @@ int main_dim(int argc, char* argv[]) { auto& app = samurai::initialize("Finite volume example for the Burgers equation", argc, argv); - using Config = samurai::MRConfig; + using Config = samurai::MRConfig; using Box = samurai::Box; using point_t = typename Box::point_t; @@ -107,7 +107,7 @@ int main_dim(int argc, char* argv[]) box_corner2.fill(right_box); Box box(box_corner1, box_corner2); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_width(6); samurai::MRMesh mesh; auto u = samurai::make_vector_field("u", mesh); diff --git a/include/samurai/algorithm/update.hpp b/include/samurai/algorithm/update.hpp index bb8ef3fbc..bad3f987c 100644 --- a/include/samurai/algorithm/update.hpp +++ b/include/samurai/algorithm/update.hpp @@ -610,7 +610,7 @@ namespace samurai using interval_t = typename Field::mesh_t::interval_t; using coord_t = typename lca_t::coord_type; - static constexpr std::size_t ghost_width = Field::mesh_t::config::ghost_width; + int ghost_width = field.mesh().ghost_width(); ArrayOfIntervalAndPoint interval_list; diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 6f5783b9d..60368d597 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -344,12 +344,15 @@ namespace samurai std::exit(EXIT_FAILURE); // partition_mesh(start_level, b); // load_balancing(); + + double scaling_factor_ = 0.; #else - double scaling_factor_ = config.scaling_factor(); + double scaling_factor_ = m_config.scaling_factor(); compute_scaling_factor(domain_builder, scaling_factor_); + m_config.scaling_factor() = scaling_factor_; // Build the domain by adding and removing boxes - cl_type domain_cl = construct_initial_mesh(domain_builder, start_level, config.approx_box_tol(), scaling_factor_); + cl_type domain_cl = construct_initial_mesh(domain_builder, start_level, m_config.approx_box_tol(), m_config.scaling_factor()); this->m_cells[mesh_id_t::cells] = {domain_cl, false}; #endif @@ -362,7 +365,7 @@ namespace samurai update_mesh_neighbour(); set_origin_point(domain_builder.origin_point()); - set_scaling_factor(scaling_factor_); + set_scaling_factor(m_config.scaling_factor()); } // template diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index e10677c37..3f7b9f248 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -124,6 +124,11 @@ namespace samurai return m_scaling_factor; } + auto& scaling_factor() + { + return m_scaling_factor; + } + auto& periodic(std::array const& periodicity) { m_periodic = periodicity; @@ -187,7 +192,7 @@ namespace samurai } } - m_ghost_width = std::max(static_cast(m_max_stencil_radius), static_cast(prediction_stencil_radius)); + m_ghost_width = std::max(m_max_stencil_radius, static_cast(prediction_stencil_radius)); } private: diff --git a/include/samurai/uniform_mesh.hpp b/include/samurai/uniform_mesh.hpp index f16e928bf..d3faf19e6 100644 --- a/include/samurai/uniform_mesh.hpp +++ b/include/samurai/uniform_mesh.hpp @@ -9,6 +9,7 @@ #include "level_cell_array.hpp" #include "level_cell_list.hpp" #include "mesh.hpp" +#include "mesh_config.hpp" #include "samurai_config.hpp" namespace samurai @@ -77,6 +78,8 @@ namespace samurai void set_scaling_factor(double scaling_factor); double cell_length(std::size_t level) const; + auto cfg() const; + private: void update_sub_mesh(); @@ -241,6 +244,12 @@ namespace samurai return samurai::cell_length(scaling_factor(), level); } + template + inline auto UniformMesh::cfg() const + { + return mesh_config(); + } + template inline bool operator==(const UniformMesh& mesh1, const UniformMesh& mesh2) { From 856704025a70e0edaf562ba95d868d1643436fc7 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Wed, 24 Sep 2025 14:46:29 +0200 Subject: [PATCH 12/60] fix errors --- demos/FiniteVolume/burgers.cpp | 2 +- include/samurai/uniform_mesh.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/demos/FiniteVolume/burgers.cpp b/demos/FiniteVolume/burgers.cpp index 1cb37e215..b7f589dbb 100644 --- a/demos/FiniteVolume/burgers.cpp +++ b/demos/FiniteVolume/burgers.cpp @@ -107,7 +107,7 @@ int main_dim(int argc, char* argv[]) box_corner2.fill(right_box); Box box(box_corner1, box_corner2); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_width(6); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_size(6); samurai::MRMesh mesh; auto u = samurai::make_vector_field("u", mesh); diff --git a/include/samurai/uniform_mesh.hpp b/include/samurai/uniform_mesh.hpp index d3faf19e6..7fc1694fe 100644 --- a/include/samurai/uniform_mesh.hpp +++ b/include/samurai/uniform_mesh.hpp @@ -247,7 +247,7 @@ namespace samurai template inline auto UniformMesh::cfg() const { - return mesh_config(); + return mesh_config(); } template From 9c463dd3357a3c6923fa42b748cd097227a98745 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Wed, 24 Sep 2025 16:50:03 +0200 Subject: [PATCH 13/60] fox errors --- include/samurai/amr/mesh.hpp | 12 +++---- include/samurai/io/restart.hpp | 3 +- include/samurai/mesh.hpp | 60 +++++++++++++------------------- include/samurai/mesh_config.hpp | 45 +++++++++++++++++------- include/samurai/mr/mesh.hpp | 16 +++++---- tests/test_adapt.cpp | 3 +- tests/test_bc.cpp | 3 +- tests/test_corner_projection.cpp | 5 ++- tests/test_domain_with_hole.cpp | 3 +- tests/test_field.cpp | 5 +-- tests/test_for_each.cpp | 5 +-- 11 files changed, 88 insertions(+), 72 deletions(-) diff --git a/include/samurai/amr/mesh.hpp b/include/samurai/amr/mesh.hpp index e5b7dbd5d..1ae49bdf6 100644 --- a/include/samurai/amr/mesh.hpp +++ b/include/samurai/amr/mesh.hpp @@ -69,8 +69,8 @@ namespace samurai::amr Mesh() = default; Mesh(const ca_type& ca, const self_type& ref_mesh); Mesh(const cl_type& cl, const self_type& ref_mesh); - Mesh(const cl_type& cl, std::size_t min_level, std::size_t max_level); - Mesh(const ca_type& ca, std::size_t min_level, std::size_t max_level); + Mesh(const mesh_config& config, const cl_type& cl); + Mesh(const mesh_config& config, const ca_type& ca); Mesh(const Box& b, std::size_t start_level, std::size_t min_level, std::size_t max_level); void update_sub_mesh_impl(); @@ -93,14 +93,14 @@ namespace samurai::amr } template - inline Mesh::Mesh(const cl_type& cl, std::size_t min_level, std::size_t max_level) - : base_type(cl, min_level, max_level) + inline Mesh::Mesh(const mesh_config& config, const cl_type& cl) + : base_type(config, cl) { } template - inline Mesh::Mesh(const ca_type& ca, std::size_t min_level, std::size_t max_level) - : base_type(ca, min_level, max_level) + inline Mesh::Mesh(const mesh_config& config, const ca_type& ca) + : base_type(config, ca) { } diff --git a/include/samurai/io/restart.hpp b/include/samurai/io/restart.hpp index a4a1259d8..b52231903 100644 --- a/include/samurai/io/restart.hpp +++ b/include/samurai/io/restart.hpp @@ -415,7 +415,8 @@ namespace samurai ca_type ca; load(file, ca); - Mesh new_mesh{ca, min_level, max_level}; + auto mesh_cfg = mesh_config().min_level(min_level).max_level(max_level); + Mesh new_mesh{mesh_cfg, ca}; std::swap(mesh, new_mesh); load_fields(file, mesh, fields...); } diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 60368d597..0ac297ef1 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -162,11 +162,11 @@ namespace samurai Mesh_base() = default; // cppcheck-suppress uninitMemberVar Mesh_base(const ca_type& ca, const self_type& ref_mesh); Mesh_base(const cl_type& cl, const self_type& ref_mesh); - Mesh_base(const cl_type& cl, std::size_t min_level, std::size_t max_level); - Mesh_base(const ca_type& ca, std::size_t min_level, std::size_t max_level); + Mesh_base(const mesh_config& config, const cl_type& cl); + Mesh_base(const mesh_config& config, const ca_type& ca); Mesh_base(mesh_config& config, const samurai::Box& b, std::size_t start_level); - Mesh_base(mesh_config& config, const samurai::DomainBuilder& domain_builder, std::size_t start_level); + Mesh_base(const mesh_config& config, const samurai::DomainBuilder& domain_builder, std::size_t start_level); // cppcheck-suppress uninitMemberVar Mesh_base(const samurai::Box&, std::size_t, std::size_t, std::size_t, double, double) @@ -213,8 +213,6 @@ namespace samurai lca_type m_domain; lca_type m_subdomain; - std::size_t m_min_level; - std::size_t m_max_level; std::array m_periodic; mesh_t m_cells; ca_type m_union; @@ -237,8 +235,7 @@ namespace samurai ar & m_domain; ar & m_subdomain; ar & m_union; - ar & m_min_level; - ar & m_max_level; + ar & m_config; } #endif }; @@ -264,8 +261,6 @@ namespace samurai template inline Mesh_base::Mesh_base(mesh_config& config, const samurai::Box& b, std::size_t start_level) : m_domain{start_level, b, (config.parse_args(), config.approx_box_tol()), config.scaling_factor()} - , m_min_level{config.min_level()} - , m_max_level{config.max_level()} , m_periodic{config.periodic()} , m_config(config) { @@ -320,13 +315,13 @@ namespace samurai // } template - Mesh_base::Mesh_base(mesh_config& config, + Mesh_base::Mesh_base(const mesh_config& config, const samurai::DomainBuilder& domain_builder, [[maybe_unused]] std::size_t start_level) - : m_min_level{(config.parse_args(), config.min_level())} - , m_max_level{config.max_level()} - , m_config(config) + : m_config(config) { + m_config.parse_args(); + if (std::any_of(config.periodic().begin(), config.periodic().end(), [](bool b) @@ -440,12 +435,11 @@ namespace samurai // } template - inline Mesh_base::Mesh_base(const cl_type& cl, std::size_t min_level, std::size_t max_level) - : m_min_level{min_level} - , m_max_level{max_level} + inline Mesh_base::Mesh_base(const mesh_config& config, const cl_type& cl) + : m_config(config) { + m_config.parse_args(); m_periodic.fill(false); - assert(min_level <= max_level); this->m_cells[mesh_id_t::cells] = {cl}; @@ -462,12 +456,11 @@ namespace samurai } template - inline Mesh_base::Mesh_base(const ca_type& ca, std::size_t min_level, std::size_t max_level) - : m_min_level{min_level} - , m_max_level{max_level} + inline Mesh_base::Mesh_base(mesh_config const& config, const ca_type& ca) + : m_config{config} { + m_config.parse_args(); m_periodic.fill(false); - assert(min_level <= max_level); this->m_cells[mesh_id_t::cells] = ca; @@ -498,8 +491,6 @@ namespace samurai template inline Mesh_base::Mesh_base(const ca_type& ca, const self_type& ref_mesh) : m_domain(ref_mesh.m_domain) - , m_min_level(ref_mesh.m_min_level) - , m_max_level(ref_mesh.m_max_level) , m_periodic(ref_mesh.m_periodic) , m_mpi_neighbourhood(ref_mesh.m_mpi_neighbourhood) , m_config(ref_mesh.m_config) @@ -520,8 +511,6 @@ namespace samurai template inline Mesh_base::Mesh_base(const cl_type& cl, const self_type& ref_mesh) : m_domain(ref_mesh.m_domain) - , m_min_level(ref_mesh.m_min_level) - , m_max_level(ref_mesh.m_max_level) , m_periodic(ref_mesh.m_periodic) , m_mpi_neighbourhood(ref_mesh.m_mpi_neighbourhood) , m_config(ref_mesh.m_config) @@ -550,7 +539,7 @@ namespace samurai // negartive directions, we actually need 2 times the stencil width inside the hole. // min_level where the BC can be applied - std::size_t min_level_bc = m_min_level; + std::size_t min_level_bc = m_config.min_level(); if (scaling_factor <= 0) { scaling_factor = domain_builder.largest_subdivision(); @@ -666,25 +655,25 @@ namespace samurai template inline std::size_t Mesh_base::max_level() const { - return m_max_level; + return m_config.max_level(); } template inline std::size_t& Mesh_base::max_level() { - return m_max_level; + return m_config.max_level(); } template inline std::size_t Mesh_base::min_level() const { - return m_min_level; + return m_config.min_level(); } template inline std::size_t& Mesh_base::min_level() { - return m_min_level; + return m_config.min_level(); } template @@ -903,8 +892,7 @@ namespace samurai swap(m_subdomain, mesh.m_subdomain); swap(m_mpi_neighbourhood, mesh.m_mpi_neighbourhood); swap(m_union, mesh.m_union); - swap(m_max_level, mesh.m_max_level); - swap(m_min_level, mesh.m_min_level); + swap(m_config, mesh.m_config); } template @@ -1072,7 +1060,7 @@ namespace samurai inline void Mesh_base::construct_domain() { #ifdef SAMURAI_WITH_MPI - lcl_type lcl = {m_max_level}; + lcl_type lcl = {max_level()}; mpi::communicator world; std::vector all_subdomains(static_cast(world.size())); mpi::all_gather(world, m_subdomain, all_subdomains); @@ -1096,12 +1084,12 @@ namespace samurai inline void Mesh_base::construct_subdomain() { // lcl_type lcl = {m_cells[mesh_id_t::cells].max_level()}; - lcl_type lcl = {m_max_level}; + lcl_type lcl = {max_level()}; for_each_interval(m_cells[mesh_id_t::cells], [&](std::size_t level, const auto& i, const auto& index) { - std::size_t shift = m_max_level - level; + std::size_t shift = max_level() - level; interval_t to_add = i << shift; auto shift_index = index << shift; static_nested_loop(0, @@ -1126,7 +1114,7 @@ namespace samurai template inline void Mesh_base::construct_union() { - std::size_t max_lvl = m_max_level; + std::size_t max_lvl = max_level(); // Construction of union cells // =========================== diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index 3f7b9f248..c104a70a7 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -18,6 +18,24 @@ namespace samurai static constexpr std::size_t dim = dim_; static constexpr std::size_t prediction_stencil_radius = prediction_stencil_radius_; + private: + + int m_max_stencil_radius = 1; + std::size_t m_graduation_width = default_config::graduation_width; + int m_ghost_width = default_config::ghost_width; + + std::size_t m_min_level = 0; + std::size_t m_max_level = 6; + + double m_approx_box_tol = 0.05; + double m_scaling_factor = 0; + + std::array m_periodic; + + bool m_disable_args_parse = false; + + public: + mesh_config() { m_periodic.fill(false); @@ -197,18 +215,21 @@ namespace samurai private: - int m_max_stencil_radius = 1; - std::size_t m_graduation_width = default_config::graduation_width; - int m_ghost_width = default_config::ghost_width; - - std::size_t m_min_level = 0; - std::size_t m_max_level = 6; - - double m_approx_box_tol = 0.05; - double m_scaling_factor = 0; - - std::array m_periodic; +#ifdef SAMURAI_WITH_MPI + friend class boost::serialization::access; - bool m_disable_args_parse = false; + template + void serialize(Archive& ar, const unsigned long) + { + // ar & m_max_stencil_radius; + // ar & m_graduation_width; + // ar & m_ghost_width; + ar & m_min_level; + ar & m_max_level; + // ar & m_approx_box_tol; + // ar & m_scaling_factor; + // ar & m_disable_args_parse; + } +#endif }; } diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 20752bb69..e7f162a88 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -78,9 +78,12 @@ namespace samurai MRMesh() = default; MRMesh(const ca_type& ca, const self_type& ref_mesh); MRMesh(const cl_type& cl, const self_type& ref_mesh); - MRMesh(const cl_type& cl, std::size_t min_level, std::size_t max_level); - MRMesh(const ca_type& ca, std::size_t min_level, std::size_t max_level); + MRMesh(const mesh_config& config, const cl_type& cl); + MRMesh(const mesh_config& config, const ca_type& ca); MRMesh(mesh_config& config, const samurai::Box& b); + MRMesh(mesh_config& config, const samurai::DomainBuilder& domain_builder); + + // deprecated constructors MRMesh(const samurai::Box& b, std::size_t min_level, std::size_t max_level, @@ -91,7 +94,6 @@ namespace samurai std::size_t max_level, double approx_box_tol = lca_type::default_approx_box_tol, double scaling_factor = 0); - MRMesh(mesh_config& config, const samurai::DomainBuilder& domain_builder); MRMesh(const samurai::Box& b, std::size_t min_level, std::size_t max_level, @@ -118,14 +120,14 @@ namespace samurai } template - inline MRMesh::MRMesh(const cl_type& cl, std::size_t min_level, std::size_t max_level) - : base_type(cl, min_level, max_level) + inline MRMesh::MRMesh(const mesh_config& config, const cl_type& cl) + : base_type(config, cl) { } template - inline MRMesh::MRMesh(const ca_type& ca, std::size_t min_level, std::size_t max_level) - : base_type(ca, min_level, max_level) + inline MRMesh::MRMesh(const mesh_config& config, const ca_type& ca) + : base_type(config, ca) { } diff --git a/tests/test_adapt.cpp b/tests/test_adapt.cpp index c4b86c39d..58a73d314 100644 --- a/tests/test_adapt.cpp +++ b/tests/test_adapt.cpp @@ -32,7 +32,8 @@ namespace samurai static constexpr std::size_t dim = TypeParam::value; using config = MRConfig; using box_t = Box; - auto mesh = MRMesh(box_t{xt::zeros({dim}), xt::ones({dim})}, 2, 4); + auto mesh_cfg = mesh_config().min_level(2).max_level(4); + auto mesh = MRMesh(mesh_cfg, box_t{xt::zeros({dim}), xt::ones({dim})}); auto u_1 = make_scalar_field("u_1", mesh); auto u_2 = make_vector_field("u_2", mesh); auto u_3 = make_vector_field("u_3", mesh); diff --git a/tests/test_bc.cpp b/tests/test_bc.cpp index e0e428c21..3d66e33cb 100644 --- a/tests/test_bc.cpp +++ b/tests/test_bc.cpp @@ -60,7 +60,8 @@ namespace samurai using config = MRConfig; Box box = {{0}, {1}}; - auto mesh = MRMesh(box, 2, 4); + auto mesh_cfg = mesh_config().min_level(2).max_level(4); + auto mesh = MRMesh(mesh_cfg, box); auto u = make_scalar_field("u", mesh); make_bc>(u, diff --git a/tests/test_corner_projection.cpp b/tests/test_corner_projection.cpp index a7e78e3f3..ac0627cdd 100644 --- a/tests/test_corner_projection.cpp +++ b/tests/test_corner_projection.cpp @@ -18,10 +18,9 @@ namespace samurai Box box({-1., -1.}, {1., 1.}); - std::size_t min_level = 2; - std::size_t max_level = 6; + auto mesh_cfg = mesh_config().min_level(2).max_level(6); - Mesh mesh{box, min_level, max_level}; + Mesh mesh{mesh_cfg, box}; direction_t direction = {-1, -1}; // corner direction std::size_t level = 6; diff --git a/tests/test_domain_with_hole.cpp b/tests/test_domain_with_hole.cpp index a69527962..42c225610 100644 --- a/tests/test_domain_with_hole.cpp +++ b/tests/test_domain_with_hole.cpp @@ -36,7 +36,8 @@ namespace samurai domain_with_hole_cl[level][index_y].add_interval({interval}); }); - samurai::MRMesh mesh{domain_with_hole_cl, level, level}; + auto mesh_cfg = mesh_config().min_level(level).max_level(level); + samurai::MRMesh mesh{mesh_cfg, domain_with_hole_cl}; EXPECT_EQ(mesh.nb_cells(mesh_id_t::cells), domain_lca.nb_cells() - hole_lca.nb_cells()); } diff --git a/tests/test_field.cpp b/tests/test_field.cpp index f8f6fb5d1..f919533ff 100644 --- a/tests/test_field.cpp +++ b/tests/test_field.cpp @@ -104,8 +104,9 @@ namespace samurai cl[1][{0}].add_interval({4, 6}); cl[2][{0}].add_interval({4, 8}); - auto mesh = MRMesh(cl, 1, 2); - auto field = make_scalar_field("u", mesh); + auto mesh_cfg = mesh_config<2>().min_level(1).max_level(2); + auto mesh = MRMesh(mesh_cfg, cl); + auto field = make_scalar_field("u", mesh); std::size_t index = 0; for_each_cell(mesh, diff --git a/tests/test_for_each.cpp b/tests/test_for_each.cpp index d207b960c..ef91c3134 100644 --- a/tests/test_for_each.cpp +++ b/tests/test_for_each.cpp @@ -14,8 +14,9 @@ namespace samurai cl_type cl2; cl2[level][{}].add_interval({0, 3}); - auto m1 = Mesh(cl1, level, level); - auto m2 = Mesh(cl2, level, level); + auto mesh_cfg = mesh_config<1>().min_level(level).max_level(level); + auto m1 = Mesh(mesh_cfg, cl1); + auto m2 = Mesh(mesh_cfg, cl2); return std::make_tuple(m1, m2); } From 9f52b412c2b86a8e539a96473329e5072fb6d79b Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Wed, 24 Sep 2025 17:50:04 +0200 Subject: [PATCH 14/60] fix cppcheck --- include/samurai/domain_builder.hpp | 46 ++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/include/samurai/domain_builder.hpp b/include/samurai/domain_builder.hpp index 8c9ebba6b..4d6d3d29d 100644 --- a/include/samurai/domain_builder.hpp +++ b/include/samurai/domain_builder.hpp @@ -3,6 +3,8 @@ #pragma once +#include + #include "box.hpp" namespace samurai @@ -81,15 +83,34 @@ namespace samurai { double largest_subdivision = m_added_boxes[0].min_length(); - // The largest subdivision must be smaller than the smallest legnth of all boxes - for (const auto& box : m_added_boxes) + auto gcd_loop = [](double largest_subdiv, const auto& boxes) { - largest_subdivision = gcd_float(largest_subdivision, box.min_length()); - } - for (const auto& box : m_removed_boxes) - { - largest_subdivision = gcd_float(largest_subdivision, box.min_length()); - } + // for (const auto& box : boxes) + // { + // largest_subdiv = gcd_float(largest_subdiv, box.min_length()); + // } + // return largest_subdiv; + + return std::accumulate(boxes.begin(), + boxes.end(), + largest_subdiv, + [](double l, const auto& box) + { + return gcd_float(l, box.min_length()); + }); + }; + + // The largest subdivision must be smaller than the smallest legnth of all boxes + largest_subdivision = gcd_loop(largest_subdivision, m_added_boxes); + largest_subdivision = gcd_loop(largest_subdivision, m_removed_boxes); + // for (const auto& box : m_added_boxes) + // { + // largest_subdivision = gcd_float(largest_subdivision, box.min_length()); + // } + // for (const auto& box : m_removed_boxes) + // { + // largest_subdivision = gcd_float(largest_subdivision, box.min_length()); + // } // The largest subdivision must be smaller than the smallest length of all differences for (const auto& box : m_added_boxes) @@ -99,10 +120,11 @@ namespace samurai if (rbox.intersects(box)) { std::vector diff = box.difference(rbox); - for (const auto& dbox : diff) - { - largest_subdivision = gcd_float(largest_subdivision, dbox.min_length()); - } + largest_subdivision = gcd_loop(largest_subdivision, diff); + // for (const auto& dbox : diff) + // { + // largest_subdivision = gcd_float(largest_subdivision, dbox.min_length()); + // } } } } From d4c086fb81178bef4b9403709d14dbb7207674d1 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Wed, 24 Sep 2025 19:27:41 +0200 Subject: [PATCH 15/60] fix amr mesh --- demos/FiniteVolume/AMR_Burgers_Hat.cpp | 2 +- include/samurai/algorithm/update.hpp | 3 ++- include/samurai/amr/mesh.hpp | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/demos/FiniteVolume/AMR_Burgers_Hat.cpp b/demos/FiniteVolume/AMR_Burgers_Hat.cpp index 6b65c7fac..1efa0a197 100644 --- a/demos/FiniteVolume/AMR_Burgers_Hat.cpp +++ b/demos/FiniteVolume/AMR_Burgers_Hat.cpp @@ -240,7 +240,7 @@ int main(int argc, char* argv[]) if (restart_file.empty()) { - mesh = {box, start_level, config.min_level(), config.max_level()}; + mesh = {config, box, start_level}; init_solution(phi); } else diff --git a/include/samurai/algorithm/update.hpp b/include/samurai/algorithm/update.hpp index bad3f987c..c36280140 100644 --- a/include/samurai/algorithm/update.hpp +++ b/include/samurai/algorithm/update.hpp @@ -4,6 +4,7 @@ #pragma once #include +#include #include @@ -400,7 +401,7 @@ namespace samurai template void update_outer_ghosts(std::size_t level, Field& field) { - static_assert(Field::mesh_t::config::prediction_order <= 1); + static_assert(std::remove_cvref_t::prediction_stencil_radius <= 1); constexpr std::size_t dim = Field::dim; diff --git a/include/samurai/amr/mesh.hpp b/include/samurai/amr/mesh.hpp index 1ae49bdf6..619be0ed7 100644 --- a/include/samurai/amr/mesh.hpp +++ b/include/samurai/amr/mesh.hpp @@ -71,7 +71,7 @@ namespace samurai::amr Mesh(const cl_type& cl, const self_type& ref_mesh); Mesh(const mesh_config& config, const cl_type& cl); Mesh(const mesh_config& config, const ca_type& ca); - Mesh(const Box& b, std::size_t start_level, std::size_t min_level, std::size_t max_level); + Mesh(mesh_config& config, const Box& b, std::size_t start_level); void update_sub_mesh_impl(); }; @@ -105,8 +105,8 @@ namespace samurai::amr } template - inline Mesh::Mesh(const Box& b, std::size_t start_level, std::size_t min_level, std::size_t max_level) - : base_type(b, start_level, min_level, max_level) + inline Mesh::Mesh(mesh_config& config, const Box& b, std::size_t start_level) + : base_type(config, b, start_level) { } From c1aa3dd700e529bfba7c3ce143ad0efb8e3072f1 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Thu, 25 Sep 2025 11:35:50 +0200 Subject: [PATCH 16/60] fix compilation --- demos/FiniteVolume/level_set.cpp | 2 +- demos/FiniteVolume/level_set_from_scratch.cpp | 15 ++++++++------- demos/highorder/main.cpp | 11 ++++++++--- demos/multigrid/main.cpp | 6 ++++-- demos/p4est/simple_2d.cpp | 5 +++-- demos/tutorial/AMR_1D_Burgers/step_3/main.cpp | 4 ++-- demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp | 8 ++++---- demos/tutorial/AMR_1D_Burgers/step_4/main.cpp | 5 ++--- .../AMR_1D_Burgers/step_4/update_mesh.hpp | 2 +- demos/tutorial/AMR_1D_Burgers/step_5/main.cpp | 5 ++--- demos/tutorial/AMR_1D_Burgers/step_6/main.cpp | 5 ++--- demos/tutorial/reconstruction_1d.cpp | 15 ++++++++++----- demos/tutorial/reconstruction_2d.cpp | 15 ++++++++++----- demos/tutorial/reconstruction_3d.cpp | 15 ++++++++++----- include/samurai/mesh.hpp | 8 ++++---- 15 files changed, 71 insertions(+), 50 deletions(-) diff --git a/demos/FiniteVolume/level_set.cpp b/demos/FiniteVolume/level_set.cpp index d9c708eb2..983ef9e4c 100644 --- a/demos/FiniteVolume/level_set.cpp +++ b/demos/FiniteVolume/level_set.cpp @@ -296,7 +296,7 @@ int main(int argc, char* argv[]) if (restart_file.empty()) { - mesh = {box, start_level, config.min_level(), config.max_level()}; + mesh = {config, box, start_level}; init_level_set(phi); } else diff --git a/demos/FiniteVolume/level_set_from_scratch.cpp b/demos/FiniteVolume/level_set_from_scratch.cpp index 7b8c6f1f5..1aaaac801 100644 --- a/demos/FiniteVolume/level_set_from_scratch.cpp +++ b/demos/FiniteVolume/level_set_from_scratch.cpp @@ -86,18 +86,18 @@ class AMRMesh : public samurai::Mesh_base, Config> { } - inline AMRMesh(const cl_type& cl, std::size_t min_level, std::size_t max_level) - : base_type(cl, min_level, max_level) + inline AMRMesh(const samurai::mesh_config& cfg, const cl_type& cl) + : base_type(cfg, cl) { } - inline AMRMesh(const ca_type& ca, std::size_t min_level, std::size_t max_level) - : base_type(ca, min_level, max_level) + inline AMRMesh(const samurai::mesh_config& cfg, const ca_type& ca) + : base_type(cfg, ca) { } - inline AMRMesh(const samurai::Box& b, std::size_t start_level, std::size_t min_level, std::size_t max_level) - : base_type(b, start_level, min_level, max_level) + inline AMRMesh(samurai::mesh_config& cfg, const samurai::Box& b, std::size_t start_level) + : base_type(cfg, b, start_level) { } @@ -639,7 +639,8 @@ int main(int argc, char* argv[]) if (restart_file.empty()) { - mesh = {box, config.max_level(), config.min_level(), config.max_level()}; + config.parse_args(); + mesh = {config, box, config.max_level()}; init_level_set(phi); } else diff --git a/demos/highorder/main.cpp b/demos/highorder/main.cpp index baabb3b5b..b71fe0a45 100644 --- a/demos/highorder/main.cpp +++ b/demos/highorder/main.cpp @@ -116,7 +116,7 @@ int main(int argc, char* argv[]) constexpr std::size_t stencil_width = 2; constexpr std::size_t graduation_width = 4; constexpr std::size_t prediction_order = 1; - using Config = samurai::MRConfig; + using Config = samurai::MRConfig; // Simulation parameters xt::xtensor_fixed> min_corner = {0., 0.}; @@ -149,7 +149,11 @@ int main(int argc, char* argv[]) using mesh_id_t = typename mesh_t::mesh_id_t; using cl_type = typename mesh_t::cl_type; - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config() + .min_level(min_level) + .max_level(max_level) + .graduation_width(graduation_width) + .max_stencil_radius(stencil_width); mesh_t init_mesh{config, box}; auto adapt_field = samurai::make_scalar_field("adapt_field", @@ -196,7 +200,8 @@ int main(int argc, char* argv[]) }); }); // mesh = {cl, mesh.min_level() + 1, mesh.max_level() + 1}; - mesh = {cl, min_level + i_ref + 1, max_level + i_ref + 1}; + auto mesh_cfg = samurai::mesh_config().min_level(min_level + i_ref + 1).max_level(max_level + i_ref + 1); + mesh = {mesh_cfg, cl}; } // std::cout << mesh << std::endl; // samurai::save("refine_mesh", mesh); diff --git a/demos/multigrid/main.cpp b/demos/multigrid/main.cpp index c7eb04e8d..e55fbf132 100644 --- a/demos/multigrid/main.cpp +++ b/demos/multigrid/main.cpp @@ -89,7 +89,8 @@ Mesh create_uniform_mesh(std::size_t level) min_level = level; max_level = level; - return Mesh(box, start_level, min_level, max_level); // amr::Mesh + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + return Mesh(config, box, start_level); // amr::Mesh // return Mesh(box, /*start_level,*/ min_level, max_level); // MRMesh } @@ -112,7 +113,8 @@ template } static_assert(Mesh::dim == 1, "create_refined_mesh() not implemented for this dimension"); - return Mesh(cl, min_level, max_level); // amr::Mesh + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + return Mesh(config, cl); // amr::Mesh // return Mesh(box, /*start_level,*/ min_level, max_level); // MRMesh } diff --git a/demos/p4est/simple_2d.cpp b/demos/p4est/simple_2d.cpp index e7fea6a03..4e1393d18 100644 --- a/demos/p4est/simple_2d.cpp +++ b/demos/p4est/simple_2d.cpp @@ -187,7 +187,7 @@ void refine_2(mesh_t& mesh, std::size_t max_level) } }); - mesh = {cl, mesh.min_level(), mesh.max_level()}; + mesh = {mesh.cfg(), cl}; } } @@ -241,7 +241,8 @@ int main(int argc, char* argv[]) // samurai::CellArray mesh_2(cl); using Config = samurai::MRConfig; using mesh_id_t = typename samurai::MRMesh::mesh_id_t; - samurai::MRMesh mesh_2(cl, 1, max_level); + auto config = samurai::mesh_config().min_level(1).max_level(max_level); + samurai::MRMesh mesh_2(config, cl); tic(); refine_2(mesh_2, max_level); diff --git a/demos/tutorial/AMR_1D_Burgers/step_3/main.cpp b/demos/tutorial/AMR_1D_Burgers/step_3/main.cpp index 920d331aa..75b3a82d6 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_3/main.cpp +++ b/demos/tutorial/AMR_1D_Burgers/step_3/main.cpp @@ -56,8 +56,8 @@ int main(int argc, char* argv[]) const std::size_t max_level = 6; // <-------------------------------- const samurai::Box box({-3}, {3}); - Mesh> mesh(box, start_level, min_level, - max_level); // <-------------------------------- + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + Mesh> mesh(config, box, start_level); // <-------------------------------- auto phi = init_sol(mesh); diff --git a/demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp b/demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp index 3f8cef37d..7e8a1e2a9 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp +++ b/demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp @@ -64,14 +64,14 @@ class Mesh : public samurai::Mesh_base, Config> Mesh() = default; // Constructor starting from a cell list - inline Mesh(const cl_type& cl, std::size_t min_level, std::size_t max_level) - : base_type(cl, min_level, max_level) + inline Mesh(const samurai::mesh_config& cfg, const cl_type& cl) + : base_type(cfg, cl) { } // Constructor from a given box (domain) - inline Mesh(const samurai::Box& b, std::size_t start_level, std::size_t min_level, std::size_t max_level) - : base_type(b, start_level, min_level, max_level, 0, 1) + inline Mesh(samurai::mesh_config& cfg, const samurai::Box& b, std::size_t start_level) + : base_type(cfg.approx_box_tol(0).scaling_factor(1), b, start_level) { } diff --git a/demos/tutorial/AMR_1D_Burgers/step_4/main.cpp b/demos/tutorial/AMR_1D_Burgers/step_4/main.cpp index 5bdbe5353..db728ef20 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_4/main.cpp +++ b/demos/tutorial/AMR_1D_Burgers/step_4/main.cpp @@ -41,8 +41,6 @@ int main(int argc, char* argv[]) std::string filename = "amr_1d_burgers_step_4"; app.add_option("--start-level", start_level, "Start level of the AMR")->capture_default_str()->group("AMR parameter"); - app.add_option("--min-level", min_level, "Minimum level of the AMR")->capture_default_str()->group("AMR parameter"); - app.add_option("--max-level", max_level, "Maximum level of the AMR")->capture_default_str()->group("AMR parameter"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); SAMURAI_PARSE(argc, argv); @@ -55,7 +53,8 @@ int main(int argc, char* argv[]) constexpr std::size_t dim = 1; const samurai::Box box({-3}, {3}); - Mesh> mesh(box, start_level, min_level, max_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + Mesh> mesh(config, box, start_level); auto phi = init_sol(mesh); diff --git a/demos/tutorial/AMR_1D_Burgers/step_4/update_mesh.hpp b/demos/tutorial/AMR_1D_Burgers/step_4/update_mesh.hpp index 49a13c983..5d09621df 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_4/update_mesh.hpp +++ b/demos/tutorial/AMR_1D_Burgers/step_4/update_mesh.hpp @@ -62,7 +62,7 @@ bool update_mesh(Field& f, const Tag& tag) } }); - mesh_t new_mesh(cell_list, mesh.min_level(), mesh.max_level()); + mesh_t new_mesh(mesh.cfg(), cell_list); if (new_mesh == mesh) { diff --git a/demos/tutorial/AMR_1D_Burgers/step_5/main.cpp b/demos/tutorial/AMR_1D_Burgers/step_5/main.cpp index ea3348292..9bb750808 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_5/main.cpp +++ b/demos/tutorial/AMR_1D_Burgers/step_5/main.cpp @@ -43,8 +43,6 @@ int main(int argc, char* argv[]) std::string filename = "amr_1d_burgers_step_5"; app.add_option("--start-level", start_level, "Start level of the AMR")->capture_default_str()->group("AMR parameter"); - app.add_option("--min-level", min_level, "Minimum level of the AMR")->capture_default_str()->group("AMR parameter"); - app.add_option("--max-level", max_level, "Maximum level of the AMR")->capture_default_str()->group("AMR parameter"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); SAMURAI_PARSE(argc, argv); @@ -57,7 +55,8 @@ int main(int argc, char* argv[]) constexpr std::size_t dim = 1; const samurai::Box box({-3}, {3}); - Mesh> mesh(box, start_level, min_level, max_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + Mesh> mesh(config, box, start_level); auto phi = init_sol(mesh); diff --git a/demos/tutorial/AMR_1D_Burgers/step_6/main.cpp b/demos/tutorial/AMR_1D_Burgers/step_6/main.cpp index 48d4573fd..03e0767ec 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_6/main.cpp +++ b/demos/tutorial/AMR_1D_Burgers/step_6/main.cpp @@ -54,8 +54,6 @@ int main(int argc, char* argv[]) app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters"); app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--start-level", start_level, "Start level of the AMR")->capture_default_str()->group("AMR parameter"); - app.add_option("--min-level", min_level, "Minimum level of the AMR")->capture_default_str()->group("AMR parameter"); - app.add_option("--max-level", max_level, "Maximum level of the AMR")->capture_default_str()->group("AMR parameter"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_option("--nfiles", nfiles, "Number of output files")->capture_default_str()->group("Output"); @@ -69,7 +67,8 @@ int main(int argc, char* argv[]) constexpr std::size_t dim = 1; const samurai::Box box({-3}, {3}); - Mesh> mesh(box, start_level, min_level, max_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + Mesh> mesh(config, box, start_level); auto phi = init_sol(mesh); diff --git a/demos/tutorial/reconstruction_1d.cpp b/demos/tutorial/reconstruction_1d.cpp index 3e0946dc1..9c86cb5f8 100644 --- a/demos/tutorial/reconstruction_1d.cpp +++ b/demos/tutorial/reconstruction_1d.cpp @@ -63,7 +63,7 @@ int main(int argc, char* argv[]) constexpr std::size_t graduation_width_ = 2; constexpr std::size_t max_refinement_level_ = samurai::default_config::max_level; constexpr std::size_t prediction_order_ = 1; - using MRConfig = samurai::MRConfig; + using MRConfig = samurai::MRConfig; Case test_case{Case::abs}; const std::map map{ @@ -81,8 +81,6 @@ int main(int argc, char* argv[]) std::string filename = "reconstruction_1d"; app.add_option("--case", test_case, "Test case")->capture_default_str()->transform(CLI::CheckedTransformer(map, CLI::ignore_case)); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); @@ -100,8 +98,15 @@ int main(int argc, char* argv[]) using UMesh = samurai::UniformMesh; const samurai::Box box({-1}, {1}); - MRMesh mrmesh{box, min_level, max_level, 0, 1}; - UMesh umesh{box, max_level, 0, 1}; + auto config = samurai::mesh_config() + .min_level(min_level) + .max_level(max_level) + .approx_box_tol(0) + .scaling_factor(1) + .graduation_width(graduation_width_) + .max_stencil_radius(max_stencil_width_); + MRMesh mrmesh{config, box}; + UMesh umesh{box, mrmesh.max_level(), 0, 1}; auto u = init(mrmesh, test_case); auto u_exact = init(umesh, test_case); diff --git a/demos/tutorial/reconstruction_2d.cpp b/demos/tutorial/reconstruction_2d.cpp index 8dbd50d88..165d4949e 100644 --- a/demos/tutorial/reconstruction_2d.cpp +++ b/demos/tutorial/reconstruction_2d.cpp @@ -91,7 +91,7 @@ int main(int argc, char* argv[]) constexpr std::size_t graduation_width_ = 2; constexpr std::size_t max_refinement_level_ = samurai::default_config::max_level; constexpr std::size_t prediction_order_ = 1; - using MRConfig = samurai::MRConfig; + using MRConfig = samurai::MRConfig; Case test_case{Case::abs}; const std::map map{ @@ -109,8 +109,6 @@ int main(int argc, char* argv[]) std::string filename = "reconstruction_2d"; app.add_option("--case", test_case, "Test case")->capture_default_str()->transform(CLI::CheckedTransformer(map, CLI::ignore_case)); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); @@ -128,8 +126,15 @@ int main(int argc, char* argv[]) using UMesh = samurai::UniformMesh; const samurai::Box box({-1, -1}, {1, 1}); - MRMesh mrmesh{box, min_level, max_level, 0, 1}; - UMesh umesh{box, max_level, 0, 1}; + auto config = samurai::mesh_config() + .min_level(min_level) + .max_level(max_level) + .approx_box_tol(0) + .scaling_factor(1) + .graduation_width(graduation_width_) + .max_stencil_radius(max_stencil_width_); + MRMesh mrmesh{config, box}; + UMesh umesh{box, mrmesh.max_level(), 0, 1}; auto u = init(mrmesh, test_case); auto u_exact = init(umesh, test_case); diff --git a/demos/tutorial/reconstruction_3d.cpp b/demos/tutorial/reconstruction_3d.cpp index b2def1b5b..2be5310df 100644 --- a/demos/tutorial/reconstruction_3d.cpp +++ b/demos/tutorial/reconstruction_3d.cpp @@ -97,7 +97,7 @@ int main(int argc, char* argv[]) constexpr std::size_t graduation_width_ = 2; constexpr std::size_t max_refinement_level_ = samurai::default_config::max_level; constexpr std::size_t prediction_order_ = 1; - using MRConfig = samurai::MRConfig; + using MRConfig = samurai::MRConfig; Case test_case{Case::abs}; const std::map map{ @@ -115,8 +115,6 @@ int main(int argc, char* argv[]) std::string filename = "reconstruction_3d"; app.add_option("--case", test_case, "Test case")->capture_default_str()->transform(CLI::CheckedTransformer(map, CLI::ignore_case)); - app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution"); - app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); @@ -134,8 +132,15 @@ int main(int argc, char* argv[]) using UMesh = samurai::UniformMesh; const samurai::Box box({-1, -1, -1}, {1, 1, 1}); - MRMesh mrmesh{box, min_level, max_level, 0, 1}; - UMesh umesh{box, max_level, 0, 1}; + auto config = samurai::mesh_config() + .min_level(min_level) + .max_level(max_level) + .approx_box_tol(0) + .scaling_factor(1) + .graduation_width(graduation_width_) + .max_stencil_radius(max_stencil_width_); + MRMesh mrmesh{config, box}; + UMesh umesh{box, mrmesh.max_level(), 0, 1}; auto u = init(mrmesh, test_case); auto u_exact = init(umesh, test_case); diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 0ac297ef1..b0939801f 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -539,7 +539,7 @@ namespace samurai // negartive directions, we actually need 2 times the stencil width inside the hole. // min_level where the BC can be applied - std::size_t min_level_bc = m_config.min_level(); + std::size_t min_level_bc = min_level(); if (scaling_factor <= 0) { scaling_factor = domain_builder.largest_subdivision(); @@ -547,7 +547,7 @@ namespace samurai auto largest_cell_length = samurai::cell_length(scaling_factor, min_level_bc); for (const auto& box : domain_builder.removed_boxes()) { - while (box.min_length() < 2 * largest_cell_length * config::max_stencil_width) + while (box.min_length() < 2 * largest_cell_length * max_stencil_radius()) { scaling_factor /= 2; largest_cell_length /= 2; @@ -559,10 +559,10 @@ namespace samurai auto largest_cell_length = samurai::cell_length(scaling_factor, min_level_bc); for (const auto& box : domain_builder.removed_boxes()) { - if (box.min_length() < 2 * largest_cell_length * config::max_stencil_width) + if (box.min_length() < 2 * largest_cell_length * max_stencil_radius()) { std::cerr << "The hole " << box << " is too small to apply the BC at level " << min_level_bc - << " with the given scaling factor. We need to be able to construct " << (2 * config::max_stencil_width) + << " with the given scaling factor. We need to be able to construct " << (2 * max_stencil_radius()) << " ghosts in each direction inside the hole." << std::endl; std::cerr << "Please choose a smaller scaling factor or enlarge the hole." << std::endl; std::exit(1); From 84dd5a53e305b674be5f0f059e663e3997627e78 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Thu, 25 Sep 2025 14:51:35 +0200 Subject: [PATCH 17/60] fix tests and demos --- demos/FiniteVolume/manual_block_matrix_assembly.cpp | 5 +++-- demos/FiniteVolume/nagumo.cpp | 3 ++- demos/tutorial/proj_on_mesh.cpp | 9 ++++----- tests/test_find.cpp | 3 ++- tests/test_hdf5.cpp | 3 ++- tests/test_mra.cpp | 3 ++- tests/test_periodic.cpp | 11 ++++------- tests/test_restart.cpp | 3 ++- tests/test_scaling.cpp | 3 ++- tests/test_subset.cpp | 5 +++-- 10 files changed, 26 insertions(+), 22 deletions(-) diff --git a/demos/FiniteVolume/manual_block_matrix_assembly.cpp b/demos/FiniteVolume/manual_block_matrix_assembly.cpp index 03b86f243..3c82f997c 100644 --- a/demos/FiniteVolume/manual_block_matrix_assembly.cpp +++ b/demos/FiniteVolume/manual_block_matrix_assembly.cpp @@ -197,8 +197,9 @@ int main(int argc, char* argv[]) std::size_t max_level = 3; Box box({0, 0}, {1, 1}); - samurai::MRMesh mesh_e{box, min_level, max_level}; - samurai::MRMesh mesh_s{box, min_level, max_level}; + auto mesh_cfg = samurai::mesh_config().min_level(min_level).max_level(max_level); + samurai::MRMesh mesh_e{mesh_cfg, box}; + samurai::MRMesh mesh_s{mesh_cfg, box}; //-------------------------------// // Fields and auxiliary unknowns // diff --git a/demos/FiniteVolume/nagumo.cpp b/demos/FiniteVolume/nagumo.cpp index 5e71fd265..dba39d60e 100644 --- a/demos/FiniteVolume/nagumo.cpp +++ b/demos/FiniteVolume/nagumo.cpp @@ -128,7 +128,8 @@ int main(int argc, char* argv[]) if (restart_file.empty()) { - mesh = {box, min_level, max_level}; + auto mesh_cfg = samurai::mesh_config().min_level(min_level).max_level(max_level); + mesh = {mesh_cfg, box}; u.resize(); // Initial solution samurai::for_each_cell(mesh, diff --git a/demos/tutorial/proj_on_mesh.cpp b/demos/tutorial/proj_on_mesh.cpp index 36e91fe18..09ba9f056 100644 --- a/demos/tutorial/proj_on_mesh.cpp +++ b/demos/tutorial/proj_on_mesh.cpp @@ -57,12 +57,11 @@ int main() using Config = samurai::MRConfig; auto box = samurai::Box({0., 0., 0.}, {1., 1., 1.}); - const std::size_t min_level = 2; - const std::size_t max_level = 8; - auto mesh1 = samurai::MRMesh(box, min_level, max_level); - auto f1 = init_field(mesh1, 0); + auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(8); + auto mesh1 = samurai::MRMesh(mesh_cfg, box); + auto f1 = init_field(mesh1, 0); - auto mesh2 = samurai::MRMesh(box, min_level, max_level); + auto mesh2 = samurai::MRMesh(mesh_cfg, box); auto f2 = init_field(mesh2, 0.1); auto adapt_1 = samurai::make_MRAdapt(f1); diff --git a/tests/test_find.cpp b/tests/test_find.cpp index 8e1efd1ac..d8c5fcb16 100644 --- a/tests/test_find.cpp +++ b/tests/test_find.cpp @@ -20,7 +20,8 @@ namespace samurai std::size_t min_level = 2; std::size_t max_level = 6; - Mesh mesh{box, min_level, max_level}; + auto mesh_cfg = samurai::mesh_config().min_level(min_level).max_level(max_level); + Mesh mesh{mesh_cfg, box}; auto u = samurai::make_scalar_field("u", mesh, diff --git a/tests/test_hdf5.cpp b/tests/test_hdf5.cpp index f3567a707..3717f1993 100644 --- a/tests/test_hdf5.cpp +++ b/tests/test_hdf5.cpp @@ -94,7 +94,8 @@ namespace samurai min_corner.fill(-1); max_corner.fill(1); Box box(min_corner, max_corner); - Mesh mesh(box, 4, 4); + auto mesh_cfg = samurai::mesh_config().min_level(4).max_level(4); + Mesh mesh(mesh_cfg, box); test_save(mesh); args::save_debug_fields = true; test_save(mesh); diff --git a/tests/test_mra.cpp b/tests/test_mra.cpp index 0eeb51cde..b249ef31b 100644 --- a/tests/test_mra.cpp +++ b/tests/test_mra.cpp @@ -16,7 +16,8 @@ namespace samurai const std::size_t min_level = 2; const std::size_t max_level = 10; - return samurai::MRMesh(box, min_level, max_level); + auto mesh_cfg = samurai::mesh_config().min_level(min_level).max_level(max_level); + return samurai::MRMesh(mesh_cfg, box); } void init_field(auto& u, double factor = 1.0) diff --git a/tests/test_periodic.cpp b/tests/test_periodic.cpp index 9405df454..19332a34e 100644 --- a/tests/test_periodic.cpp +++ b/tests/test_periodic.cpp @@ -45,7 +45,7 @@ namespace samurai TYPED_TEST(dim_test, periodic) { static constexpr std::size_t dim = TypeParam::value; - using Config = MRConfig; + using Config = MRConfig; // Simulation parameters xt::xtensor_fixed> min_corner, max_corner; @@ -53,16 +53,13 @@ namespace samurai max_corner.fill(1); // Multiresolution parameters - std::size_t min_level = 3, max_level = 6; - Box box(min_corner, max_corner); - std::array bc; - bc.fill(true); - MRMesh mesh{box, min_level, max_level, bc}; + auto mesh_cfg = samurai::mesh_config().min_level(3).max_level(6).periodic(true).graduation_width(1); + MRMesh mesh{mesh_cfg, box}; using mesh_id_t = typename MRMesh::mesh_id_t; double dt = 1; - double Tf = 2 / mesh.cell_length(max_level); + double Tf = 2 / mesh.cell_length(mesh.max_level()); double t = 0.; auto u = init(mesh); diff --git a/tests/test_restart.cpp b/tests/test_restart.cpp index 094c87df6..68de8ef41 100644 --- a/tests/test_restart.cpp +++ b/tests/test_restart.cpp @@ -19,8 +19,9 @@ namespace samurai box_corner1.fill(0); box_corner2.fill(box_boundary); Box box(box_corner1, box_corner2); + auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(5); - return Mesh(box, 2, 5); + return Mesh(mesh_cfg, box); } TEST(restart, restart_lca) diff --git a/tests/test_scaling.cpp b/tests/test_scaling.cpp index bd35f93e2..a9a090608 100644 --- a/tests/test_scaling.cpp +++ b/tests/test_scaling.cpp @@ -17,8 +17,9 @@ namespace samurai box_corner1.fill(0); box_corner2.fill(box_boundary); Box box(box_corner1, box_corner2); + auto mesh_cfg = samurai::mesh_config().min_level(level).max_level(level); - return Mesh(box, level, level); + return Mesh(mesh_cfg, box); } /** diff --git a/tests/test_subset.cpp b/tests/test_subset.cpp index 71e28144e..20fa4e814 100644 --- a/tests/test_subset.cpp +++ b/tests/test_subset.cpp @@ -484,8 +484,9 @@ namespace samurai { using Config = MRConfig<2>; - const Box box({0, 0}, {1, 1}); - MRMesh mesh{box, 0, 3}; + const Box box({0, 0}, {1, 1}); + auto mesh_cfg = samurai::mesh_config().min_level(0).max_level(3); + MRMesh mesh{mesh_cfg, box}; auto& domain = mesh.domain(); xt::xtensor_fixed> dir = {0, 1 << (3 - 1)}; From a69794077ee051ad13db86e38c157b8a32e1277c Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 30 Sep 2025 13:20:17 +0200 Subject: [PATCH 18/60] fix demos --- demos/FiniteVolume/BZ/bz_2d.cpp | 5 ++-- demos/FiniteVolume/burgers_os.cpp | 11 ++++++-- demos/FiniteVolume/level_set.cpp | 4 +-- demos/FiniteVolume/linear_convection.cpp | 6 ++--- .../linear_convection_obstacle.cpp | 4 +-- demos/FiniteVolume/stokes_2d.cpp | 4 +-- demos/Weno/VF_level_set_houc5_amr.cpp | 12 ++++----- demos/Weno/VF_level_set_os5_amr.cpp | 12 ++++----- demos/Weno/heat_weno5_amr.cpp | 12 ++++----- demos/Weno/weno5_amr.cpp | 12 ++++----- demos/highorder/main.cpp | 23 ++++++++-------- demos/tutorial/reconstruction_1d.cpp | 25 +++++++---------- demos/tutorial/reconstruction_2d.cpp | 25 +++++++---------- demos/tutorial/reconstruction_3d.cpp | 27 +++++++------------ include/samurai/mesh_config.hpp | 1 + 15 files changed, 79 insertions(+), 104 deletions(-) diff --git a/demos/FiniteVolume/BZ/bz_2d.cpp b/demos/FiniteVolume/BZ/bz_2d.cpp index 05d7efd64..40f9e8371 100644 --- a/demos/FiniteVolume/BZ/bz_2d.cpp +++ b/demos/FiniteVolume/BZ/bz_2d.cpp @@ -289,8 +289,9 @@ int main() const double regularity = 1.; // Regularity guess for multiresolution const double epsilon_MR = 2.e-4; // Threshold used by multiresolution - using Config = samurai::MRConfig; - samurai::MRMesh mesh(box, min_level, max_level); // Constructing mesh from the box + using Config = samurai::MRConfig; + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_radius(2); + samurai::MRMesh mesh(config, box); // Constructing mesh from the box using mesh_id_t = typename decltype(mesh)::mesh_id_t; diff --git a/demos/FiniteVolume/burgers_os.cpp b/demos/FiniteVolume/burgers_os.cpp index 4d3bce296..639046317 100644 --- a/demos/FiniteVolume/burgers_os.cpp +++ b/demos/FiniteVolume/burgers_os.cpp @@ -90,7 +90,7 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the linear convection equation", argc, argv); static constexpr std::size_t dim = 1; - using Config = samurai::MRConfig; + using Config = samurai::MRConfig; using Box = samurai::Box; using point_t = typename Box::point_t; @@ -147,7 +147,14 @@ int main(int argc, char* argv[]) samurai::LevelCellArray<1> lca_left(max_level, box_left, {-1}, 0.05, 2); samurai::LevelCellArray<1> lca_right(max_level, box_right, {-1}, 0.05, 2); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).periodic(true).approx_box_tol(0.05).scaling_factor(2); + auto config = samurai::mesh_config() + .min_level(min_level) + .max_level(max_level) + .periodic(true) + .approx_box_tol(0.05) + .scaling_factor(2) + .max_stencil_radius(2) + .graduation_width(2); std::cout << " max_level = " << config.max_level() << " min_level = " << config.min_level() << std::endl; samurai::MRMesh mesh{config, box}; diff --git a/demos/FiniteVolume/level_set.cpp b/demos/FiniteVolume/level_set.cpp index 983ef9e4c..f31eb1df2 100644 --- a/demos/FiniteVolume/level_set.cpp +++ b/demos/FiniteVolume/level_set.cpp @@ -253,7 +253,7 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example with a level set in 2d using AMR", argc, argv); constexpr std::size_t dim = 2; - using Config = samurai::amr::Config; + using Config = samurai::amr::Config; // Simulation parameters xt::xtensor_fixed> min_corner = {0., 0.}; @@ -290,7 +290,7 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box(min_corner, max_corner); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_radius(2); samurai::amr::Mesh mesh; auto phi = samurai::make_scalar_field("phi", mesh); diff --git a/demos/FiniteVolume/linear_convection.cpp b/demos/FiniteVolume/linear_convection.cpp index 41d8a5fe5..284a4530f 100644 --- a/demos/FiniteVolume/linear_convection.cpp +++ b/demos/FiniteVolume/linear_convection.cpp @@ -37,7 +37,7 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the linear convection equation", argc, argv); static constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; + using Config = samurai::MRConfig; using Box = samurai::Box; using point_t = typename Box::point_t; @@ -87,14 +87,12 @@ int main(int argc, char* argv[]) box_corner1.fill(left_box); box_corner2.fill(right_box); Box box(box_corner1, box_corner2); - std::array periodic; - periodic.fill(true); samurai::MRMesh mesh; auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { - auto config = samurai::mesh_config().min_level(1).max_level(dim == 1 ? 6 : 4).periodic(periodic).max_stencil_radius(3); + auto config = samurai::mesh_config().min_level(1).max_level(dim == 1 ? 6 : 4).periodic(true).max_stencil_width(6); mesh = {config, box}; // Initial solution u = samurai::make_scalar_field("u", diff --git a/demos/FiniteVolume/linear_convection_obstacle.cpp b/demos/FiniteVolume/linear_convection_obstacle.cpp index 5d807c984..8080bfa83 100644 --- a/demos/FiniteVolume/linear_convection_obstacle.cpp +++ b/demos/FiniteVolume/linear_convection_obstacle.cpp @@ -36,7 +36,7 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the linear convection equation", argc, argv); static constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; + using Config = samurai::MRConfig; using Mesh = samurai::MRMesh; std::cout << "------------------------- Linear convection -------------------------" << std::endl; @@ -75,7 +75,7 @@ int main(int argc, char* argv[]) samurai::DomainBuilder domain({-1., -1.}, {1., 1.}); domain.remove({0.0, 0.0}, {0.4, 0.4}); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_width(6); Mesh mesh = {config, domain}; // Mesh mesh(domain, min_level, max_level); diff --git a/demos/FiniteVolume/stokes_2d.cpp b/demos/FiniteVolume/stokes_2d.cpp index 3644aa4cb..7b00cda72 100644 --- a/demos/FiniteVolume/stokes_2d.cpp +++ b/demos/FiniteVolume/stokes_2d.cpp @@ -153,7 +153,7 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Stokes problem", argc, argv); constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; + using Config = samurai::MRConfig; using Mesh = samurai::MRMesh; using mesh_id_t = typename Mesh::mesh_id_t; static constexpr bool is_soa = false; @@ -195,7 +195,7 @@ int main(int argc, char* argv[]) PetscCheck(size == 1, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "This is a uniprocessor example only!"); auto box = samurai::Box({0, 0}, {1, 1}); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_radius(2); auto mesh = Mesh(config, box); //--------------------// diff --git a/demos/Weno/VF_level_set_houc5_amr.cpp b/demos/Weno/VF_level_set_houc5_amr.cpp index 541859416..274e0ca86 100644 --- a/demos/Weno/VF_level_set_houc5_amr.cpp +++ b/demos/Weno/VF_level_set_houc5_amr.cpp @@ -261,19 +261,17 @@ int main() { samurai::initialize(); - constexpr std::size_t dim = 2; - constexpr std::size_t ghost_width = 3; + constexpr std::size_t dim = 2; std::size_t start_level = 8; - std::size_t min_level = 2; - std::size_t max_level = 8; samurai::Box box{ {0, 0}, {1, 1} }; - using Config = samurai::amr::Config; - samurai::amr::Mesh mesh(box, start_level, min_level, max_level); + using Config = samurai::amr::Config; + auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(8).max_stencil_radius(3); + samurai::amr::Mesh mesh(mesh_cfg, box, start_level); auto field = init_field(mesh); @@ -282,7 +280,7 @@ int main() update_bc_for_level_(field, level); }; - double dt = 0.5 / (1 << max_level); + double dt = 0.5 * mesh.min_cell_length(); double Tf = 2.; // Final time std::size_t max_ite = Tf / dt; diff --git a/demos/Weno/VF_level_set_os5_amr.cpp b/demos/Weno/VF_level_set_os5_amr.cpp index 612435186..16003f092 100644 --- a/demos/Weno/VF_level_set_os5_amr.cpp +++ b/demos/Weno/VF_level_set_os5_amr.cpp @@ -278,18 +278,16 @@ int main() { samurai::initialize(); - constexpr std::size_t dim = 2; - constexpr std::size_t ghost_width = 3; - std::size_t start_level = 6; - std::size_t min_level = 2; - std::size_t max_level = 8; + constexpr std::size_t dim = 2; + std::size_t start_level = 6; samurai::Box box{ {0, 0}, {1, 1} }; - using Config = samurai::amr::Config; - samurai::amr::Mesh mesh(box, start_level, min_level, max_level); + using Config = samurai::amr::Config; + auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(8).max_stencil_radius(3); + samurai::amr::Mesh mesh(mesh_cfg, box, start_level); auto field = init_field(mesh); diff --git a/demos/Weno/heat_weno5_amr.cpp b/demos/Weno/heat_weno5_amr.cpp index e3bffc6a9..abbe2c767 100644 --- a/demos/Weno/heat_weno5_amr.cpp +++ b/demos/Weno/heat_weno5_amr.cpp @@ -720,18 +720,16 @@ int main() { samurai::initialize(); - constexpr std::size_t dim = 2; - constexpr std::size_t ghost_width = 3; - std::size_t start_level = 7; - std::size_t min_level = 2; - std::size_t max_level = 10; + constexpr std::size_t dim = 2; + std::size_t start_level = 7; samurai::Box box{ {0, 0, 0}, {1, 1, 1} }; - using Config = samurai::amr::Config; - samurai::amr::Mesh mesh(box, start_level, min_level, max_level); + using Config = samurai::amr::Config; + auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(10).max_stencil_radius(3); + samurai::amr::Mesh mesh(mesh_cfg, box, start_level); using mesh_id_t = typename Config::mesh_id_t; auto field = init_field::call(samurai::Dim{}, mesh); diff --git a/demos/Weno/weno5_amr.cpp b/demos/Weno/weno5_amr.cpp index 5492c6f2a..185bbefa2 100644 --- a/demos/Weno/weno5_amr.cpp +++ b/demos/Weno/weno5_amr.cpp @@ -437,18 +437,16 @@ int main() { samurai::initialize(); - constexpr std::size_t dim = 2; - constexpr std::size_t ghost_width = 3; - std::size_t start_level = 7; - std::size_t min_level = 2; - std::size_t max_level = 10; + constexpr std::size_t dim = 2; + std::size_t start_level = 7; samurai::Box box{ {0, 0, 0}, {1, 1, 1} }; - using Config = samurai::amr::Config; - samurai::amr::Mesh mesh(box, start_level, min_level, max_level); + using Config = samurai::amr::Config; + auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(10).max_stencil_radius(3); + samurai::amr::Mesh mesh(mesh_cfg, box, start_level); using mesh_id_t = typename Config::mesh_id_t; auto field = init_field::call(samurai::Dim{}, mesh); diff --git a/demos/highorder/main.cpp b/demos/highorder/main.cpp index b71fe0a45..ec7316180 100644 --- a/demos/highorder/main.cpp +++ b/demos/highorder/main.cpp @@ -112,19 +112,16 @@ int main(int argc, char* argv[]) { auto& app = samurai::initialize("Finite volume example for the advection equation in 2d using multiresolution", argc, argv); - constexpr std::size_t dim = 2; - constexpr std::size_t stencil_width = 2; - constexpr std::size_t graduation_width = 4; - constexpr std::size_t prediction_order = 1; - using Config = samurai::MRConfig; + constexpr std::size_t dim = 2; + using Config = samurai::MRConfig; + + constexpr std::size_t prediction_stencil_radius = 1; // Simulation parameters xt::xtensor_fixed> min_corner = {0., 0.}; xt::xtensor_fixed> max_corner = {1., 1.}; // Multiresolution parameters - std::size_t min_level = 4; - std::size_t max_level = 4; std::size_t refinement = 5; bool correction = false; @@ -149,11 +146,13 @@ int main(int argc, char* argv[]) using mesh_id_t = typename mesh_t::mesh_id_t; using cl_type = typename mesh_t::cl_type; - auto config = samurai::mesh_config() - .min_level(min_level) - .max_level(max_level) - .graduation_width(graduation_width) - .max_stencil_radius(stencil_width); + // clang-format off + auto config = samurai::mesh_config() + .min_level(4) + .max_level(4) + .graduation_width(4) + .max_stencil_width(4); + // clang-format on mesh_t init_mesh{config, box}; auto adapt_field = samurai::make_scalar_field("adapt_field", diff --git a/demos/tutorial/reconstruction_1d.cpp b/demos/tutorial/reconstruction_1d.cpp index 9c86cb5f8..78ad23e27 100644 --- a/demos/tutorial/reconstruction_1d.cpp +++ b/demos/tutorial/reconstruction_1d.cpp @@ -58,12 +58,8 @@ int main(int argc, char* argv[]) { auto& app = samurai::initialize("1d reconstruction of an adapted solution using multiresolution", argc, argv); - constexpr size_t dim = 1; - constexpr std::size_t max_stencil_width_ = 2; - constexpr std::size_t graduation_width_ = 2; - constexpr std::size_t max_refinement_level_ = samurai::default_config::max_level; - constexpr std::size_t prediction_order_ = 1; - using MRConfig = samurai::MRConfig; + constexpr size_t dim = 1; + using MRConfig = samurai::MRConfig; Case test_case{Case::abs}; const std::map map{ @@ -72,10 +68,6 @@ int main(int argc, char* argv[]) {"tanh", Case::tanh} }; - // Adaptation parameters - std::size_t min_level = 3; - std::size_t max_level = 8; - // Output parameters fs::path path = fs::current_path(); std::string filename = "reconstruction_1d"; @@ -98,13 +90,14 @@ int main(int argc, char* argv[]) using UMesh = samurai::UniformMesh; const samurai::Box box({-1}, {1}); + // clang-format off auto config = samurai::mesh_config() - .min_level(min_level) - .max_level(max_level) - .approx_box_tol(0) - .scaling_factor(1) - .graduation_width(graduation_width_) - .max_stencil_radius(max_stencil_width_); + .min_level(3) + .max_level(8) + .scaling_factor(1) + .graduation_width(2) + .max_stencil_radius(2); + // clang-format on MRMesh mrmesh{config, box}; UMesh umesh{box, mrmesh.max_level(), 0, 1}; auto u = init(mrmesh, test_case); diff --git a/demos/tutorial/reconstruction_2d.cpp b/demos/tutorial/reconstruction_2d.cpp index 165d4949e..66a78d466 100644 --- a/demos/tutorial/reconstruction_2d.cpp +++ b/demos/tutorial/reconstruction_2d.cpp @@ -86,12 +86,8 @@ int main(int argc, char* argv[]) { auto& app = samurai::initialize("2d reconstruction of an adapted solution using multiresolution", argc, argv); - constexpr size_t dim = 2; - constexpr std::size_t max_stencil_width_ = 2; - constexpr std::size_t graduation_width_ = 2; - constexpr std::size_t max_refinement_level_ = samurai::default_config::max_level; - constexpr std::size_t prediction_order_ = 1; - using MRConfig = samurai::MRConfig; + constexpr size_t dim = 2; + using MRConfig = samurai::MRConfig; Case test_case{Case::abs}; const std::map map{ @@ -100,10 +96,6 @@ int main(int argc, char* argv[]) {"tanh", Case::tanh} }; - // Adaptation parameters - std::size_t min_level = 3; - std::size_t max_level = 8; - // Output parameters fs::path path = fs::current_path(); std::string filename = "reconstruction_2d"; @@ -126,13 +118,14 @@ int main(int argc, char* argv[]) using UMesh = samurai::UniformMesh; const samurai::Box box({-1, -1}, {1, 1}); + // clang-format off auto config = samurai::mesh_config() - .min_level(min_level) - .max_level(max_level) - .approx_box_tol(0) - .scaling_factor(1) - .graduation_width(graduation_width_) - .max_stencil_radius(max_stencil_width_); + .min_level(3) + .max_level(8) + .scaling_factor(1) + .graduation_width(2) + .max_stencil_radius(2); + // clang-format on MRMesh mrmesh{config, box}; UMesh umesh{box, mrmesh.max_level(), 0, 1}; auto u = init(mrmesh, test_case); diff --git a/demos/tutorial/reconstruction_3d.cpp b/demos/tutorial/reconstruction_3d.cpp index 2be5310df..c68ff2096 100644 --- a/demos/tutorial/reconstruction_3d.cpp +++ b/demos/tutorial/reconstruction_3d.cpp @@ -90,14 +90,8 @@ int main(int argc, char* argv[]) { auto& app = samurai::initialize("3d reconstruction of an adapted solution using multiresolution", argc, argv); - constexpr size_t dim = 3; - constexpr std::size_t max_stencil_width_ = 2; - // constexpr std::size_t graduation_width_ = - // samurai::default_config::graduation_width; - constexpr std::size_t graduation_width_ = 2; - constexpr std::size_t max_refinement_level_ = samurai::default_config::max_level; - constexpr std::size_t prediction_order_ = 1; - using MRConfig = samurai::MRConfig; + constexpr size_t dim = 3; + using MRConfig = samurai::MRConfig; Case test_case{Case::abs}; const std::map map{ @@ -106,10 +100,6 @@ int main(int argc, char* argv[]) {"tanh", Case::tanh} }; - // Adaptation parameters - std::size_t min_level = 2; - std::size_t max_level = 5; - // Output parameters fs::path path = fs::current_path(); std::string filename = "reconstruction_3d"; @@ -132,13 +122,14 @@ int main(int argc, char* argv[]) using UMesh = samurai::UniformMesh; const samurai::Box box({-1, -1, -1}, {1, 1, 1}); + // clang-format off auto config = samurai::mesh_config() - .min_level(min_level) - .max_level(max_level) - .approx_box_tol(0) - .scaling_factor(1) - .graduation_width(graduation_width_) - .max_stencil_radius(max_stencil_width_); + .min_level(2) + .max_level(5) + .scaling_factor(1) + .graduation_width(2) + .max_stencil_radius(2); + // clang-format on MRMesh mrmesh{config, box}; UMesh umesh{box, mrmesh.max_level(), 0, 1}; auto u = init(mrmesh, test_case); diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index c104a70a7..73b7bdc07 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -26,6 +26,7 @@ namespace samurai std::size_t m_min_level = 0; std::size_t m_max_level = 6; + // std::size_t m_initial_level; double m_approx_box_tol = 0.05; double m_scaling_factor = 0; From ab30c272e77e3d9b1096928b29ea35d430f74fdd Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 30 Sep 2025 13:41:31 +0200 Subject: [PATCH 19/60] fix demos --- demos/FiniteVolume/linear_convection.cpp | 2 +- demos/FiniteVolume/linear_convection_obstacle.cpp | 2 +- demos/highorder/main.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/demos/FiniteVolume/linear_convection.cpp b/demos/FiniteVolume/linear_convection.cpp index 284a4530f..827e99555 100644 --- a/demos/FiniteVolume/linear_convection.cpp +++ b/demos/FiniteVolume/linear_convection.cpp @@ -92,7 +92,7 @@ int main(int argc, char* argv[]) if (restart_file.empty()) { - auto config = samurai::mesh_config().min_level(1).max_level(dim == 1 ? 6 : 4).periodic(true).max_stencil_width(6); + auto config = samurai::mesh_config().min_level(1).max_level(dim == 1 ? 6 : 4).periodic(true).max_stencil_size(6); mesh = {config, box}; // Initial solution u = samurai::make_scalar_field("u", diff --git a/demos/FiniteVolume/linear_convection_obstacle.cpp b/demos/FiniteVolume/linear_convection_obstacle.cpp index 8080bfa83..f2cf63222 100644 --- a/demos/FiniteVolume/linear_convection_obstacle.cpp +++ b/demos/FiniteVolume/linear_convection_obstacle.cpp @@ -75,7 +75,7 @@ int main(int argc, char* argv[]) samurai::DomainBuilder domain({-1., -1.}, {1., 1.}); domain.remove({0.0, 0.0}, {0.4, 0.4}); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_width(6); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_size(6); Mesh mesh = {config, domain}; // Mesh mesh(domain, min_level, max_level); diff --git a/demos/highorder/main.cpp b/demos/highorder/main.cpp index ec7316180..71160e778 100644 --- a/demos/highorder/main.cpp +++ b/demos/highorder/main.cpp @@ -151,7 +151,7 @@ int main(int argc, char* argv[]) .min_level(4) .max_level(4) .graduation_width(4) - .max_stencil_width(4); + .max_stencil_size(4); // clang-format on mesh_t init_mesh{config, box}; From 8de741c17be20062f9fd5d21251371ac36d9db4e Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 30 Sep 2025 14:14:31 +0200 Subject: [PATCH 20/60] fix demos --- demos/highorder/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demos/highorder/main.cpp b/demos/highorder/main.cpp index 71160e778..d3f09da7c 100644 --- a/demos/highorder/main.cpp +++ b/demos/highorder/main.cpp @@ -314,8 +314,8 @@ int main(int argc, char* argv[]) }); samurai::save(fmt::format("error_ref_{}", ite), mesh, error_field); - samurai::save(fmt::format("solution_{}_{}_ref_{}", min_level, max_level, ite), mesh, u); - samurai::save(fmt::format("solution_recons_{}_{}_ref_{}", min_level, max_level, ite), u_recons.mesh(), u_recons); + samurai::save(fmt::format("solution_{}_{}_ref_{}", mesh.min_level(), mesh.max_level(), ite), mesh, u); + samurai::save(fmt::format("solution_recons_{}_{}_ref_{}", mesh.min_level(), mesh.max_level(), ite), u_recons.mesh(), u_recons); h_coarse = h; error_coarse = error; error_recons_coarse = error_recons; From 087bc16c7710679eff7d50aba6e5d83826f60698 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 30 Sep 2025 15:10:10 +0200 Subject: [PATCH 21/60] fix demos --- demos/highorder/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/demos/highorder/main.cpp b/demos/highorder/main.cpp index d3f09da7c..dfc76e703 100644 --- a/demos/highorder/main.cpp +++ b/demos/highorder/main.cpp @@ -199,8 +199,8 @@ int main(int argc, char* argv[]) }); }); // mesh = {cl, mesh.min_level() + 1, mesh.max_level() + 1}; - auto mesh_cfg = samurai::mesh_config().min_level(min_level + i_ref + 1).max_level(max_level + i_ref + 1); - mesh = {mesh_cfg, cl}; + auto mesh_cfg = samurai::mesh_config().min_level(init_mesh.min_level() + i_ref + 1).max_level(init_mesh.max_level() + i_ref + 1); + mesh = {mesh_cfg, cl}; } // std::cout << mesh << std::endl; // samurai::save("refine_mesh", mesh); @@ -232,7 +232,7 @@ int main(int argc, char* argv[]) // set.apply_op(samurai::projection(f)); // auto f_recons = samurai::make_scalar_field("f_recons", mesh); // auto error_f = samurai::make_scalar_field("error", mesh); - // set.apply_op(samurai::prediction(f_recons, f)); + // set.apply_op(samurai::prediction(f_recons, f)); // samurai::for_each_interval(mesh[mesh_id_t::cells], [&](std::size_t level, // const auto& i, const auto& index) // { From 472b9567bdfabade6e72d32f1c9a0f85df1cea55 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 30 Sep 2025 16:18:52 +0200 Subject: [PATCH 22/60] fix demos --- demos/FiniteVolume/stokes_2d.cpp | 12 +++++------- demos/p4est/simple_2d.cpp | 11 ++++------- demos/tutorial/graduation_case_3.cpp | 2 +- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/demos/FiniteVolume/stokes_2d.cpp b/demos/FiniteVolume/stokes_2d.cpp index 7b00cda72..6d0ed01ed 100644 --- a/demos/FiniteVolume/stokes_2d.cpp +++ b/demos/FiniteVolume/stokes_2d.cpp @@ -165,10 +165,8 @@ int main(int argc, char* argv[]) std::string test_case = "ns"; - std::size_t min_level = 5; - std::size_t max_level = 5; - double Tf = 1.; - double dt = Tf / 100; + double Tf = 1.; + double dt = Tf / 100; std::size_t nfiles = 50; @@ -195,7 +193,7 @@ int main(int argc, char* argv[]) PetscCheck(size == 1, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "This is a uniprocessor example only!"); auto box = samurai::Box({0, 0}, {1, 1}); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_radius(2); + auto config = samurai::mesh_config().min_level(5).max_level(5).max_stencil_radius(2); auto mesh = Mesh(config, box); //--------------------// @@ -466,7 +464,7 @@ int main(int argc, char* argv[]) std::cout << fmt::format("iteration {}: t = {:.2f}, dt = {}", nt++, t_np1, dt); // Mesh adaptation - if (min_level != max_level) + if (mesh.min_level() != mesh.max_level()) { MRadaptation(mra_config); min_level_np1 = mesh[mesh_id_t::cells].min_level(); @@ -547,7 +545,7 @@ int main(int argc, char* argv[]) samurai::save(path, fmt::format("{}_ite_{}", filename, nsave), velocity.mesh(), velocity, div_velocity); } - if (min_level != max_level) + if (mesh.min_level() != mesh.max_level()) { // Reconstruction on the finest level auto velocity_recons = samurai::reconstruction(velocity); diff --git a/demos/p4est/simple_2d.cpp b/demos/p4est/simple_2d.cpp index 4e1393d18..eae02d347 100644 --- a/demos/p4est/simple_2d.cpp +++ b/demos/p4est/simple_2d.cpp @@ -201,17 +201,15 @@ int main(int argc, char* argv[]) constexpr size_t dim = 2; - // Adaptation parameters - std::size_t max_level = 9; - // Output parameters fs::path path = fs::current_path(); std::string filename = "simple_2d"; - app.add_option("--max-level", max_level, "Maximum level of the adaptation")->capture_default_str()->group("Adaptation parameters"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); SAMURAI_PARSE(argc, argv); + auto config = samurai::mesh_config().min_level(1).max_level(9); + config.parse_args(); if (!fs::exists(path)) { @@ -232,7 +230,7 @@ int main(int argc, char* argv[]) std::cout << "nb_cells: " << mesh_1.nb_cells() << "\n"; tic(); - refine_1(mesh_1, max_level); + refine_1(mesh_1, config.max_level()); auto duration = toc(); std::cout << "Version 1: " << duration << "s" << std::endl; toc(); @@ -241,11 +239,10 @@ int main(int argc, char* argv[]) // samurai::CellArray mesh_2(cl); using Config = samurai::MRConfig; using mesh_id_t = typename samurai::MRMesh::mesh_id_t; - auto config = samurai::mesh_config().min_level(1).max_level(max_level); samurai::MRMesh mesh_2(config, cl); tic(); - refine_2(mesh_2, max_level); + refine_2(mesh_2, config.max_level()); duration = toc(); std::cout << "Version 2: " << duration << "s" << std::endl; std::cout << "nb_cells: " << mesh_2.nb_cells(mesh_id_t::cells) << "\n"; diff --git a/demos/tutorial/graduation_case_3.cpp b/demos/tutorial/graduation_case_3.cpp index ef4b76c49..1bf58d875 100644 --- a/demos/tutorial/graduation_case_3.cpp +++ b/demos/tutorial/graduation_case_3.cpp @@ -43,7 +43,7 @@ int main(int argc, char* argv[]) std::string filename = "graduation_case_3"; app.add_option("--start-level", start_level, "where to start the mesh generator")->capture_default_str(); - app.add_option("--max-level", max_level, "Maximum level of the mesh generator")->capture_default_str(); + app.add_option("--maximum-level", max_level, "Maximum level of the mesh generator")->capture_default_str(); app.add_flag("--with-graduation", with_graduation, "Make the mesh graduated")->capture_default_str(); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); From 7c4c4568ae2a8e1c58e3144379fc0c1e0bae61a8 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Fri, 3 Oct 2025 15:23:57 +0200 Subject: [PATCH 23/60] add factories fo meshes --- demos/FiniteVolume/AMR_Burgers_Hat.cpp | 7 +- demos/FiniteVolume/BZ/bz_2d.cpp | 5 +- demos/FiniteVolume/advection_1d.cpp | 5 +- demos/FiniteVolume/advection_2d.cpp | 7 +- demos/FiniteVolume/advection_2d_user_bc.cpp | 5 +- demos/FiniteVolume/burgers.cpp | 3 +- demos/FiniteVolume/burgers_mra.cpp | 5 +- demos/FiniteVolume/burgers_os.cpp | 10 +- demos/FiniteVolume/heat.cpp | 7 +- demos/FiniteVolume/heat_heterogeneous.cpp | 5 +- demos/FiniteVolume/heat_nonlinear.cpp | 6 +- demos/FiniteVolume/level_set.cpp | 15 +-- demos/FiniteVolume/level_set_from_scratch.cpp | 25 ++-- demos/FiniteVolume/lid_driven_cavity.cpp | 24 ++-- demos/FiniteVolume/linear_convection.cpp | 9 +- .../linear_convection_obstacle.cpp | 4 +- .../manual_block_matrix_assembly.cpp | 5 +- demos/FiniteVolume/nagumo.cpp | 6 +- demos/FiniteVolume/scalar_burgers_2d.cpp | 5 +- demos/FiniteVolume/stokes_2d.cpp | 7 +- demos/highorder/main.cpp | 20 +-- demos/multigrid/main.cpp | 45 ++++--- .../samurai_new/multigrid/LevelCtx.hpp | 14 +-- .../multigrid/petsc/GeometricMultigrid.hpp | 8 +- .../samurai_new/multigrid/petsc/SamuraiDM.hpp | 10 +- .../multigrid/petsc/intergrid_operators.hpp | 26 ++-- demos/p4est/simple_2d.cpp | 6 +- demos/tutorial/proj_on_mesh.cpp | 5 +- demos/tutorial/reconstruction_1d.cpp | 19 ++- demos/tutorial/reconstruction_2d.cpp | 18 ++- demos/tutorial/reconstruction_3d.cpp | 18 ++- docs/source/tutorial/reaction_diffusion.rst | 6 +- include/mesh.hpp | 0 include/samurai/algorithm/graduation.hpp | 2 +- include/samurai/algorithm/update.hpp | 6 +- include/samurai/amr/mesh.hpp | 76 ++++++++---- include/samurai/mesh_config.hpp | 23 +++- include/samurai/mr/mesh.hpp | 95 +++++++++----- include/samurai/mr/mesh_with_overleaves.hpp | 22 ++-- include/samurai/mr/operators.hpp | 6 +- .../samurai/petsc/fv/FV_scheme_assembly.hpp | 116 +++++++++--------- include/samurai/reconstruction.hpp | 56 +++++---- include/samurai/samurai_config.hpp | 10 +- .../flux_based/flux_based_scheme__nonlin.hpp | 2 +- tests/test_adapt.cpp | 14 +-- tests/test_bc.cpp | 3 +- tests/test_corner_projection.cpp | 9 +- tests/test_domain_with_hole.cpp | 11 +- tests/test_field.cpp | 4 +- tests/test_find.cpp | 12 +- tests/test_for_each.cpp | 16 +-- tests/test_hdf5.cpp | 7 +- tests/test_mra.cpp | 5 +- tests/test_periodic.cpp | 7 +- tests/test_restart.cpp | 4 +- tests/test_scaling.cpp | 4 +- tests/test_subset.cpp | 11 +- 57 files changed, 454 insertions(+), 427 deletions(-) create mode 100644 include/mesh.hpp diff --git a/demos/FiniteVolume/AMR_Burgers_Hat.cpp b/demos/FiniteVolume/AMR_Burgers_Hat.cpp index 1efa0a197..a25852f74 100644 --- a/demos/FiniteVolume/AMR_Burgers_Hat.cpp +++ b/demos/FiniteVolume/AMR_Burgers_Hat.cpp @@ -197,7 +197,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the Burgers equation in 2d using AMR", argc, argv); constexpr std::size_t dim = 1; // cppcheck-suppress unreadVariable - using Config = samurai::amr::Config; // Simulation parameters double left_box = -3; @@ -235,12 +234,12 @@ int main(int argc, char* argv[]) const samurai::Box box({left_box}, {right_box}); auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); - samurai::amr::Mesh mesh; - auto phi = samurai::make_scalar_field("phi", mesh); + auto mesh = samurai::amr::make_Mesh(config); + auto phi = samurai::make_scalar_field("phi", mesh); if (restart_file.empty()) { - mesh = {config, box, start_level}; + mesh = samurai::amr::make_Mesh(config, box, start_level); init_solution(phi); } else diff --git a/demos/FiniteVolume/BZ/bz_2d.cpp b/demos/FiniteVolume/BZ/bz_2d.cpp index 40f9e8371..8e430d573 100644 --- a/demos/FiniteVolume/BZ/bz_2d.cpp +++ b/demos/FiniteVolume/BZ/bz_2d.cpp @@ -289,9 +289,8 @@ int main() const double regularity = 1.; // Regularity guess for multiresolution const double epsilon_MR = 2.e-4; // Threshold used by multiresolution - using Config = samurai::MRConfig; - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_radius(2); - samurai::MRMesh mesh(config, box); // Constructing mesh from the box + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_radius(2); + auto mesh = samurai::make_MRMesh(config, box); // Constructing mesh from the box using mesh_id_t = typename decltype(mesh)::mesh_id_t; diff --git a/demos/FiniteVolume/advection_1d.cpp b/demos/FiniteVolume/advection_1d.cpp index 13df511b7..2fcb76602 100644 --- a/demos/FiniteVolume/advection_1d.cpp +++ b/demos/FiniteVolume/advection_1d.cpp @@ -62,7 +62,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the advection equation in 1d using multiresolution", argc, argv); constexpr std::size_t dim = 1; // cppcheck-suppress unreadVariable - using Config = samurai::MRConfig; // Simulation parameters double left_box = -2; @@ -99,8 +98,8 @@ int main(int argc, char* argv[]) const samurai::Box box({left_box}, {right_box}); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).periodic(is_periodic); - samurai::MRMesh mesh = {config, box}; + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).periodic(is_periodic); + auto mesh = samurai::make_MRMesh(config, box); // samurai::MRMesh mesh; auto u = samurai::make_scalar_field("u", mesh); diff --git a/demos/FiniteVolume/advection_2d.cpp b/demos/FiniteVolume/advection_2d.cpp index 51bec0295..0d1be4d0d 100644 --- a/demos/FiniteVolume/advection_2d.cpp +++ b/demos/FiniteVolume/advection_2d.cpp @@ -63,7 +63,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the advection equation in 2d using multiresolution", argc, argv); constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; // Simulation parameters xt::xtensor_fixed> min_corner = {0., 0.}; @@ -100,12 +99,12 @@ int main(int argc, char* argv[]) const samurai::Box box(min_corner, max_corner); auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); - samurai::MRMesh mesh; - auto u = samurai::make_scalar_field("u", mesh); + auto mesh = samurai::make_MRMesh(config); + auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { - mesh = {config, box}; + mesh = samurai::make_MRMesh(config, box); init(u); } else diff --git a/demos/FiniteVolume/advection_2d_user_bc.cpp b/demos/FiniteVolume/advection_2d_user_bc.cpp index 11fefe75d..eab0328c0 100644 --- a/demos/FiniteVolume/advection_2d_user_bc.cpp +++ b/demos/FiniteVolume/advection_2d_user_bc.cpp @@ -95,7 +95,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the advection equation in 2d using multiresolution", argc, argv); constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; // Simulation parameters xt::xtensor_fixed> min_corner = {0., 0.}; @@ -132,8 +131,8 @@ int main(int argc, char* argv[]) const samurai::Box box(min_corner, max_corner); auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); - samurai::MRMesh mesh{config, box}; - auto u = samurai::make_scalar_field("u", mesh); + auto mesh = samurai::make_MRMesh(config, box); + auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { diff --git a/demos/FiniteVolume/burgers.cpp b/demos/FiniteVolume/burgers.cpp index b7f589dbb..f1a507ff1 100644 --- a/demos/FiniteVolume/burgers.cpp +++ b/demos/FiniteVolume/burgers.cpp @@ -52,7 +52,6 @@ int main_dim(int argc, char* argv[]) { auto& app = samurai::initialize("Finite volume example for the Burgers equation", argc, argv); - using Config = samurai::MRConfig; using Box = samurai::Box; using point_t = typename Box::point_t; @@ -108,7 +107,7 @@ int main_dim(int argc, char* argv[]) Box box(box_corner1, box_corner2); auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_size(6); - samurai::MRMesh mesh; + auto mesh = samurai::make_MRMesh(config, box); auto u = samurai::make_vector_field("u", mesh); auto u1 = samurai::make_vector_field("u1", mesh); diff --git a/demos/FiniteVolume/burgers_mra.cpp b/demos/FiniteVolume/burgers_mra.cpp index e5b6455e9..5fad9eb2f 100644 --- a/demos/FiniteVolume/burgers_mra.cpp +++ b/demos/FiniteVolume/burgers_mra.cpp @@ -226,7 +226,6 @@ void run_simulation(Field& u, int main(int argc, char* argv[]) { constexpr std::size_t dim = 1; - using Config = samurai::MRConfig; using Box = samurai::Box; auto& app = samurai::initialize("Finite volume example for the Burgers equation in 1d", argc, argv); @@ -269,10 +268,10 @@ int main(int argc, char* argv[]) Box box({left_box}, {right_box}); auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_radius(2).graduation_width(2); - samurai::MRMesh mesh{config, box}; + auto mesh = samurai::make_MRMesh(config, box); // samurai::MRMesh mesh{box, min_level, max_level}; auto max_level_config = samurai::mesh_config().min_level(max_level).max_level(max_level).max_stencil_radius(2); - samurai::MRMesh max_level_mesh{max_level_config, box}; + auto max_level_mesh = samurai::make_MRMesh(max_level_config, box); auto u = samurai::make_scalar_field("u", mesh); auto unp1 = samurai::make_scalar_field("unp1", mesh); diff --git a/demos/FiniteVolume/burgers_os.cpp b/demos/FiniteVolume/burgers_os.cpp index 639046317..4bb5ba4a7 100644 --- a/demos/FiniteVolume/burgers_os.cpp +++ b/demos/FiniteVolume/burgers_os.cpp @@ -90,9 +90,9 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the linear convection equation", argc, argv); static constexpr std::size_t dim = 1; - using Config = samurai::MRConfig; - using Box = samurai::Box; - using point_t = typename Box::point_t; + + using Box = samurai::Box; + using point_t = typename Box::point_t; std::cout << "------------------------- Burgers 1D -------------------------" << std::endl; @@ -155,10 +155,10 @@ int main(int argc, char* argv[]) .scaling_factor(2) .max_stencil_radius(2) .graduation_width(2); + config.parse_args(); std::cout << " max_level = " << config.max_level() << " min_level = " << config.min_level() << std::endl; - samurai::MRMesh mesh{config, box}; - + auto mesh = samurai::make_MRMesh(config, box); auto u = samurai::make_scalar_field("u", mesh); auto unp1 = samurai::make_scalar_field("unp1", mesh); diff --git a/demos/FiniteVolume/heat.cpp b/demos/FiniteVolume/heat.cpp index fc45a722e..414c44e09 100644 --- a/demos/FiniteVolume/heat.cpp +++ b/demos/FiniteVolume/heat.cpp @@ -49,7 +49,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the heat equation", argc, argv); static constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; using Box = samurai::Box; using point_t = typename Box::point_t; @@ -119,14 +118,14 @@ int main(int argc, char* argv[]) box_corner1.fill(left_box); box_corner2.fill(right_box); Box box(box_corner1, box_corner2); - samurai::MRMesh mesh; + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto mesh = samurai::make_MRMesh(config); auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); - mesh = {config, box}; + mesh = samurai::make_MRMesh(config, box); u.resize(); // Initial solution if (init_sol == "dirac") diff --git a/demos/FiniteVolume/heat_heterogeneous.cpp b/demos/FiniteVolume/heat_heterogeneous.cpp index e352e46c9..e27809813 100644 --- a/demos/FiniteVolume/heat_heterogeneous.cpp +++ b/demos/FiniteVolume/heat_heterogeneous.cpp @@ -37,7 +37,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the heat equation", argc, argv); static constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; using Box = samurai::Box; using point_t = typename Box::point_t; @@ -92,14 +91,14 @@ int main(int argc, char* argv[]) box_corner2.fill(right_box); Box box(box_corner1, box_corner2); auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); - samurai::MRMesh mesh; + auto mesh = samurai::make_MRMesh(config); auto u = samurai::make_scalar_field("u", mesh); auto unp1 = samurai::make_scalar_field("unp1", mesh); if (restart_file.empty()) { - mesh = {config, box}; + mesh = samurai::make_MRMesh(config, box); u.resize(); // Initial solution: crenel samurai::for_each_cell(mesh, diff --git a/demos/FiniteVolume/heat_nonlinear.cpp b/demos/FiniteVolume/heat_nonlinear.cpp index e89b1ea7a..188959362 100644 --- a/demos/FiniteVolume/heat_nonlinear.cpp +++ b/demos/FiniteVolume/heat_nonlinear.cpp @@ -102,7 +102,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the heat equation", argc, argv); static constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; using Box = samurai::Box; using point_t = typename Box::point_t; @@ -167,12 +166,13 @@ int main(int argc, char* argv[]) box_corner2.fill(right_box); Box box(box_corner1, box_corner2); auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); - samurai::MRMesh mesh; + auto mesh = samurai::make_MRMesh(config); + ; auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { - mesh = {config, box}; + mesh = samurai::make_MRMesh(config, box); u = samurai::make_scalar_field("u", mesh, [&](const auto& coords) diff --git a/demos/FiniteVolume/level_set.cpp b/demos/FiniteVolume/level_set.cpp index f31eb1df2..533ad08ed 100644 --- a/demos/FiniteVolume/level_set.cpp +++ b/demos/FiniteVolume/level_set.cpp @@ -253,7 +253,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example with a level set in 2d using AMR", argc, argv); constexpr std::size_t dim = 2; - using Config = samurai::amr::Config; // Simulation parameters xt::xtensor_fixed> min_corner = {0., 0.}; @@ -265,8 +264,6 @@ int main(int argc, char* argv[]) // AMR parameters std::size_t start_level = 8; - std::size_t min_level = 4; - std::size_t max_level = 8; bool correction = false; // Output parameters @@ -290,13 +287,13 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box(min_corner, max_corner); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_radius(2); - samurai::amr::Mesh mesh; - auto phi = samurai::make_scalar_field("phi", mesh); + auto config = samurai::mesh_config().min_level(4).max_level(8).max_stencil_radius(2); + auto mesh = samurai::amr::make_Mesh(config); + auto phi = samurai::make_scalar_field("phi", mesh); if (restart_file.empty()) { - mesh = {config, box, start_level}; + mesh = samurai::amr::make_Mesh(config, box, start_level); init_level_set(phi); } else @@ -372,9 +369,9 @@ int main(int argc, char* argv[]) // TVD-RK2 samurai::update_ghost(phi); phihat.resize(); - phihat = phi - dt_fict * H_wrap(phi, phi_0, max_level); + phihat = phi - dt_fict * H_wrap(phi, phi_0, mesh.max_level()); samurai::update_ghost(phihat); - phinp1 = .5 * phi_0 + .5 * (phihat - dt_fict * H_wrap(phihat, phi_0, max_level)); + phinp1 = .5 * phi_0 + .5 * (phihat - dt_fict * H_wrap(phihat, phi_0, mesh.max_level())); std::swap(phi.array(), phinp1.array()); } diff --git a/demos/FiniteVolume/level_set_from_scratch.cpp b/demos/FiniteVolume/level_set_from_scratch.cpp index 1aaaac801..bc1aef808 100644 --- a/demos/FiniteVolume/level_set_from_scratch.cpp +++ b/demos/FiniteVolume/level_set_from_scratch.cpp @@ -54,13 +54,13 @@ struct fmt::formatter : formatter template struct AMRConfig { - static constexpr std::size_t dim = dim_; - static constexpr std::size_t max_refinement_level = 20; - static constexpr int max_stencil_width = 2; - static constexpr int ghost_width = 2; - static constexpr std::size_t prediction_order = 1; - using interval_t = samurai::Interval; - using mesh_id_t = SimpleID; + static constexpr std::size_t dim = dim_; + static constexpr std::size_t max_refinement_level = 20; + static constexpr int max_stencil_width = 2; + static constexpr int ghost_width = 2; + static constexpr std::size_t prediction_stencil_radius = 1; + using interval_t = samurai::Interval; + using mesh_id_t = SimpleID; }; template @@ -607,8 +607,6 @@ int main(int argc, char* argv[]) // AMR parameters std::size_t start_level = 8; - std::size_t min_level = 4; - std::size_t max_level = 8; bool correction = false; // Output parameters @@ -632,15 +630,14 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box(min_corner, max_corner); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(4).max_level(8); AMRMesh mesh; auto phi = samurai::make_scalar_field("phi", mesh); if (restart_file.empty()) { - config.parse_args(); - mesh = {config, box, config.max_level()}; + mesh = {config, box, start_level}; init_level_set(phi); } else @@ -715,9 +712,9 @@ int main(int argc, char* argv[]) update_ghosts(phi, u); auto phihat = samurai::make_scalar_field("phi", mesh); samurai::make_bc>(phihat, 0.); - phihat = phi - dt_fict * H_wrap(phi, phi_0, max_level); + phihat = phi - dt_fict * H_wrap(phi, phi_0, mesh.max_level()); update_ghosts(phihat, u); - phinp1 = .5 * phi_0 + .5 * (phihat - dt_fict * H_wrap(phihat, phi_0, max_level)); + phinp1 = .5 * phi_0 + .5 * (phihat - dt_fict * H_wrap(phihat, phi_0, mesh.max_level())); std::swap(phi.array(), phinp1.array()); } diff --git a/demos/FiniteVolume/lid_driven_cavity.cpp b/demos/FiniteVolume/lid_driven_cavity.cpp index fa782a7f4..8518e22ee 100644 --- a/demos/FiniteVolume/lid_driven_cavity.cpp +++ b/demos/FiniteVolume/lid_driven_cavity.cpp @@ -96,12 +96,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Lid-driven cavity", argc, argv); constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; - using Mesh = samurai::MRMesh; - using mesh_id_t = typename Mesh::mesh_id_t; - - using Config2 = samurai::MRConfig; - using Mesh2 = samurai::MRMesh; static constexpr bool is_soa = false; static constexpr bool monolithic = true; @@ -110,11 +104,9 @@ int main(int argc, char* argv[]) // Parameters // //----------------// - std::size_t min_level = 3; - std::size_t max_level = 6; - double Tf = 5.; - double dt = Tf / 100; - double cfl = 0.95; + double Tf = 5.; + double dt = Tf / 100; + double cfl = 0.95; int ink_init = 20; @@ -156,8 +148,10 @@ int main(int argc, char* argv[]) // where v = velocity // p = pressure - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_radius(2); - auto mesh = Mesh(config, box); + auto config = samurai::mesh_config().min_level(3).max_level(6).max_stencil_radius(2); + auto mesh = samurai::make_MRMesh(config, box); + + using mesh_id_t = typename decltype(mesh)::mesh_id_t; // Fields for the Navier-Stokes equations auto velocity = samurai::make_vector_field("velocity", mesh); @@ -235,7 +229,7 @@ int main(int argc, char* argv[]) // 2nd mesh auto config2 = samurai::mesh_config().min_level(1).max_level(mesh.max_level()).max_stencil_size(6).disable_args_parse(); - auto mesh2 = Mesh2(config2, box); + auto mesh2 = samurai::make_MRMesh(config2, box); // Ink data fields auto ink = samurai::make_scalar_field("ink", mesh2); @@ -325,7 +319,7 @@ int main(int argc, char* argv[]) std::cout << fmt::format("iteration {}: t = {:.2f}, dt = {}", nt++, t, dt); // Mesh adaptation for Navier-Stokes - if (min_level != max_level) + if (mesh.min_level() != mesh.max_level()) { MRadaptation(mra_config); min_level_np1 = mesh[mesh_id_t::cells].min_level(); diff --git a/demos/FiniteVolume/linear_convection.cpp b/demos/FiniteVolume/linear_convection.cpp index 827e99555..d6189bda5 100644 --- a/demos/FiniteVolume/linear_convection.cpp +++ b/demos/FiniteVolume/linear_convection.cpp @@ -37,7 +37,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the linear convection equation", argc, argv); static constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; using Box = samurai::Box; using point_t = typename Box::point_t; @@ -87,13 +86,13 @@ int main(int argc, char* argv[]) box_corner1.fill(left_box); box_corner2.fill(right_box); Box box(box_corner1, box_corner2); - samurai::MRMesh mesh; - auto u = samurai::make_scalar_field("u", mesh); + auto config = samurai::mesh_config().min_level(1).max_level(dim == 1 ? 6 : 4).periodic(true).max_stencil_size(6); + auto mesh = samurai::make_MRMesh(config); + auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { - auto config = samurai::mesh_config().min_level(1).max_level(dim == 1 ? 6 : 4).periodic(true).max_stencil_size(6); - mesh = {config, box}; + mesh = samurai::make_MRMesh(config, box); // Initial solution u = samurai::make_scalar_field("u", mesh, diff --git a/demos/FiniteVolume/linear_convection_obstacle.cpp b/demos/FiniteVolume/linear_convection_obstacle.cpp index f2cf63222..48ea36dcd 100644 --- a/demos/FiniteVolume/linear_convection_obstacle.cpp +++ b/demos/FiniteVolume/linear_convection_obstacle.cpp @@ -36,8 +36,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the linear convection equation", argc, argv); static constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; - using Mesh = samurai::MRMesh; std::cout << "------------------------- Linear convection -------------------------" << std::endl; @@ -76,7 +74,7 @@ int main(int argc, char* argv[]) domain.remove({0.0, 0.0}, {0.4, 0.4}); auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_size(6); - Mesh mesh = {config, domain}; + auto mesh = samurai::make_MRMesh(config, domain); // Mesh mesh(domain, min_level, max_level); // Initial solution diff --git a/demos/FiniteVolume/manual_block_matrix_assembly.cpp b/demos/FiniteVolume/manual_block_matrix_assembly.cpp index 3c82f997c..9155f1064 100644 --- a/demos/FiniteVolume/manual_block_matrix_assembly.cpp +++ b/demos/FiniteVolume/manual_block_matrix_assembly.cpp @@ -188,7 +188,6 @@ int main(int argc, char* argv[]) samurai::initialize(argc, argv); static constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; using Box = samurai::Box; std::cout << "------------------------- Begin -------------------------" << std::endl; @@ -198,8 +197,8 @@ int main(int argc, char* argv[]) Box box({0, 0}, {1, 1}); auto mesh_cfg = samurai::mesh_config().min_level(min_level).max_level(max_level); - samurai::MRMesh mesh_e{mesh_cfg, box}; - samurai::MRMesh mesh_s{mesh_cfg, box}; + auto mesh_e = samurai::make_MRMesh(mesh_cfg, box); + auto mesh_s = samurai::make_MRMesh(mesh_cfg, box); //-------------------------------// // Fields and auxiliary unknowns // diff --git a/demos/FiniteVolume/nagumo.cpp b/demos/FiniteVolume/nagumo.cpp index dba39d60e..81bc9f666 100644 --- a/demos/FiniteVolume/nagumo.cpp +++ b/demos/FiniteVolume/nagumo.cpp @@ -37,7 +37,6 @@ int main(int argc, char* argv[]) static constexpr std::size_t dim = 1; static constexpr std::size_t n_comp = 1; - using Config = samurai::MRConfig; using Box = samurai::Box; using point_t = typename Box::point_t; @@ -108,9 +107,8 @@ int main(int argc, char* argv[]) box_corner2.fill(right_box); Box box(box_corner1, box_corner2); auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); - samurai::MRMesh mesh{config, box}; - - auto u = samurai::make_vector_field("u", mesh); + auto mesh = samurai::make_MRMesh(config, box); + auto u = samurai::make_vector_field("u", mesh); double z0 = left_box / 5; // wave initial position double c = sqrt(k * D / 2); // wave velocity diff --git a/demos/FiniteVolume/scalar_burgers_2d.cpp b/demos/FiniteVolume/scalar_burgers_2d.cpp index 5a643d1b3..4d30273cb 100644 --- a/demos/FiniteVolume/scalar_burgers_2d.cpp +++ b/demos/FiniteVolume/scalar_burgers_2d.cpp @@ -182,7 +182,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the scalar Burgers equation in 2d using multiresolution", argc, argv); constexpr size_t dim = 2; - using Config = samurai::MRConfig; // Simulation parameters xt::xtensor_fixed> min_corner = {0., 0.}; @@ -223,13 +222,13 @@ int main(int argc, char* argv[]) const samurai::Box box(min_corner, max_corner); auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); - samurai::MRMesh mesh; + auto mesh = samurai::make_MRMesh(config); auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { - mesh = {config, box}; + mesh = samurai::make_MRMesh(config, box); init(u); } else diff --git a/demos/FiniteVolume/stokes_2d.cpp b/demos/FiniteVolume/stokes_2d.cpp index 6d0ed01ed..12ece901a 100644 --- a/demos/FiniteVolume/stokes_2d.cpp +++ b/demos/FiniteVolume/stokes_2d.cpp @@ -153,9 +153,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Stokes problem", argc, argv); constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; - using Mesh = samurai::MRMesh; - using mesh_id_t = typename Mesh::mesh_id_t; static constexpr bool is_soa = false; static constexpr bool monolithic = true; @@ -194,7 +191,9 @@ int main(int argc, char* argv[]) auto box = samurai::Box({0, 0}, {1, 1}); auto config = samurai::mesh_config().min_level(5).max_level(5).max_stencil_radius(2); - auto mesh = Mesh(config, box); + auto mesh = samurai::make_MRMesh(config, box); + + using mesh_id_t = typename decltype(mesh)::mesh_id_t; //--------------------// // Stationary problem // diff --git a/demos/highorder/main.cpp b/demos/highorder/main.cpp index dfc76e703..96a146d71 100644 --- a/demos/highorder/main.cpp +++ b/demos/highorder/main.cpp @@ -113,7 +113,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("Finite volume example for the advection equation in 2d using multiresolution", argc, argv); constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; constexpr std::size_t prediction_stencil_radius = 1; @@ -142,18 +141,19 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); samurai::Box box(min_corner, max_corner); - using mesh_t = samurai::MRMesh; - using mesh_id_t = typename mesh_t::mesh_id_t; - using cl_type = typename mesh_t::cl_type; // clang-format off auto config = samurai::mesh_config() - .min_level(4) - .max_level(4) - .graduation_width(4) - .max_stencil_size(4); + .min_level(4) + .max_level(4) + .graduation_width(4) + .max_stencil_size(4); // clang-format on - mesh_t init_mesh{config, box}; + auto init_mesh = samurai::make_MRMesh(config, box); + + using mesh_t = decltype(init_mesh); + using mesh_id_t = typename mesh_t::mesh_id_t; + using cl_type = typename mesh_t::cl_type; auto adapt_field = samurai::make_scalar_field("adapt_field", init_mesh, @@ -200,7 +200,7 @@ int main(int argc, char* argv[]) }); // mesh = {cl, mesh.min_level() + 1, mesh.max_level() + 1}; auto mesh_cfg = samurai::mesh_config().min_level(init_mesh.min_level() + i_ref + 1).max_level(init_mesh.max_level() + i_ref + 1); - mesh = {mesh_cfg, cl}; + mesh = samurai::make_MRMesh(mesh_cfg, cl); } // std::cout << mesh << std::endl; // samurai::save("refine_mesh", mesh); diff --git a/demos/multigrid/main.cpp b/demos/multigrid/main.cpp index e55fbf132..42f73bebd 100644 --- a/demos/multigrid/main.cpp +++ b/demos/multigrid/main.cpp @@ -66,21 +66,21 @@ static char help[] = "Solution of the Poisson problem in the domain [0,1]^d.\n" "-log_view -pc_mg_log Monitors the multigrid performance\n" "\n"; -template -Mesh create_uniform_mesh(std::size_t level) +template +auto create_uniform_mesh(std::size_t level) { - using Box = samurai::Box; + using Box = samurai::Box; Box box; - if constexpr (Mesh::dim == 1) + if constexpr (dim == 1) { box = Box({0}, {1}); } - else if constexpr (Mesh::dim == 2) + else if constexpr (dim == 2) { box = Box({0, 0}, {1, 1}); } - else if constexpr (Mesh::dim == 3) + else if constexpr (dim == 3) { box = Box({0, 0, 0}, {1, 1, 1}); } @@ -89,32 +89,33 @@ Mesh create_uniform_mesh(std::size_t level) min_level = level; max_level = level; - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); - return Mesh(config, box, start_level); // amr::Mesh + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + return samurai::amr::make_Mesh(config, box, start_level); // amr::Mesh // return Mesh(box, /*start_level,*/ min_level, max_level); // MRMesh } -template -[[maybe_unused]] Mesh create_refined_mesh(std::size_t level) +template +[[maybe_unused]] auto create_refined_mesh(std::size_t level) { - using cl_type = typename Mesh::cl_type; - std::size_t min_level, max_level; min_level = level - 1; max_level = level; + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + + using cl_type = typename decltype(samurai::amr::make_Mesh(config))::cl_type; + int i = 1 << min_level; cl_type cl; - if constexpr (Mesh::dim == 1) + if constexpr (dim == 1) { cl[min_level][{}].add_interval({0, i / 2}); cl[max_level][{}].add_interval({i, 2 * i}); } - static_assert(Mesh::dim == 1, "create_refined_mesh() not implemented for this dimension"); + static_assert(dim == 1, "create_refined_mesh() not implemented for this dimension"); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); - return Mesh(config, cl); // amr::Mesh + return samurai::amr::make_Mesh(config, cl); // amr::Mesh // return Mesh(box, /*start_level,*/ min_level, max_level); // MRMesh } @@ -122,14 +123,12 @@ int main(int argc, char* argv[]) { samurai::initialize(argc, argv); - constexpr std::size_t dim = 2; - using Config = samurai::amr::Config; - using Mesh = samurai::amr::Mesh; - // using Config = samurai::MRConfig; - // using Mesh = samurai::MRMesh; + constexpr std::size_t dim = 2; constexpr unsigned int n_comp = 1; constexpr bool is_soa = true; - using Field = samurai::VectorField; + using Field = decltype(samurai::make_vector_field( + "type", + std::declval(1))&>())); // samurai::VectorField; PetscMPIInt size; PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); @@ -199,7 +198,7 @@ int main(int argc, char* argv[]) // Mesh creation // //---------------// - Mesh mesh = create_uniform_mesh(static_cast(level)); + auto mesh = create_uniform_mesh(static_cast(level)); // print_mesh(mesh); if (save_mesh) diff --git a/demos/multigrid/samurai_new/multigrid/LevelCtx.hpp b/demos/multigrid/samurai_new/multigrid/LevelCtx.hpp index 230d82ef1..8358d07ad 100644 --- a/demos/multigrid/samurai_new/multigrid/LevelCtx.hpp +++ b/demos/multigrid/samurai_new/multigrid/LevelCtx.hpp @@ -33,24 +33,24 @@ namespace samurai_new LevelContext* finer = nullptr; LevelContext* coarser = nullptr; TransferOperators transfer_ops; - int prediction_order; + int prediction_stencil_radius; LevelContext(Dsctzr& d, Mesh& m, TransferOperators to, int pred_order) : _mesh(m) , _discretizer(d) { - level = 0; - transfer_ops = to; - prediction_order = pred_order; + level = 0; + transfer_ops = to; + prediction_stencil_radius = pred_order; } LevelContext(LevelContext& fine_ctx) : _mesh(samurai_new::coarsen(fine_ctx.mesh())) , _discretizer(Dsctzr::create_coarse(fine_ctx.assembly(), _mesh)) { - level = fine_ctx.level + 1; - transfer_ops = fine_ctx.transfer_ops; - prediction_order = fine_ctx.prediction_order; + level = fine_ctx.level + 1; + transfer_ops = fine_ctx.transfer_ops; + prediction_stencil_radius = fine_ctx.prediction_stencil_radius; this->finer = &fine_ctx; fine_ctx.coarser = this; diff --git a/demos/multigrid/samurai_new/multigrid/petsc/GeometricMultigrid.hpp b/demos/multigrid/samurai_new/multigrid/petsc/GeometricMultigrid.hpp index 1e2603914..76043a2c2 100644 --- a/demos/multigrid/samurai_new/multigrid/petsc/GeometricMultigrid.hpp +++ b/demos/multigrid/samurai_new/multigrid/petsc/GeometricMultigrid.hpp @@ -57,8 +57,8 @@ namespace samurai_new PetscOptionsGetInt(NULL, NULL, "--samg_transfer_ops", &transfer_ops_arg, NULL); samurai_new::TransferOperators transfer_ops = static_cast(transfer_ops_arg); - PetscInt prediction_order = 0; - PetscOptionsGetInt(NULL, NULL, "--samg_pred_order", &prediction_order, NULL); + PetscInt prediction_stencil_radius = 0; + PetscOptionsGetInt(NULL, NULL, "--samg_pred_order", &prediction_stencil_radius, NULL); PetscBool smoother_is_set = PETSC_FALSE; Smoothers smoother = SymGaussSeidel; @@ -121,9 +121,9 @@ namespace samurai_new } std::cout << std::endl; - std::cout << " prediction order : " << prediction_order << std::endl; + std::cout << " prediction order : " << prediction_stencil_radius << std::endl; - _samuraiDM = new SamuraiDM(PETSC_COMM_SELF, *_discretizer, *_mesh, transfer_ops, prediction_order); + _samuraiDM = new SamuraiDM(PETSC_COMM_SELF, *_discretizer, *_mesh, transfer_ops, prediction_stencil_radius); KSPSetDM(ksp, _samuraiDM->PetscDM()); // Default outer solver: CG diff --git a/demos/multigrid/samurai_new/multigrid/petsc/SamuraiDM.hpp b/demos/multigrid/samurai_new/multigrid/petsc/SamuraiDM.hpp index 3c56c1458..8571731bb 100644 --- a/demos/multigrid/samurai_new/multigrid/petsc/SamuraiDM.hpp +++ b/demos/multigrid/samurai_new/multigrid/petsc/SamuraiDM.hpp @@ -21,8 +21,8 @@ namespace samurai_new using Mesh = typename Dsctzr::Mesh; using Field = typename Dsctzr::field_t; - SamuraiDM(MPI_Comm comm, Dsctzr& assembly, Mesh& mesh, TransferOperators to, int prediction_order) - : _ctx(assembly, mesh, to, prediction_order) + SamuraiDM(MPI_Comm comm, Dsctzr& assembly, Mesh& mesh, TransferOperators to, int prediction_stencil_radius) + : _ctx(assembly, mesh, to, prediction_stencil_radius) { DMShellCreate(comm, &_dm); DefineShellFunctions(_dm, _ctx); @@ -155,7 +155,7 @@ namespace samurai_new { Field coarse_field("coarse_field", coarse_ctx->mesh()); samurai::petsc::copy(x, coarse_field); - Field fine_field = multigrid::prolong(coarse_field, fine_ctx->mesh(), coarse_ctx->prediction_order); + Field fine_field = multigrid::prolong(coarse_field, fine_ctx->mesh(), coarse_ctx->prediction_stencil_radius); samurai::petsc::copy(fine_field, y); // std::cout << "prolongated vector (marche):" << std::endl; @@ -168,7 +168,7 @@ namespace samurai_new double* yarray; VecGetArrayRead(x, &xarray); VecGetArray(y, &yarray); - multigrid::prolong(coarse_ctx->mesh(), fine_ctx->mesh(), xarray, yarray, coarse_ctx->prediction_order); + multigrid::prolong(coarse_ctx->mesh(), fine_ctx->mesh(), xarray, yarray, coarse_ctx->prediction_stencil_radius); VecRestoreArrayRead(x, &xarray); VecRestoreArray(y, &yarray); @@ -227,7 +227,7 @@ namespace samurai_new MatSetSizes(*P, nf, nc, nf, nc); MatSetFromOptions(*P); MatSeqAIJSetPreallocation(*P, stencil_size, NULL); - multigrid::set_prolong_matrix(coarse_ctx->mesh(), fine_ctx->mesh(), *P, coarse_ctx->prediction_order); + multigrid::set_prolong_matrix(coarse_ctx->mesh(), fine_ctx->mesh(), *P, coarse_ctx->prediction_stencil_radius); MatAssemblyBegin(*P, MAT_FINAL_ASSEMBLY); MatAssemblyEnd(*P, MAT_FINAL_ASSEMBLY); diff --git a/demos/multigrid/samurai_new/multigrid/petsc/intergrid_operators.hpp b/demos/multigrid/samurai_new/multigrid/petsc/intergrid_operators.hpp index b0d6853a2..7baa18637 100644 --- a/demos/multigrid/samurai_new/multigrid/petsc/intergrid_operators.hpp +++ b/demos/multigrid/samurai_new/multigrid/petsc/intergrid_operators.hpp @@ -11,7 +11,7 @@ namespace samurai_new { template - void prolong(const Mesh& coarse_mesh, const Mesh& fine_mesh, const double* carray, double* farray, int prediction_order) + void prolong(const Mesh& coarse_mesh, const Mesh& fine_mesh, const double* carray, double* farray, int prediction_stencil_radius) { using mesh_id_t = typename Mesh::mesh_id_t; static constexpr std::size_t dim = Mesh::dim; @@ -46,7 +46,7 @@ namespace samurai_new { auto i_f = fine_mesh.get_index(level, (2 * i).start); auto i_c = coarse_mesh.get_index(level - 1, i.start); - if (prediction_order == 0) + if (prediction_stencil_radius == 0) { for (std::size_t ii = 0; ii < i.size(); ++ii) { @@ -55,7 +55,7 @@ namespace samurai_new farray[i_f + 2 * ii + 1] = carray[i_c + ii]; } } - else if (prediction_order == 1) + else if (prediction_stencil_radius == 1) { for (std::size_t ii = 0; ii < i.size(); ++ii) { @@ -74,7 +74,7 @@ namespace samurai_new auto i_f_2j = fine_mesh.get_index(level, (2 * i).start, 2 * j); auto i_f_2jp1 = fine_mesh.get_index(level, (2 * i).start, 2 * j + 1); - if (prediction_order == 0) + if (prediction_stencil_radius == 0) { for (std::size_t ii = 0; ii < i.size(); ++ii) { @@ -85,7 +85,7 @@ namespace samurai_new farray[i_f_2jp1 + 2 * ii + 1] = carray[i_c_j + ii]; } } - else if (prediction_order == 1) + else if (prediction_stencil_radius == 1) { auto i_c_jm1 = coarse_mesh.get_index(level - 1, i.start, j - 1); auto i_c_jp1 = coarse_mesh.get_index(level - 1, i.start, j + 1); @@ -198,7 +198,7 @@ namespace samurai_new } template - void set_prolong_matrix(const Mesh& coarse_mesh, const Mesh& fine_mesh, Mat& P, int prediction_order) + void set_prolong_matrix(const Mesh& coarse_mesh, const Mesh& fine_mesh, Mat& P, int prediction_stencil_radius) { using mesh_id_t = typename Mesh::mesh_id_t; static constexpr std::size_t dim = Mesh::dim; @@ -235,7 +235,7 @@ namespace samurai_new { auto i_f = static_cast(fine_mesh.get_index(level, (2 * i).start)); auto i_c = static_cast(coarse_mesh.get_index(level - 1, i.start)); - if (prediction_order == 0) + if (prediction_stencil_radius == 0) { for (int ii = 0; ii < static_cast(i.size()); ++ii) { @@ -244,7 +244,7 @@ namespace samurai_new MatSetValue(P, i_f + 2 * ii + 1, i_c + ii, 1, INSERT_VALUES); } } - else if (prediction_order == 1) + else if (prediction_stencil_radius == 1) { for (int ii = 0; ii < static_cast(i.size()); ++ii) { @@ -273,7 +273,7 @@ namespace samurai_new auto i_f_2j = static_cast(fine_mesh.get_index(level, (2 * i).start, 2 * j)); auto i_f_2jp1 = static_cast(fine_mesh.get_index(level, (2 * i).start, 2 * j + 1)); - if (prediction_order == 0) + if (prediction_stencil_radius == 0) { for (int ii = 0; ii < static_cast(i.size()); ++ii) { @@ -291,7 +291,7 @@ namespace samurai_new MatSetValue(P, fine_top_right, coarse, 1, INSERT_VALUES); } } - else if (prediction_order == 1) + else if (prediction_stencil_radius == 1) { auto i_c_jm1 = static_cast(coarse_mesh.get_index(level - 1, i.start, j - 1)); auto i_c_jp1 = static_cast(coarse_mesh.get_index(level - 1, i.start, j + 1)); @@ -487,7 +487,7 @@ namespace samurai_new } template - Field prolong(const Field& coarse_field, typename Field::mesh_t& fine_mesh, int prediction_order) + Field prolong(const Field& coarse_field, typename Field::mesh_t& fine_mesh, int prediction_stencil_radius) { using mesh_id_t = typename Field::mesh_t::mesh_id_t; static constexpr std::size_t dim = Field::mesh_t::dim; @@ -512,11 +512,11 @@ namespace samurai_new // Coarse cells to fine cells: prediction auto others = samurai::intersection(cm[level - 1], fm[level]).on(level - 1); - if (prediction_order == 0) + if (prediction_stencil_radius == 0) { others.apply_op(samurai::prediction<0, true>(fine_field, coarse_field)); } - else if (prediction_order == 1) + else if (prediction_stencil_radius == 1) { others.apply_op(samurai::prediction<1, true>(fine_field, coarse_field)); } diff --git a/demos/p4est/simple_2d.cpp b/demos/p4est/simple_2d.cpp index eae02d347..4b6c6b3d7 100644 --- a/demos/p4est/simple_2d.cpp +++ b/demos/p4est/simple_2d.cpp @@ -236,10 +236,8 @@ int main(int argc, char* argv[]) toc(); std::cout << "nb_cells: " << mesh_1.nb_cells() << "\n"; - // samurai::CellArray mesh_2(cl); - using Config = samurai::MRConfig; - using mesh_id_t = typename samurai::MRMesh::mesh_id_t; - samurai::MRMesh mesh_2(config, cl); + auto mesh_2 = samurai::make_MRMesh(config, cl); + using mesh_id_t = typename decltype(mesh_2)::mesh_id_t; tic(); refine_2(mesh_2, config.max_level()); diff --git a/demos/tutorial/proj_on_mesh.cpp b/demos/tutorial/proj_on_mesh.cpp index 09ba9f056..965509115 100644 --- a/demos/tutorial/proj_on_mesh.cpp +++ b/demos/tutorial/proj_on_mesh.cpp @@ -54,14 +54,13 @@ int main() samurai::initialize(); constexpr std::size_t dim = 3; - using Config = samurai::MRConfig; auto box = samurai::Box({0., 0., 0.}, {1., 1., 1.}); auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(8); - auto mesh1 = samurai::MRMesh(mesh_cfg, box); + auto mesh1 = samurai::make_MRMesh(mesh_cfg, box); auto f1 = init_field(mesh1, 0); - auto mesh2 = samurai::MRMesh(mesh_cfg, box); + auto mesh2 = samurai::make_MRMesh(mesh_cfg, box); auto f2 = init_field(mesh2, 0.1); auto adapt_1 = samurai::make_MRAdapt(f1); diff --git a/demos/tutorial/reconstruction_1d.cpp b/demos/tutorial/reconstruction_1d.cpp index 78ad23e27..bb67bf86e 100644 --- a/demos/tutorial/reconstruction_1d.cpp +++ b/demos/tutorial/reconstruction_1d.cpp @@ -59,7 +59,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("1d reconstruction of an adapted solution using multiresolution", argc, argv); constexpr size_t dim = 1; - using MRConfig = samurai::MRConfig; Case test_case{Case::abs}; const std::map map{ @@ -83,23 +82,23 @@ int main(int argc, char* argv[]) fs::create_directory(path); } - using MRMesh = samurai::MRMesh; - using mrmesh_id_t = typename MRMesh::mesh_id_t; - using UConfig = samurai::UniformConfig; using UMesh = samurai::UniformMesh; const samurai::Box box({-1}, {1}); // clang-format off auto config = samurai::mesh_config() - .min_level(3) - .max_level(8) - .scaling_factor(1) - .graduation_width(2) - .max_stencil_radius(2); + .min_level(3) + .max_level(8) + .scaling_factor(1) + .graduation_width(2) + .max_stencil_radius(2); // clang-format on - MRMesh mrmesh{config, box}; + auto mrmesh = samurai::make_MRMesh(config, box); UMesh umesh{box, mrmesh.max_level(), 0, 1}; + + using mrmesh_id_t = typename decltype(mrmesh)::mesh_id_t; + auto u = init(mrmesh, test_case); auto u_exact = init(umesh, test_case); diff --git a/demos/tutorial/reconstruction_2d.cpp b/demos/tutorial/reconstruction_2d.cpp index 66a78d466..93e24a2e6 100644 --- a/demos/tutorial/reconstruction_2d.cpp +++ b/demos/tutorial/reconstruction_2d.cpp @@ -87,7 +87,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("2d reconstruction of an adapted solution using multiresolution", argc, argv); constexpr size_t dim = 2; - using MRConfig = samurai::MRConfig; Case test_case{Case::abs}; const std::map map{ @@ -111,26 +110,25 @@ int main(int argc, char* argv[]) fs::create_directory(path); } - using MRMesh = samurai::MRMesh; - using mrmesh_id_t = typename MRMesh::mesh_id_t; - using UConfig = samurai::UniformConfig; using UMesh = samurai::UniformMesh; const samurai::Box box({-1, -1}, {1, 1}); // clang-format off auto config = samurai::mesh_config() - .min_level(3) - .max_level(8) - .scaling_factor(1) - .graduation_width(2) - .max_stencil_radius(2); + .min_level(3) + .max_level(8) + .scaling_factor(1) + .graduation_width(2) + .max_stencil_radius(2); // clang-format on - MRMesh mrmesh{config, box}; + auto mrmesh = samurai::make_MRMesh(config, box); UMesh umesh{box, mrmesh.max_level(), 0, 1}; auto u = init(mrmesh, test_case); auto u_exact = init(umesh, test_case); + using mrmesh_id_t = typename decltype(mrmesh)::mesh_id_t; + auto MRadaptation = samurai::make_MRAdapt(u); auto mra_config = samurai::mra_config().regularity(2); MRadaptation(mra_config); diff --git a/demos/tutorial/reconstruction_3d.cpp b/demos/tutorial/reconstruction_3d.cpp index c68ff2096..2a8ba255e 100644 --- a/demos/tutorial/reconstruction_3d.cpp +++ b/demos/tutorial/reconstruction_3d.cpp @@ -91,7 +91,6 @@ int main(int argc, char* argv[]) auto& app = samurai::initialize("3d reconstruction of an adapted solution using multiresolution", argc, argv); constexpr size_t dim = 3; - using MRConfig = samurai::MRConfig; Case test_case{Case::abs}; const std::map map{ @@ -115,26 +114,25 @@ int main(int argc, char* argv[]) fs::create_directory(path); } - using MRMesh = samurai::MRMesh; - using mrmesh_id_t = typename MRMesh::mesh_id_t; - using UConfig = samurai::UniformConfig; using UMesh = samurai::UniformMesh; const samurai::Box box({-1, -1, -1}, {1, 1, 1}); // clang-format off auto config = samurai::mesh_config() - .min_level(2) - .max_level(5) - .scaling_factor(1) - .graduation_width(2) - .max_stencil_radius(2); + .min_level(2) + .max_level(5) + .scaling_factor(1) + .graduation_width(2) + .max_stencil_radius(2); // clang-format on - MRMesh mrmesh{config, box}; + auto mrmesh = samurai::make_MRMesh(config, box); UMesh umesh{box, mrmesh.max_level(), 0, 1}; auto u = init(mrmesh, test_case); auto u_exact = init(umesh, test_case); + using mrmesh_id_t = typename decltype(mrmesh)::mesh_id_t; + auto MRadaptation = samurai::make_MRAdapt(u); auto mra_config = samurai::mra_config().regularity(2); MRadaptation(mra_config); diff --git a/docs/source/tutorial/reaction_diffusion.rst b/docs/source/tutorial/reaction_diffusion.rst index facc13951..49e04b7f2 100644 --- a/docs/source/tutorial/reaction_diffusion.rst +++ b/docs/source/tutorial/reaction_diffusion.rst @@ -45,18 +45,16 @@ The mesh is created by the following code: double right_box = 10; // Mesh creation - using Config = samurai::MRConfig; using Box = samurai::Box; using point_t = typename Box::point_t; - std::size_t min_level = 0; - std::size_t max_level = 4; + auto config = samurai::mesh_config().min_level(0).max_level(4); point_t box_corner1, box_corner2; box_corner1.fill(left_box); box_corner2.fill(right_box); Box box(box_corner1, box_corner2); - samurai::MRMesh mesh{box, min_level, max_level}; + auto mesh = samurai::make_MRMesh(config, box); Here, we have used the mesh type :code:`MRMesh`, but any other type of mesh can be chosen. Then, solution fields at two time steps (:math:`u_n` and :math:`u_{n+1}`) are declared, and boundary conditions are attached: diff --git a/include/mesh.hpp b/include/mesh.hpp new file mode 100644 index 000000000..e69de29bb diff --git a/include/samurai/algorithm/graduation.hpp b/include/samurai/algorithm/graduation.hpp index 72860d31d..9339670e9 100644 --- a/include/samurai/algorithm/graduation.hpp +++ b/include/samurai/algorithm/graduation.hpp @@ -135,7 +135,7 @@ namespace samurai std::size_t max_level = mesh.max_level(); - constexpr int ghost_width = mesh_t::config::graduation_width; // cppcheck-suppress unreadVariable + constexpr int ghost_width = mesh_t::config::prediction_stencil_radius; // cppcheck-suppress unreadVariable for (std::size_t level = max_level; level > 0; --level) { diff --git a/include/samurai/algorithm/update.hpp b/include/samurai/algorithm/update.hpp index c36280140..ce59413ec 100644 --- a/include/samurai/algorithm/update.hpp +++ b/include/samurai/algorithm/update.hpp @@ -37,7 +37,7 @@ namespace samurai void update_ghost(Field& field, Fields&... fields) { using mesh_id_t = typename Field::mesh_t::mesh_id_t; - constexpr std::size_t pred_order = Field::mesh_t::config::prediction_order; + constexpr std::size_t pred_order = Field::mesh_t::config::prediction_stencil_radius; auto& mesh = field.mesh(); std::size_t max_level = mesh.max_level(); @@ -62,7 +62,7 @@ namespace samurai void update_ghost_mro(Field& field) { using mesh_id_t = typename Field::mesh_t::mesh_id_t; - constexpr std::size_t pred_order = Field::mesh_t::config::prediction_order; + constexpr std::size_t pred_order = Field::mesh_t::config::prediction_stencil_radius; auto& mesh = field.mesh(); std::size_t max_level = mesh.max_level(); @@ -534,7 +534,7 @@ namespace samurai void update_ghost_mr(Field& field, Fields&... other_fields) { using mesh_id_t = typename Field::mesh_t::mesh_id_t; - constexpr std::size_t pred_order = Field::mesh_t::config::prediction_order; + constexpr std::size_t pred_order = Field::mesh_t::config::prediction_stencil_radius; times::timers.start("ghost update"); diff --git a/include/samurai/amr/mesh.hpp b/include/samurai/amr/mesh.hpp index 619be0ed7..0ff0e83ab 100644 --- a/include/samurai/amr/mesh.hpp +++ b/include/samurai/amr/mesh.hpp @@ -25,24 +25,24 @@ namespace samurai::amr // reference = cells_and_ghosts }; - template - struct Config - { - static constexpr std::size_t dim = dim_; - static constexpr std::size_t max_refinement_level = max_refinement_level_; - static constexpr int max_stencil_width = max_stencil_width_; - static constexpr int prediction_order = prediction_order_; - static constexpr int ghost_width = std::max(static_cast(max_stencil_width), static_cast(prediction_order)); - static constexpr int graduation_width = graduation_width_; - - using interval_t = TInterval; - using mesh_id_t = AMR_Id; - }; + // template + // struct Config + // { + // static constexpr std::size_t dim = dim_; + // static constexpr std::size_t max_refinement_level = max_refinement_level_; + // static constexpr int max_stencil_width = max_stencil_width_; + // static constexpr int prediction_stencil_radius = prediction_stencil_radius_; + // static constexpr int ghost_width = std::max(static_cast(max_stencil_width), + // static_cast(prediction_stencil_radius)); static constexpr int graduation_width = graduation_width_; + + // using interval_t = TInterval; + // using mesh_id_t = AMR_Id; + // }; ///////////////////////// // AMR mesh definition // @@ -74,6 +74,8 @@ namespace samurai::amr Mesh(mesh_config& config, const Box& b, std::size_t start_level); void update_sub_mesh_impl(); + + using base_type::cfg; }; ///////////////////////////// @@ -118,11 +120,13 @@ namespace samurai::amr [&](std::size_t level, const auto& interval, const auto& index_yz) { lcl_type& lcl = cl[level]; - static_nested_loop( + static_nested_loop( + -cfg().ghost_width(), + cfg().ghost_width() + 1, [&](auto stencil) { auto index = xt::eval(index_yz + stencil); - lcl[index].add_interval({interval.start - config::ghost_width, interval.end + config::ghost_width}); + lcl[index].add_interval({interval.start - cfg().ghost_width(), interval.end + cfg().ghost_width()}); }); }); this->cells()[mesh_id_t::cells_and_ghosts] = {cl, false}; @@ -176,11 +180,12 @@ namespace samurai::amr [&](const auto& interval, const auto& index_yz) { // add ghosts for the prediction - static_nested_loop( + static_nested_loop( [&](auto stencil) { auto index = xt::eval(index_yz + stencil); - lcl[index].add_interval({interval.start - config::prediction_order, interval.end + config::prediction_order}); + lcl[index].add_interval( + {interval.start - config::prediction_stencil_radius, interval.end + config::prediction_stencil_radius}); }); }); } @@ -199,7 +204,32 @@ namespace samurai::amr this->cells()[mesh_id_t::all_cells][level] = {lcl}; } } -} + + template > + auto make_Mesh(const mesh_config_t&) + { + return Mesh(); + } + + template > + auto make_Mesh(const mesh_config_t& cfg, const typename Mesh::cl_type& cl) + { + return Mesh(cfg, cl); + } + + template > + auto make_Mesh(const mesh_config_t& cfg, const typename Mesh::ca_type& ca) + { + return Mesh(cfg, ca); + } + + template + auto make_Mesh(mesh_config_t& cfg, const samurai::Box& b, std::size_t start_level) + { + using complete_cfg_t = complete_mesh_config; + return Mesh(cfg, b, start_level); + } +} // namespace samurai::amr template <> struct fmt::formatter : formatter diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index 73b7bdc07..68041b4e6 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -10,13 +10,19 @@ namespace samurai { - template + template class mesh_config { public: - static constexpr std::size_t dim = dim_; - static constexpr std::size_t prediction_stencil_radius = prediction_stencil_radius_; + static constexpr std::size_t dim = dim_; + static constexpr int prediction_stencil_radius = prediction_stencil_radius_; + static constexpr std::size_t max_refinement_level = max_refinement_level_; + + using interval_t = interval_t_; private: @@ -233,4 +239,13 @@ namespace samurai } #endif }; -} + + template + class complete_mesh_config + : public mesh_config + { + public: + + using mesh_id_t = mesh_id_t_; + }; +} // namespace samurai diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index e7f162a88..1c112db16 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -30,28 +30,29 @@ namespace samurai reference = all_cells }; - template - struct MRConfig - { - static constexpr std::size_t dim = dim_; - static constexpr std::size_t max_refinement_level = max_refinement_level_; - // static constexpr int max_stencil_width = max_stencil_width_; - // static constexpr std::size_t graduation_width = graduation_width_; - static constexpr int prediction_order = prediction_order_; - - // static constexpr int ghost_width = std::max(std::max(2 * - // static_cast(graduation_width) - 1, - // static_cast(max_stencil_width)), - // static_cast(prediction_order)); - // static constexpr int ghost_width = std::max(static_cast(max_stencil_width_), static_cast(prediction_order)); - using interval_t = TInterval; - using mesh_id_t = MRMeshId; - }; + // template + // struct MRConfig + // { + // // static constexpr std::size_t dim = dim_; + // // static constexpr std::size_t max_refinement_level = max_refinement_level_; + // // // static constexpr int max_stencil_width = max_stencil_width_; + // // // static constexpr std::size_t graduation_width = graduation_width_; + // // static constexpr int prediction_stencil_radius = prediction_stencil_radius_; + + // // // static constexpr int ghost_width = std::max(std::max(2 * + // // // static_cast(graduation_width) - 1, + // // // static_cast(max_stencil_width)), + // // // static_cast(prediction_stencil_radius)); + // // // static constexpr int ghost_width = std::max(static_cast(max_stencil_width_), + // static_cast(prediction_stencil_radius)); + // // using interval_t = TInterval; + // // using mesh_id_t = MRMeshId; + // }; template class MRMesh : public samurai::Mesh_base, Config> @@ -233,12 +234,12 @@ namespace samurai { lcl_type& lcl = cell_list[level - 1]; - static_nested_loop( + 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}); + lcl[(index_yz >> 1) + stencil].add_interval({new_interval.start - config::prediction_stencil_radius, + new_interval.end + config::prediction_stencil_radius}); }); }); @@ -251,12 +252,12 @@ namespace samurai { lcl_type& lcl = cell_list[level - 2]; - static_nested_loop( + 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}); + lcl[(index_yz >> 2) + stencil].add_interval({new_interval.start - config::prediction_stencil_radius, + new_interval.end + config::prediction_stencil_radius}); }); } }); @@ -281,12 +282,12 @@ namespace samurai { lcl_type& lclm1 = cell_list[level - 1]; - static_nested_loop( + 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}); + lclm1[(index_yz >> 1) + stencil].add_interval({new_interval.start - config::prediction_stencil_radius, + new_interval.end + config::prediction_stencil_radius}); }); } }); @@ -513,6 +514,38 @@ namespace samurai return out; } } + + template > + auto make_MRMesh(const mesh_config_t&) + { + return MRMesh(); + } + + template > + auto make_MRMesh(const mesh_config_t& cfg, const typename MRMesh::cl_type& cl) + { + return MRMesh(cfg, cl); + } + + template > + auto make_MRMesh(const mesh_config_t& cfg, const typename MRMesh::ca_type& ca) + { + return MRMesh(cfg, ca); + } + + template + auto make_MRMesh(mesh_config_t& cfg, const samurai::Box& b) + { + using complete_cfg_t = complete_mesh_config; + return MRMesh(cfg, b); + } + + template + auto make_MRMesh(mesh_config_t& cfg, const samurai::DomainBuilder& domain_builder) + { + using complete_cfg_t = complete_mesh_config; + return MRMesh(cfg, domain_builder); + } } // namespace samurai template <> diff --git a/include/samurai/mr/mesh_with_overleaves.hpp b/include/samurai/mr/mesh_with_overleaves.hpp index f94ee3e15..dd7de08fd 100644 --- a/include/samurai/mr/mesh_with_overleaves.hpp +++ b/include/samurai/mr/mesh_with_overleaves.hpp @@ -28,21 +28,21 @@ namespace samurai }; template + std::size_t max_stencil_width_ = default_config::ghost_width, + std::size_t graduation_width_ = default_config::graduation_width, + std::size_t max_refinement_level_ = default_config::max_level, + std::size_t prediction_stencil_radius_ = default_config::prediction_stencil_radius, + class TInterval = default_config::interval_t> struct MROConfig { - static constexpr std::size_t dim = dim_; - static constexpr std::size_t max_refinement_level = max_refinement_level_; - static constexpr std::size_t max_stencil_width = max_stencil_width_; - static constexpr std::size_t graduation_width = graduation_width_; - static constexpr std::size_t prediction_order = prediction_order_; + static constexpr std::size_t dim = dim_; + static constexpr std::size_t max_refinement_level = max_refinement_level_; + static constexpr std::size_t max_stencil_width = max_stencil_width_; + static constexpr std::size_t graduation_width = graduation_width_; + static constexpr std::size_t prediction_stencil_radius = prediction_stencil_radius_; static constexpr int ghost_width = std::max(std::max(2 * static_cast(graduation_width) - 1, static_cast(max_stencil_width)), - static_cast(prediction_order)); + static_cast(prediction_stencil_radius)); using interval_t = TInterval; using mesh_id_t = MROMeshId; }; diff --git a/include/samurai/mr/operators.hpp b/include/samurai/mr/operators.hpp index 256ddedda..01f8ecdf8 100644 --- a/include/samurai/mr/operators.hpp +++ b/include/samurai/mr/operators.hpp @@ -248,7 +248,7 @@ namespace samurai INIT_OPERATOR(compute_detail_op) - template + template inline void operator()(Dim<1>, T1& detail, const T2& field) const { if constexpr (order == 0) @@ -265,7 +265,7 @@ namespace samurai } } - template + template inline void operator()(Dim<2>, T1& detail, const T2& field) const { if constexpr (order == 0) @@ -311,7 +311,7 @@ namespace samurai } } - template + template inline void operator()(Dim<3>, T1& detail, const T2& field) const { if constexpr (order == 0) diff --git a/include/samurai/petsc/fv/FV_scheme_assembly.hpp b/include/samurai/petsc/fv/FV_scheme_assembly.hpp index abe9ab2b9..f68d1ad87 100644 --- a/include/samurai/petsc/fv/FV_scheme_assembly.hpp +++ b/include/samurai/petsc/fv/FV_scheme_assembly.hpp @@ -28,25 +28,25 @@ namespace samurai public: - using cfg_t = typename Scheme::cfg_t; - using bdry_cfg_t = typename Scheme::bdry_cfg; - using field_t = typename Scheme::field_t; - using output_field_t = typename cfg_t::output_field_t; - using mesh_t = typename field_t::mesh_t; - using mesh_id_t = typename mesh_t::mesh_id_t; - using interval_t = typename mesh_t::interval_t; - using mesh_interval_t = typename mesh_t::mesh_interval_t; - using field_value_type = typename field_t::value_type; // double - using coord_index_t = typename interval_t::coord_index_t; - using index_t = typename interval_t::index_t; - static constexpr std::size_t dim = field_t::dim; - static constexpr std::size_t input_n_comp = field_t::n_comp; - static constexpr std::size_t output_n_comp = output_field_t::n_comp; - static constexpr std::size_t prediction_order = mesh_t::config::prediction_order; - static constexpr std::size_t bdry_neighbourhood_width = bdry_cfg_t::neighbourhood_width; - static constexpr std::size_t bdry_stencil_size = bdry_cfg_t::stencil_size; - static constexpr std::size_t nb_bdry_ghosts = bdry_cfg_t::nb_ghosts; - using cell_t = Cell; + using cfg_t = typename Scheme::cfg_t; + using bdry_cfg_t = typename Scheme::bdry_cfg; + using field_t = typename Scheme::field_t; + using output_field_t = typename cfg_t::output_field_t; + using mesh_t = typename field_t::mesh_t; + using mesh_id_t = typename mesh_t::mesh_id_t; + using interval_t = typename mesh_t::interval_t; + using mesh_interval_t = typename mesh_t::mesh_interval_t; + using field_value_type = typename field_t::value_type; // double + using coord_index_t = typename interval_t::coord_index_t; + using index_t = typename interval_t::index_t; + static constexpr std::size_t dim = field_t::dim; + static constexpr std::size_t input_n_comp = field_t::n_comp; + static constexpr std::size_t output_n_comp = output_field_t::n_comp; + static constexpr std::size_t prediction_stencil_radius = mesh_t::config::prediction_stencil_radius; + static constexpr std::size_t bdry_neighbourhood_width = bdry_cfg_t::neighbourhood_width; + static constexpr std::size_t bdry_stencil_size = bdry_cfg_t::stencil_size; + static constexpr std::size_t nb_bdry_ghosts = bdry_cfg_t::nb_ghosts; + using cell_t = Cell; using dirichlet_t = DirichletImpl; using neumann_t = NeumannImpl; @@ -695,7 +695,7 @@ namespace samurai // 1 + 9=10 in 2D // Order 2: cell + hypercube of 5 coarser cells --> 1 + 5= 6 in 1D // 1 +25=21 in 2D - static constexpr std::size_t pred_stencil_size = 1 + ce_pow(2 * prediction_order + 1, dim); + static constexpr std::size_t pred_stencil_size = 1 + ce_pow(2 * prediction_stencil_radius + 1, dim); nnz[static_cast(row_index(ghost, field_i))] = pred_stencil_size; } @@ -828,19 +828,20 @@ namespace samurai auto ig = ii >> 1; double isign = (ii & 1) ? -1 : 1; - auto interpx = samurai::interp_coeffs<2 * prediction_order + 1>(isign); + auto interpx = samurai::interp_coeffs<2 * prediction_stencil_radius + 1>(isign); auto parent_index = this->col_index(static_cast(this->mesh().get_index(ghost.level - 1, ig)), field_i); MatSetValue(A, ghost_index, parent_index, -scaling, current_insert_mode()); for (std::size_t ci = 0; ci < interpx.size(); ++ci) { - if (ci != prediction_order) + if (ci != prediction_stencil_radius) { double value = -interpx[ci]; auto coarse_cell_index = this->col_index( static_cast( - this->mesh().get_index(ghost.level - 1, ig + static_cast(ci - prediction_order))), + this->mesh().get_index(ghost.level - 1, + ig + static_cast(ci - prediction_stencil_radius))), field_i); MatSetValue(A, ghost_index, coarse_cell_index, scaling * value, current_insert_mode()); } @@ -859,17 +860,17 @@ namespace samurai auto ig = ii >> 1; double isign = (ii & 1) ? -1 : 1; - auto interpx = samurai::interp_coeffs<2 * prediction_order + 1>(isign); + auto interpx = samurai::interp_coeffs<2 * prediction_stencil_radius + 1>(isign); auto parent_index = this->mesh().get_index(ghost.level - 1, ig); linear_comb.emplace_back(parent_index, 1.); for (std::size_t ci = 0; ci < interpx.size(); ++ci) { - if (ci != prediction_order) + if (ci != prediction_stencil_radius) { auto coarse_cell_index = this->mesh().get_index(ghost.level - 1, - ig + static_cast(ci - prediction_order)); + ig + static_cast(ci - prediction_stencil_radius)); linear_comb.emplace_back(coarse_cell_index, interpx[ci]); } } @@ -896,8 +897,8 @@ namespace samurai double isign = (ii & 1) ? -1 : 1; double jsign = (j & 1) ? -1 : 1; - auto interpx = samurai::interp_coeffs<2 * prediction_order + 1>(isign); - auto interpy = samurai::interp_coeffs<2 * prediction_order + 1>(jsign); + auto interpx = samurai::interp_coeffs<2 * prediction_stencil_radius + 1>(isign); + auto interpy = samurai::interp_coeffs<2 * prediction_stencil_radius + 1>(jsign); auto parent_index = this->col_index(static_cast(this->mesh().get_index(ghost.level - 1, ig, jg)), field_i); @@ -907,14 +908,15 @@ namespace samurai { for (std::size_t cj = 0; cj < interpy.size(); ++cj) { - if (ci != prediction_order || cj != prediction_order) + if (ci != prediction_stencil_radius || cj != prediction_stencil_radius) { double value = -interpx[ci] * interpy[cj]; - auto coarse_cell_index = this->col_index(static_cast(this->mesh().get_index( - ghost.level - 1, - ig + static_cast(ci - prediction_order), - jg + static_cast(cj - prediction_order))), - field_i); + auto coarse_cell_index = this->col_index( + static_cast( + this->mesh().get_index(ghost.level - 1, + ig + static_cast(ci - prediction_stencil_radius), + jg + static_cast(cj - prediction_stencil_radius))), + field_i); MatSetValue(A, ghost_index, coarse_cell_index, scaling * value, current_insert_mode()); } } @@ -936,8 +938,8 @@ namespace samurai double isign = (ii & 1) ? -1 : 1; double jsign = (j & 1) ? -1 : 1; - auto interpx = samurai::interp_coeffs<2 * prediction_order + 1>(isign); - auto interpy = samurai::interp_coeffs<2 * prediction_order + 1>(jsign); + auto interpx = samurai::interp_coeffs<2 * prediction_stencil_radius + 1>(isign); + auto interpy = samurai::interp_coeffs<2 * prediction_stencil_radius + 1>(jsign); auto parent_index = this->mesh().get_index(ghost.level - 1, ig, jg); linear_comb.emplace_back(parent_index, 1.); @@ -946,11 +948,11 @@ namespace samurai { for (std::size_t cj = 0; cj < interpy.size(); ++cj) { - if (ci != prediction_order || cj != prediction_order) + if (ci != prediction_stencil_radius || cj != prediction_stencil_radius) { auto coarse_cell_index = this->mesh().get_index(ghost.level - 1, - ig + static_cast(ci - prediction_order), - jg + static_cast(cj - prediction_order)); + ig + static_cast(ci - prediction_stencil_radius), + jg + static_cast(cj - prediction_stencil_radius)); linear_comb.emplace_back(coarse_cell_index, interpx[ci] * interpy[cj]); } } @@ -981,9 +983,9 @@ namespace samurai double jsign = (j & 1) ? -1 : 1; double ksign = (k & 1) ? -1 : 1; - auto interpx = samurai::interp_coeffs<2 * prediction_order + 1>(isign); - auto interpy = samurai::interp_coeffs<2 * prediction_order + 1>(jsign); - auto interpz = samurai::interp_coeffs<2 * prediction_order + 1>(ksign); + auto interpx = samurai::interp_coeffs<2 * prediction_stencil_radius + 1>(isign); + auto interpy = samurai::interp_coeffs<2 * prediction_stencil_radius + 1>(jsign); + auto interpz = samurai::interp_coeffs<2 * prediction_stencil_radius + 1>(ksign); auto parent_index = this->col_index(static_cast(this->mesh().get_index(ghost.level - 1, ig, jg, kg)), field_i); @@ -995,15 +997,16 @@ namespace samurai { for (std::size_t ck = 0; ck < interpz.size(); ++ck) { - if (ci != prediction_order || cj != prediction_order || ck != prediction_order) + if (ci != prediction_stencil_radius || cj != prediction_stencil_radius + || ck != prediction_stencil_radius) { double value = -interpx[ci] * interpy[cj] * interpz[ck]; auto coarse_cell_index = this->col_index( - static_cast( - this->mesh().get_index(ghost.level - 1, - ig + static_cast(ci - prediction_order), - jg + static_cast(cj - prediction_order), - kg + static_cast(ck - prediction_order))), + static_cast(this->mesh().get_index( + ghost.level - 1, + ig + static_cast(ci - prediction_stencil_radius), + jg + static_cast(cj - prediction_stencil_radius), + kg + static_cast(ck - prediction_stencil_radius))), field_i); MatSetValue(A, ghost_index, coarse_cell_index, scaling * value, current_insert_mode()); } @@ -1030,9 +1033,9 @@ namespace samurai double jsign = (j & 1) ? -1 : 1; double ksign = (k & 1) ? -1 : 1; - auto interpx = samurai::interp_coeffs<2 * prediction_order + 1>(isign); - auto interpy = samurai::interp_coeffs<2 * prediction_order + 1>(jsign); - auto interpz = samurai::interp_coeffs<2 * prediction_order + 1>(ksign); + auto interpx = samurai::interp_coeffs<2 * prediction_stencil_radius + 1>(isign); + auto interpy = samurai::interp_coeffs<2 * prediction_stencil_radius + 1>(jsign); + auto interpz = samurai::interp_coeffs<2 * prediction_stencil_radius + 1>(ksign); auto parent_index = this->mesh().get_index(ghost.level - 1, ig, jg, kg); linear_comb.emplace_back(parent_index, 1.); @@ -1043,12 +1046,13 @@ namespace samurai { for (std::size_t ck = 0; ck < interpz.size(); ++ck) { - if (ci != prediction_order || cj != prediction_order || ck != prediction_order) + if (ci != prediction_stencil_radius || cj != prediction_stencil_radius || ck != prediction_stencil_radius) { - auto coarse_cell_index = this->mesh().get_index(ghost.level - 1, - ig + static_cast(ci - prediction_order), - jg + static_cast(cj - prediction_order), - kg + static_cast(ck - prediction_order)); + auto coarse_cell_index = this->mesh().get_index( + ghost.level - 1, + ig + static_cast(ci - prediction_stencil_radius), + jg + static_cast(cj - prediction_stencil_radius), + kg + static_cast(ck - prediction_stencil_radius)); linear_comb.emplace_back(coarse_cell_index, interpx[ci] * interpy[cj] * interpz[ck]); } } diff --git a/include/samurai/reconstruction.hpp b/include/samurai/reconstruction.hpp index b99df2e7e..fff5c61e4 100644 --- a/include/samurai/reconstruction.hpp +++ b/include/samurai/reconstruction.hpp @@ -373,7 +373,7 @@ namespace samurai // inline void operator()(Dim, std::size_t& reconstruct_level, T1& dest, const T2& src) const // { // using index_t = typename T2::interval_t::value_t; - // constexpr std::size_t prediction_order = T2::mesh_t::config::prediction_order; + // constexpr std::size_t prediction_stencil_radius = T2::mesh_t::config::prediction_stencil_radius; // std::size_t delta_l = reconstruct_level - level; // if (delta_l == 0) @@ -386,7 +386,7 @@ namespace samurai // detail::multi_dim_loop(interp_coeff_values, // [&](auto&... out_indices) // { - // auto& pred = prediction(delta_l, out_indices...); + // auto& pred = prediction(delta_l, out_indices...); // for (const auto& kv : pred.coeff) // { // std::apply( @@ -404,8 +404,8 @@ namespace samurai template inline void operator()(Dim<1>, std::size_t& reconstruct_level, T1& dest, const T2& src) const { - using index_t = typename T2::interval_t::value_t; - constexpr std::size_t prediction_order = T2::mesh_t::config::prediction_order; + using index_t = typename T2::interval_t::value_t; + constexpr std::size_t prediction_stencil_radius = T2::mesh_t::config::prediction_stencil_radius; std::size_t delta_l = reconstruct_level - level; if (delta_l == 0) @@ -417,7 +417,7 @@ namespace samurai index_t nb_cells = 1 << delta_l; for (index_t ii = 0; ii < nb_cells; ++ii) { - auto pred = prediction(delta_l, ii); + auto pred = prediction(delta_l, ii); for (const auto& kv : pred.coeff) { auto i_f = (i << delta_l) + ii; @@ -432,8 +432,8 @@ namespace samurai inline void operator()(Dim<2>, std::size_t& reconstruct_level, T1& dest, const T2& src) const { - using index_t = typename T2::interval_t::value_t; - constexpr std::size_t prediction_order = T2::mesh_t::config::prediction_order; + using index_t = typename T2::interval_t::value_t; + constexpr std::size_t prediction_stencil_radius = T2::mesh_t::config::prediction_stencil_radius; std::size_t delta_l = reconstruct_level - level; if (delta_l == 0) @@ -448,7 +448,7 @@ namespace samurai auto j_f = (j << delta_l) + jj; for (index_t ii = 0; ii < nb_cells; ++ii) { - const auto& pred = prediction(delta_l, ii, jj); + const auto& pred = prediction(delta_l, ii, jj); auto i_f = (i << delta_l) + ii; i_f.step = nb_cells; @@ -464,8 +464,8 @@ namespace samurai template inline void operator()(Dim<3>, std::size_t& reconstruct_level, T1& dest, const T2& src) const { - using index_t = typename T2::interval_t::value_t; - constexpr std::size_t prediction_order = T2::mesh_t::config::prediction_order; + using index_t = typename T2::interval_t::value_t; + constexpr std::size_t prediction_stencil_radius = T2::mesh_t::config::prediction_stencil_radius; std::size_t delta_l = reconstruct_level - level; if (delta_l == 0) @@ -483,7 +483,7 @@ namespace samurai auto j_f = (j << delta_l) + jj; for (index_t ii = 0; ii < nb_cells; ++ii) { - const auto& pred = prediction(delta_l, ii, jj, kk); + const auto& pred = prediction(delta_l, ii, jj, kk); auto i_f = (i << delta_l) + ii; i_f.step = nb_cells; @@ -559,7 +559,7 @@ namespace samurai namespace detail { - template + template requires(Field::dim == sizeof...(index_t) + 1 && (std::same_as && ...)) decltype(auto) get_prediction(std::size_t level, std::size_t delta_l, const std::tuple& ii) { @@ -571,7 +571,7 @@ namespace samurai auto iter = std::apply( [&](auto&... index) { - return values.find({prediction_order, level, index...}); + return values.find({prediction_stencil_radius, level, index...}); }, ii); @@ -584,7 +584,9 @@ namespace samurai std::apply( [&](auto&... index) { - values[{prediction_order, level, index...}] += prediction(delta_l, ii_...); + values[{prediction_stencil_radius, level, index...}] += prediction( + delta_l, + ii_...); }, ii); }); @@ -593,12 +595,12 @@ namespace samurai return std::apply( [&](auto&... index) -> auto& { - return values[{prediction_order, level, index...}]; + return values[{prediction_stencil_radius, level, index...}]; }, ii); } - template + template requires((std::same_as && ...)) decltype(auto) get_prediction(std::size_t, std::size_t delta_l, const std::tuple& ii) { @@ -606,12 +608,12 @@ namespace samurai return std::apply( [delta_l](const auto&... index) -> auto& { - return prediction(delta_l, index...); + return prediction(delta_l, index...); }, ii); } - template + template requires(Field::dim == sizeof...(index_t) + 1 && Field::dim == sizeof...(cell_index_t) && ((std::same_as && ...) || (std::same_as && ...)) @@ -625,7 +627,7 @@ namespace samurai { using result_t = std::decay_t; - const auto& pred = get_prediction(level, delta_l, ii); + const auto& pred = get_prediction(level, delta_l, ii); if constexpr (std::is_same_v) { @@ -668,7 +670,7 @@ namespace samurai { return f(element, level, indices...); }; - detail::portion_impl(result, f, get_f, level, delta_l, i, ii); + detail::portion_impl(result, f, get_f, level, delta_l, i, ii); } template @@ -689,7 +691,7 @@ namespace samurai return result; } - template + template void portion(auto& result, const Field& f, std::size_t level, @@ -702,7 +704,7 @@ namespace samurai return f(level, indices...); }; - detail::portion_impl(result, get_f, level, delta_l, i, ii); + detail::portion_impl(result, get_f, level, delta_l, i, ii); } template @@ -713,10 +715,10 @@ namespace samurai const std::tuple& i, const std::tuple& ii) { - portion(result, f, level, delta_l, i, ii); + portion(result, f, level, delta_l, i, ii); } - template + template auto portion(const Field& f, std::size_t level, std::size_t delta_l, @@ -729,7 +731,7 @@ namespace samurai return zeros_like(f(level, indices...)); }, i); - portion(result, f, level, delta_l, i, ii); + portion(result, f, level, delta_l, i, ii); return result; } @@ -740,7 +742,7 @@ namespace samurai const std::tuple& i, const std::tuple& ii) { - return portion(f, level, delta_l, i, ii); + return portion(f, level, delta_l, i, ii); } namespace detail @@ -801,7 +803,7 @@ namespace samurai auto src_tuple = detail::extract_src_tuple(src_indices); auto dst_tuple = detail::extract_dst_tuple(delta_l, dst_indices); - detail::portion_impl(result, get_f, level, delta_l, src_tuple, dst_tuple); + detail::portion_impl(result, get_f, level, delta_l, src_tuple, dst_tuple); } template diff --git a/include/samurai/samurai_config.hpp b/include/samurai/samurai_config.hpp index 73034122b..9a3a2b757 100644 --- a/include/samurai/samurai_config.hpp +++ b/include/samurai/samurai_config.hpp @@ -15,10 +15,10 @@ namespace samurai namespace default_config { - static constexpr std::size_t max_level = 20; - static constexpr int ghost_width = 1; - static constexpr int graduation_width = 1; - static constexpr std::size_t prediction_order = 1; + static constexpr std::size_t max_level = 20; + static constexpr int ghost_width = 1; + static constexpr int graduation_width = 1; + static constexpr std::size_t prediction_stencil_radius = 1; using index_t = signed long long int; using value_t = int; @@ -26,7 +26,7 @@ namespace samurai inline auto default_prediction_fn = [](auto& new_field, const auto& old_field) // cppcheck-suppress constParameterReference { - constexpr std::size_t pred_order = std::decay_t::mesh_t::config::prediction_order; + constexpr std::size_t pred_order = std::decay_t::mesh_t::config::prediction_stencil_radius; return prediction(new_field, old_field); }; } diff --git a/include/samurai/schemes/fv/flux_based/flux_based_scheme__nonlin.hpp b/include/samurai/schemes/fv/flux_based/flux_based_scheme__nonlin.hpp index c8c5eced7..18aaf8b63 100644 --- a/include/samurai/schemes/fv/flux_based/flux_based_scheme__nonlin.hpp +++ b/include/samurai/schemes/fv/flux_based/flux_based_scheme__nonlin.hpp @@ -201,7 +201,7 @@ namespace samurai { copy_stencil_values(field, cells, stencil_values_list[0]); } - else if constexpr (mesh_t::config::prediction_order == 0 && stencil_size <= 4) + else if constexpr (mesh_t::config::prediction_stencil_radius == 0 && stencil_size <= 4) { for (std::size_t fine_flux_index = 0; fine_flux_index < flux_params.n_fine_fluxes; ++fine_flux_index) { diff --git a/tests/test_adapt.cpp b/tests/test_adapt.cpp index 58a73d314..a87407a9f 100644 --- a/tests/test_adapt.cpp +++ b/tests/test_adapt.cpp @@ -30,13 +30,13 @@ namespace samurai ::samurai::initialize(); static constexpr std::size_t dim = TypeParam::value; - using config = MRConfig; - using box_t = Box; - auto mesh_cfg = mesh_config().min_level(2).max_level(4); - auto mesh = MRMesh(mesh_cfg, box_t{xt::zeros({dim}), xt::ones({dim})}); - auto u_1 = make_scalar_field("u_1", mesh); - auto u_2 = make_vector_field("u_2", mesh); - auto u_3 = make_vector_field("u_3", mesh); + + using box_t = Box; + auto mesh_cfg = mesh_config().min_level(2).max_level(4); + auto mesh = make_MRMesh(mesh_cfg, box_t{xt::zeros({dim}), xt::ones({dim})}); + auto u_1 = make_scalar_field("u_1", mesh); + auto u_2 = make_vector_field("u_2", mesh); + auto u_3 = make_vector_field("u_3", mesh); auto adapt = make_MRAdapt(u_1, u_2, u_3); auto mra_config = samurai::mra_config().regularity(2.); diff --git a/tests/test_bc.cpp b/tests/test_bc.cpp index 3d66e33cb..8b4fb7aac 100644 --- a/tests/test_bc.cpp +++ b/tests/test_bc.cpp @@ -57,11 +57,10 @@ namespace samurai TEST(bc, scalar_function) { static constexpr std::size_t dim = 1; - using config = MRConfig; Box box = {{0}, {1}}; auto mesh_cfg = mesh_config().min_level(2).max_level(4); - auto mesh = MRMesh(mesh_cfg, box); + auto mesh = make_MRMesh(mesh_cfg, box); auto u = make_scalar_field("u", mesh); make_bc>(u, diff --git a/tests/test_corner_projection.cpp b/tests/test_corner_projection.cpp index ac0627cdd..3f5da7a4c 100644 --- a/tests/test_corner_projection.cpp +++ b/tests/test_corner_projection.cpp @@ -9,18 +9,17 @@ namespace samurai TEST(subset, corner_projection) { static constexpr std::size_t dim = 2; - using Config = MRConfig; using Box = Box; - using Mesh = MRMesh; - using interval_t = typename Mesh::interval_t; - using mesh_id_t = typename Mesh::mesh_id_t; using direction_t = DirectionVector; Box box({-1., -1.}, {1., 1.}); auto mesh_cfg = mesh_config().min_level(2).max_level(6); + auto mesh = make_MRMesh(mesh_cfg, box); - Mesh mesh{mesh_cfg, box}; + using Mesh = decltype(mesh); + using interval_t = typename Mesh::interval_t; + using mesh_id_t = typename Mesh::mesh_id_t; direction_t direction = {-1, -1}; // corner direction std::size_t level = 6; diff --git a/tests/test_domain_with_hole.cpp b/tests/test_domain_with_hole.cpp index 42c225610..0f3ab9932 100644 --- a/tests/test_domain_with_hole.cpp +++ b/tests/test_domain_with_hole.cpp @@ -9,15 +9,15 @@ namespace samurai { static constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; - using Mesh = samurai::MRMesh; + std::size_t level = 3; + auto mesh_cfg = mesh_config().min_level(level).max_level(level); + + using Mesh = decltype(make_MRMesh(mesh_cfg)); using mesh_id_t = typename Mesh::mesh_id_t; using cl_t = typename Mesh::cl_type; using lca_t = typename Mesh::lca_type; using Box = samurai::Box; - std::size_t level = 3; - const Box domain_box({-1., -1.}, {1., 1.}); const Box hole_box({0.0, 0.0}, {0.2, 0.2}); @@ -36,8 +36,7 @@ namespace samurai domain_with_hole_cl[level][index_y].add_interval({interval}); }); - auto mesh_cfg = mesh_config().min_level(level).max_level(level); - samurai::MRMesh mesh{mesh_cfg, domain_with_hole_cl}; + auto mesh = samurai::make_MRMesh(mesh_cfg, domain_with_hole_cl); EXPECT_EQ(mesh.nb_cells(mesh_id_t::cells), domain_lca.nb_cells() - hole_lca.nb_cells()); } diff --git a/tests/test_field.cpp b/tests/test_field.cpp index f919533ff..9c0ce447d 100644 --- a/tests/test_field.cpp +++ b/tests/test_field.cpp @@ -12,7 +12,6 @@ namespace samurai TEST(field, from_expr) { Box box{{0}, {1}}; - // using Config = MRConfig<1>; // auto mesh = MRMesh(box, 3, 3); using Config = UniformConfig<1>; @@ -98,14 +97,13 @@ namespace samurai TEST(field, iterator) { - using config = MRConfig<2>; CellList<2> cl; cl[1][{0}].add_interval({0, 2}); cl[1][{0}].add_interval({4, 6}); cl[2][{0}].add_interval({4, 8}); auto mesh_cfg = mesh_config<2>().min_level(1).max_level(2); - auto mesh = MRMesh(mesh_cfg, cl); + auto mesh = make_MRMesh(mesh_cfg, cl); auto field = make_scalar_field("u", mesh); std::size_t index = 0; diff --git a/tests/test_find.cpp b/tests/test_find.cpp index d8c5fcb16..ec1b8ff49 100644 --- a/tests/test_find.cpp +++ b/tests/test_find.cpp @@ -10,18 +10,11 @@ namespace samurai TEST(find, test) { static constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; using Box = samurai::Box; - using Mesh = samurai::MRMesh; - using coords_t = typename Mesh::cell_t::coords_t; - Box box({-1., -1.}, {1., 1.}); - std::size_t min_level = 2; - std::size_t max_level = 6; - - auto mesh_cfg = samurai::mesh_config().min_level(min_level).max_level(max_level); - Mesh mesh{mesh_cfg, box}; + auto mesh_cfg = mesh_config().min_level(2).max_level(6); + auto mesh = make_MRMesh(mesh_cfg, box); auto u = samurai::make_scalar_field("u", mesh, @@ -36,6 +29,7 @@ namespace samurai auto mra_config = samurai::mra_config().epsilon(1e-3); MRadaptation(mra_config); + using coords_t = typename decltype(mesh)::cell_t::coords_t; coords_t coords = {0.4, 0.8}; auto cell = samurai::find_cell(mesh, coords); diff --git a/tests/test_for_each.cpp b/tests/test_for_each.cpp index ef91c3134..9e392ce21 100644 --- a/tests/test_for_each.cpp +++ b/tests/test_for_each.cpp @@ -5,8 +5,8 @@ namespace samurai { auto create_meshes(std::size_t level) { - using Config = amr::Config<1>; - using Mesh = amr::Mesh; + using Config = mesh_config<1>; + using Mesh = decltype(amr::make_Mesh(std::declval())); using cl_type = typename Mesh::cl_type; cl_type cl1; @@ -15,15 +15,15 @@ namespace samurai cl2[level][{}].add_interval({0, 3}); auto mesh_cfg = mesh_config<1>().min_level(level).max_level(level); - auto m1 = Mesh(mesh_cfg, cl1); - auto m2 = Mesh(mesh_cfg, cl2); + auto m1 = amr::make_Mesh(mesh_cfg, cl1); + auto m2 = amr::make_Mesh(mesh_cfg, cl2); return std::make_tuple(m1, m2); } TEST(set, for_each_interval) { - using Config = amr::Config<1>; - using Mesh = amr::Mesh; + using Config = mesh_config<1>; + using Mesh = decltype(amr::make_Mesh(std::declval())); using mesh_id_t = typename Mesh::mesh_id_t; std::size_t level = 1; @@ -46,8 +46,8 @@ namespace samurai TEST(set, for_each_cell) { - using Config = amr::Config<1>; - using Mesh = amr::Mesh; + using Config = mesh_config<1>; + using Mesh = decltype(amr::make_Mesh(std::declval())); using mesh_id_t = typename Mesh::mesh_id_t; std::size_t level = 1; diff --git a/tests/test_hdf5.cpp b/tests/test_hdf5.cpp index 3717f1993..d0d21de87 100644 --- a/tests/test_hdf5.cpp +++ b/tests/test_hdf5.cpp @@ -87,15 +87,14 @@ namespace samurai TYPED_TEST(hdf5_test, mr_mesh) { static constexpr std::size_t dim = TypeParam::value; - using Config = MRConfig; - using Mesh = MRMesh; + xt::xtensor_fixed> min_corner; xt::xtensor_fixed> max_corner; min_corner.fill(-1); max_corner.fill(1); Box box(min_corner, max_corner); - auto mesh_cfg = samurai::mesh_config().min_level(4).max_level(4); - Mesh mesh(mesh_cfg, box); + auto mesh_cfg = mesh_config().min_level(4).max_level(4); + auto mesh = make_MRMesh(mesh_cfg, box); test_save(mesh); args::save_debug_fields = true; test_save(mesh); diff --git a/tests/test_mra.cpp b/tests/test_mra.cpp index b249ef31b..b5005b4a0 100644 --- a/tests/test_mra.cpp +++ b/tests/test_mra.cpp @@ -11,13 +11,12 @@ namespace samurai auto init_mesh() { constexpr std::size_t dim = 2; - using Config = samurai::MRConfig; auto box = samurai::Box({0., 0.}, {1., 1.}); const std::size_t min_level = 2; const std::size_t max_level = 10; - auto mesh_cfg = samurai::mesh_config().min_level(min_level).max_level(max_level); - return samurai::MRMesh(mesh_cfg, box); + auto mesh_cfg = mesh_config().min_level(min_level).max_level(max_level); + return make_MRMesh(mesh_cfg, box); } void init_field(auto& u, double factor = 1.0) diff --git a/tests/test_periodic.cpp b/tests/test_periodic.cpp index 19332a34e..85b2c0031 100644 --- a/tests/test_periodic.cpp +++ b/tests/test_periodic.cpp @@ -45,7 +45,6 @@ namespace samurai TYPED_TEST(dim_test, periodic) { static constexpr std::size_t dim = TypeParam::value; - using Config = MRConfig; // Simulation parameters xt::xtensor_fixed> min_corner, max_corner; @@ -54,9 +53,9 @@ namespace samurai // Multiresolution parameters Box box(min_corner, max_corner); - auto mesh_cfg = samurai::mesh_config().min_level(3).max_level(6).periodic(true).graduation_width(1); - MRMesh mesh{mesh_cfg, box}; - using mesh_id_t = typename MRMesh::mesh_id_t; + auto mesh_cfg = samurai::mesh_config().min_level(3).max_level(6).periodic(true).graduation_width(1); + auto mesh = samurai::make_MRMesh(mesh_cfg, box); + using mesh_id_t = typename decltype(mesh)::mesh_id_t; double dt = 1; double Tf = 2 / mesh.cell_length(mesh.max_level()); diff --git a/tests/test_restart.cpp b/tests/test_restart.cpp index 68de8ef41..88620e730 100644 --- a/tests/test_restart.cpp +++ b/tests/test_restart.cpp @@ -10,8 +10,6 @@ namespace samurai template auto create_mesh(double box_boundary) { - using Config = samurai::MRConfig; - using Mesh = samurai::MRMesh; using Box = samurai::Box; using point_t = typename Box::point_t; @@ -21,7 +19,7 @@ namespace samurai Box box(box_corner1, box_corner2); auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(5); - return Mesh(mesh_cfg, box); + return make_MRMesh(mesh_cfg, box); } TEST(restart, restart_lca) diff --git a/tests/test_scaling.cpp b/tests/test_scaling.cpp index a9a090608..f5fd05d43 100644 --- a/tests/test_scaling.cpp +++ b/tests/test_scaling.cpp @@ -8,8 +8,6 @@ namespace samurai template auto create_mesh(double box_boundary, std::size_t level) { - using Config = samurai::MRConfig; - using Mesh = samurai::MRMesh; using Box = samurai::Box; using point_t = typename Box::point_t; @@ -19,7 +17,7 @@ namespace samurai Box box(box_corner1, box_corner2); auto mesh_cfg = samurai::mesh_config().min_level(level).max_level(level); - return Mesh(mesh_cfg, box); + return samurai::make_MRMesh(mesh_cfg, box); } /** diff --git a/tests/test_subset.cpp b/tests/test_subset.cpp index 20fa4e814..8406304d1 100644 --- a/tests/test_subset.cpp +++ b/tests/test_subset.cpp @@ -483,11 +483,12 @@ namespace samurai } { - using Config = MRConfig<2>; - const Box box({0, 0}, {1, 1}); - auto mesh_cfg = samurai::mesh_config().min_level(0).max_level(3); - MRMesh mesh{mesh_cfg, box}; - auto& domain = mesh.domain(); + static constexpr std::size_t dim = 2; + const Box box({0, 0}, {1, 1}); + auto mesh_cfg = samurai::mesh_config().min_level(0).max_level(3); + auto mesh = samurai::make_MRMesh(mesh_cfg, box); + auto& domain = mesh.domain(); + xt::xtensor_fixed> dir = {0, 1 << (3 - 1)}; auto expected = expected_t{ From c37e5d48eeff5f650b4cbc654f5f3ad09306b268 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Fri, 3 Oct 2025 15:38:07 +0200 Subject: [PATCH 24/60] fix capture this --- include/samurai/amr/mesh.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/samurai/amr/mesh.hpp b/include/samurai/amr/mesh.hpp index 0ff0e83ab..2410cce9c 100644 --- a/include/samurai/amr/mesh.hpp +++ b/include/samurai/amr/mesh.hpp @@ -116,13 +116,14 @@ namespace samurai::amr inline void Mesh::update_sub_mesh_impl() { cl_type cl; - for_each_interval(this->cells()[mesh_id_t::cells], + auto ghost_width = cfg().ghost_width(); + for_each_interval(this->cells()[mesh_id_t::cells, ghost_width], [&](std::size_t level, const auto& interval, const auto& index_yz) { lcl_type& lcl = cl[level]; static_nested_loop( - -cfg().ghost_width(), - cfg().ghost_width() + 1, + -ghost_width, + ghost_width + 1, [&](auto stencil) { auto index = xt::eval(index_yz + stencil); From 6d733fd27e3759e81dabf2acb29c7655cca6c870 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Fri, 3 Oct 2025 15:46:37 +0200 Subject: [PATCH 25/60] fix capture this --- include/samurai/amr/mesh.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/samurai/amr/mesh.hpp b/include/samurai/amr/mesh.hpp index 2410cce9c..3d428abf0 100644 --- a/include/samurai/amr/mesh.hpp +++ b/include/samurai/amr/mesh.hpp @@ -127,7 +127,7 @@ namespace samurai::amr [&](auto stencil) { auto index = xt::eval(index_yz + stencil); - lcl[index].add_interval({interval.start - cfg().ghost_width(), interval.end + cfg().ghost_width()}); + lcl[index].add_interval({interval.start - ghost_width, interval.end + ghost_width}); }); }); this->cells()[mesh_id_t::cells_and_ghosts] = {cl, false}; From 125dc0a9a0b33446b945e1841466d4788880c22b Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Fri, 3 Oct 2025 15:59:37 +0200 Subject: [PATCH 26/60] fix update_sub_mesh_impl --- include/samurai/amr/mesh.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/samurai/amr/mesh.hpp b/include/samurai/amr/mesh.hpp index 3d428abf0..09d1ee9ed 100644 --- a/include/samurai/amr/mesh.hpp +++ b/include/samurai/amr/mesh.hpp @@ -117,8 +117,8 @@ namespace samurai::amr { cl_type cl; auto ghost_width = cfg().ghost_width(); - for_each_interval(this->cells()[mesh_id_t::cells, ghost_width], - [&](std::size_t level, const auto& interval, const auto& index_yz) + for_each_interval(this->cells()[mesh_id_t::cells], + [&, ghost_width](std::size_t level, const auto& interval, const auto& index_yz) { lcl_type& lcl = cl[level]; static_nested_loop( From ad1304e8c842db52eb769e6b6dcf4f7faad945fe Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 6 Oct 2025 13:07:30 +0200 Subject: [PATCH 27/60] fix demos --- demos/FiniteVolume/level_set_from_scratch.cpp | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/demos/FiniteVolume/level_set_from_scratch.cpp b/demos/FiniteVolume/level_set_from_scratch.cpp index bc1aef808..86780a593 100644 --- a/demos/FiniteVolume/level_set_from_scratch.cpp +++ b/demos/FiniteVolume/level_set_from_scratch.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -51,16 +52,10 @@ struct fmt::formatter : formatter } }; -template -struct AMRConfig +template > +struct AMRConfig : samurai::mesh_config { - static constexpr std::size_t dim = dim_; - static constexpr std::size_t max_refinement_level = 20; - static constexpr int max_stencil_width = 2; - static constexpr int ghost_width = 2; - static constexpr std::size_t prediction_stencil_radius = 1; - using interval_t = samurai::Interval; - using mesh_id_t = SimpleID; + using mesh_id_t = SimpleID; }; template @@ -104,17 +99,19 @@ class AMRMesh : public samurai::Mesh_base, Config> inline void update_sub_mesh_impl() { cl_type cl; - for_each_interval( - this->cells()[mesh_id_t::cells], - [&](std::size_t level, const auto& interval, const auto& index_yz) - { - samurai::static_nested_loop( - [&](auto stencil) - { - auto index = xt::eval(index_yz + stencil); - cl[level][index].add_interval({interval.start - config::ghost_width, interval.end + config::ghost_width}); - }); - }); + auto ghost_width = this->cfg().ghost_width(); + for_each_interval(this->cells()[mesh_id_t::cells], + [&](std::size_t level, const auto& interval, const auto& index_yz) + { + samurai::static_nested_loop( + -ghost_width, + ghost_width + 1, + [&](auto stencil) + { + auto index = xt::eval(index_yz + stencil); + cl[level][index].add_interval({interval.start - ghost_width, interval.end + ghost_width}); + }); + }); this->cells()[mesh_id_t::cells_and_ghosts] = {cl, false}; } }; @@ -630,7 +627,7 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box(min_corner, max_corner); - auto config = samurai::mesh_config().min_level(4).max_level(8); + auto config = samurai::mesh_config().min_level(4).max_level(8).max_stencil_radius(2); AMRMesh mesh; auto phi = samurai::make_scalar_field("phi", mesh); From f95da719d24ce1b0d0df01be905c261db3c73f98 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 7 Oct 2025 12:15:09 +0200 Subject: [PATCH 28/60] add some documentation --- include/samurai/mesh_config.hpp | 178 +++++++++++++++++++++++++++++--- 1 file changed, 165 insertions(+), 13 deletions(-) diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index 68041b4e6..97e1202ab 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -48,22 +48,42 @@ namespace samurai m_periodic.fill(false); } + // m_max_stencil_radius --------------------------- + + /** + * @brief set max stencil radius in chained config + * + * @param stencil_radius + * @return auto& returns this object + */ auto& max_stencil_radius(int stencil_radius) { m_max_stencil_radius = stencil_radius; return *this; } + /** + * @brief get a reference on max stencil radius + */ auto& max_stencil_radius() { return m_max_stencil_radius; } - auto& max_stencil_radius() const + /** + * @brief get a reference on max stencil radius + */ + const auto& max_stencil_radius() const { return m_max_stencil_radius; } + /** + * @brief set stencil radius from a size (size is twice the size of the radius) + * + * @param stencil_size + * @return auto& returns this object + */ auto& max_stencil_size(int stencil_size) { m_max_stencil_radius = stencil_size / 2; @@ -74,114 +94,246 @@ namespace samurai return *this; } + /** + * @brief get value of max stencil size + */ auto max_stencil_size() const { return m_max_stencil_radius * 2; } - auto ghost_width() const - { - return m_ghost_width; - } + // m_graduation_width ----------------------------- + /** + * @brief set graduation width in chained config + * + * @param grad_width + * @return auto& returns this object + */ auto& graduation_width(std::size_t grad_width) { m_graduation_width = grad_width; return *this; } - auto& graduation_width() const + /** + * @brief get a reference on graduation width + */ + auto& graduation_width() + { + return m_graduation_width; + } + + /** + * @brief get a reference on graduation width + */ + const auto& graduation_width() const { return m_graduation_width; } + // m_ghost_width ---------------------------------- + + /** + * @brief get a reference on ghost width + */ + const auto& ghost_width() const + { + return m_ghost_width; + } + + // m_min_level ------------------------------------ + + /** + * @brief set min level in chained config + * + * @param level + * @return auto& returns this object + */ auto& min_level(std::size_t level) { m_min_level = level; return *this; } + /** + * @brief get a reference on min level + */ auto& min_level() { return m_min_level; } - auto& min_level() const + /** + * @brief get a reference on min level + */ + const auto& min_level() const { return m_min_level; } + // m_max_level ------------------------------------ + + /** + * @brief set max level in chained config + * + * @param level + * @return auto& returns this object + */ auto& max_level(std::size_t level) { m_max_level = level; return *this; } + /** + * @brief get a reference on max level + */ auto& max_level() { return m_max_level; } - auto& max_level() const + /** + * @brief get a reference on max level + */ + const auto& max_level() const { return m_max_level; } + // m_approx_box_tol ------------------------------- + + /** + * @brief set approximation box tolerance in chained config + * + * @param tol + * @return auto& returns this object + */ auto& approx_box_tol(double tol) { m_approx_box_tol = tol; return *this; } - auto& approx_box_tol() const + /** + * @brief get a reference on approximation box tolerance + */ + auto& approx_box_tol() + { + return m_approx_box_tol; + } + + /** + * @brief get a reference on approximation box tolerance + */ + const auto& approx_box_tol() const { return m_approx_box_tol; } + // m_scaling_factor ------------------------------- + + /** + * @brief set scaling factor in chained config + * + * @param factor + * @return auto& returns this object + */ auto& scaling_factor(double factor) { m_scaling_factor = factor; return *this; } - auto& scaling_factor() const + /** + * @brief get a reference on scaling factor + */ + auto& scaling_factor() { return m_scaling_factor; } - auto& scaling_factor() + /** + * @brief get a reference on scaling factor + */ + const auto& scaling_factor() const { return m_scaling_factor; } + // m_periodic ------------------------------------- + + /** + * @brief set periodicity in chained config + * + * @param periodicity + * @return auto& returns this object + */ auto& periodic(std::array const& periodicity) { m_periodic = periodicity; return *this; } + /** + * @brief set periodicity in chained config with a value to fill in each direction + * + * @param periodicity + * @return auto& returns this object + */ auto& periodic(bool periodicity) { m_periodic.fill(periodicity); return *this; } - auto& periodic() const + /** + * @brief get a reference on periodicity array + */ + auto& periodic() + { + return m_periodic; + } + + /** + * @brief get a reference on periodicity array + */ + const auto& periodic() const { return m_periodic; } - auto& periodic(std::size_t i) const + /** + * @brief get a reference on periodicity in direction i + */ + auto& periodic(std::size_t i) + { + return m_periodic[i]; + } + + /** + * @brief get a reference on periodicity in direction i + */ + const auto& periodic(std::size_t i) const { return m_periodic[i]; } + // m_disable_args_parse --------------------------- + + /** + * @brief disable argument parse + */ auto& disable_args_parse() { m_disable_args_parse = false; return *this; } + /** + * @brief parse arguments and set value to default samurai config value if needed + */ void parse_args() { if (!m_disable_args_parse) From 4add1224e40e453a86bc8ab829d0f3f7682a8943 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 7 Oct 2025 13:33:55 +0200 Subject: [PATCH 29/60] fix codacy --- include/samurai/mesh.hpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index b0939801f..d14889f22 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -340,7 +340,6 @@ namespace samurai // partition_mesh(start_level, b); // load_balancing(); - double scaling_factor_ = 0.; #else double scaling_factor_ = m_config.scaling_factor(); compute_scaling_factor(domain_builder, scaling_factor_); @@ -751,18 +750,7 @@ namespace samurai template inline double Mesh_base::min_cell_length() const { - if (args::finer_level_flux != 0) - { - return cell_length(max_level()); - } - else - { -#ifdef SAMURAI_WITH_MPI - return cell_length(max_level()); -#else - return cell_length(m_cells[mesh_id_t::cells].max_level()); -#endif - } + return cell_length(max_level()); } template From 695cefbad8a9831b074de12679541b906b213f03 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 7 Oct 2025 15:36:38 +0200 Subject: [PATCH 30/60] add disable minimal ghost width --- demos/FiniteVolume/AMR_Burgers_Hat.cpp | 4 +-- demos/FiniteVolume/advection_1d.cpp | 8 ++--- demos/FiniteVolume/advection_2d.cpp | 6 +--- demos/FiniteVolume/advection_2d_user_bc.cpp | 6 +--- demos/FiniteVolume/burgers_mra.cpp | 8 ++--- demos/FiniteVolume/burgers_os.cpp | 2 +- demos/FiniteVolume/heat.cpp | 6 +--- demos/FiniteVolume/heat_heterogeneous.cpp | 6 +--- demos/FiniteVolume/heat_nonlinear.cpp | 6 +--- demos/FiniteVolume/lid_driven_cavity.cpp | 2 +- .../manual_block_matrix_assembly.cpp | 5 +--- demos/FiniteVolume/nagumo.cpp | 6 +--- demos/FiniteVolume/scalar_burgers_2d.cpp | 2 +- demos/FiniteVolume/stokes_2d.cpp | 2 +- demos/highorder/main.cpp | 3 +- demos/multigrid/main.cpp | 15 +++++----- include/samurai/mesh_config.hpp | 30 +++++++++++++++++-- include/samurai/reconstruction.hpp | 4 +-- include/samurai/samurai_config.hpp | 8 ++--- 19 files changed, 58 insertions(+), 71 deletions(-) diff --git a/demos/FiniteVolume/AMR_Burgers_Hat.cpp b/demos/FiniteVolume/AMR_Burgers_Hat.cpp index a25852f74..541b00533 100644 --- a/demos/FiniteVolume/AMR_Burgers_Hat.cpp +++ b/demos/FiniteVolume/AMR_Burgers_Hat.cpp @@ -208,8 +208,6 @@ int main(int argc, char* argv[]) // AMR parameters std::size_t start_level = 7; - std::size_t min_level = 2; - std::size_t max_level = 7; bool correction = false; // Output parameters @@ -233,7 +231,7 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box({left_box}, {right_box}); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(2).max_level(7).max_stencil_size(2).disable_minimal_ghost_width(); auto mesh = samurai::amr::make_Mesh(config); auto phi = samurai::make_scalar_field("phi", mesh); diff --git a/demos/FiniteVolume/advection_1d.cpp b/demos/FiniteVolume/advection_1d.cpp index 2fcb76602..d99bca29d 100644 --- a/demos/FiniteVolume/advection_1d.cpp +++ b/demos/FiniteVolume/advection_1d.cpp @@ -73,10 +73,6 @@ int main(int argc, char* argv[]) double t = 0.; std::string restart_file; - // Multiresolution parameters - std::size_t min_level = 6; - std::size_t max_level = 12; - // Output parameters fs::path path = fs::current_path(); std::string filename = "FV_advection_1d"; @@ -98,8 +94,8 @@ int main(int argc, char* argv[]) const samurai::Box box({left_box}, {right_box}); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).periodic(is_periodic); - auto mesh = samurai::make_MRMesh(config, box); + auto config = samurai::mesh_config().min_level(6).max_level(12).periodic(is_periodic).max_stencil_size(2).disable_minimal_ghost_width(); + auto mesh = samurai::make_MRMesh(config, box); // samurai::MRMesh mesh; auto u = samurai::make_scalar_field("u", mesh); diff --git a/demos/FiniteVolume/advection_2d.cpp b/demos/FiniteVolume/advection_2d.cpp index 0d1be4d0d..82cc6e1be 100644 --- a/demos/FiniteVolume/advection_2d.cpp +++ b/demos/FiniteVolume/advection_2d.cpp @@ -75,10 +75,6 @@ int main(int argc, char* argv[]) double t = 0.; std::string restart_file; - // Multiresolution parameters - std::size_t min_level = 4; - std::size_t max_level = 10; - // Output parameters fs::path path = fs::current_path(); std::string filename = "FV_advection_2d"; @@ -98,7 +94,7 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box(min_corner, max_corner); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(4).max_level(10).max_stencil_size(2).disable_minimal_ghost_width(); auto mesh = samurai::make_MRMesh(config); auto u = samurai::make_scalar_field("u", mesh); diff --git a/demos/FiniteVolume/advection_2d_user_bc.cpp b/demos/FiniteVolume/advection_2d_user_bc.cpp index eab0328c0..75eb69089 100644 --- a/demos/FiniteVolume/advection_2d_user_bc.cpp +++ b/demos/FiniteVolume/advection_2d_user_bc.cpp @@ -107,10 +107,6 @@ int main(int argc, char* argv[]) double t = 0.; std::string restart_file; - // Multiresolution parameters - std::size_t min_level = 4; - std::size_t max_level = 10; - // Output parameters fs::path path = fs::current_path(); std::string filename = "FV_advection_2d"; @@ -130,7 +126,7 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box(min_corner, max_corner); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(4).max_level(10).max_stencil_size(2).disable_minimal_ghost_width(); auto mesh = samurai::make_MRMesh(config, box); auto u = samurai::make_scalar_field("u", mesh); diff --git a/demos/FiniteVolume/burgers_mra.cpp b/demos/FiniteVolume/burgers_mra.cpp index 5fad9eb2f..264db23d0 100644 --- a/demos/FiniteVolume/burgers_mra.cpp +++ b/demos/FiniteVolume/burgers_mra.cpp @@ -244,10 +244,6 @@ int main(int argc, char* argv[]) // Time integration double cfl = 0.95; - // Multiresolution parameters - std::size_t min_level = 1; - std::size_t max_level = 7; - // Output parameters fs::path path = fs::current_path(); std::string filename = "burgers_mra"; @@ -267,10 +263,10 @@ int main(int argc, char* argv[]) //--------------------// Box box({left_box}, {right_box}); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_radius(2).graduation_width(2); + auto config = samurai::mesh_config().min_level(1).max_level(7).max_stencil_radius(2).graduation_width(2); auto mesh = samurai::make_MRMesh(config, box); // samurai::MRMesh mesh{box, min_level, max_level}; - auto max_level_config = samurai::mesh_config().min_level(max_level).max_level(max_level).max_stencil_radius(2); + auto max_level_config = samurai::mesh_config().min_level(mesh.max_level()).max_level(mesh.max_level()).max_stencil_radius(2); auto max_level_mesh = samurai::make_MRMesh(max_level_config, box); auto u = samurai::make_scalar_field("u", mesh); diff --git a/demos/FiniteVolume/burgers_os.cpp b/demos/FiniteVolume/burgers_os.cpp index 4bb5ba4a7..29600d2cd 100644 --- a/demos/FiniteVolume/burgers_os.cpp +++ b/demos/FiniteVolume/burgers_os.cpp @@ -153,7 +153,7 @@ int main(int argc, char* argv[]) .periodic(true) .approx_box_tol(0.05) .scaling_factor(2) - .max_stencil_radius(2) + .max_stencil_radius(1) .graduation_width(2); config.parse_args(); std::cout << " max_level = " << config.max_level() << " min_level = " << config.min_level() << std::endl; diff --git a/demos/FiniteVolume/heat.cpp b/demos/FiniteVolume/heat.cpp index 414c44e09..a5457a61f 100644 --- a/demos/FiniteVolume/heat.cpp +++ b/demos/FiniteVolume/heat.cpp @@ -82,10 +82,6 @@ int main(int argc, char* argv[]) double t0 = 0.; std::string restart_file; - // Multiresolution parameters - std::size_t min_level = 4; - std::size_t max_level = dim == 1 ? 5 : 8; - // Output parameters fs::path path = fs::current_path(); std::string filename = "heat_" + std::to_string(dim) + "D"; @@ -118,7 +114,7 @@ int main(int argc, char* argv[]) box_corner1.fill(left_box); box_corner2.fill(right_box); Box box(box_corner1, box_corner2); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(4).max_level(dim == 1 ? 5 : 8).max_stencil_size(2).disable_minimal_ghost_width(); auto mesh = samurai::make_MRMesh(config); auto u = samurai::make_scalar_field("u", mesh); diff --git a/demos/FiniteVolume/heat_heterogeneous.cpp b/demos/FiniteVolume/heat_heterogeneous.cpp index e27809813..431d6afd8 100644 --- a/demos/FiniteVolume/heat_heterogeneous.cpp +++ b/demos/FiniteVolume/heat_heterogeneous.cpp @@ -58,10 +58,6 @@ int main(int argc, char* argv[]) double t = 0.; std::string restart_file; - // Multiresolution parameters - std::size_t min_level = 3; - std::size_t max_level = 6; - // Output parameters fs::path path = fs::current_path(); std::string filename = "heat_heterog_" + std::to_string(dim) + "D"; @@ -90,7 +86,7 @@ int main(int argc, char* argv[]) box_corner1.fill(left_box); box_corner2.fill(right_box); Box box(box_corner1, box_corner2); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(3).max_level(6).max_stencil_size(2).disable_minimal_ghost_width(); auto mesh = samurai::make_MRMesh(config); auto u = samurai::make_scalar_field("u", mesh); diff --git a/demos/FiniteVolume/heat_nonlinear.cpp b/demos/FiniteVolume/heat_nonlinear.cpp index 188959362..654c46e39 100644 --- a/demos/FiniteVolume/heat_nonlinear.cpp +++ b/demos/FiniteVolume/heat_nonlinear.cpp @@ -133,10 +133,6 @@ int main(int argc, char* argv[]) double t = 0.; std::string restart_file; - // Multiresolution parameters - std::size_t min_level = 4; - std::size_t max_level = 4; - // Output parameters fs::path path = fs::current_path(); std::string filename = "heat_nonlinear_" + std::to_string(dim) + "D"; @@ -165,7 +161,7 @@ int main(int argc, char* argv[]) box_corner1.fill(left_box); box_corner2.fill(right_box); Box box(box_corner1, box_corner2); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(4).max_level(4).max_stencil_size(2).disable_minimal_ghost_width(); auto mesh = samurai::make_MRMesh(config); ; auto u = samurai::make_scalar_field("u", mesh); diff --git a/demos/FiniteVolume/lid_driven_cavity.cpp b/demos/FiniteVolume/lid_driven_cavity.cpp index 8518e22ee..95495a55e 100644 --- a/demos/FiniteVolume/lid_driven_cavity.cpp +++ b/demos/FiniteVolume/lid_driven_cavity.cpp @@ -148,7 +148,7 @@ int main(int argc, char* argv[]) // where v = velocity // p = pressure - auto config = samurai::mesh_config().min_level(3).max_level(6).max_stencil_radius(2); + auto config = samurai::mesh_config().min_level(3).max_level(6).max_stencil_size(2); auto mesh = samurai::make_MRMesh(config, box); using mesh_id_t = typename decltype(mesh)::mesh_id_t; diff --git a/demos/FiniteVolume/manual_block_matrix_assembly.cpp b/demos/FiniteVolume/manual_block_matrix_assembly.cpp index 9155f1064..5c165d18e 100644 --- a/demos/FiniteVolume/manual_block_matrix_assembly.cpp +++ b/demos/FiniteVolume/manual_block_matrix_assembly.cpp @@ -192,11 +192,8 @@ int main(int argc, char* argv[]) std::cout << "------------------------- Begin -------------------------" << std::endl; - std::size_t min_level = 3; - std::size_t max_level = 3; - Box box({0, 0}, {1, 1}); - auto mesh_cfg = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto mesh_cfg = samurai::mesh_config().min_level(3).max_level(3); auto mesh_e = samurai::make_MRMesh(mesh_cfg, box); auto mesh_s = samurai::make_MRMesh(mesh_cfg, box); diff --git a/demos/FiniteVolume/nagumo.cpp b/demos/FiniteVolume/nagumo.cpp index 81bc9f666..def48dfad 100644 --- a/demos/FiniteVolume/nagumo.cpp +++ b/demos/FiniteVolume/nagumo.cpp @@ -69,10 +69,6 @@ int main(int argc, char* argv[]) double t = 0.; std::string restart_file; - // Multiresolution parameters - std::size_t min_level = 4; - std::size_t max_level = 8; - // Output parameters fs::path path = fs::current_path(); std::string filename = "nagumo"; @@ -106,7 +102,7 @@ int main(int argc, char* argv[]) box_corner1.fill(left_box); box_corner2.fill(right_box); Box box(box_corner1, box_corner2); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(4).max_level(8).disable_minimal_ghost_width(); auto mesh = samurai::make_MRMesh(config, box); auto u = samurai::make_vector_field("u", mesh); diff --git a/demos/FiniteVolume/scalar_burgers_2d.cpp b/demos/FiniteVolume/scalar_burgers_2d.cpp index 4d30273cb..588b1a770 100644 --- a/demos/FiniteVolume/scalar_burgers_2d.cpp +++ b/demos/FiniteVolume/scalar_burgers_2d.cpp @@ -221,7 +221,7 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box(min_corner, max_corner); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).disable_minimal_ghost_width(); auto mesh = samurai::make_MRMesh(config); auto u = samurai::make_scalar_field("u", mesh); diff --git a/demos/FiniteVolume/stokes_2d.cpp b/demos/FiniteVolume/stokes_2d.cpp index 12ece901a..ca96994d9 100644 --- a/demos/FiniteVolume/stokes_2d.cpp +++ b/demos/FiniteVolume/stokes_2d.cpp @@ -190,7 +190,7 @@ int main(int argc, char* argv[]) PetscCheck(size == 1, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "This is a uniprocessor example only!"); auto box = samurai::Box({0, 0}, {1, 1}); - auto config = samurai::mesh_config().min_level(5).max_level(5).max_stencil_radius(2); + auto config = samurai::mesh_config().min_level(5).max_level(5).max_stencil_size(2); auto mesh = samurai::make_MRMesh(config, box); using mesh_id_t = typename decltype(mesh)::mesh_id_t; diff --git a/demos/highorder/main.cpp b/demos/highorder/main.cpp index 96a146d71..56519636b 100644 --- a/demos/highorder/main.cpp +++ b/demos/highorder/main.cpp @@ -199,7 +199,8 @@ int main(int argc, char* argv[]) }); }); // mesh = {cl, mesh.min_level() + 1, mesh.max_level() + 1}; - auto mesh_cfg = samurai::mesh_config().min_level(init_mesh.min_level() + i_ref + 1).max_level(init_mesh.max_level() + i_ref + 1); + auto mesh_cfg = mesh.cfg(); + mesh_cfg.min_level(init_mesh.min_level() + i_ref + 1).max_level(init_mesh.max_level() + i_ref + 1); mesh = samurai::make_MRMesh(mesh_cfg, cl); } // std::cout << mesh << std::endl; diff --git a/demos/multigrid/main.cpp b/demos/multigrid/main.cpp index 42f73bebd..5cdd990bd 100644 --- a/demos/multigrid/main.cpp +++ b/demos/multigrid/main.cpp @@ -89,9 +89,9 @@ auto create_uniform_mesh(std::size_t level) min_level = level; max_level = level; - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).disable_minimal_ghost_width(); return samurai::amr::make_Mesh(config, box, start_level); // amr::Mesh - // return Mesh(box, /*start_level,*/ min_level, max_level); // MRMesh + // return samurai::make_MRMesh(box, /*start_level,*/ min_level, max_level); // MRMesh } template @@ -101,9 +101,9 @@ template min_level = level - 1; max_level = level; - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).disable_minimal_ghost_width(); - using cl_type = typename decltype(samurai::amr::make_Mesh(config))::cl_type; + using cl_type = typename decltype(config)::cl_type; int i = 1 << min_level; @@ -116,7 +116,7 @@ template static_assert(dim == 1, "create_refined_mesh() not implemented for this dimension"); return samurai::amr::make_Mesh(config, cl); // amr::Mesh - // return Mesh(box, /*start_level,*/ min_level, max_level); // MRMesh + // return samurai::make_MRMesh(box, /*start_level,*/ min_level, max_level); // MRMesh } int main(int argc, char* argv[]) @@ -126,9 +126,8 @@ int main(int argc, char* argv[]) constexpr std::size_t dim = 2; constexpr unsigned int n_comp = 1; constexpr bool is_soa = true; - using Field = decltype(samurai::make_vector_field( - "type", - std::declval(1))&>())); // samurai::VectorField; + using Mesh = decltype(create_uniform_mesh(1)); + using Field = samurai::VectorField; PetscMPIInt size; PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index 97e1202ab..ff5f7538c 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -4,14 +4,16 @@ #pragma once #include "arguments.hpp" +#include "cell_array.hpp" #include "samurai_config.hpp" + #include namespace samurai { template class mesh_config @@ -24,6 +26,13 @@ namespace samurai using interval_t = interval_t_; + using cell_t = Cell; + using cl_type = CellList; + using lcl_type = typename cl_type::lcl_type; + + using ca_type = CellArray; + using lca_type = typename ca_type::lca_type; + private: int m_max_stencil_radius = 1; @@ -39,7 +48,8 @@ namespace samurai std::array m_periodic; - bool m_disable_args_parse = false; + bool m_disable_args_parse = false; + bool m_disable_minimal_ghost_width = false; public: @@ -327,7 +337,14 @@ namespace samurai */ auto& disable_args_parse() { - m_disable_args_parse = false; + m_disable_args_parse = true; + return *this; + } + + // disable_minimal_ghost_width -------------------- + auto& disable_minimal_ghost_width() + { + m_disable_minimal_ghost_width = true; return *this; } @@ -370,6 +387,13 @@ namespace samurai } m_ghost_width = std::max(m_max_stencil_radius, static_cast(prediction_stencil_radius)); + + if (!m_disable_minimal_ghost_width) + { + // 2 is because prediction_stencil_radius=1, if >1 we don't know what to do... + // The idea is to have enough ghosts at the boundary for the reconstruction and the transfer to work. + m_max_stencil_radius = std::max(m_max_stencil_radius, 2); + } } private: diff --git a/include/samurai/reconstruction.hpp b/include/samurai/reconstruction.hpp index fff5c61e4..00af7d166 100644 --- a/include/samurai/reconstruction.hpp +++ b/include/samurai/reconstruction.hpp @@ -516,7 +516,7 @@ namespace samurai if (field.mesh().max_stencil_radius() < 2) { - std::cerr << "The reconstruction function requires at least 2 ghosts on the boundary.\nTo fix this issue, set mesh_config.max_stencil_radius(2) or mesh_config.max_stencil_size(4)." + std::cerr << "The reconstruction function requires at least 2 ghosts on the boundary.\nTo fix this issue, remove mesh_config.disable_minimal_ghost_width()." << std::endl; exit(EXIT_FAILURE); } @@ -819,7 +819,7 @@ namespace samurai if (field_src.mesh().max_stencil_radius() < 2) { - std::cerr << "The transfert function requires at least 2 ghosts on the boundary.\nTo fix this issue, set mesh_config.max_stencil_radius(2) or mesh_config.max_stencil_size(4)." + std::cerr << "The transfer function requires at least 2 ghosts on the boundary.\nTo fix this issue, remove mesh_config.disable_minimal_ghost_width()." << std::endl; exit(EXIT_FAILURE); } diff --git a/include/samurai/samurai_config.hpp b/include/samurai/samurai_config.hpp index 9a3a2b757..ab4782295 100644 --- a/include/samurai/samurai_config.hpp +++ b/include/samurai/samurai_config.hpp @@ -15,10 +15,10 @@ namespace samurai namespace default_config { - static constexpr std::size_t max_level = 20; - static constexpr int ghost_width = 1; - static constexpr int graduation_width = 1; - static constexpr std::size_t prediction_stencil_radius = 1; + static constexpr std::size_t max_level = 20; + static constexpr int ghost_width = 1; + static constexpr int graduation_width = 1; + static constexpr int prediction_stencil_radius = 1; using index_t = signed long long int; using value_t = int; From c7a293f97b2c1cac66cedddc3ddcbe1ca8e164e1 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 7 Oct 2025 15:55:29 +0200 Subject: [PATCH 31/60] fix demos --- demos/FiniteVolume/burgers_os.cpp | 5 ++--- demos/FiniteVolume/nagumo.cpp | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/demos/FiniteVolume/burgers_os.cpp b/demos/FiniteVolume/burgers_os.cpp index 29600d2cd..7be7eed4d 100644 --- a/demos/FiniteVolume/burgers_os.cpp +++ b/demos/FiniteVolume/burgers_os.cpp @@ -144,14 +144,13 @@ int main(int argc, char* argv[]) Box box_left(box_corner1, 0.5 * (box_corner1 + box_corner2)); Box box_right(0.5 * (box_corner1 + box_corner2), box_corner2); - samurai::LevelCellArray<1> lca_left(max_level, box_left, {-1}, 0.05, 2); - samurai::LevelCellArray<1> lca_right(max_level, box_right, {-1}, 0.05, 2); + samurai::LevelCellArray<1> lca_left(max_level, box_left, {-1}, -1., 2); + samurai::LevelCellArray<1> lca_right(max_level, box_right, {-1}, -1., 2); auto config = samurai::mesh_config() .min_level(min_level) .max_level(max_level) .periodic(true) - .approx_box_tol(0.05) .scaling_factor(2) .max_stencil_radius(1) .graduation_width(2); diff --git a/demos/FiniteVolume/nagumo.cpp b/demos/FiniteVolume/nagumo.cpp index def48dfad..fa2337c3f 100644 --- a/demos/FiniteVolume/nagumo.cpp +++ b/demos/FiniteVolume/nagumo.cpp @@ -122,8 +122,6 @@ int main(int argc, char* argv[]) if (restart_file.empty()) { - auto mesh_cfg = samurai::mesh_config().min_level(min_level).max_level(max_level); - mesh = {mesh_cfg, box}; u.resize(); // Initial solution samurai::for_each_cell(mesh, From 5f38d61d329db09317ed71b567c8ed8b3f6bd84c Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 7 Oct 2025 17:29:15 +0200 Subject: [PATCH 32/60] fix demos --- demos/FiniteVolume/AMR_Burgers_Hat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/FiniteVolume/AMR_Burgers_Hat.cpp b/demos/FiniteVolume/AMR_Burgers_Hat.cpp index 541b00533..bda0af936 100644 --- a/demos/FiniteVolume/AMR_Burgers_Hat.cpp +++ b/demos/FiniteVolume/AMR_Burgers_Hat.cpp @@ -252,7 +252,7 @@ int main(int argc, char* argv[]) auto tag = samurai::make_scalar_field("tag", mesh); const xt::xtensor_fixed> stencil_grad{{1}, {-1}}; - const double dx = mesh.cell_length(max_level); + const double dx = mesh.min_cell_length(); double dt = 0.99 * dx; const double dt_save = Tf / static_cast(nfiles); From 1303e14e6d4200ca5502a0b8a83d5e6925eb85d6 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 13 Oct 2025 11:39:36 +0200 Subject: [PATCH 33/60] refactoring --- demos/FiniteVolume/advection_1d.cpp | 3 +-- demos/FiniteVolume/advection_2d.cpp | 2 +- demos/FiniteVolume/advection_2d_user_bc.cpp | 2 +- demos/FiniteVolume/burgers.cpp | 2 +- demos/FiniteVolume/burgers_os.cpp | 2 +- demos/FiniteVolume/heat.cpp | 2 +- demos/FiniteVolume/heat_heterogeneous.cpp | 2 +- demos/FiniteVolume/heat_nonlinear.cpp | 2 +- demos/FiniteVolume/level_set.cpp | 4 ++-- demos/FiniteVolume/level_set_from_scratch.cpp | 4 ++-- demos/FiniteVolume/linear_convection.cpp | 2 +- demos/FiniteVolume/linear_convection_obstacle.cpp | 3 +-- demos/FiniteVolume/nagumo.cpp | 2 +- demos/FiniteVolume/scalar_burgers_2d.cpp | 2 +- include/samurai/algorithm/graduation.hpp | 14 +++++++++++--- 15 files changed, 27 insertions(+), 21 deletions(-) diff --git a/demos/FiniteVolume/advection_1d.cpp b/demos/FiniteVolume/advection_1d.cpp index d99bca29d..669e5f833 100644 --- a/demos/FiniteVolume/advection_1d.cpp +++ b/demos/FiniteVolume/advection_1d.cpp @@ -101,7 +101,6 @@ int main(int argc, char* argv[]) if (restart_file.empty()) { - // mesh = {box, min_level, max_level, std::array{is_periodic}}; mesh = {config, box}; init(u); } @@ -110,7 +109,7 @@ int main(int argc, char* argv[]) samurai::load(restart_file, mesh, u); } - double dt = cfl * mesh.cell_length(mesh.max_level()); + double dt = cfl * mesh.min_cell_length(); const double dt_save = Tf / static_cast(nfiles); if (!is_periodic) diff --git a/demos/FiniteVolume/advection_2d.cpp b/demos/FiniteVolume/advection_2d.cpp index 82cc6e1be..b8283279d 100644 --- a/demos/FiniteVolume/advection_2d.cpp +++ b/demos/FiniteVolume/advection_2d.cpp @@ -109,7 +109,7 @@ int main(int argc, char* argv[]) } samurai::make_bc>(u, 0.); - double dt = cfl * mesh.cell_length(mesh.max_level()); + double dt = cfl * mesh.min_cell_length(); const double dt_save = Tf / static_cast(nfiles); auto unp1 = samurai::make_scalar_field("unp1", mesh); diff --git a/demos/FiniteVolume/advection_2d_user_bc.cpp b/demos/FiniteVolume/advection_2d_user_bc.cpp index 75eb69089..aca61944d 100644 --- a/demos/FiniteVolume/advection_2d_user_bc.cpp +++ b/demos/FiniteVolume/advection_2d_user_bc.cpp @@ -141,7 +141,7 @@ int main(int argc, char* argv[]) } samurai::make_bc(u, 0.); - double dt = cfl * mesh.cell_length(mesh.max_level()); + double dt = cfl * mesh.min_cell_length(); const double dt_save = Tf / static_cast(nfiles); auto unp1 = samurai::make_scalar_field("unp1", mesh); diff --git a/demos/FiniteVolume/burgers.cpp b/demos/FiniteVolume/burgers.cpp index f1a507ff1..75291dc7e 100644 --- a/demos/FiniteVolume/burgers.cpp +++ b/demos/FiniteVolume/burgers.cpp @@ -220,7 +220,7 @@ int main_dim(int argc, char* argv[]) // Time iteration // //--------------------// - double dx = mesh.cell_length(mesh.max_level()); + double dx = mesh.min_cell_length(); dt = cfl * dx / pow(2, dim); auto MRadaptation = samurai::make_MRAdapt(u); diff --git a/demos/FiniteVolume/burgers_os.cpp b/demos/FiniteVolume/burgers_os.cpp index 7be7eed4d..975f04a04 100644 --- a/demos/FiniteVolume/burgers_os.cpp +++ b/demos/FiniteVolume/burgers_os.cpp @@ -190,7 +190,7 @@ int main(int argc, char* argv[]) // Time iteration // //--------------------// - double dx = mesh.cell_length(mesh.max_level()); + double dx = mesh.cmin_cell_length(); dt = cfl * dx / velocity(0); while (t != Tf) diff --git a/demos/FiniteVolume/heat.cpp b/demos/FiniteVolume/heat.cpp index a5457a61f..d04e9bdfd 100644 --- a/demos/FiniteVolume/heat.cpp +++ b/demos/FiniteVolume/heat.cpp @@ -169,7 +169,7 @@ int main(int argc, char* argv[]) if (explicit_scheme) { - double dx = mesh.cell_length(mesh.max_level()); + double dx = mesh.min_cell_length(); dt = cfl * (dx * dx) / (pow(2, dim) * diff_coeff); } diff --git a/demos/FiniteVolume/heat_heterogeneous.cpp b/demos/FiniteVolume/heat_heterogeneous.cpp index 431d6afd8..5c33d32dd 100644 --- a/demos/FiniteVolume/heat_heterogeneous.cpp +++ b/demos/FiniteVolume/heat_heterogeneous.cpp @@ -147,7 +147,7 @@ int main(int argc, char* argv[]) if (explicit_scheme) { double diff_coeff = 4; - double dx = mesh.cell_length(mesh.max_level()); + double dx = mesh.min_cell_length(); dt = cfl * (dx * dx) / (pow(2, dim) * diff_coeff); } diff --git a/demos/FiniteVolume/heat_nonlinear.cpp b/demos/FiniteVolume/heat_nonlinear.cpp index 654c46e39..7286ff2cb 100644 --- a/demos/FiniteVolume/heat_nonlinear.cpp +++ b/demos/FiniteVolume/heat_nonlinear.cpp @@ -199,7 +199,7 @@ int main(int argc, char* argv[]) if (explicit_scheme) { double diff_coeff = 1; - double dx = mesh.cell_length(mesh.max_level()); + double dx = mesh.min_cell_length(); dt = cfl * (dx * dx) / (pow(2, dim) * diff_coeff); } diff --git a/demos/FiniteVolume/level_set.cpp b/demos/FiniteVolume/level_set.cpp index 533ad08ed..d28af4230 100644 --- a/demos/FiniteVolume/level_set.cpp +++ b/demos/FiniteVolume/level_set.cpp @@ -90,7 +90,7 @@ void AMR_criteria(const Field& f, Tag& tag) samurai::for_each_cell(mesh[mesh_id_t::cells], [&](auto cell) { - const double dx = mesh.cell_length(mesh.max_level()); + const double dx = mesh.min_cell_length(); if (std::abs(f[cell]) < 1.2 * 5 * std::sqrt(2.) * dx) { @@ -301,7 +301,7 @@ int main(int argc, char* argv[]) samurai::load(restart_file, mesh, phi); } - double dt = cfl * mesh.cell_length(mesh.max_level()); + double dt = cfl * mesh.min_cell_length(); const double dt_save = Tf / static_cast(nfiles); auto u = init_velocity(mesh); diff --git a/demos/FiniteVolume/level_set_from_scratch.cpp b/demos/FiniteVolume/level_set_from_scratch.cpp index 86780a593..28f259687 100644 --- a/demos/FiniteVolume/level_set_from_scratch.cpp +++ b/demos/FiniteVolume/level_set_from_scratch.cpp @@ -332,7 +332,7 @@ void AMR_criteria(const Field& f, Tag& tag) samurai::for_each_cell(mesh[SimpleID::cells], [&](auto cell) { - const double dx = mesh.cell_length(mesh.max_level()); + const double dx = mesh.min_cell_length(); if (std::abs(f[cell]) < 1.2 * 5 * std::sqrt(2.) * dx) { @@ -642,7 +642,7 @@ int main(int argc, char* argv[]) samurai::load(restart_file, mesh, phi); } - double dt = cfl * mesh.cell_length(mesh.max_level()); + double dt = cfl * mesh.min_cell_length(); const double dt_save = Tf / static_cast(nfiles); // We initialize the level set function diff --git a/demos/FiniteVolume/linear_convection.cpp b/demos/FiniteVolume/linear_convection.cpp index d6189bda5..f4347f992 100644 --- a/demos/FiniteVolume/linear_convection.cpp +++ b/demos/FiniteVolume/linear_convection.cpp @@ -137,7 +137,7 @@ int main(int argc, char* argv[]) if (dt == 0) { - double dx = mesh.cell_length(mesh.max_level()); + double dx = mesh.min_cell_length(); auto a = xt::abs(velocity); double sum_velocities = xt::sum(xt::abs(velocity))(); dt = cfl * dx / sum_velocities; diff --git a/demos/FiniteVolume/linear_convection_obstacle.cpp b/demos/FiniteVolume/linear_convection_obstacle.cpp index 48ea36dcd..922104048 100644 --- a/demos/FiniteVolume/linear_convection_obstacle.cpp +++ b/demos/FiniteVolume/linear_convection_obstacle.cpp @@ -75,7 +75,6 @@ int main(int argc, char* argv[]) auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_size(6); auto mesh = samurai::make_MRMesh(config, domain); - // Mesh mesh(domain, min_level, max_level); // Initial solution auto u = samurai::make_scalar_field("u", @@ -115,7 +114,7 @@ int main(int argc, char* argv[]) if (dt == 0) { - double dx = mesh.cell_length(mesh.max_level()); + double dx = mesh.min_cell_length(); auto a = xt::abs(constant_velocity); double sum_velocities = xt::sum(xt::abs(constant_velocity))(); dt = cfl * dx / sum_velocities; diff --git a/demos/FiniteVolume/nagumo.cpp b/demos/FiniteVolume/nagumo.cpp index fa2337c3f..7ad13ada2 100644 --- a/demos/FiniteVolume/nagumo.cpp +++ b/demos/FiniteVolume/nagumo.cpp @@ -169,7 +169,7 @@ int main(int argc, char* argv[]) dt = Tf / 100; if (explicit_diffusion) { - double dx = mesh.cell_length(mesh.max_level()); + double dx = mesh.min_cell_length(); dt = cfl * (dx * dx) / (pow(2, dim) * D); } } diff --git a/demos/FiniteVolume/scalar_burgers_2d.cpp b/demos/FiniteVolume/scalar_burgers_2d.cpp index 588b1a770..ec85e7d42 100644 --- a/demos/FiniteVolume/scalar_burgers_2d.cpp +++ b/demos/FiniteVolume/scalar_burgers_2d.cpp @@ -238,7 +238,7 @@ int main(int argc, char* argv[]) samurai::make_bc>(u, 0.); - double dt = cfl * mesh.cell_length(mesh.max_level()); + double dt = cfl * mesh.min_cell_length(); const double dt_save = Tf / static_cast(nfiles); auto unp1 = samurai::make_scalar_field("unp1", mesh); diff --git a/include/samurai/algorithm/graduation.hpp b/include/samurai/algorithm/graduation.hpp index 9339670e9..1ac7d2fd6 100644 --- a/include/samurai/algorithm/graduation.hpp +++ b/include/samurai/algorithm/graduation.hpp @@ -135,8 +135,6 @@ namespace samurai std::size_t max_level = mesh.max_level(); - constexpr int ghost_width = mesh_t::config::prediction_stencil_radius; // cppcheck-suppress unreadVariable - for (std::size_t level = max_level; level > 0; --level) { /** @@ -159,7 +157,17 @@ namespace samurai auto subset_2 = intersection(mesh[mesh_id_t::cells][level], mesh[mesh_id_t::cells][level]); - subset_2.apply_op(tag_to_keep(tag, CellFlag::refine)); + auto ghost_width = mesh.cfg().graduation_width(); + // maximum ghost width is set to 9 + static_for<1, 10>::apply( + [&](auto static_ghost_width_) + { + static constexpr int static_ghost_width = static_cast(static_ghost_width_()); + if (ghost_width == static_ghost_width) + { + subset_2.apply_op(tag_to_keep(tag, CellFlag::refine)); + } + }); /** * K C K K From 3881faea571aa7e0b0124bc7663f2263b6670297 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 13 Oct 2025 13:54:49 +0200 Subject: [PATCH 34/60] add start_level in mesh_config --- demos/FiniteVolume/AMR_Burgers_Hat.cpp | 8 ++-- demos/FiniteVolume/level_set.cpp | 8 ++-- demos/FiniteVolume/level_set_from_scratch.cpp | 12 +++--- demos/Weno/VF_level_set_houc5_amr.cpp | 6 +-- demos/Weno/VF_level_set_os5_amr.cpp | 5 +-- demos/Weno/heat_weno5_amr.cpp | 5 +-- demos/Weno/weno5_amr.cpp | 5 +-- demos/from_obj/main.cpp | 6 +-- demos/multigrid/main.cpp | 4 +- demos/pablo/bubble_2d.cpp | 2 +- demos/tutorial/AMR_1D_Burgers/step_3/main.cpp | 4 +- demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp | 2 +- demos/tutorial/AMR_1D_Burgers/step_4/main.cpp | 3 +- demos/tutorial/AMR_1D_Burgers/step_5/main.cpp | 5 +-- demos/tutorial/AMR_1D_Burgers/step_6/main.cpp | 5 +-- demos/tutorial/graduation_case_1.cpp | 2 +- demos/tutorial/graduation_case_3.cpp | 2 +- include/samurai/amr/mesh.hpp | 10 ++--- include/samurai/arguments.hpp | 3 +- include/samurai/mesh.hpp | 23 ++++++----- include/samurai/mesh_config.hpp | 40 +++++++++++++++++-- 21 files changed, 91 insertions(+), 69 deletions(-) diff --git a/demos/FiniteVolume/AMR_Burgers_Hat.cpp b/demos/FiniteVolume/AMR_Burgers_Hat.cpp index bda0af936..16d2ea51a 100644 --- a/demos/FiniteVolume/AMR_Burgers_Hat.cpp +++ b/demos/FiniteVolume/AMR_Burgers_Hat.cpp @@ -207,8 +207,7 @@ int main(int argc, char* argv[]) std::string restart_file; // AMR parameters - std::size_t start_level = 7; - bool correction = false; + bool correction = false; // Output parameters fs::path path = fs::current_path(); @@ -221,7 +220,6 @@ int main(int argc, char* argv[]) app.add_option("--Ti", t, "Initial time")->capture_default_str()->group("Simulation parameters"); app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters"); - app.add_option("--start-level", start_level, "Start level of AMR")->capture_default_str()->group("AMR parameters"); app.add_option("--with-correction", correction, "Apply flux correction at the interface of two refinement levels") ->capture_default_str() ->group("AMR parameters"); @@ -231,13 +229,13 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box({left_box}, {right_box}); - auto config = samurai::mesh_config().min_level(2).max_level(7).max_stencil_size(2).disable_minimal_ghost_width(); + auto config = samurai::mesh_config().min_level(2).max_level(7).max_stencil_size(2).start_level(7).disable_minimal_ghost_width(); auto mesh = samurai::amr::make_Mesh(config); auto phi = samurai::make_scalar_field("phi", mesh); if (restart_file.empty()) { - mesh = samurai::amr::make_Mesh(config, box, start_level); + mesh = samurai::amr::make_Mesh(config, box); init_solution(phi); } else diff --git a/demos/FiniteVolume/level_set.cpp b/demos/FiniteVolume/level_set.cpp index d28af4230..5c10105ea 100644 --- a/demos/FiniteVolume/level_set.cpp +++ b/demos/FiniteVolume/level_set.cpp @@ -263,8 +263,7 @@ int main(int argc, char* argv[]) std::string restart_file; // AMR parameters - std::size_t start_level = 8; - bool correction = false; + bool correction = false; // Output parameters fs::path path = fs::current_path(); @@ -277,7 +276,6 @@ int main(int argc, char* argv[]) app.add_option("--Ti", t, "Initial time")->capture_default_str()->group("Simulation parameters"); app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters"); - app.add_option("--start-level", start_level, "Start level of AMR")->capture_default_str()->group("AMR parameters"); app.add_option("--with-correction", correction, "Apply flux correction at the interface of two refinement levels") ->capture_default_str() ->group("AMR parameters"); @@ -287,13 +285,13 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box(min_corner, max_corner); - auto config = samurai::mesh_config().min_level(4).max_level(8).max_stencil_radius(2); + auto config = samurai::mesh_config().min_level(4).max_level(8).start_level(8).max_stencil_radius(2); auto mesh = samurai::amr::make_Mesh(config); auto phi = samurai::make_scalar_field("phi", mesh); if (restart_file.empty()) { - mesh = samurai::amr::make_Mesh(config, box, start_level); + mesh = samurai::amr::make_Mesh(config, box); init_level_set(phi); } else diff --git a/demos/FiniteVolume/level_set_from_scratch.cpp b/demos/FiniteVolume/level_set_from_scratch.cpp index 28f259687..32a312749 100644 --- a/demos/FiniteVolume/level_set_from_scratch.cpp +++ b/demos/FiniteVolume/level_set_from_scratch.cpp @@ -91,8 +91,8 @@ class AMRMesh : public samurai::Mesh_base, Config> { } - inline AMRMesh(samurai::mesh_config& cfg, const samurai::Box& b, std::size_t start_level) - : base_type(cfg, b, start_level) + inline AMRMesh(samurai::mesh_config& cfg, const samurai::Box& b) + : base_type(cfg, b) { } @@ -603,8 +603,7 @@ int main(int argc, char* argv[]) std::string restart_file; // AMR parameters - std::size_t start_level = 8; - bool correction = false; + bool correction = false; // Output parameters fs::path path = fs::current_path(); @@ -617,7 +616,6 @@ int main(int argc, char* argv[]) app.add_option("--Ti", t, "Initial time")->capture_default_str()->group("Simulation parameters"); app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters"); - app.add_option("--start-level", start_level, "Start level of AMR")->capture_default_str()->group("AMR parameters"); app.add_flag("--with-correction", correction, "Apply flux correction at the interface of two refinement levels") ->capture_default_str() ->group("AMR parameters"); @@ -627,14 +625,14 @@ int main(int argc, char* argv[]) SAMURAI_PARSE(argc, argv); const samurai::Box box(min_corner, max_corner); - auto config = samurai::mesh_config().min_level(4).max_level(8).max_stencil_radius(2); + auto config = samurai::mesh_config().min_level(4).max_level(8).start_level(8).max_stencil_radius(2); AMRMesh mesh; auto phi = samurai::make_scalar_field("phi", mesh); if (restart_file.empty()) { - mesh = {config, box, start_level}; + mesh = {config, box}; init_level_set(phi); } else diff --git a/demos/Weno/VF_level_set_houc5_amr.cpp b/demos/Weno/VF_level_set_houc5_amr.cpp index 274e0ca86..83915234d 100644 --- a/demos/Weno/VF_level_set_houc5_amr.cpp +++ b/demos/Weno/VF_level_set_houc5_amr.cpp @@ -263,15 +263,13 @@ int main() constexpr std::size_t dim = 2; - std::size_t start_level = 8; - samurai::Box box{ {0, 0}, {1, 1} }; using Config = samurai::amr::Config; - auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(8).max_stencil_radius(3); - samurai::amr::Mesh mesh(mesh_cfg, box, start_level); + auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(8).start_level(8).max_stencil_radius(3); + samurai::amr::Mesh mesh(mesh_cfg, box); auto field = init_field(mesh); diff --git a/demos/Weno/VF_level_set_os5_amr.cpp b/demos/Weno/VF_level_set_os5_amr.cpp index 16003f092..fc130c05e 100644 --- a/demos/Weno/VF_level_set_os5_amr.cpp +++ b/demos/Weno/VF_level_set_os5_amr.cpp @@ -279,15 +279,14 @@ int main() samurai::initialize(); constexpr std::size_t dim = 2; - std::size_t start_level = 6; samurai::Box box{ {0, 0}, {1, 1} }; using Config = samurai::amr::Config; - auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(8).max_stencil_radius(3); - samurai::amr::Mesh mesh(mesh_cfg, box, start_level); + auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(8).start_level(6).max_stencil_radius(3); + samurai::amr::Mesh mesh(mesh_cfg, box); auto field = init_field(mesh); diff --git a/demos/Weno/heat_weno5_amr.cpp b/demos/Weno/heat_weno5_amr.cpp index abbe2c767..dee5aa7e2 100644 --- a/demos/Weno/heat_weno5_amr.cpp +++ b/demos/Weno/heat_weno5_amr.cpp @@ -721,15 +721,14 @@ int main() samurai::initialize(); constexpr std::size_t dim = 2; - std::size_t start_level = 7; samurai::Box box{ {0, 0, 0}, {1, 1, 1} }; using Config = samurai::amr::Config; - auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(10).max_stencil_radius(3); - samurai::amr::Mesh mesh(mesh_cfg, box, start_level); + auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(10).start_level(7).max_stencil_radius(3); + samurai::amr::Mesh mesh(mesh_cfg, box); using mesh_id_t = typename Config::mesh_id_t; auto field = init_field::call(samurai::Dim{}, mesh); diff --git a/demos/Weno/weno5_amr.cpp b/demos/Weno/weno5_amr.cpp index 185bbefa2..10eeed861 100644 --- a/demos/Weno/weno5_amr.cpp +++ b/demos/Weno/weno5_amr.cpp @@ -438,15 +438,14 @@ int main() samurai::initialize(); constexpr std::size_t dim = 2; - std::size_t start_level = 7; samurai::Box box{ {0, 0, 0}, {1, 1, 1} }; using Config = samurai::amr::Config; - auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(10).max_stencil_radius(3); - samurai::amr::Mesh mesh(mesh_cfg, box, start_level); + auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(10).start_level(7).max_stencil_radius(3); + samurai::amr::Mesh mesh(mesh_cfg, box); using mesh_id_t = typename Config::mesh_id_t; auto field = init_field::call(samurai::Dim{}, mesh); diff --git a/demos/from_obj/main.cpp b/demos/from_obj/main.cpp index 8821a4b69..1b7ada890 100644 --- a/demos/from_obj/main.cpp +++ b/demos/from_obj/main.cpp @@ -30,7 +30,7 @@ void save_mesh(const fs::path& path, const std::string& filename, const Mesh& me int main(int argc, char** argv) { constexpr std::size_t dim = 3; - std::size_t start_level = 1; + std::size_t initial_level = 1; std::size_t max_level = 8; bool keep_inside = false; bool keep_outside = false; @@ -41,7 +41,7 @@ int main(int argc, char** argv) CLI::App app{"Create an adapted mesh from an OBJ file"}; app.add_option("--input", input_file, "input File")->required()->check(CLI::ExistingFile); - app.add_option("--start-level", start_level, "Start level of the output adaptive mesh")->capture_default_str(); + app.add_option("--init-level", initial_level, "Start level of the output adaptive mesh")->capture_default_str(); app.add_flag("--keep-inside", keep_inside, "Keep the cells inside the object")->capture_default_str(); app.add_flag("--keep-outside", keep_outside, "Keep the cells outside the object")->capture_default_str(); app.add_option("--max-level", max_level, "Maximum level of the output adaptive mesh")->capture_default_str(); @@ -50,7 +50,7 @@ int main(int argc, char** argv) std::string output_file = fs::path(input_file).stem(); - auto mesh = samurai::from_geometry(input_file, start_level, max_level, keep_outside, keep_inside); + auto mesh = samurai::from_geometry(input_file, initial_level, max_level, keep_outside, keep_inside); make_graduation(mesh); save_mesh(path, fmt::format("mesh_{}", output_file), mesh); diff --git a/demos/multigrid/main.cpp b/demos/multigrid/main.cpp index 5cdd990bd..947f92d6a 100644 --- a/demos/multigrid/main.cpp +++ b/demos/multigrid/main.cpp @@ -89,8 +89,8 @@ auto create_uniform_mesh(std::size_t level) min_level = level; max_level = level; - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).disable_minimal_ghost_width(); - return samurai::amr::make_Mesh(config, box, start_level); // amr::Mesh + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).start_level(start_level).disable_minimal_ghost_width(); + return samurai::amr::make_Mesh(config, box); // amr::Mesh // return samurai::make_MRMesh(box, /*start_level,*/ min_level, max_level); // MRMesh } diff --git a/demos/pablo/bubble_2d.cpp b/demos/pablo/bubble_2d.cpp index e7c132800..ce6b4be46 100644 --- a/demos/pablo/bubble_2d.cpp +++ b/demos/pablo/bubble_2d.cpp @@ -258,7 +258,7 @@ int main(int argc, char* argv[]) app.add_option("--nb-bubbles", nb_bubbles, "Number of bubbles")->capture_default_str()->group("Simulation parameters"); app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--dt", dt, "Time step")->capture_default_str()->group("Simulation parameters"); - app.add_option("--start-level", start_level, "Start level of AMR")->capture_default_str()->group("Adaptation parameters"); + app.add_option("--initial-level", start_level, "Start level of AMR")->capture_default_str()->group("Adaptation parameters"); app.add_option("--minimum-level", min_level, "Minimum level of AMR")->capture_default_str()->group("Adaptation parameters"); app.add_option("--maximum-level", max_level, "Maximum level of AMR")->capture_default_str()->group("Adaptation parameters"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); diff --git a/demos/tutorial/AMR_1D_Burgers/step_3/main.cpp b/demos/tutorial/AMR_1D_Burgers/step_3/main.cpp index 75b3a82d6..6c8f464b3 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_3/main.cpp +++ b/demos/tutorial/AMR_1D_Burgers/step_3/main.cpp @@ -56,8 +56,8 @@ int main(int argc, char* argv[]) const std::size_t max_level = 6; // <-------------------------------- const samurai::Box box({-3}, {3}); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); - Mesh> mesh(config, box, start_level); // <-------------------------------- + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).start_level(start_level); + Mesh> mesh(config, box); // <-------------------------------- auto phi = init_sol(mesh); diff --git a/demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp b/demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp index 7e8a1e2a9..7a06cafe8 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp +++ b/demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp @@ -71,7 +71,7 @@ class Mesh : public samurai::Mesh_base, Config> // Constructor from a given box (domain) inline Mesh(samurai::mesh_config& cfg, const samurai::Box& b, std::size_t start_level) - : base_type(cfg.approx_box_tol(0).scaling_factor(1), b, start_level) + : base_type(cfg.approx_box_tol(0).scaling_factor(1).start_level(start_level), b) { } diff --git a/demos/tutorial/AMR_1D_Burgers/step_4/main.cpp b/demos/tutorial/AMR_1D_Burgers/step_4/main.cpp index db728ef20..21a6ec811 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_4/main.cpp +++ b/demos/tutorial/AMR_1D_Burgers/step_4/main.cpp @@ -40,7 +40,6 @@ int main(int argc, char* argv[]) fs::path path = fs::current_path(); std::string filename = "amr_1d_burgers_step_4"; - app.add_option("--start-level", start_level, "Start level of the AMR")->capture_default_str()->group("AMR parameter"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); SAMURAI_PARSE(argc, argv); @@ -53,7 +52,7 @@ int main(int argc, char* argv[]) constexpr std::size_t dim = 1; const samurai::Box box({-3}, {3}); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).start_level(start_level); Mesh> mesh(config, box, start_level); auto phi = init_sol(mesh); diff --git a/demos/tutorial/AMR_1D_Burgers/step_5/main.cpp b/demos/tutorial/AMR_1D_Burgers/step_5/main.cpp index 9bb750808..8a9935b86 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_5/main.cpp +++ b/demos/tutorial/AMR_1D_Burgers/step_5/main.cpp @@ -42,7 +42,6 @@ int main(int argc, char* argv[]) fs::path path = fs::current_path(); std::string filename = "amr_1d_burgers_step_5"; - app.add_option("--start-level", start_level, "Start level of the AMR")->capture_default_str()->group("AMR parameter"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); SAMURAI_PARSE(argc, argv); @@ -55,8 +54,8 @@ int main(int argc, char* argv[]) constexpr std::size_t dim = 1; const samurai::Box box({-3}, {3}); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); - Mesh> mesh(config, box, start_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).start_level(start_level); + Mesh> mesh(config, box); auto phi = init_sol(mesh); diff --git a/demos/tutorial/AMR_1D_Burgers/step_6/main.cpp b/demos/tutorial/AMR_1D_Burgers/step_6/main.cpp index 03e0767ec..3a6b7715d 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_6/main.cpp +++ b/demos/tutorial/AMR_1D_Burgers/step_6/main.cpp @@ -53,7 +53,6 @@ int main(int argc, char* argv[]) app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters"); app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); - app.add_option("--start-level", start_level, "Start level of the AMR")->capture_default_str()->group("AMR parameter"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); app.add_option("--filename", filename, "File name prefix")->capture_default_str()->group("Output"); app.add_option("--nfiles", nfiles, "Number of output files")->capture_default_str()->group("Output"); @@ -67,8 +66,8 @@ int main(int argc, char* argv[]) constexpr std::size_t dim = 1; const samurai::Box box({-3}, {3}); - auto config = samurai::mesh_config().min_level(min_level).max_level(max_level); - Mesh> mesh(config, box, start_level); + auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).start_level(start_level); + Mesh> mesh(config, box); auto phi = init_sol(mesh); diff --git a/demos/tutorial/graduation_case_1.cpp b/demos/tutorial/graduation_case_1.cpp index aa9997765..994467d9b 100644 --- a/demos/tutorial/graduation_case_1.cpp +++ b/demos/tutorial/graduation_case_1.cpp @@ -69,7 +69,7 @@ int main(int argc, char* argv[]) fs::path path = fs::current_path(); std::string filename = "graduation_case_1"; - app.add_option("--start-level", start_level, "where to start the mesh generator")->capture_default_str(); + app.add_option("--starting-level", start_level, "where to start the mesh generator")->capture_default_str(); app.add_option("--max-refinement-level", max_refinement_level, "Maximum level of the mesh generator")->capture_default_str(); app.add_flag("--with-corner", with_corner, "Make the graduation including the diagonal")->capture_default_str(); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); diff --git a/demos/tutorial/graduation_case_3.cpp b/demos/tutorial/graduation_case_3.cpp index 1bf58d875..761ddc9be 100644 --- a/demos/tutorial/graduation_case_3.cpp +++ b/demos/tutorial/graduation_case_3.cpp @@ -42,7 +42,7 @@ int main(int argc, char* argv[]) fs::path path = fs::current_path(); std::string filename = "graduation_case_3"; - app.add_option("--start-level", start_level, "where to start the mesh generator")->capture_default_str(); + app.add_option("--starting-level", start_level, "where to start the mesh generator")->capture_default_str(); app.add_option("--maximum-level", max_level, "Maximum level of the mesh generator")->capture_default_str(); app.add_flag("--with-graduation", with_graduation, "Make the mesh graduated")->capture_default_str(); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); diff --git a/include/samurai/amr/mesh.hpp b/include/samurai/amr/mesh.hpp index 09d1ee9ed..f8cf4c8f7 100644 --- a/include/samurai/amr/mesh.hpp +++ b/include/samurai/amr/mesh.hpp @@ -71,7 +71,7 @@ namespace samurai::amr Mesh(const cl_type& cl, const self_type& ref_mesh); Mesh(const mesh_config& config, const cl_type& cl); Mesh(const mesh_config& config, const ca_type& ca); - Mesh(mesh_config& config, const Box& b, std::size_t start_level); + Mesh(mesh_config& config, const Box& b); void update_sub_mesh_impl(); @@ -107,8 +107,8 @@ namespace samurai::amr } template - inline Mesh::Mesh(mesh_config& config, const Box& b, std::size_t start_level) - : base_type(config, b, start_level) + inline Mesh::Mesh(mesh_config& config, const Box& b) + : base_type(config, b) { } @@ -225,10 +225,10 @@ namespace samurai::amr } template - auto make_Mesh(mesh_config_t& cfg, const samurai::Box& b, std::size_t start_level) + auto make_Mesh(mesh_config_t& cfg, const samurai::Box& b) { using complete_cfg_t = complete_mesh_config; - return Mesh(cfg, b, start_level); + return Mesh(cfg, b); } } // namespace samurai::amr diff --git a/include/samurai/arguments.hpp b/include/samurai/arguments.hpp index c662011a2..0f6750a72 100644 --- a/include/samurai/arguments.hpp +++ b/include/samurai/arguments.hpp @@ -11,6 +11,7 @@ namespace samurai // Mesh arguments static std::size_t min_level = std::numeric_limits::max(); static std::size_t max_level = std::numeric_limits::max(); + static std::size_t start_level = std::numeric_limits::max(); static std::size_t graduation_width = std::numeric_limits::max(); static int max_stencil_radius = std::numeric_limits::max(); @@ -32,8 +33,8 @@ namespace samurai { app.add_option("--min-level", args::min_level, "The minimum level of the mesh")->group("SAMURAI"); app.add_option("--max-level", args::max_level, "The maximum level of the mesh")->group("SAMURAI"); + app.add_option("--start-level", args::max_level, "Start level of AMR")->group("SAMURAI"); app.add_option("--graduation-width", args::graduation_width, "The graduation width of the mesh")->group("SAMURAI"); - // app.add_option("--graduation-width", args::graduation_width, "The graduation width of the mesh")->group("SAMURAI"); app.add_option("--max-stencil-radius", args::max_stencil_radius, "The maximum number of neighbour in each direction")->group("SAMURAI"); #ifdef SAMURAI_WITH_MPI diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index d14889f22..2ba0f9b5a 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -164,9 +164,9 @@ namespace samurai Mesh_base(const cl_type& cl, const self_type& ref_mesh); Mesh_base(const mesh_config& config, const cl_type& cl); Mesh_base(const mesh_config& config, const ca_type& ca); - Mesh_base(mesh_config& config, const samurai::Box& b, std::size_t start_level); + Mesh_base(mesh_config& config, const samurai::Box& b); - Mesh_base(const mesh_config& config, const samurai::DomainBuilder& domain_builder, std::size_t start_level); + Mesh_base(const mesh_config& config, const samurai::DomainBuilder& domain_builder); // cppcheck-suppress uninitMemberVar Mesh_base(const samurai::Box&, std::size_t, std::size_t, std::size_t, double, double) @@ -259,16 +259,16 @@ namespace samurai } template - inline Mesh_base::Mesh_base(mesh_config& config, const samurai::Box& b, std::size_t start_level) - : m_domain{start_level, b, (config.parse_args(), config.approx_box_tol()), config.scaling_factor()} + inline Mesh_base::Mesh_base(mesh_config& config, const samurai::Box& b) + : m_domain{config.start_level(), b, (config.parse_args(), config.approx_box_tol()), config.scaling_factor()} , m_periodic{config.periodic()} , m_config(config) { #ifdef SAMURAI_WITH_MPI - partition_mesh(start_level, b); + partition_mesh(m_config().start_level(), b); // load_balancing(); #else - this->m_cells[mesh_id_t::cells][start_level] = {start_level, b, config.approx_box_tol(), config.scaling_factor()}; + this->m_cells[mesh_id_t::cells][m_config.start_level()] = {m_config.start_level(), b, config.approx_box_tol(), config.scaling_factor()}; #endif construct_subdomain(); construct_union(); @@ -315,9 +315,7 @@ namespace samurai // } template - Mesh_base::Mesh_base(const mesh_config& config, - const samurai::DomainBuilder& domain_builder, - [[maybe_unused]] std::size_t start_level) + Mesh_base::Mesh_base(const mesh_config& config, const samurai::DomainBuilder& domain_builder) : m_config(config) { m_config.parse_args(); @@ -337,7 +335,7 @@ namespace samurai #ifdef SAMURAI_WITH_MPI std::cerr << "MPI is not implemented with DomainBuilder." << std::endl; std::exit(EXIT_FAILURE); - // partition_mesh(start_level, b); + // partition_mesh(m_config.start_level(), b); // load_balancing(); #else @@ -346,7 +344,10 @@ namespace samurai m_config.scaling_factor() = scaling_factor_; // Build the domain by adding and removing boxes - cl_type domain_cl = construct_initial_mesh(domain_builder, start_level, m_config.approx_box_tol(), m_config.scaling_factor()); + cl_type domain_cl = construct_initial_mesh(domain_builder, + m_config.start_level(), + m_config.approx_box_tol(), + m_config.scaling_factor()); this->m_cells[mesh_id_t::cells] = {domain_cl, false}; #endif diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index ff5f7538c..7da91bca5 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -39,9 +39,9 @@ namespace samurai std::size_t m_graduation_width = default_config::graduation_width; int m_ghost_width = default_config::ghost_width; - std::size_t m_min_level = 0; - std::size_t m_max_level = 6; - // std::size_t m_initial_level; + std::size_t m_min_level = 0; + std::size_t m_max_level = 6; + std::size_t m_start_level = 6; double m_approx_box_tol = 0.05; double m_scaling_factor = 0; @@ -212,6 +212,36 @@ namespace samurai return m_max_level; } + // m_start_level ------------------------------------ + + /** + * @brief set start level in chained config + * + * @param level + * @return auto& returns this object + */ + auto& start_level(std::size_t level) + { + m_start_level = level; + return *this; + } + + /** + * @brief get a reference on start level + */ + auto& start_level() + { + return m_start_level; + } + + /** + * @brief get a reference on start level + */ + const auto& start_level() const + { + return m_start_level; + } + // m_approx_box_tol ------------------------------- /** @@ -371,6 +401,10 @@ namespace samurai { m_max_level = args::max_level; } + if (args::start_level != std::numeric_limits::max()) + { + m_start_level = args::start_level; + } // if (args::approx_box_tol != std::numeric_limits::infinity()) // { // m_approx_box_tol = args::approx_box_tol; From f1862643cda06b02704f567ae1f612a45023d83e Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 13 Oct 2025 13:55:25 +0200 Subject: [PATCH 35/60] typo --- demos/FiniteVolume/burgers_os.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/FiniteVolume/burgers_os.cpp b/demos/FiniteVolume/burgers_os.cpp index 975f04a04..e31b6ec3a 100644 --- a/demos/FiniteVolume/burgers_os.cpp +++ b/demos/FiniteVolume/burgers_os.cpp @@ -190,7 +190,7 @@ int main(int argc, char* argv[]) // Time iteration // //--------------------// - double dx = mesh.cmin_cell_length(); + double dx = mesh.min_cell_length(); dt = cfl * dx / velocity(0); while (t != Tf) From b478604aba2dbf1167956b382921c33b77d56a1d Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 13 Oct 2025 14:12:41 +0200 Subject: [PATCH 36/60] fix start_level --- include/samurai/mr/mesh.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 1c112db16..4fb8d4592 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -134,13 +134,13 @@ namespace samurai template inline MRMesh::MRMesh(mesh_config& config, const samurai::Box& b) - : base_type(config, b, (config.parse_args(), config.max_level())) + : base_type(config.start_level(config.max_level()), b) { } template inline MRMesh::MRMesh(mesh_config& config, const samurai::DomainBuilder& domain_builder) - : base_type(config, domain_builder, (config.parse_args(), config.max_level())) + : base_type(config.start_level(config.max_level()), domain_builder) { } From 869cc3cb177181deb5ac23ac6c5f87b0c979ba92 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 13 Oct 2025 14:24:03 +0200 Subject: [PATCH 37/60] fix start_level --- include/samurai/mesh.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 2ba0f9b5a..cd0272390 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -265,7 +265,7 @@ namespace samurai , m_config(config) { #ifdef SAMURAI_WITH_MPI - partition_mesh(m_config().start_level(), b); + partition_mesh(m_config.start_level(), b); // load_balancing(); #else this->m_cells[mesh_id_t::cells][m_config.start_level()] = {m_config.start_level(), b, config.approx_box_tol(), config.scaling_factor()}; From e62c521fbc78f7b18c235e4ad09b57b7a7d53e27 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 13 Oct 2025 15:17:42 +0200 Subject: [PATCH 38/60] fix start_level --- demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp b/demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp index 7a06cafe8..e30c6f293 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp +++ b/demos/tutorial/AMR_1D_Burgers/step_3/mesh.hpp @@ -70,8 +70,8 @@ class Mesh : public samurai::Mesh_base, Config> } // Constructor from a given box (domain) - inline Mesh(samurai::mesh_config& cfg, const samurai::Box& b, std::size_t start_level) - : base_type(cfg.approx_box_tol(0).scaling_factor(1).start_level(start_level), b) + inline Mesh(samurai::mesh_config& cfg, const samurai::Box& b) + : base_type(cfg.approx_box_tol(0).scaling_factor(1), b) { } From 943e3307dc4e6788930122989fe5c496e0585f2a Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 13 Oct 2025 15:43:09 +0200 Subject: [PATCH 39/60] fix start_level --- demos/tutorial/AMR_1D_Burgers/step_4/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/tutorial/AMR_1D_Burgers/step_4/main.cpp b/demos/tutorial/AMR_1D_Burgers/step_4/main.cpp index 21a6ec811..5fb129533 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_4/main.cpp +++ b/demos/tutorial/AMR_1D_Burgers/step_4/main.cpp @@ -53,7 +53,7 @@ int main(int argc, char* argv[]) const samurai::Box box({-3}, {3}); auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).start_level(start_level); - Mesh> mesh(config, box, start_level); + Mesh> mesh(config, box); auto phi = init_sol(mesh); From d0457522ca8283739106e75b27a7d74328832443 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 13 Oct 2025 16:42:45 +0200 Subject: [PATCH 40/60] fix start_level --- include/samurai/mr/mesh.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 4fb8d4592..22969effc 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -121,14 +121,14 @@ namespace samurai } template - inline MRMesh::MRMesh(const mesh_config& config, const cl_type& cl) - : base_type(config, cl) + inline MRMesh::MRMesh(mesh_config& config, const cl_type& cl) + : base_type(config.start_level(config.max_level()), cl) { } template - inline MRMesh::MRMesh(const mesh_config& config, const ca_type& ca) - : base_type(config, ca) + inline MRMesh::MRMesh(mesh_config& config, const ca_type& ca) + : base_type(config.start_level(config.max_level()), ca) { } From a685ec5059f852a6e8a4eeeae5b4af58156fb991 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 13 Oct 2025 16:52:19 +0200 Subject: [PATCH 41/60] fix start_level --- include/samurai/mr/mesh.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 22969effc..6d657db11 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -79,8 +79,8 @@ namespace samurai MRMesh() = default; MRMesh(const ca_type& ca, const self_type& ref_mesh); MRMesh(const cl_type& cl, const self_type& ref_mesh); - MRMesh(const mesh_config& config, const cl_type& cl); - MRMesh(const mesh_config& config, const ca_type& ca); + MRMesh(mesh_config& config, const cl_type& cl); + MRMesh(mesh_config& config, const ca_type& ca); MRMesh(mesh_config& config, const samurai::Box& b); MRMesh(mesh_config& config, const samurai::DomainBuilder& domain_builder); From 80916267b4e99fc41da5f6e86dbcf940b51a7827 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 13 Oct 2025 16:59:57 +0200 Subject: [PATCH 42/60] fix start_level --- include/samurai/mr/mesh.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 6d657db11..a224f9c89 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -522,13 +522,13 @@ namespace samurai } template > - auto make_MRMesh(const mesh_config_t& cfg, const typename MRMesh::cl_type& cl) + auto make_MRMesh(mesh_config_t& cfg, const typename MRMesh::cl_type& cl) { return MRMesh(cfg, cl); } template > - auto make_MRMesh(const mesh_config_t& cfg, const typename MRMesh::ca_type& ca) + auto make_MRMesh(mesh_config_t& cfg, const typename MRMesh::ca_type& ca) { return MRMesh(cfg, ca); } From ebf10421923f298c9b43cf1c62e307dc3f533d60 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 13 Oct 2025 21:51:47 +0200 Subject: [PATCH 43/60] fix start_level with copy of mesh_config --- include/samurai/mesh.hpp | 6 +- include/samurai/mesh_config.hpp | 130 ++++++++++++++++++++++++++++++++ include/samurai/mr/mesh.hpp | 12 +-- 3 files changed, 139 insertions(+), 9 deletions(-) diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index cd0272390..0cb2f46ff 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -166,7 +166,7 @@ namespace samurai Mesh_base(const mesh_config& config, const ca_type& ca); Mesh_base(mesh_config& config, const samurai::Box& b); - Mesh_base(const mesh_config& config, const samurai::DomainBuilder& domain_builder); + Mesh_base(mesh_config& config, const samurai::DomainBuilder& domain_builder); // cppcheck-suppress uninitMemberVar Mesh_base(const samurai::Box&, std::size_t, std::size_t, std::size_t, double, double) @@ -315,7 +315,7 @@ namespace samurai // } template - Mesh_base::Mesh_base(const mesh_config& config, const samurai::DomainBuilder& domain_builder) + Mesh_base::Mesh_base(mesh_config& config, const samurai::DomainBuilder& domain_builder) : m_config(config) { m_config.parse_args(); @@ -456,7 +456,7 @@ namespace samurai } template - inline Mesh_base::Mesh_base(mesh_config const& config, const ca_type& ca) + inline Mesh_base::Mesh_base(const mesh_config& config, const ca_type& ca) : m_config{config} { m_config.parse_args(); diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index 7da91bca5..3043dabe3 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -72,6 +72,19 @@ namespace samurai return *this; } + /** + * @brief copy config and set max stencil radius in chained const config + * + * @param stencil_radius + * @return auto returns a new mesh_config + */ + auto max_stencil_radius(int stencil_radius) const + { + auto copy = *this; + copy.max_stencil_radius(stencil_radius); + return copy; + } + /** * @brief get a reference on max stencil radius */ @@ -104,6 +117,19 @@ namespace samurai return *this; } + /** + * @brief copy config and set stencil radius from a size in chained const config + * + * @param stencil_size + * @return auto returns a new mesh_config + */ + auto max_stencil_size(int stencil_size) const + { + auto copy = *this; + copy.max_stencil_size(stencil_size); + return copy; + } + /** * @brief get value of max stencil size */ @@ -126,6 +152,19 @@ namespace samurai return *this; } + /** + * @brief copy config and set graduation width in chained const config + * + * @param grad_width + * @return auto returns a new mesh_config + */ + auto graduation_width(std::size_t grad_width) const + { + auto copy = *this; + copy.graduation_width(grad_width); + return copy; + } + /** * @brief get a reference on graduation width */ @@ -166,6 +205,19 @@ namespace samurai return *this; } + /** + * @brief copy config and set min level in chained const config + * + * @param level + * @return auto returns a new mesh_config + */ + auto min_level(std::size_t level) const + { + auto copy = *this; + copy.min_level(level); + return copy; + } + /** * @brief get a reference on min level */ @@ -196,6 +248,19 @@ namespace samurai return *this; } + /** + * @brief copy config and set max level in chained const config + * + * @param level + * @return auto returns a new mesh_config + */ + auto max_level(std::size_t level) const + { + auto copy = *this; + copy.max_level(level); + return copy; + } + /** * @brief get a reference on max level */ @@ -226,6 +291,19 @@ namespace samurai return *this; } + /** + * @brief copy config and set start level in chained const config + * + * @param level + * @return auto returns a new mesh_config + */ + auto start_level(std::size_t level) const + { + auto copy = *this; + copy.start_level(level); + return copy; + } + /** * @brief get a reference on start level */ @@ -256,6 +334,19 @@ namespace samurai return *this; } + /** + * @brief copy config and set approximation box tolerance in chained const config + * + * @param tol + * @return auto returns a new mesh_config + */ + auto approx_box_tol(double tol) const + { + auto copy = *this; + copy.approx_box_tol(tol); + return copy; + } + /** * @brief get a reference on approximation box tolerance */ @@ -286,6 +377,19 @@ namespace samurai return *this; } + /** + * @brief copy config and set scaling factor in chained const config + * + * @param factor + * @return auto returns a new mesh_config + */ + auto scaling_factor(double factor) const + { + auto copy = *this; + copy.scaling_factor(factor); + return copy; + } + /** * @brief get a reference on scaling factor */ @@ -316,6 +420,19 @@ namespace samurai return *this; } + /** + * @brief copy config and set periodicity in chained const config + * + * @param factor + * @return auto returns a new mesh_config + */ + auto periodic(std::array const& periodicity) const + { + auto copy = *this; + copy.periodic(periodicity); + return copy; + } + /** * @brief set periodicity in chained config with a value to fill in each direction * @@ -328,6 +445,19 @@ namespace samurai return *this; } + /** + * @brief copy config and set periodicity in chained const config + * + * @param factor + * @return auto returns a new mesh_config + */ + auto periodic(bool periodicity) const + { + auto copy = *this; + copy.periodic(periodicity); + return copy; + } + /** * @brief get a reference on periodicity array */ diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index a224f9c89..38314219f 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -79,8 +79,8 @@ namespace samurai MRMesh() = default; MRMesh(const ca_type& ca, const self_type& ref_mesh); MRMesh(const cl_type& cl, const self_type& ref_mesh); - MRMesh(mesh_config& config, const cl_type& cl); - MRMesh(mesh_config& config, const ca_type& ca); + MRMesh(const mesh_config& config, const cl_type& cl); + MRMesh(const mesh_config& config, const ca_type& ca); MRMesh(mesh_config& config, const samurai::Box& b); MRMesh(mesh_config& config, const samurai::DomainBuilder& domain_builder); @@ -121,13 +121,13 @@ namespace samurai } template - inline MRMesh::MRMesh(mesh_config& config, const cl_type& cl) + inline MRMesh::MRMesh(const mesh_config& config, const cl_type& cl) : base_type(config.start_level(config.max_level()), cl) { } template - inline MRMesh::MRMesh(mesh_config& config, const ca_type& ca) + inline MRMesh::MRMesh(const mesh_config& config, const ca_type& ca) : base_type(config.start_level(config.max_level()), ca) { } @@ -522,13 +522,13 @@ namespace samurai } template > - auto make_MRMesh(mesh_config_t& cfg, const typename MRMesh::cl_type& cl) + auto make_MRMesh(const mesh_config_t& cfg, const typename MRMesh::cl_type& cl) { return MRMesh(cfg, cl); } template > - auto make_MRMesh(mesh_config_t& cfg, const typename MRMesh::ca_type& ca) + auto make_MRMesh(const mesh_config_t& cfg, const typename MRMesh::ca_type& ca) { return MRMesh(cfg, ca); } From cdd3b94a91def3c447068ac8b25e30990df491a6 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 13 Oct 2025 21:59:34 +0200 Subject: [PATCH 44/60] fix cppcheck --- include/samurai/mesh_config.hpp | 60 ++++++++++++++++----------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index 3043dabe3..e1918dae7 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -80,9 +80,9 @@ namespace samurai */ auto max_stencil_radius(int stencil_radius) const { - auto copy = *this; - copy.max_stencil_radius(stencil_radius); - return copy; + auto copy_ = *this; + copy_.max_stencil_radius(stencil_radius); + return copy_; } /** @@ -125,9 +125,9 @@ namespace samurai */ auto max_stencil_size(int stencil_size) const { - auto copy = *this; - copy.max_stencil_size(stencil_size); - return copy; + auto copy_ = *this; + copy_.max_stencil_size(stencil_size); + return copy_; } /** @@ -160,9 +160,9 @@ namespace samurai */ auto graduation_width(std::size_t grad_width) const { - auto copy = *this; - copy.graduation_width(grad_width); - return copy; + auto copy_ = *this; + copy_.graduation_width(grad_width); + return copy_; } /** @@ -213,9 +213,9 @@ namespace samurai */ auto min_level(std::size_t level) const { - auto copy = *this; - copy.min_level(level); - return copy; + auto copy_ = *this; + copy_.min_level(level); + return copy_; } /** @@ -256,9 +256,9 @@ namespace samurai */ auto max_level(std::size_t level) const { - auto copy = *this; - copy.max_level(level); - return copy; + auto copy_ = *this; + copy_.max_level(level); + return copy_; } /** @@ -299,9 +299,9 @@ namespace samurai */ auto start_level(std::size_t level) const { - auto copy = *this; - copy.start_level(level); - return copy; + auto copy_ = *this; + copy_.start_level(level); + return copy_; } /** @@ -342,9 +342,9 @@ namespace samurai */ auto approx_box_tol(double tol) const { - auto copy = *this; - copy.approx_box_tol(tol); - return copy; + auto copy_ = *this; + copy_.approx_box_tol(tol); + return copy_; } /** @@ -385,9 +385,9 @@ namespace samurai */ auto scaling_factor(double factor) const { - auto copy = *this; - copy.scaling_factor(factor); - return copy; + auto copy_ = *this; + copy_.scaling_factor(factor); + return copy_; } /** @@ -428,9 +428,9 @@ namespace samurai */ auto periodic(std::array const& periodicity) const { - auto copy = *this; - copy.periodic(periodicity); - return copy; + auto copy_ = *this; + copy_.periodic(periodicity); + return copy_; } /** @@ -453,9 +453,9 @@ namespace samurai */ auto periodic(bool periodicity) const { - auto copy = *this; - copy.periodic(periodicity); - return copy; + auto copy_ = *this; + copy_.periodic(periodicity); + return copy_; } /** From eafab17fecce80700fbed0f015b99fe91babd6f5 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 14 Oct 2025 13:56:51 +0200 Subject: [PATCH 45/60] remove const hack and fix start_level --- include/samurai/mesh.hpp | 2 +- include/samurai/mesh_config.hpp | 136 ++------------------------------ include/samurai/mr/mesh.hpp | 32 ++++++-- 3 files changed, 31 insertions(+), 139 deletions(-) diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 0cb2f46ff..650ab3ff1 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -260,7 +260,7 @@ namespace samurai template inline Mesh_base::Mesh_base(mesh_config& config, const samurai::Box& b) - : m_domain{config.start_level(), b, (config.parse_args(), config.approx_box_tol()), config.scaling_factor()} + : m_domain{(config.parse_args(), config.start_level()), b, config.approx_box_tol(), config.scaling_factor()} , m_periodic{config.periodic()} , m_config(config) { diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index e1918dae7..fe9e185c4 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -72,19 +72,6 @@ namespace samurai return *this; } - /** - * @brief copy config and set max stencil radius in chained const config - * - * @param stencil_radius - * @return auto returns a new mesh_config - */ - auto max_stencil_radius(int stencil_radius) const - { - auto copy_ = *this; - copy_.max_stencil_radius(stencil_radius); - return copy_; - } - /** * @brief get a reference on max stencil radius */ @@ -117,19 +104,6 @@ namespace samurai return *this; } - /** - * @brief copy config and set stencil radius from a size in chained const config - * - * @param stencil_size - * @return auto returns a new mesh_config - */ - auto max_stencil_size(int stencil_size) const - { - auto copy_ = *this; - copy_.max_stencil_size(stencil_size); - return copy_; - } - /** * @brief get value of max stencil size */ @@ -152,19 +126,6 @@ namespace samurai return *this; } - /** - * @brief copy config and set graduation width in chained const config - * - * @param grad_width - * @return auto returns a new mesh_config - */ - auto graduation_width(std::size_t grad_width) const - { - auto copy_ = *this; - copy_.graduation_width(grad_width); - return copy_; - } - /** * @brief get a reference on graduation width */ @@ -205,19 +166,6 @@ namespace samurai return *this; } - /** - * @brief copy config and set min level in chained const config - * - * @param level - * @return auto returns a new mesh_config - */ - auto min_level(std::size_t level) const - { - auto copy_ = *this; - copy_.min_level(level); - return copy_; - } - /** * @brief get a reference on min level */ @@ -248,19 +196,6 @@ namespace samurai return *this; } - /** - * @brief copy config and set max level in chained const config - * - * @param level - * @return auto returns a new mesh_config - */ - auto max_level(std::size_t level) const - { - auto copy_ = *this; - copy_.max_level(level); - return copy_; - } - /** * @brief get a reference on max level */ @@ -291,19 +226,6 @@ namespace samurai return *this; } - /** - * @brief copy config and set start level in chained const config - * - * @param level - * @return auto returns a new mesh_config - */ - auto start_level(std::size_t level) const - { - auto copy_ = *this; - copy_.start_level(level); - return copy_; - } - /** * @brief get a reference on start level */ @@ -334,19 +256,6 @@ namespace samurai return *this; } - /** - * @brief copy config and set approximation box tolerance in chained const config - * - * @param tol - * @return auto returns a new mesh_config - */ - auto approx_box_tol(double tol) const - { - auto copy_ = *this; - copy_.approx_box_tol(tol); - return copy_; - } - /** * @brief get a reference on approximation box tolerance */ @@ -377,19 +286,6 @@ namespace samurai return *this; } - /** - * @brief copy config and set scaling factor in chained const config - * - * @param factor - * @return auto returns a new mesh_config - */ - auto scaling_factor(double factor) const - { - auto copy_ = *this; - copy_.scaling_factor(factor); - return copy_; - } - /** * @brief get a reference on scaling factor */ @@ -420,19 +316,6 @@ namespace samurai return *this; } - /** - * @brief copy config and set periodicity in chained const config - * - * @param factor - * @return auto returns a new mesh_config - */ - auto periodic(std::array const& periodicity) const - { - auto copy_ = *this; - copy_.periodic(periodicity); - return copy_; - } - /** * @brief set periodicity in chained config with a value to fill in each direction * @@ -445,19 +328,6 @@ namespace samurai return *this; } - /** - * @brief copy config and set periodicity in chained const config - * - * @param factor - * @return auto returns a new mesh_config - */ - auto periodic(bool periodicity) const - { - auto copy_ = *this; - copy_.periodic(periodicity); - return copy_; - } - /** * @brief get a reference on periodicity array */ @@ -508,6 +378,12 @@ namespace samurai return *this; } + auto clone() const + { + auto copy_ = *this; + return copy_; + } + /** * @brief parse arguments and set value to default samurai config value if needed */ diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 38314219f..33d60caff 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -122,25 +122,25 @@ namespace samurai template inline MRMesh::MRMesh(const mesh_config& config, const cl_type& cl) - : base_type(config.start_level(config.max_level()), cl) + : base_type(config, cl) { } template inline MRMesh::MRMesh(const mesh_config& config, const ca_type& ca) - : base_type(config.start_level(config.max_level()), ca) + : base_type(config, ca) { } template inline MRMesh::MRMesh(mesh_config& config, const samurai::Box& b) - : base_type(config.start_level(config.max_level()), b) + : base_type(config, b) { } template inline MRMesh::MRMesh(mesh_config& config, const samurai::DomainBuilder& domain_builder) - : base_type(config.start_level(config.max_level()), domain_builder) + : base_type(config, domain_builder) { } @@ -524,27 +524,43 @@ namespace samurai template > auto make_MRMesh(const mesh_config_t& cfg, const typename MRMesh::cl_type& cl) { + auto mesh_cfg = cfg.clone(); + mesh_cfg.parse_args(); + mesh_cfg.start_level() = mesh_cfg.max_level(); + return MRMesh(cfg, cl); } template > auto make_MRMesh(const mesh_config_t& cfg, const typename MRMesh::ca_type& ca) { + auto mesh_cfg = cfg.clone(); + mesh_cfg.parse_args(); + mesh_cfg.start_level() = mesh_cfg.max_level(); + return MRMesh(cfg, ca); } template - auto make_MRMesh(mesh_config_t& cfg, const samurai::Box& b) + auto make_MRMesh(const mesh_config_t& cfg, const samurai::Box& b) { using complete_cfg_t = complete_mesh_config; - return MRMesh(cfg, b); + + auto mesh_cfg = cfg.clone(); + mesh_cfg.parse_args(); + mesh_cfg.start_level() = mesh_cfg.max_level(); + return MRMesh(mesh_cfg, b); } template - auto make_MRMesh(mesh_config_t& cfg, const samurai::DomainBuilder& domain_builder) + auto make_MRMesh(const mesh_config_t& cfg, const samurai::DomainBuilder& domain_builder) { using complete_cfg_t = complete_mesh_config; - return MRMesh(cfg, domain_builder); + + auto mesh_cfg = cfg.clone(); + mesh_cfg.parse_args(); + mesh_cfg.start_level() = mesh_cfg.max_level(); + return MRMesh(mesh_cfg, domain_builder); } } // namespace samurai From 3618e56ecb95795b780776b1aebb5da4b64b6e7c Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Wed, 15 Oct 2025 13:27:52 +0200 Subject: [PATCH 46/60] clean code --- demos/FiniteVolume/advection_1d.cpp | 3 +-- demos/FiniteVolume/burgers_mra.cpp | 5 ++--- demos/FiniteVolume/burgers_os.cpp | 2 -- demos/pablo/bubble_2d.cpp | 10 +++++----- include/samurai/algorithm/graduation.hpp | 1 + include/samurai/algorithm/update.hpp | 12 ++---------- include/samurai/amr/mesh.hpp | 21 +-------------------- include/samurai/bc/apply_field_bc.hpp | 2 -- include/samurai/domain_builder.hpp | 20 +------------------- include/samurai/mr/mesh.hpp | 24 ------------------------ 10 files changed, 13 insertions(+), 87 deletions(-) diff --git a/demos/FiniteVolume/advection_1d.cpp b/demos/FiniteVolume/advection_1d.cpp index 669e5f833..0aa5d7e9e 100644 --- a/demos/FiniteVolume/advection_1d.cpp +++ b/demos/FiniteVolume/advection_1d.cpp @@ -96,8 +96,7 @@ int main(int argc, char* argv[]) auto config = samurai::mesh_config().min_level(6).max_level(12).periodic(is_periodic).max_stencil_size(2).disable_minimal_ghost_width(); auto mesh = samurai::make_MRMesh(config, box); - // samurai::MRMesh mesh; - auto u = samurai::make_scalar_field("u", mesh); + auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { diff --git a/demos/FiniteVolume/burgers_mra.cpp b/demos/FiniteVolume/burgers_mra.cpp index 264db23d0..5e92301c4 100644 --- a/demos/FiniteVolume/burgers_mra.cpp +++ b/demos/FiniteVolume/burgers_mra.cpp @@ -263,9 +263,8 @@ int main(int argc, char* argv[]) //--------------------// Box box({left_box}, {right_box}); - auto config = samurai::mesh_config().min_level(1).max_level(7).max_stencil_radius(2).graduation_width(2); - auto mesh = samurai::make_MRMesh(config, box); - // samurai::MRMesh mesh{box, min_level, max_level}; + auto config = samurai::mesh_config().min_level(1).max_level(7).max_stencil_radius(2).graduation_width(2); + auto mesh = samurai::make_MRMesh(config, box); auto max_level_config = samurai::mesh_config().min_level(mesh.max_level()).max_level(mesh.max_level()).max_stencil_radius(2); auto max_level_mesh = samurai::make_MRMesh(max_level_config, box); diff --git a/demos/FiniteVolume/burgers_os.cpp b/demos/FiniteVolume/burgers_os.cpp index e31b6ec3a..3e51be9cf 100644 --- a/demos/FiniteVolume/burgers_os.cpp +++ b/demos/FiniteVolume/burgers_os.cpp @@ -154,8 +154,6 @@ int main(int argc, char* argv[]) .scaling_factor(2) .max_stencil_radius(1) .graduation_width(2); - config.parse_args(); - std::cout << " max_level = " << config.max_level() << " min_level = " << config.min_level() << std::endl; auto mesh = samurai::make_MRMesh(config, box); auto u = samurai::make_scalar_field("u", mesh); diff --git a/demos/pablo/bubble_2d.cpp b/demos/pablo/bubble_2d.cpp index ce6b4be46..10bfcea1b 100644 --- a/demos/pablo/bubble_2d.cpp +++ b/demos/pablo/bubble_2d.cpp @@ -244,9 +244,9 @@ int main(int argc, char* argv[]) double dt = 0.5; // Adaptation parameters - std::size_t start_level = 4; - std::size_t min_level = 1; - std::size_t max_level = 9; + std::size_t init_level = 4; + std::size_t min_level = 1; + std::size_t max_level = 9; // Output parameters fs::path path = fs::current_path(); @@ -258,7 +258,7 @@ int main(int argc, char* argv[]) app.add_option("--nb-bubbles", nb_bubbles, "Number of bubbles")->capture_default_str()->group("Simulation parameters"); app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters"); app.add_option("--dt", dt, "Time step")->capture_default_str()->group("Simulation parameters"); - app.add_option("--initial-level", start_level, "Start level of AMR")->capture_default_str()->group("Adaptation parameters"); + app.add_option("--initial-level", init_level, "Initial level of AMR")->capture_default_str()->group("Adaptation parameters"); app.add_option("--minimum-level", min_level, "Minimum level of AMR")->capture_default_str()->group("Adaptation parameters"); app.add_option("--maximum-level", max_level, "Maximum level of AMR")->capture_default_str()->group("Adaptation parameters"); app.add_option("--path", path, "Output path")->capture_default_str()->group("Output"); @@ -289,7 +289,7 @@ int main(int argc, char* argv[]) samurai::CellArray mesh; const samurai::Box box(min_corner, max_corner); - mesh[start_level] = {start_level, box}; + mesh[init_level] = {init_level, box}; const double dt_save = Tf / static_cast(nfiles); double t = 0.; diff --git a/include/samurai/algorithm/graduation.hpp b/include/samurai/algorithm/graduation.hpp index 1ac7d2fd6..0f2b60cc3 100644 --- a/include/samurai/algorithm/graduation.hpp +++ b/include/samurai/algorithm/graduation.hpp @@ -158,6 +158,7 @@ namespace samurai auto subset_2 = intersection(mesh[mesh_id_t::cells][level], mesh[mesh_id_t::cells][level]); auto ghost_width = mesh.cfg().graduation_width(); + assert(ghost_width < 10 && "Graduation not implemented for ghost_width higher than 10"); // maximum ghost width is set to 9 static_for<1, 10>::apply( [&](auto static_ghost_width_) diff --git a/include/samurai/algorithm/update.hpp b/include/samurai/algorithm/update.hpp index ce59413ec..f7cf35ace 100644 --- a/include/samurai/algorithm/update.hpp +++ b/include/samurai/algorithm/update.hpp @@ -103,17 +103,9 @@ namespace samurai { using mesh_id_t = typename Field::mesh_t::mesh_id_t; - // assert(layer > 0 && layer <= Field::mesh_t::config::max_stencil_width); - auto& mesh = field.mesh(); -#ifndef NDEBUG - if (!(layer > 0 && layer <= mesh.max_stencil_radius())) - { - std::cerr << " " << std::endl; - exit(EXIT_FAILURE); - } -#endif + assert(layer > 0 && layer <= mesh.max_stencil_radius()); auto domain = self(mesh.domain()).on(proj_level); @@ -401,7 +393,7 @@ namespace samurai template void update_outer_ghosts(std::size_t level, Field& field) { - static_assert(std::remove_cvref_t::prediction_stencil_radius <= 1); + static_assert(Field::mesh_t::config::prediction_stencil_radius <= 1); constexpr std::size_t dim = Field::dim; diff --git a/include/samurai/amr/mesh.hpp b/include/samurai/amr/mesh.hpp index f8cf4c8f7..d52c7cb7c 100644 --- a/include/samurai/amr/mesh.hpp +++ b/include/samurai/amr/mesh.hpp @@ -25,25 +25,6 @@ namespace samurai::amr // reference = cells_and_ghosts }; - // template - // struct Config - // { - // static constexpr std::size_t dim = dim_; - // static constexpr std::size_t max_refinement_level = max_refinement_level_; - // static constexpr int max_stencil_width = max_stencil_width_; - // static constexpr int prediction_stencil_radius = prediction_stencil_radius_; - // static constexpr int ghost_width = std::max(static_cast(max_stencil_width), - // static_cast(prediction_stencil_radius)); static constexpr int graduation_width = graduation_width_; - - // using interval_t = TInterval; - // using mesh_id_t = AMR_Id; - // }; - ///////////////////////// // AMR mesh definition // ///////////////////////// @@ -118,7 +99,7 @@ namespace samurai::amr cl_type cl; auto ghost_width = cfg().ghost_width(); for_each_interval(this->cells()[mesh_id_t::cells], - [&, ghost_width](std::size_t level, const auto& interval, const auto& index_yz) + [&](std::size_t level, const auto& interval, const auto& index_yz) { lcl_type& lcl = cl[level]; static_nested_loop( diff --git a/include/samurai/bc/apply_field_bc.hpp b/include/samurai/bc/apply_field_bc.hpp index 4e634b295..c75eb7f12 100644 --- a/include/samurai/bc/apply_field_bc.hpp +++ b/include/samurai/bc/apply_field_bc.hpp @@ -381,7 +381,6 @@ namespace samurai for (int ghost_layer = ghost_layers_filled_by_bc + 1; ghost_layer <= ghost_width; ++ghost_layer) { int stencil_s = 2 * ghost_layer; - // static_for<2, std::min(max_stencil_size_implemented_PE, 2 * ghost_width) + 1>::apply( static_for<2, max_stencil_size_implemented_PE + 1>::apply( [&](auto stencil_size_) { @@ -409,7 +408,6 @@ namespace samurai for (int ghost_layer = ghost_layers_filled_by_projection_bc + 1; ghost_layer <= ghost_width; ++ghost_layer) { int stencil_s = 2 * ghost_layer; - // static_for<2, std::min(max_stencil_size_implemented_PE, 2 * ghost_width) + 1>::apply( static_for<2, max_stencil_size_implemented_PE + 1>::apply( [&](auto stencil_size_) { diff --git a/include/samurai/domain_builder.hpp b/include/samurai/domain_builder.hpp index 4d6d3d29d..60452f42b 100644 --- a/include/samurai/domain_builder.hpp +++ b/include/samurai/domain_builder.hpp @@ -85,12 +85,6 @@ namespace samurai auto gcd_loop = [](double largest_subdiv, const auto& boxes) { - // for (const auto& box : boxes) - // { - // largest_subdiv = gcd_float(largest_subdiv, box.min_length()); - // } - // return largest_subdiv; - return std::accumulate(boxes.begin(), boxes.end(), largest_subdiv, @@ -100,17 +94,9 @@ namespace samurai }); }; - // The largest subdivision must be smaller than the smallest legnth of all boxes + // The largest subdivision must be smaller than the smallest length of all boxes largest_subdivision = gcd_loop(largest_subdivision, m_added_boxes); largest_subdivision = gcd_loop(largest_subdivision, m_removed_boxes); - // for (const auto& box : m_added_boxes) - // { - // largest_subdivision = gcd_float(largest_subdivision, box.min_length()); - // } - // for (const auto& box : m_removed_boxes) - // { - // largest_subdivision = gcd_float(largest_subdivision, box.min_length()); - // } // The largest subdivision must be smaller than the smallest length of all differences for (const auto& box : m_added_boxes) @@ -121,10 +107,6 @@ namespace samurai { std::vector diff = box.difference(rbox); largest_subdivision = gcd_loop(largest_subdivision, diff); - // for (const auto& dbox : diff) - // { - // largest_subdivision = gcd_float(largest_subdivision, dbox.min_length()); - // } } } } diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 33d60caff..5828cfdb4 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -30,30 +30,6 @@ namespace samurai reference = all_cells }; - // template - // struct MRConfig - // { - // // static constexpr std::size_t dim = dim_; - // // static constexpr std::size_t max_refinement_level = max_refinement_level_; - // // // static constexpr int max_stencil_width = max_stencil_width_; - // // // static constexpr std::size_t graduation_width = graduation_width_; - // // static constexpr int prediction_stencil_radius = prediction_stencil_radius_; - - // // // static constexpr int ghost_width = std::max(std::max(2 * - // // // static_cast(graduation_width) - 1, - // // // static_cast(max_stencil_width)), - // // // static_cast(prediction_stencil_radius)); - // // // static constexpr int ghost_width = std::max(static_cast(max_stencil_width_), - // static_cast(prediction_stencil_radius)); - // // using interval_t = TInterval; - // // using mesh_id_t = MRMeshId; - // }; - template class MRMesh : public samurai::Mesh_base, Config> { From 8f5e44304f64000cdbaff5bc9e0d2cfbf39596cf Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Wed, 15 Oct 2025 15:48:03 +0200 Subject: [PATCH 47/60] remove useless file --- include/mesh.hpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 include/mesh.hpp diff --git a/include/mesh.hpp b/include/mesh.hpp deleted file mode 100644 index e69de29bb..000000000 From 97e092f0711154d34c78873f8206384592d9306d Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Wed, 15 Oct 2025 15:59:19 +0200 Subject: [PATCH 48/60] remove m_periodic --- include/samurai/mesh.hpp | 129 ++++----------------------------------- 1 file changed, 11 insertions(+), 118 deletions(-) diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 650ab3ff1..635527f46 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -171,7 +171,8 @@ namespace samurai // cppcheck-suppress uninitMemberVar Mesh_base(const samurai::Box&, std::size_t, std::size_t, std::size_t, double, double) { - std::cerr << "Delete min_level and max_level from CLI11 options and use mesh_config object in the mesh constructor" << std::endl; + std::cerr << "Delete min_level and max_level from CLI11 options and use mesh_config object and the make_Mesh function" + << std::endl; exit(EXIT_FAILURE); } @@ -185,7 +186,8 @@ namespace samurai // cppcheck-suppress uninitMemberVar Mesh_base(const samurai::Box&, std::size_t, std::size_t, std::size_t, const std::array&, double, double) { - std::cerr << "Delete min_level and max_level from CLI11 options and use mesh_config object in the mesh constructor" << std::endl; + std::cerr << "Delete min_level and max_level from CLI11 options and use mesh_config object and the make_Mesh function" + << std::endl; exit(EXIT_FAILURE); } @@ -213,7 +215,6 @@ namespace samurai lca_type m_domain; lca_type m_subdomain; - std::array m_periodic; mesh_t m_cells; ca_type m_union; std::vector m_corners; @@ -261,7 +262,6 @@ namespace samurai template inline Mesh_base::Mesh_base(mesh_config& config, const samurai::Box& b) : m_domain{(config.parse_args(), config.start_level()), b, config.approx_box_tol(), config.scaling_factor()} - , m_periodic{config.periodic()} , m_config(config) { #ifdef SAMURAI_WITH_MPI @@ -281,39 +281,6 @@ namespace samurai set_scaling_factor(scaling_factor()); } - // template - // [[deprecated("Delete min_level and max_level from CLI11 options and use mesh_config object in the constructor")]] inline - // Mesh_base::Mesh_base( - // const samurai::Box& b, - // std::size_t start_level, - // std::size_t min_level, - // std::size_t max_level, - // double approx_box_tol, - // double scaling_factor_) - // : m_domain{start_level, b, approx_box_tol, scaling_factor_} - // , m_min_level{min_level} - // , m_max_level{max_level} - // { - // assert(min_level <= max_level); - // m_periodic.fill(false); - - // #ifdef SAMURAI_WITH_MPI - // partition_mesh(start_level, b); - // // load_balancing(); - // #else - // this->m_cells[mesh_id_t::cells][start_level] = {start_level, b, approx_box_tol, scaling_factor_}; - // #endif - // construct_subdomain(); - // construct_union(); - // update_sub_mesh(); - // construct_corners(); - // renumbering(); - // update_mesh_neighbour(); - - // set_origin_point(origin_point()); - // set_scaling_factor(scaling_factor()); - // } - template Mesh_base::Mesh_base(mesh_config& config, const samurai::DomainBuilder& domain_builder) : m_config(config) @@ -330,7 +297,6 @@ namespace samurai std::cerr << "Periodicity is not implemented with DomainBuilder." << std::endl; exit(EXIT_FAILURE); } - m_periodic.fill(false); #ifdef SAMURAI_WITH_MPI std::cerr << "MPI is not implemented with DomainBuilder." << std::endl; @@ -363,83 +329,12 @@ namespace samurai set_scaling_factor(m_config.scaling_factor()); } - // template - // Mesh_base::Mesh_base(const samurai::DomainBuilder& domain_builder, - // [[maybe_unused]] std::size_t start_level, - // std::size_t min_level, - // std::size_t max_level, - // [[maybe_unused]] double approx_box_tol, - // double scaling_factor_) - // : m_min_level{min_level} - // , m_max_level{max_level} - // { - // assert(min_level <= max_level); - // m_periodic.fill(false); - - // #ifdef SAMURAI_WITH_MPI - // std::cerr << "MPI is not implemented with DomainBuilder." << std::endl; - // std::exit(1); - // // partition_mesh(start_level, b); - // // load_balancing(); - // #else - // compute_scaling_factor(domain_builder, scaling_factor_); - - // // Build the domain by adding and removing boxes - // cl_type domain_cl = construct_initial_mesh(domain_builder, start_level, approx_box_tol, scaling_factor_); - - // this->m_cells[mesh_id_t::cells] = {domain_cl, false}; - // #endif - // construct_subdomain(); - // m_domain = m_subdomain; - // construct_union(); - // update_sub_mesh(); - // construct_corners(); - // renumbering(); - // update_mesh_neighbour(); - - // set_origin_point(domain_builder.origin_point()); - // set_scaling_factor(scaling_factor_); - // } - - // template - // inline Mesh_base::Mesh_base(const samurai::Box& b, - // std::size_t start_level, - // std::size_t min_level, - // std::size_t max_level, - // const std::array& periodic, - // double approx_box_tol, - // double scaling_factor_) - // : m_domain{start_level, b, approx_box_tol, scaling_factor_} - // , m_min_level{min_level} - // , m_max_level{max_level} - // , m_periodic{periodic} - // { - // assert(min_level <= max_level); - - // #ifdef SAMURAI_WITH_MPI - // partition_mesh(start_level, b); - // // load_balancing(); - // #else - // this->m_cells[mesh_id_t::cells][start_level] = {start_level, b, approx_box_tol, scaling_factor_}; - // #endif - - // construct_subdomain(); - // construct_union(); - // update_sub_mesh(); - // construct_corners(); - // renumbering(); - // update_mesh_neighbour(); - - // set_origin_point(origin_point()); - // set_scaling_factor(scaling_factor()); - // } - template inline Mesh_base::Mesh_base(const mesh_config& config, const cl_type& cl) : m_config(config) { m_config.parse_args(); - m_periodic.fill(false); + m_config.periodic().fill(false); this->m_cells[mesh_id_t::cells] = {cl}; @@ -460,7 +355,7 @@ namespace samurai : m_config{config} { m_config.parse_args(); - m_periodic.fill(false); + m_config.periodic().fill(false); this->m_cells[mesh_id_t::cells] = ca; @@ -491,7 +386,6 @@ namespace samurai template inline Mesh_base::Mesh_base(const ca_type& ca, const self_type& ref_mesh) : m_domain(ref_mesh.m_domain) - , m_periodic(ref_mesh.m_periodic) , m_mpi_neighbourhood(ref_mesh.m_mpi_neighbourhood) , m_config(ref_mesh.m_config) { @@ -511,7 +405,6 @@ namespace samurai template inline Mesh_base::Mesh_base(const cl_type& cl, const self_type& ref_mesh) : m_domain(ref_mesh.m_domain) - , m_periodic(ref_mesh.m_periodic) , m_mpi_neighbourhood(ref_mesh.m_mpi_neighbourhood) , m_config(ref_mesh.m_config) { @@ -840,8 +733,8 @@ namespace samurai template inline bool Mesh_base::is_periodic() const { - return std::any_of(m_periodic.cbegin(), - m_periodic.cend(), + return std::any_of(m_config.periodic().cbegin(), + m_config.periodic().cend(), [](bool v) { return v; @@ -851,13 +744,13 @@ namespace samurai template inline bool Mesh_base::is_periodic(std::size_t d) const { - return m_periodic[d]; + return m_config.periodic(d); } template inline auto Mesh_base::periodicity() const -> const std::array& { - return m_periodic; + return m_config.periodic(); } template @@ -1154,7 +1047,7 @@ namespace samurai } for (std::size_t d = 0; d < dim; ++d) { - if (m_periodic[d]) + if (m_config.periodic(d)) { auto shift = get_periodic_shift(m_domain, m_subdomain.level(), d); auto periodic_set_left = intersection(nestedExpand(m_subdomain, 1), translate(neighbours[i], -shift)); From 77993a4310271721e471ae20e03414714108c11f Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Wed, 15 Oct 2025 17:36:30 +0200 Subject: [PATCH 49/60] add make_empty_Mesh and remove unconst mesh_config --- demos/FiniteVolume/AMR_Burgers_Hat.cpp | 2 +- demos/FiniteVolume/advection_2d.cpp | 2 +- demos/FiniteVolume/heat.cpp | 2 +- demos/FiniteVolume/heat_heterogeneous.cpp | 2 +- demos/FiniteVolume/heat_nonlinear.cpp | 2 +- demos/FiniteVolume/level_set.cpp | 2 +- demos/FiniteVolume/linear_convection.cpp | 2 +- demos/FiniteVolume/scalar_burgers_2d.cpp | 2 +- include/samurai/amr/mesh.hpp | 27 +++++++++++++++++------ include/samurai/mesh.hpp | 10 ++++----- include/samurai/mr/mesh.hpp | 21 ++++++++++-------- tests/test_domain_with_hole.cpp | 2 +- tests/test_for_each.cpp | 6 ++--- 13 files changed, 49 insertions(+), 33 deletions(-) diff --git a/demos/FiniteVolume/AMR_Burgers_Hat.cpp b/demos/FiniteVolume/AMR_Burgers_Hat.cpp index 16d2ea51a..2d2310ae0 100644 --- a/demos/FiniteVolume/AMR_Burgers_Hat.cpp +++ b/demos/FiniteVolume/AMR_Burgers_Hat.cpp @@ -230,7 +230,7 @@ int main(int argc, char* argv[]) const samurai::Box box({left_box}, {right_box}); auto config = samurai::mesh_config().min_level(2).max_level(7).max_stencil_size(2).start_level(7).disable_minimal_ghost_width(); - auto mesh = samurai::amr::make_Mesh(config); + auto mesh = samurai::amr::make_empty_Mesh(config); auto phi = samurai::make_scalar_field("phi", mesh); if (restart_file.empty()) diff --git a/demos/FiniteVolume/advection_2d.cpp b/demos/FiniteVolume/advection_2d.cpp index b8283279d..a3cbbdd91 100644 --- a/demos/FiniteVolume/advection_2d.cpp +++ b/demos/FiniteVolume/advection_2d.cpp @@ -95,7 +95,7 @@ int main(int argc, char* argv[]) const samurai::Box box(min_corner, max_corner); auto config = samurai::mesh_config().min_level(4).max_level(10).max_stencil_size(2).disable_minimal_ghost_width(); - auto mesh = samurai::make_MRMesh(config); + auto mesh = samurai::make_empty_MRMesh(config); auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) diff --git a/demos/FiniteVolume/heat.cpp b/demos/FiniteVolume/heat.cpp index d04e9bdfd..4e81822a9 100644 --- a/demos/FiniteVolume/heat.cpp +++ b/demos/FiniteVolume/heat.cpp @@ -115,7 +115,7 @@ int main(int argc, char* argv[]) box_corner2.fill(right_box); Box box(box_corner1, box_corner2); auto config = samurai::mesh_config().min_level(4).max_level(dim == 1 ? 5 : 8).max_stencil_size(2).disable_minimal_ghost_width(); - auto mesh = samurai::make_MRMesh(config); + auto mesh = samurai::make_empty_MRMesh(config); auto u = samurai::make_scalar_field("u", mesh); diff --git a/demos/FiniteVolume/heat_heterogeneous.cpp b/demos/FiniteVolume/heat_heterogeneous.cpp index 5c33d32dd..82008351c 100644 --- a/demos/FiniteVolume/heat_heterogeneous.cpp +++ b/demos/FiniteVolume/heat_heterogeneous.cpp @@ -87,7 +87,7 @@ int main(int argc, char* argv[]) box_corner2.fill(right_box); Box box(box_corner1, box_corner2); auto config = samurai::mesh_config().min_level(3).max_level(6).max_stencil_size(2).disable_minimal_ghost_width(); - auto mesh = samurai::make_MRMesh(config); + auto mesh = samurai::make_empty_MRMesh(config); auto u = samurai::make_scalar_field("u", mesh); auto unp1 = samurai::make_scalar_field("unp1", mesh); diff --git a/demos/FiniteVolume/heat_nonlinear.cpp b/demos/FiniteVolume/heat_nonlinear.cpp index 7286ff2cb..b1c27b8b2 100644 --- a/demos/FiniteVolume/heat_nonlinear.cpp +++ b/demos/FiniteVolume/heat_nonlinear.cpp @@ -162,7 +162,7 @@ int main(int argc, char* argv[]) box_corner2.fill(right_box); Box box(box_corner1, box_corner2); auto config = samurai::mesh_config().min_level(4).max_level(4).max_stencil_size(2).disable_minimal_ghost_width(); - auto mesh = samurai::make_MRMesh(config); + auto mesh = samurai::make_empty_MRMesh(config); ; auto u = samurai::make_scalar_field("u", mesh); diff --git a/demos/FiniteVolume/level_set.cpp b/demos/FiniteVolume/level_set.cpp index 5c10105ea..eaf2ea092 100644 --- a/demos/FiniteVolume/level_set.cpp +++ b/demos/FiniteVolume/level_set.cpp @@ -286,7 +286,7 @@ int main(int argc, char* argv[]) const samurai::Box box(min_corner, max_corner); auto config = samurai::mesh_config().min_level(4).max_level(8).start_level(8).max_stencil_radius(2); - auto mesh = samurai::amr::make_Mesh(config); + auto mesh = samurai::amr::make_empty_Mesh(config); auto phi = samurai::make_scalar_field("phi", mesh); if (restart_file.empty()) diff --git a/demos/FiniteVolume/linear_convection.cpp b/demos/FiniteVolume/linear_convection.cpp index f4347f992..b99e792d5 100644 --- a/demos/FiniteVolume/linear_convection.cpp +++ b/demos/FiniteVolume/linear_convection.cpp @@ -87,7 +87,7 @@ int main(int argc, char* argv[]) box_corner2.fill(right_box); Box box(box_corner1, box_corner2); auto config = samurai::mesh_config().min_level(1).max_level(dim == 1 ? 6 : 4).periodic(true).max_stencil_size(6); - auto mesh = samurai::make_MRMesh(config); + auto mesh = samurai::make_empty_MRMesh(config); auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) diff --git a/demos/FiniteVolume/scalar_burgers_2d.cpp b/demos/FiniteVolume/scalar_burgers_2d.cpp index ec85e7d42..c9af54bb4 100644 --- a/demos/FiniteVolume/scalar_burgers_2d.cpp +++ b/demos/FiniteVolume/scalar_burgers_2d.cpp @@ -222,7 +222,7 @@ int main(int argc, char* argv[]) const samurai::Box box(min_corner, max_corner); auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).disable_minimal_ghost_width(); - auto mesh = samurai::make_MRMesh(config); + auto mesh = samurai::make_empty_MRMesh(config); auto u = samurai::make_scalar_field("u", mesh); diff --git a/include/samurai/amr/mesh.hpp b/include/samurai/amr/mesh.hpp index d52c7cb7c..d89873590 100644 --- a/include/samurai/amr/mesh.hpp +++ b/include/samurai/amr/mesh.hpp @@ -52,7 +52,7 @@ namespace samurai::amr Mesh(const cl_type& cl, const self_type& ref_mesh); Mesh(const mesh_config& config, const cl_type& cl); Mesh(const mesh_config& config, const ca_type& ca); - Mesh(mesh_config& config, const Box& b); + Mesh(const mesh_config& config, const Box& b); void update_sub_mesh_impl(); @@ -88,7 +88,7 @@ namespace samurai::amr } template - inline Mesh::Mesh(mesh_config& config, const Box& b) + inline Mesh::Mesh(const mesh_config& config, const Box& b) : base_type(config, b) { } @@ -188,7 +188,7 @@ namespace samurai::amr } template > - auto make_Mesh(const mesh_config_t&) + auto make_empty_Mesh(const mesh_config_t&) { return Mesh(); } @@ -196,20 +196,33 @@ namespace samurai::amr template > auto make_Mesh(const mesh_config_t& cfg, const typename Mesh::cl_type& cl) { - return Mesh(cfg, cl); + auto mesh_cfg = cfg; + mesh_cfg.parse_args(); + mesh_cfg.start_level() = mesh_cfg.max_level(); + + return Mesh(mesh_cfg, cl); } template > auto make_Mesh(const mesh_config_t& cfg, const typename Mesh::ca_type& ca) { - return Mesh(cfg, ca); + auto mesh_cfg = cfg; + mesh_cfg.parse_args(); + mesh_cfg.start_level() = mesh_cfg.max_level(); + + return Mesh(mesh_cfg, ca); } template - auto make_Mesh(mesh_config_t& cfg, const samurai::Box& b) + auto make_Mesh(const mesh_config_t& cfg, const samurai::Box& b) { using complete_cfg_t = complete_mesh_config; - return Mesh(cfg, b); + + auto mesh_cfg = cfg; + mesh_cfg.parse_args(); + mesh_cfg.start_level() = mesh_cfg.max_level(); + + return Mesh(mesh_cfg, b); } } // namespace samurai::amr diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 635527f46..8eb7e0de4 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -164,9 +164,9 @@ namespace samurai Mesh_base(const cl_type& cl, const self_type& ref_mesh); Mesh_base(const mesh_config& config, const cl_type& cl); Mesh_base(const mesh_config& config, const ca_type& ca); - Mesh_base(mesh_config& config, const samurai::Box& b); + Mesh_base(const mesh_config& config, const samurai::Box& b); - Mesh_base(mesh_config& config, const samurai::DomainBuilder& domain_builder); + Mesh_base(const mesh_config& config, const samurai::DomainBuilder& domain_builder); // cppcheck-suppress uninitMemberVar Mesh_base(const samurai::Box&, std::size_t, std::size_t, std::size_t, double, double) @@ -260,8 +260,8 @@ namespace samurai } template - inline Mesh_base::Mesh_base(mesh_config& config, const samurai::Box& b) - : m_domain{(config.parse_args(), config.start_level()), b, config.approx_box_tol(), config.scaling_factor()} + inline Mesh_base::Mesh_base(const mesh_config& config, const samurai::Box& b) + : m_domain{config.start_level(), b, config.approx_box_tol(), config.scaling_factor()} , m_config(config) { #ifdef SAMURAI_WITH_MPI @@ -282,7 +282,7 @@ namespace samurai } template - Mesh_base::Mesh_base(mesh_config& config, const samurai::DomainBuilder& domain_builder) + Mesh_base::Mesh_base(const mesh_config& config, const samurai::DomainBuilder& domain_builder) : m_config(config) { m_config.parse_args(); diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 5828cfdb4..7a9a6fc7f 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -57,8 +57,8 @@ namespace samurai MRMesh(const cl_type& cl, const self_type& ref_mesh); MRMesh(const mesh_config& config, const cl_type& cl); MRMesh(const mesh_config& config, const ca_type& ca); - MRMesh(mesh_config& config, const samurai::Box& b); - MRMesh(mesh_config& config, const samurai::DomainBuilder& domain_builder); + MRMesh(const mesh_config& config, const samurai::Box& b); + MRMesh(const mesh_config& config, const samurai::DomainBuilder& domain_builder); // deprecated constructors MRMesh(const samurai::Box& b, @@ -109,13 +109,13 @@ namespace samurai } template - inline MRMesh::MRMesh(mesh_config& config, const samurai::Box& b) + inline MRMesh::MRMesh(const mesh_config& config, const samurai::Box& b) : base_type(config, b) { } template - inline MRMesh::MRMesh(mesh_config& config, const samurai::DomainBuilder& domain_builder) + inline MRMesh::MRMesh(const mesh_config& config, const samurai::DomainBuilder& domain_builder) : base_type(config, domain_builder) { } @@ -491,8 +491,9 @@ namespace samurai } } + // create an empty mesh template > - auto make_MRMesh(const mesh_config_t&) + auto make_empty_MRMesh(const mesh_config_t&) { return MRMesh(); } @@ -500,7 +501,7 @@ namespace samurai template > auto make_MRMesh(const mesh_config_t& cfg, const typename MRMesh::cl_type& cl) { - auto mesh_cfg = cfg.clone(); + auto mesh_cfg = cfg; mesh_cfg.parse_args(); mesh_cfg.start_level() = mesh_cfg.max_level(); @@ -510,7 +511,7 @@ namespace samurai template > auto make_MRMesh(const mesh_config_t& cfg, const typename MRMesh::ca_type& ca) { - auto mesh_cfg = cfg.clone(); + auto mesh_cfg = cfg; mesh_cfg.parse_args(); mesh_cfg.start_level() = mesh_cfg.max_level(); @@ -522,9 +523,10 @@ namespace samurai { using complete_cfg_t = complete_mesh_config; - auto mesh_cfg = cfg.clone(); + auto mesh_cfg = cfg; mesh_cfg.parse_args(); mesh_cfg.start_level() = mesh_cfg.max_level(); + return MRMesh(mesh_cfg, b); } @@ -533,9 +535,10 @@ namespace samurai { using complete_cfg_t = complete_mesh_config; - auto mesh_cfg = cfg.clone(); + auto mesh_cfg = cfg; mesh_cfg.parse_args(); mesh_cfg.start_level() = mesh_cfg.max_level(); + return MRMesh(mesh_cfg, domain_builder); } } // namespace samurai diff --git a/tests/test_domain_with_hole.cpp b/tests/test_domain_with_hole.cpp index 0f3ab9932..20e06dc11 100644 --- a/tests/test_domain_with_hole.cpp +++ b/tests/test_domain_with_hole.cpp @@ -12,7 +12,7 @@ namespace samurai std::size_t level = 3; auto mesh_cfg = mesh_config().min_level(level).max_level(level); - using Mesh = decltype(make_MRMesh(mesh_cfg)); + using Mesh = decltype(make_empty_MRMesh(mesh_cfg)); using mesh_id_t = typename Mesh::mesh_id_t; using cl_t = typename Mesh::cl_type; using lca_t = typename Mesh::lca_type; diff --git a/tests/test_for_each.cpp b/tests/test_for_each.cpp index 9e392ce21..508204e35 100644 --- a/tests/test_for_each.cpp +++ b/tests/test_for_each.cpp @@ -6,7 +6,7 @@ namespace samurai auto create_meshes(std::size_t level) { using Config = mesh_config<1>; - using Mesh = decltype(amr::make_Mesh(std::declval())); + using Mesh = decltype(amr::make_empty_Mesh(std::declval())); using cl_type = typename Mesh::cl_type; cl_type cl1; @@ -23,7 +23,7 @@ namespace samurai TEST(set, for_each_interval) { using Config = mesh_config<1>; - using Mesh = decltype(amr::make_Mesh(std::declval())); + using Mesh = decltype(amr::make_empty_Mesh(std::declval())); using mesh_id_t = typename Mesh::mesh_id_t; std::size_t level = 1; @@ -47,7 +47,7 @@ namespace samurai TEST(set, for_each_cell) { using Config = mesh_config<1>; - using Mesh = decltype(amr::make_Mesh(std::declval())); + using Mesh = decltype(amr::make_empty_Mesh(std::declval())); using mesh_id_t = typename Mesh::mesh_id_t; std::size_t level = 1; From 95eeb9c32e6cc4783b3baef870dc68a57e7c90ef Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Wed, 15 Oct 2025 17:40:59 +0200 Subject: [PATCH 50/60] fix cppcheck --- include/samurai/mr/mesh.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/samurai/mr/mesh.hpp b/include/samurai/mr/mesh.hpp index 7a9a6fc7f..6556974c7 100644 --- a/include/samurai/mr/mesh.hpp +++ b/include/samurai/mr/mesh.hpp @@ -503,7 +503,7 @@ namespace samurai { auto mesh_cfg = cfg; mesh_cfg.parse_args(); - mesh_cfg.start_level() = mesh_cfg.max_level(); + mesh_cfg.start_level() = mesh_cfg.max_level(); // cppcheck-suppress unreadVariable return MRMesh(cfg, cl); } @@ -513,7 +513,7 @@ namespace samurai { auto mesh_cfg = cfg; mesh_cfg.parse_args(); - mesh_cfg.start_level() = mesh_cfg.max_level(); + mesh_cfg.start_level() = mesh_cfg.max_level(); // cppcheck-suppress unreadVariable return MRMesh(cfg, ca); } @@ -525,7 +525,7 @@ namespace samurai auto mesh_cfg = cfg; mesh_cfg.parse_args(); - mesh_cfg.start_level() = mesh_cfg.max_level(); + mesh_cfg.start_level() = mesh_cfg.max_level(); // cppcheck-suppress unreadVariable return MRMesh(mesh_cfg, b); } @@ -537,7 +537,7 @@ namespace samurai auto mesh_cfg = cfg; mesh_cfg.parse_args(); - mesh_cfg.start_level() = mesh_cfg.max_level(); + mesh_cfg.start_level() = mesh_cfg.max_level(); // cppcheck-suppress unreadVariable return MRMesh(mesh_cfg, domain_builder); } From 8a0e1d75332109de88493c1217b08e99d5ced8bd Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Thu, 16 Oct 2025 17:30:49 +0200 Subject: [PATCH 51/60] fix start-level option --- include/samurai/arguments.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/samurai/arguments.hpp b/include/samurai/arguments.hpp index 0f6750a72..dea8ebe4d 100644 --- a/include/samurai/arguments.hpp +++ b/include/samurai/arguments.hpp @@ -33,7 +33,7 @@ namespace samurai { app.add_option("--min-level", args::min_level, "The minimum level of the mesh")->group("SAMURAI"); app.add_option("--max-level", args::max_level, "The maximum level of the mesh")->group("SAMURAI"); - app.add_option("--start-level", args::max_level, "Start level of AMR")->group("SAMURAI"); + app.add_option("--start-level", args::start_level, "Start level of AMR")->group("SAMURAI"); app.add_option("--graduation-width", args::graduation_width, "The graduation width of the mesh")->group("SAMURAI"); app.add_option("--max-stencil-radius", args::max_stencil_radius, "The maximum number of neighbour in each direction")->group("SAMURAI"); From 46ebaca475bdd542c58a227616f10eccf1656f37 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Thu, 16 Oct 2025 17:31:41 +0200 Subject: [PATCH 52/60] fix ghost_width in test for_each_cell --- include/samurai/amr/mesh.hpp | 3 --- include/samurai/mesh_config.hpp | 6 ------ tests/test_for_each.cpp | 12 +++++++----- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/include/samurai/amr/mesh.hpp b/include/samurai/amr/mesh.hpp index d89873590..5b171598e 100644 --- a/include/samurai/amr/mesh.hpp +++ b/include/samurai/amr/mesh.hpp @@ -198,7 +198,6 @@ namespace samurai::amr { auto mesh_cfg = cfg; mesh_cfg.parse_args(); - mesh_cfg.start_level() = mesh_cfg.max_level(); return Mesh(mesh_cfg, cl); } @@ -208,7 +207,6 @@ namespace samurai::amr { auto mesh_cfg = cfg; mesh_cfg.parse_args(); - mesh_cfg.start_level() = mesh_cfg.max_level(); return Mesh(mesh_cfg, ca); } @@ -220,7 +218,6 @@ namespace samurai::amr auto mesh_cfg = cfg; mesh_cfg.parse_args(); - mesh_cfg.start_level() = mesh_cfg.max_level(); return Mesh(mesh_cfg, b); } diff --git a/include/samurai/mesh_config.hpp b/include/samurai/mesh_config.hpp index fe9e185c4..7da91bca5 100644 --- a/include/samurai/mesh_config.hpp +++ b/include/samurai/mesh_config.hpp @@ -378,12 +378,6 @@ namespace samurai return *this; } - auto clone() const - { - auto copy_ = *this; - return copy_; - } - /** * @brief parse arguments and set value to default samurai config value if needed */ diff --git a/tests/test_for_each.cpp b/tests/test_for_each.cpp index 508204e35..bfd64b509 100644 --- a/tests/test_for_each.cpp +++ b/tests/test_for_each.cpp @@ -14,7 +14,7 @@ namespace samurai cl_type cl2; cl2[level][{}].add_interval({0, 3}); - auto mesh_cfg = mesh_config<1>().min_level(level).max_level(level); + auto mesh_cfg = mesh_config<1>().min_level(level).max_level(level).disable_minimal_ghost_width(); auto m1 = amr::make_Mesh(mesh_cfg, cl1); auto m2 = amr::make_Mesh(mesh_cfg, cl2); return std::make_tuple(m1, m2); @@ -46,15 +46,17 @@ namespace samurai TEST(set, for_each_cell) { - using Config = mesh_config<1>; - using Mesh = decltype(amr::make_empty_Mesh(std::declval())); - using mesh_id_t = typename Mesh::mesh_id_t; + using Config = mesh_config<1>; std::size_t level = 1; auto meshes = create_meshes(level); auto& m1 = std::get<0>(meshes); auto& m2 = std::get<1>(meshes); - auto set = intersection(m1[mesh_id_t::cells][level], m2[mesh_id_t::cells][level]); + + using Mesh = std::tuple_element_t<0, decltype(meshes)>; + using mesh_id_t = Mesh::mesh_id_t; + + auto set = intersection(m1[mesh_id_t::cells][level], m2[mesh_id_t::cells][level]); /** Cell indices in m1: * From d528846be716ac3a569fee2f583f19b869526bd8 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 20 Oct 2025 10:24:13 +0200 Subject: [PATCH 53/60] fix demos --- demos/FiniteVolume/advection_1d.cpp | 4 ++-- demos/FiniteVolume/advection_2d_user_bc.cpp | 4 ++-- demos/FiniteVolume/burgers.cpp | 4 ++-- demos/p4est/simple_2d.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/demos/FiniteVolume/advection_1d.cpp b/demos/FiniteVolume/advection_1d.cpp index 0aa5d7e9e..8cf3b2003 100644 --- a/demos/FiniteVolume/advection_1d.cpp +++ b/demos/FiniteVolume/advection_1d.cpp @@ -95,12 +95,12 @@ int main(int argc, char* argv[]) const samurai::Box box({left_box}, {right_box}); auto config = samurai::mesh_config().min_level(6).max_level(12).periodic(is_periodic).max_stencil_size(2).disable_minimal_ghost_width(); - auto mesh = samurai::make_MRMesh(config, box); + auto mesh = samurai::make_empty_MRMesh(config); auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { - mesh = {config, box}; + mesh = samurai::make_MRMesh(config, box); init(u); } else diff --git a/demos/FiniteVolume/advection_2d_user_bc.cpp b/demos/FiniteVolume/advection_2d_user_bc.cpp index aca61944d..301bf3361 100644 --- a/demos/FiniteVolume/advection_2d_user_bc.cpp +++ b/demos/FiniteVolume/advection_2d_user_bc.cpp @@ -127,12 +127,12 @@ int main(int argc, char* argv[]) const samurai::Box box(min_corner, max_corner); auto config = samurai::mesh_config().min_level(4).max_level(10).max_stencil_size(2).disable_minimal_ghost_width(); - auto mesh = samurai::make_MRMesh(config, box); + auto mesh = samurai::make_empty_MRMesh(config); auto u = samurai::make_scalar_field("u", mesh); if (restart_file.empty()) { - mesh = {config, box}; + mesh = samurai::make_MRMesh(config, box); init(u); } else diff --git a/demos/FiniteVolume/burgers.cpp b/demos/FiniteVolume/burgers.cpp index 75291dc7e..8d5506322 100644 --- a/demos/FiniteVolume/burgers.cpp +++ b/demos/FiniteVolume/burgers.cpp @@ -107,7 +107,7 @@ int main_dim(int argc, char* argv[]) Box box(box_corner1, box_corner2); auto config = samurai::mesh_config().min_level(min_level).max_level(max_level).max_stencil_size(6); - auto mesh = samurai::make_MRMesh(config, box); + auto mesh = samurai::make_empty_MRMesh(config); auto u = samurai::make_vector_field("u", mesh); auto u1 = samurai::make_vector_field("u1", mesh); @@ -116,7 +116,7 @@ int main_dim(int argc, char* argv[]) if (restart_file.empty()) { - mesh = {config, box}; + mesh = samurai::make_MRMesh(config, box); u.resize(); // Initial solution diff --git a/demos/p4est/simple_2d.cpp b/demos/p4est/simple_2d.cpp index 4b6c6b3d7..20d80965c 100644 --- a/demos/p4est/simple_2d.cpp +++ b/demos/p4est/simple_2d.cpp @@ -86,7 +86,7 @@ void refine_1(mesh_t& mesh, std::size_t max_level) } }); - mesh = {cl}; + mesh = samurai::make_MRMesh(mesh.cfg(), cl); } } @@ -187,7 +187,7 @@ void refine_2(mesh_t& mesh, std::size_t max_level) } }); - mesh = {mesh.cfg(), cl}; + mesh = samurai::make_MRMesh(mesh.cfg(), cl); } } From 9868ebb9835b68c272a37da2cba8f7ccf1a8920a Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 20 Oct 2025 10:52:28 +0200 Subject: [PATCH 54/60] fix demos --- demos/p4est/simple_2d.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/p4est/simple_2d.cpp b/demos/p4est/simple_2d.cpp index 20d80965c..c016a5236 100644 --- a/demos/p4est/simple_2d.cpp +++ b/demos/p4est/simple_2d.cpp @@ -86,7 +86,7 @@ void refine_1(mesh_t& mesh, std::size_t max_level) } }); - mesh = samurai::make_MRMesh(mesh.cfg(), cl); + mesh = {cl}; } } From 84d176f25fd7c781cfd1da5bd8b72fec7c0fc532 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 20 Oct 2025 11:07:35 +0200 Subject: [PATCH 55/60] change unsing typename --- tests/test_for_each.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tests/test_for_each.cpp b/tests/test_for_each.cpp index bfd64b509..3cf5e1052 100644 --- a/tests/test_for_each.cpp +++ b/tests/test_for_each.cpp @@ -22,15 +22,15 @@ namespace samurai TEST(set, for_each_interval) { - using Config = mesh_config<1>; - using Mesh = decltype(amr::make_empty_Mesh(std::declval())); - using mesh_id_t = typename Mesh::mesh_id_t; - std::size_t level = 1; auto meshes = create_meshes(level); auto& m1 = std::get<0>(meshes); auto& m2 = std::get<1>(meshes); - auto set = intersection(m1[mesh_id_t::cells][level], m2[mesh_id_t::cells][level]); + + using Mesh = std::tuple_element_t<0, decltype(meshes)>; + using mesh_id_t = Mesh::mesh_id_t; + + auto set = intersection(m1[mesh_id_t::cells][level], m2[mesh_id_t::cells][level]); int nb_intervals = 0; for_each_interval(set, @@ -46,8 +46,6 @@ namespace samurai TEST(set, for_each_cell) { - using Config = mesh_config<1>; - std::size_t level = 1; auto meshes = create_meshes(level); auto& m1 = std::get<0>(meshes); From 1621d033a5e3c08aef8a3c8d7f65ddd7f5fa9df9 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 20 Oct 2025 15:36:44 +0200 Subject: [PATCH 56/60] fix level_set_from_scratch --- demos/FiniteVolume/level_set_from_scratch.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/demos/FiniteVolume/level_set_from_scratch.cpp b/demos/FiniteVolume/level_set_from_scratch.cpp index 32a312749..e8c5865e1 100644 --- a/demos/FiniteVolume/level_set_from_scratch.cpp +++ b/demos/FiniteVolume/level_set_from_scratch.cpp @@ -626,13 +626,14 @@ int main(int argc, char* argv[]) const samurai::Box box(min_corner, max_corner); auto config = samurai::mesh_config().min_level(4).max_level(8).start_level(8).max_stencil_radius(2); + config.parse_args(); AMRMesh mesh; auto phi = samurai::make_scalar_field("phi", mesh); if (restart_file.empty()) { - mesh = {config, box}; + mesh = AMRMesh(config, box); init_level_set(phi); } else From a770232273ac5fda89a2ca669eef16548b8434c6 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 20 Oct 2025 16:19:52 +0200 Subject: [PATCH 57/60] fix ldc --- demos/FiniteVolume/lid_driven_cavity.cpp | 5 ++++- include/samurai/mesh.hpp | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/demos/FiniteVolume/lid_driven_cavity.cpp b/demos/FiniteVolume/lid_driven_cavity.cpp index 95495a55e..b6b1007a8 100644 --- a/demos/FiniteVolume/lid_driven_cavity.cpp +++ b/demos/FiniteVolume/lid_driven_cavity.cpp @@ -148,7 +148,7 @@ int main(int argc, char* argv[]) // where v = velocity // p = pressure - auto config = samurai::mesh_config().min_level(3).max_level(6).max_stencil_size(2); + auto config = samurai::mesh_config().min_level(3).max_level(6).max_stencil_radius(2); auto mesh = samurai::make_MRMesh(config, box); using mesh_id_t = typename decltype(mesh)::mesh_id_t; @@ -231,6 +231,9 @@ int main(int argc, char* argv[]) auto config2 = samurai::mesh_config().min_level(1).max_level(mesh.max_level()).max_stencil_size(6).disable_args_parse(); auto mesh2 = samurai::make_MRMesh(config2, box); + std::cout << config2.start_level() << " " << config2.min_level() << " " << config2.max_level() << std::endl; + std::cout << mesh2.cfg().start_level() << " " << mesh2.cfg().min_level() << " " << mesh2.cfg().max_level() << std::endl; + // Ink data fields auto ink = samurai::make_scalar_field("ink", mesh2); auto ink_np1 = samurai::make_scalar_field("ink_np1", mesh2); diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 8eb7e0de4..7139b8f50 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -268,7 +268,10 @@ namespace samurai partition_mesh(m_config.start_level(), b); // load_balancing(); #else - this->m_cells[mesh_id_t::cells][m_config.start_level()] = {m_config.start_level(), b, config.approx_box_tol(), config.scaling_factor()}; + this->m_cells[mesh_id_t::cells][m_config.start_level()] = {m_config.start_level(), + b, + m_config.approx_box_tol(), + m_config.scaling_factor()}; #endif construct_subdomain(); construct_union(); From 0d7978401e4fc8bfc9c081f4e5e1b4bb9e8bc999 Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Mon, 20 Oct 2025 19:04:51 +0200 Subject: [PATCH 58/60] remove parse_args in Mesh_base constructor --- include/samurai/mesh.hpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 7139b8f50..3f1be9992 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -288,8 +288,6 @@ namespace samurai Mesh_base::Mesh_base(const mesh_config& config, const samurai::DomainBuilder& domain_builder) : m_config(config) { - m_config.parse_args(); - if (std::any_of(config.periodic().begin(), config.periodic().end(), [](bool b) @@ -336,9 +334,6 @@ namespace samurai inline Mesh_base::Mesh_base(const mesh_config& config, const cl_type& cl) : m_config(config) { - m_config.parse_args(); - m_config.periodic().fill(false); - this->m_cells[mesh_id_t::cells] = {cl}; construct_subdomain(); @@ -357,9 +352,6 @@ namespace samurai inline Mesh_base::Mesh_base(const mesh_config& config, const ca_type& ca) : m_config{config} { - m_config.parse_args(); - m_config.periodic().fill(false); - this->m_cells[mesh_id_t::cells] = ca; construct_subdomain(); From c76910ce9524b7caa68c81c7eefb4ccb3250ea2c Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 21 Oct 2025 10:47:23 +0200 Subject: [PATCH 59/60] fix snippets with new interface --- docs/source/howto/snippet/field/scalar_field.cpp | 5 +++-- docs/source/howto/snippet/field/vector_field.cpp | 5 +++-- docs/source/howto/snippet/loop/for_each_cell_field.cpp | 4 ++-- docs/source/howto/snippet/loop/for_each_cell_mesh.cpp | 4 ++-- docs/source/howto/snippet/loop/for_each_interval_field.cpp | 4 ++-- docs/source/howto/snippet/loop/for_each_interval_mesh.cpp | 4 ++-- docs/source/howto/snippet/mesh/amrmesh.cpp | 5 +++-- docs/source/howto/snippet/mesh/mrmesh.cpp | 5 +++-- docs/source/howto/snippet/save/dump_mesh.cpp | 4 ++-- docs/source/howto/snippet/save/save_all_submeshes.cpp | 4 ++-- docs/source/howto/snippet/save/save_field.cpp | 4 ++-- docs/source/howto/snippet/save/save_mesh.cpp | 4 ++-- docs/source/howto/snippet/timers/custom_timer.cpp | 4 ++-- 13 files changed, 30 insertions(+), 26 deletions(-) diff --git a/docs/source/howto/snippet/field/scalar_field.cpp b/docs/source/howto/snippet/field/scalar_field.cpp index 0a1794235..85c805e7c 100644 --- a/docs/source/howto/snippet/field/scalar_field.cpp +++ b/docs/source/howto/snippet/field/scalar_field.cpp @@ -5,10 +5,11 @@ int main() { static constexpr std::size_t dim = 2; - using config_t = samurai::MRConfig; samurai::Box box({0.0, 0.0}, {1.0, 1.0}); - samurai::MRMesh mesh(box, 2, 5); // min level 2, max level 5 + + auto config = samurai::mesh_config().min_level(2).max_level(5); + auto mesh = samurai::make_MRMesh(config, box); auto field = samurai::make_scalar_field("u", mesh); diff --git a/docs/source/howto/snippet/field/vector_field.cpp b/docs/source/howto/snippet/field/vector_field.cpp index 2627bd985..b1acd32f8 100644 --- a/docs/source/howto/snippet/field/vector_field.cpp +++ b/docs/source/howto/snippet/field/vector_field.cpp @@ -5,10 +5,11 @@ int main() { static constexpr std::size_t dim = 2; - using config_t = samurai::MRConfig; samurai::Box box({0.0, 0.0}, {1.0, 1.0}); - samurai::MRMesh mesh(box, 2, 5); // min level 2, max level 5 + + auto config = samurai::mesh_config().min_level(2).max_level(5); + auto mesh = samurai::make_MRMesh(config, box); auto field = samurai::make_vector_field("v", mesh); // 3 components diff --git a/docs/source/howto/snippet/loop/for_each_cell_field.cpp b/docs/source/howto/snippet/loop/for_each_cell_field.cpp index da2a00e72..aea7c8a9b 100644 --- a/docs/source/howto/snippet/loop/for_each_cell_field.cpp +++ b/docs/source/howto/snippet/loop/for_each_cell_field.cpp @@ -6,10 +6,10 @@ int main() { static constexpr std::size_t dim = 2; - using config_t = samurai::MRConfig; samurai::Box box({0.0, 0.0}, {1.0, 1.0}); - samurai::MRMesh mesh(box, 2, 5); // min level 2, max level 5 + auto config = samurai::mesh_config().min_level(2).max_level(5); + auto mesh = samurai::make_MRMesh(config, box); auto field = samurai::make_scalar_field("u", mesh); diff --git a/docs/source/howto/snippet/loop/for_each_cell_mesh.cpp b/docs/source/howto/snippet/loop/for_each_cell_mesh.cpp index 6213dbf40..f977bdf20 100644 --- a/docs/source/howto/snippet/loop/for_each_cell_mesh.cpp +++ b/docs/source/howto/snippet/loop/for_each_cell_mesh.cpp @@ -5,10 +5,10 @@ int main() { static constexpr std::size_t dim = 2; - using config_t = samurai::MRConfig; samurai::Box box({0.0, 0.0}, {1.0, 1.0}); - samurai::MRMesh mesh(box, 2, 5); // min level 2, max level 5 + auto config = samurai::mesh_config().min_level(2).max_level(5); + auto mesh = samurai::make_MRMesh(config, box); samurai::for_each_cell(mesh, [&](const auto& cell) diff --git a/docs/source/howto/snippet/loop/for_each_interval_field.cpp b/docs/source/howto/snippet/loop/for_each_interval_field.cpp index 41c21f086..0f0f117f7 100644 --- a/docs/source/howto/snippet/loop/for_each_interval_field.cpp +++ b/docs/source/howto/snippet/loop/for_each_interval_field.cpp @@ -6,10 +6,10 @@ int main() { static constexpr std::size_t dim = 2; - using config_t = samurai::MRConfig; samurai::Box box({-1.0, -1.0}, {1.0, 1.0}); - samurai::MRMesh mesh(box, 0, 2); // min level 0, max level 2 + auto config = samurai::mesh_config().min_level(0).max_level(2); + auto mesh = samurai::make_MRMesh(config, box); auto field = samurai::make_scalar_field("u", mesh); diff --git a/docs/source/howto/snippet/loop/for_each_interval_mesh.cpp b/docs/source/howto/snippet/loop/for_each_interval_mesh.cpp index 131945bb4..fb3875a92 100644 --- a/docs/source/howto/snippet/loop/for_each_interval_mesh.cpp +++ b/docs/source/howto/snippet/loop/for_each_interval_mesh.cpp @@ -5,10 +5,10 @@ int main() { static constexpr std::size_t dim = 2; - using config_t = samurai::MRConfig; samurai::Box box({0.0, 0.0}, {1.0, 1.0}); - samurai::MRMesh mesh(box, 2, 5); // min level 2, max level 5 + auto config = samurai::mesh_config().min_level(2).max_level(5); + auto mesh = samurai::make_MRMesh(config, box); samurai::for_each_interval(mesh, [&](std::size_t level, const auto& interval, const auto& index) diff --git a/docs/source/howto/snippet/mesh/amrmesh.cpp b/docs/source/howto/snippet/mesh/amrmesh.cpp index 5c377011e..e5e837f40 100644 --- a/docs/source/howto/snippet/mesh/amrmesh.cpp +++ b/docs/source/howto/snippet/mesh/amrmesh.cpp @@ -4,10 +4,11 @@ int main() { static constexpr std::size_t dim = 2; - using config_t = samurai::amr::Config; samurai::Box box({0.0, 0.0}, {1.0, 1.0}); - samurai::amr::Mesh mesh(box, 4, 2, 5); // start level 4, min level 2, max level 5 + + auto config = samurai::mesh_config().min_level(2).max_level(5).start_level(4); + auto mesh = samurai::amr::make_Mesh(config, box); return 0; } diff --git a/docs/source/howto/snippet/mesh/mrmesh.cpp b/docs/source/howto/snippet/mesh/mrmesh.cpp index 7ab70e068..dd503914b 100644 --- a/docs/source/howto/snippet/mesh/mrmesh.cpp +++ b/docs/source/howto/snippet/mesh/mrmesh.cpp @@ -4,10 +4,11 @@ int main() { static constexpr std::size_t dim = 2; - using config_t = samurai::MRConfig; samurai::Box box({0.0, 0.0}, {1.0, 1.0}); - samurai::MRMesh mesh(box, 2, 5); // min level 2, max level 5 + + auto config = samurai::mesh_config().min_level(2).max_level(5); + auto mesh = samurai::make_MRMesh(config, box); return 0; } diff --git a/docs/source/howto/snippet/save/dump_mesh.cpp b/docs/source/howto/snippet/save/dump_mesh.cpp index c5473bd0b..df2ef81e5 100644 --- a/docs/source/howto/snippet/save/dump_mesh.cpp +++ b/docs/source/howto/snippet/save/dump_mesh.cpp @@ -9,10 +9,10 @@ namespace fs = std::filesystem; int main() { static constexpr std::size_t dim = 2; - using config_t = samurai::MRConfig; samurai::Box box({0.0, 0.0}, {1.0, 1.0}); - samurai::MRMesh mesh(box, 2, 5); // min level 2, max level 5 + auto config = samurai::mesh_config().min_level(2).max_level(5); + auto mesh = samurai::make_MRMesh(config, box); auto field_1 = samurai::make_scalar_field("u", mesh); auto field_2 = samurai::make_vector_field("v", mesh); diff --git a/docs/source/howto/snippet/save/save_all_submeshes.cpp b/docs/source/howto/snippet/save/save_all_submeshes.cpp index 45ac0601b..0aef00012 100644 --- a/docs/source/howto/snippet/save/save_all_submeshes.cpp +++ b/docs/source/howto/snippet/save/save_all_submeshes.cpp @@ -9,10 +9,10 @@ namespace fs = std::filesystem; int main() { static constexpr std::size_t dim = 2; - using config_t = samurai::MRConfig; samurai::Box box({0.0, 0.0}, {1.0, 1.0}); - samurai::MRMesh mesh(box, 2, 5); // min level 2, max level 5 + auto config = samurai::mesh_config().min_level(2).max_level(5); + auto mesh = samurai::make_MRMesh(config, box); auto field_1 = samurai::make_scalar_field("u", mesh); auto field_2 = samurai::make_vector_field("v", mesh); diff --git a/docs/source/howto/snippet/save/save_field.cpp b/docs/source/howto/snippet/save/save_field.cpp index 19fe42689..9af2aa13e 100644 --- a/docs/source/howto/snippet/save/save_field.cpp +++ b/docs/source/howto/snippet/save/save_field.cpp @@ -6,10 +6,10 @@ int main() { static constexpr std::size_t dim = 2; - using config_t = samurai::MRConfig; samurai::Box box({0.0, 0.0}, {1.0, 1.0}); - samurai::MRMesh mesh(box, 2, 5); // min level 2, max level 5 + auto config = samurai::mesh_config().min_level(2).max_level(5); + auto mesh = samurai::make_MRMesh(config, box); auto field_1 = samurai::make_scalar_field("u", mesh); auto field_2 = samurai::make_vector_field("v", mesh); diff --git a/docs/source/howto/snippet/save/save_mesh.cpp b/docs/source/howto/snippet/save/save_mesh.cpp index fdb3c15c2..eed964c30 100644 --- a/docs/source/howto/snippet/save/save_mesh.cpp +++ b/docs/source/howto/snippet/save/save_mesh.cpp @@ -5,10 +5,10 @@ int main() { static constexpr std::size_t dim = 2; - using config_t = samurai::MRConfig; samurai::Box box({0.0, 0.0}, {1.0, 1.0}); - samurai::MRMesh mesh(box, 2, 5); // min level 2, max level 5 + auto config = samurai::mesh_config().min_level(2).max_level(5); + auto mesh = samurai::make_MRMesh(config, box); samurai::save("output_path", "mesh_filename", mesh); // or diff --git a/docs/source/howto/snippet/timers/custom_timer.cpp b/docs/source/howto/snippet/timers/custom_timer.cpp index 048d2a755..305b102cd 100644 --- a/docs/source/howto/snippet/timers/custom_timer.cpp +++ b/docs/source/howto/snippet/timers/custom_timer.cpp @@ -8,12 +8,12 @@ int main(int argc, char** argv) { static constexpr std::size_t dim = 2; - using config_t = samurai::MRConfig; samurai::initialize("Custom timer example", argc, argv); samurai::Box box({0.0, 0.0}, {1.0, 1.0}); - samurai::MRMesh mesh(box, 2, 5); // min level 2, max level 5 + auto config = samurai::mesh_config().min_level(2).max_level(5); + auto mesh = samurai::make_MRMesh(config, box); auto field = samurai::make_scalar_field("u", mesh); From d8e878ae7480aad53d685e804dbab9304e4ef8ee Mon Sep 17 00:00:00 2001 From: Josselin Massot Date: Tue, 21 Oct 2025 13:37:23 +0200 Subject: [PATCH 60/60] fix restart test --- include/samurai/io/restart.hpp | 2 +- include/samurai/mesh.hpp | 2 +- tests/test_restart.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/samurai/io/restart.hpp b/include/samurai/io/restart.hpp index b52231903..3343acc58 100644 --- a/include/samurai/io/restart.hpp +++ b/include/samurai/io/restart.hpp @@ -415,7 +415,7 @@ namespace samurai ca_type ca; load(file, ca); - auto mesh_cfg = mesh_config().min_level(min_level).max_level(max_level); + auto mesh_cfg = mesh_config().min_level(min_level).max_level(max_level).disable_args_parse(); Mesh new_mesh{mesh_cfg, ca}; std::swap(mesh, new_mesh); load_fields(file, mesh, fields...); diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 3f1be9992..8a39c6626 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -350,7 +350,7 @@ namespace samurai template inline Mesh_base::Mesh_base(const mesh_config& config, const ca_type& ca) - : m_config{config} + : m_config(config) { this->m_cells[mesh_id_t::cells] = ca; diff --git a/tests/test_restart.cpp b/tests/test_restart.cpp index 88620e730..b6b64e4da 100644 --- a/tests/test_restart.cpp +++ b/tests/test_restart.cpp @@ -17,7 +17,7 @@ namespace samurai box_corner1.fill(0); box_corner2.fill(box_boundary); Box box(box_corner1, box_corner2); - auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(5); + auto mesh_cfg = samurai::mesh_config().min_level(2).max_level(5).disable_minimal_ghost_width(); return make_MRMesh(mesh_cfg, box); }