From d85065482b392920c98563a79520729f7a3b94fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20David--Cl=C3=A9ris?= Date: Wed, 13 May 2026 10:45:05 +0200 Subject: [PATCH 1/8] [Phys] add Epstein drag stopping time for spherical dust grains Add epstein_stopping_time and epstein_supersonic_correction functions to shamphys, implementing the Epstein drag stopping time formula with a supersonic correction factor from Kwok 1975. Assisted-by: claude-code --- src/shamphys/include/shamphys/Dust.hpp | 71 ++++++++++++++++++++++++++ src/shampylib/src/pyShamphys.cpp | 57 +++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 src/shamphys/include/shamphys/Dust.hpp diff --git a/src/shamphys/include/shamphys/Dust.hpp b/src/shamphys/include/shamphys/Dust.hpp new file mode 100644 index 0000000000..03762b90af --- /dev/null +++ b/src/shamphys/include/shamphys/Dust.hpp @@ -0,0 +1,71 @@ +// -------------------------------------------------------// +// +// SHAMROCK code for hydrodynamics +// Copyright (c) 2021-2026 Timothée David--Cléris +// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1 +// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information +// +// -------------------------------------------------------// + +#pragma once + +/** + * @file Dust.hpp + * @brief Epstein drag stopping time for spherical dust grains + */ + +#include "shambase/constants.hpp" +#include "shambackends/sycl.hpp" + +namespace shamphys { + + /** + * @brief Epstein drag supersonic correction factor + * + * Corrects the Epstein drag for supersonic drift between dust and gas. + * When the drift speed exceeds the gas thermal speed, the relative + * motion must be accounted for in the drag force. + * + * \f[ + * f(\Delta v, c_s) = \sqrt{1 + \frac{9\pi}{128} \frac{\Delta v^2}{c_s^2}} + * \f] + * + * @param delta_v Drift speed between dust and gas + * @param cs Gas sound speed + * @return Supersonic correction factor f(delta_v, cs) + */ + template + constexpr T epstein_supersonic_correction(T delta_v, T cs) { + auto div = delta_v / cs; + return sycl::sqrt(T(1.0) + T(9.0 / 128.0) * shambase::constants::pi * div * div); + } + + /** + * @brief Epstein drag stopping time for spherical dust grains + * + * \f[ + * t_s = \frac{\rho_{\rm grain} \, s_{\rm grain}}{\rho \, c_s \, f} + * \sqrt{\frac{\pi \gamma}{8}} + * \f] + * + * where \f$\rho = \rho_{\rm g} + \rho_{\rm d}\f$ is the total density, + * \f$f\f$ is the supersonic correction (1.0 for the subsonic case), + * \f$\gamma\f$ is the adiabatic index, + * \f$\rho_{\rm grain}\f$ is the grain internal density, and + * \f$s_{\rm grain}\f$ is the grain radius. + * + * @param rho_grain Internal density of the dust grain + * @param s_grain Radius of the dust grain + * @param rho Total density (\f$\rho_{\rm g} + \rho_{\rm d}\f$) + * @param cs Gas sound speed + * @param gamma Adiabatic index + * @param f Supersonic correction factor (default 1.0) + * @return Stopping time + */ + template + constexpr T epstein_stopping_time(T rho_grain, T s_grain, T rho, T cs, T gamma, T f = T(1.0)) { + return (rho_grain * s_grain / (rho * cs * f)) + * sycl::sqrt(shambase::constants::pi * gamma / T(8)); + } + +} // namespace shamphys diff --git a/src/shampylib/src/pyShamphys.cpp b/src/shampylib/src/pyShamphys.cpp index 9f9c7bfce8..a7a7b5d5b7 100644 --- a/src/shampylib/src/pyShamphys.cpp +++ b/src/shampylib/src/pyShamphys.cpp @@ -20,6 +20,7 @@ #include "shambindings/pytypealias.hpp" #include "shamcomm/logs.hpp" #include "shamphys/BlackHoles.hpp" +#include "shamphys/Dust.hpp" #include "shamphys/HydroSoundwave.hpp" #include "shamphys/Planets.hpp" #include "shamphys/SedovTaylor.hpp" @@ -274,6 +275,62 @@ Register_pymod(shamphyslibinit) { units : unit system )pbdoc"); + shamphys_module.def( + "epstein_supersonic_correction", + [](double delta_v, double cs) { + return shamphys::epstein_supersonic_correction(delta_v, cs); + }, + py::kw_only(), + py::arg("delta_v"), + py::arg("cs"), + R"pbdoc( + Epstein drag supersonic correction factor for spherical dust grains. + + Corrects the Epstein drag force when the drift speed between dust + and gas exceeds the thermal speed. + + \f$f(\Delta v, c_s) = \sqrt{1 + \frac{9\pi}{128} \frac{\Delta v^2}{c_s^2}}\f$ + + Args: + delta_v: Drift speed between dust and gas + cs: Gas sound speed + + Returns: + The supersonic correction factor f(delta_v, cs) + )pbdoc"); + + shamphys_module.def( + "epstein_stopping_time", + [](double rho_grain, double s_grain, double rho, double cs, double gamma, double f) { + return shamphys::epstein_stopping_time(rho_grain, s_grain, rho, cs, gamma, f); + }, + py::kw_only(), + py::arg("rho_grain"), + py::arg("s_grain"), + py::arg("rho"), + py::arg("cs"), + py::arg("gamma"), + py::arg("f"), + R"pbdoc( + Epstein drag stopping time for spherical dust grains. + + \f$t_s = \frac{\rho_{\rm grain} \, s_{\rm grain}}{\rho \, c_s \, f} \sqrt{\frac{\pi \gamma}{8}}\f] + + where \f$\rho = \rho_{\rm g} + \rho_{\rm d}\f$ is the total density and \f$f\f$ + is the supersonic correction factor. + + Args: + rho_grain: Internal density of the dust grain + s_grain: Radius of the dust grain + rho: Total density (\f$\rho_{\rm g} + \rho_{\rm d}\f$) + cs: Gas sound speed + gamma: Adiabatic index + f: Supersonic correction factor (1.0 for subsonic) + + Returns: + The stopping time + )pbdoc"); + shamcomm::logs::debug_ln("[Py]", "registering shamrock.phys.HydroSoundwave"); py::class_(shamphys_module, "HydroSoundwave") .def( From 5ecc638c24e8be777857abc0d1de74958f8d5cd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20David--Cl=C3=A9ris?= Date: Wed, 13 May 2026 11:39:27 +0200 Subject: [PATCH 2/8] review --- src/shamphys/include/shamphys/Dust.hpp | 17 +++++++++++++++-- src/shampylib/src/pyShamphys.cpp | 4 ++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/shamphys/include/shamphys/Dust.hpp b/src/shamphys/include/shamphys/Dust.hpp index 03762b90af..a02e1cc47a 100644 --- a/src/shamphys/include/shamphys/Dust.hpp +++ b/src/shamphys/include/shamphys/Dust.hpp @@ -11,6 +11,7 @@ /** * @file Dust.hpp + * @author Timothée David--Cléris (tim.shamrock@proton.me) * @brief Epstein drag stopping time for spherical dust grains */ @@ -30,12 +31,17 @@ namespace shamphys { * f(\Delta v, c_s) = \sqrt{1 + \frac{9\pi}{128} \frac{\Delta v^2}{c_s^2}} * \f] * + * Corresponds to Eq. 249 in the PHANTOM paper. + * * @param delta_v Drift speed between dust and gas * @param cs Gas sound speed * @return Supersonic correction factor f(delta_v, cs) */ template - constexpr T epstein_supersonic_correction(T delta_v, T cs) { + inline T epstein_supersonic_correction(T delta_v, T cs) noexcept { + + SHAM_ASSERT(cs > 0); + auto div = delta_v / cs; return sycl::sqrt(T(1.0) + T(9.0 / 128.0) * shambase::constants::pi * div * div); } @@ -48,6 +54,8 @@ namespace shamphys { * \sqrt{\frac{\pi \gamma}{8}} * \f] * + * Corresponds to Eq. 250 in the PHANTOM paper. + * * where \f$\rho = \rho_{\rm g} + \rho_{\rm d}\f$ is the total density, * \f$f\f$ is the supersonic correction (1.0 for the subsonic case), * \f$\gamma\f$ is the adiabatic index, @@ -63,7 +71,12 @@ namespace shamphys { * @return Stopping time */ template - constexpr T epstein_stopping_time(T rho_grain, T s_grain, T rho, T cs, T gamma, T f = T(1.0)) { + inline T epstein_stopping_time( + T rho_grain, T s_grain, T rho, T cs, T gamma, T f = T(1.0)) noexcept { + + SHAM_ASSERT(rho * cs * f > 0); + SHAM_ASSERT(gamma > 0); + return (rho_grain * s_grain / (rho * cs * f)) * sycl::sqrt(shambase::constants::pi * gamma / T(8)); } diff --git a/src/shampylib/src/pyShamphys.cpp b/src/shampylib/src/pyShamphys.cpp index a7a7b5d5b7..8c2e4292f4 100644 --- a/src/shampylib/src/pyShamphys.cpp +++ b/src/shampylib/src/pyShamphys.cpp @@ -310,11 +310,11 @@ Register_pymod(shamphyslibinit) { py::arg("rho"), py::arg("cs"), py::arg("gamma"), - py::arg("f"), + py::arg("f") = 1.0, R"pbdoc( Epstein drag stopping time for spherical dust grains. - \f$t_s = \frac{\rho_{\rm grain} \, s_{\rm grain}}{\rho \, c_s \, f} \sqrt{\frac{\pi \gamma}{8}}\f] + \f[t_s = \frac{\rho_{\rm grain} \, s_{\rm grain}}{\rho \, c_s \, f} \sqrt{\frac{\pi \gamma}{8}}\f] where \f$\rho = \rho_{\rm g} + \rho_{\rm d}\f$ is the total density and \f$f\f$ is the supersonic correction factor. From ddd4868956607abbcd955e008b7d5c9cc31c0eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20David--Cl=C3=A9ris?= Date: Wed, 13 May 2026 11:45:53 +0200 Subject: [PATCH 3/8] review --- src/shamphys/include/shamphys/Dust.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shamphys/include/shamphys/Dust.hpp b/src/shamphys/include/shamphys/Dust.hpp index a02e1cc47a..a96647cfc3 100644 --- a/src/shamphys/include/shamphys/Dust.hpp +++ b/src/shamphys/include/shamphys/Dust.hpp @@ -17,6 +17,7 @@ #include "shambase/constants.hpp" #include "shambackends/sycl.hpp" +#include "shambase/assert.hpp" namespace shamphys { From 4373db031e8be1a894e063bef8ee9bf44d0b0741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20David--Cl=C3=A9ris?= Date: Thu, 14 May 2026 13:30:40 +0200 Subject: [PATCH 4/8] yeah boy --- src/shambase/include/shambase/call_lambda.hpp | 30 ++++ .../include/shambindings/pybindaliases.hpp | 148 +++++++++++++++++- src/shambindings/src/pybindings.cpp | 21 +++ src/shampylib/src/pyShamphys.cpp | 12 +- 4 files changed, 202 insertions(+), 9 deletions(-) create mode 100644 src/shambase/include/shambase/call_lambda.hpp diff --git a/src/shambase/include/shambase/call_lambda.hpp b/src/shambase/include/shambase/call_lambda.hpp new file mode 100644 index 0000000000..1775048dc6 --- /dev/null +++ b/src/shambase/include/shambase/call_lambda.hpp @@ -0,0 +1,30 @@ +// -------------------------------------------------------// +// +// SHAMROCK code for hydrodynamics +// Copyright (c) 2021-2026 Timothée David--Cléris +// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1 +// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information +// +// -------------------------------------------------------// + +#pragma once + +/** + * @file print.hpp + * @author Timothée David--Cléris (tim.shamrock@proton.me) + * @brief TODO + */ + +namespace shambase { + + /// TODO dox header + struct call_lambda { + + /// Call the lambda on construction + template + inline explicit call_lambda(Func &&f) { + f(); + } + }; + +} // namespace shambase diff --git a/src/shambindings/include/shambindings/pybindaliases.hpp b/src/shambindings/include/shambindings/pybindaliases.hpp index a46460cd9d..9cf7e16368 100644 --- a/src/shambindings/include/shambindings/pybindaliases.hpp +++ b/src/shambindings/include/shambindings/pybindaliases.hpp @@ -21,23 +21,147 @@ * we can then wrap them conveniently in a single macro call. */ +#include "shambase/call_lambda.hpp" +#include "shambase/exception.hpp" #include +#include +#include /// alias to pybind11 namespace namespace py = pybind11; +// ------------------------------------------------------------------ +// Submodule registry +// ------------------------------------------------------------------ + +namespace shambindings::submodules { + + // ------------------------------------------------------------------ + // Generic registry + // ------------------------------------------------------------------ + + template + struct registry_t { + + // note here that std::less<> is for transparent lookup with string_view + using map_t = std::map>; + std::unique_ptr storage = {}; + + using getter_fn = std::function; + std::optional>> overrides; + + map_t &data() { + if (!storage) { + storage = std::make_unique(); + } + return *storage; + } + + void reset() { + storage.reset(); + overrides = std::nullopt; + } + + // enable override system lazily + auto &override_map() { + if (!overrides) { + overrides.emplace(); + } + return *overrides; + } + + void set_override(std::string_view key, getter_fn fn) { + override_map().insert_or_assign(std::string(key), std::move(fn)); + } + + void clear_overrides() { overrides = std::nullopt; } + + // does not include overrides + std::vector keys() const { + if (!storage) { + return {}; + } + + std::vector out; + out.reserve(storage->size()); + + for (auto const &kv : *storage) { + out.push_back(kv.first); + } + + return out; + } + + T &get(std::string_view key) { + + // global override first + if (overrides) { + if (auto it = overrides->find(key); it != overrides->end()) { + return it->second(); + } + } + + auto &map = data(); + + if (auto it = map.find(key); it != map.end()) { + return it->second; + } + + throw shambase::make_except_with_loc( + "registry entry not found: " + std::string(key)); + } + + void insert(std::string_view key, T &&value) { + auto [it, inserted] = data().emplace(std::string(key), std::move(value)); + + if (!inserted) { + throw shambase::make_except_with_loc( + "registry entry already exists: " + std::string(key)); + } + } + }; + + // ------------------------------------------------------------------ + // Registry types + // ------------------------------------------------------------------ + + using module_factory_t = std::function; + + // ------------------------------------------------------------------ + // Global registries + // ------------------------------------------------------------------ + + registry_t &modules(); + + registry_t &builders(); + + // ------------------------------------------------------------------ + // Global build call + // ------------------------------------------------------------------ + + inline void build_all_modules() { + auto &module_map = modules().data(); + + // Get snapshot of builder keys + std::vector keys = builders().keys(); + + // Lexicographic order + std::sort(keys.begin(), keys.end()); + + for (auto const &key : keys) { + auto &builder = builders().get(key); + module_map.emplace(key, builder()); + } + } + +} // namespace shambindings::submodules + /// function signature used to register python modules using fct_sig = std::function; /// Register a python module init function to be ran on init void register_pybind_init_func(fct_sig); -/// Utility struct to register python modules through static init -struct PyBindStaticInit { - /// Constructor to register the python init function using static init - inline explicit PyBindStaticInit(fct_sig t) { register_pybind_init_func(std::move(t)); } -}; - /** * @brief Register a python module init function using static initialisation * @@ -55,6 +179,14 @@ struct PyBindStaticInit { */ #define Register_pymod(placeholdername) \ void pymod_##placeholdername(py::module &m); \ - void (*pymod_ptr_##placeholdername)(py::module & m) = pymod_##placeholdername; \ - PyBindStaticInit pymod_class_obj_##placeholdername(pymod_ptr_##placeholdername); \ + shambase::call_lambda pymod_class_obj_##placeholdername([]() { \ + register_pybind_init_func(pymod_##placeholdername); \ + }); \ void pymod_##placeholdername(py::module &m) + +#define Register_pymodsubmodule(placeholdername, path) \ + py::module pymod_##placeholdername(); \ + shambase::call_lambda pymod_class_obj_##placeholdername([]() { \ + shambindings::submodules::builders().insert(path, pymod_##placeholdername); \ + }); \ + py::module pymod_##placeholdername() diff --git a/src/shambindings/src/pybindings.cpp b/src/shambindings/src/pybindings.cpp index d1aa6ba29b..ec7e03925d 100644 --- a/src/shambindings/src/pybindings.cpp +++ b/src/shambindings/src/pybindings.cpp @@ -116,6 +116,20 @@ void register_py_to_sham_print(py::module &m) { }); } +namespace shambindings::submodules { + + registry_t &modules() { + static auto _reg = registry_t{}; + return _reg; + } + + registry_t &builders() { + static auto _reg = registry_t{}; + return _reg; + } + +} // namespace shambindings::submodules + namespace shambindings { enum { None = 0, Lib = 1, Embed = 2 } init_state = None; @@ -130,12 +144,19 @@ namespace shambindings { &py_func_printer_normal, &py_func_printer_ln, &py_func_flush_func); } + submodules::modules().set_override("shamrock", [&]() -> py::module & { + return m; + }); + if (static_init_shamrock_pybind) { for (auto fct : *static_init_shamrock_pybind) { fct(m); } } + submodules::builders().reset(); + submodules::modules().reset(); + if (is_lib_mode) { init_state = Lib; } else { diff --git a/src/shampylib/src/pyShamphys.cpp b/src/shampylib/src/pyShamphys.cpp index 8c2e4292f4..3b3d6ca8a1 100644 --- a/src/shampylib/src/pyShamphys.cpp +++ b/src/shampylib/src/pyShamphys.cpp @@ -37,9 +37,19 @@ #include #include +Register_pymodsubmodule(blablabla, "shamrock.phys") { + return shambindings::submodules::modules() + .get("shamrock") + .def_submodule("phys", "Physics Library"); +} + Register_pymod(shamphyslibinit) { - py::module shamphys_module = m.def_submodule("phys", "Physics Library"); + shambindings::submodules::build_all_modules(); + + py::module &shamphys_module = shambindings::submodules::modules().get("shamrock.phys"); + + // py::module shamphys_module = m.def_submodule("phys", "Physics Library"); // Planets.hpp From b7f36f5a86ccfa1f55e31b289d8253dbea7b8f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20David--Cl=C3=A9ris?= Date: Thu, 14 May 2026 13:40:11 +0200 Subject: [PATCH 5/8] doc --- src/shambase/include/shambase/call_lambda.hpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/shambase/include/shambase/call_lambda.hpp b/src/shambase/include/shambase/call_lambda.hpp index 1775048dc6..42d3d3a0aa 100644 --- a/src/shambase/include/shambase/call_lambda.hpp +++ b/src/shambase/include/shambase/call_lambda.hpp @@ -12,12 +12,17 @@ /** * @file print.hpp * @author Timothée David--Cléris (tim.shamrock@proton.me) - * @brief TODO + * @brief Call a lambda at static or local scope construction time */ namespace shambase { - /// TODO dox header + /** + * @brief Execute a lambda when a `call_lambda` object is constructed. + * + * Useful for static initialization side effects (registering data, + * registering modules, etc.) without needing a named function. + */ struct call_lambda { /// Call the lambda on construction From 483f8ca51c6984e9a94d6c9248c090fd5f4c739f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20David--Cl=C3=A9ris?= Date: Thu, 14 May 2026 13:55:49 +0200 Subject: [PATCH 6/8] some c++ clockwork --- .../include/shambindings/pybindaliases.hpp | 31 +++++++++++++------ src/shambindings/src/pybindings.cpp | 2 ++ src/shampylib/src/pyShamphys.cpp | 6 ++-- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/shambindings/include/shambindings/pybindaliases.hpp b/src/shambindings/include/shambindings/pybindaliases.hpp index 9cf7e16368..a8580312ae 100644 --- a/src/shambindings/include/shambindings/pybindaliases.hpp +++ b/src/shambindings/include/shambindings/pybindaliases.hpp @@ -23,6 +23,7 @@ #include "shambase/call_lambda.hpp" #include "shambase/exception.hpp" +#include "shambase/unique_name_macro.hpp" #include #include #include @@ -162,6 +163,13 @@ using fct_sig = std::function; /// Register a python module init function to be ran on init void register_pybind_init_func(fct_sig); +#define Register_pymod_int(funcname, lambda_name) \ + static void funcname(py::module &m); \ + static shambase::call_lambda lambda_name([]() { \ + register_pybind_init_func(funcname); \ + }); \ + static void funcname(py::module &m) + /** * @brief Register a python module init function using static initialisation * @@ -178,15 +186,18 @@ void register_pybind_init_func(fct_sig); * @endcode */ #define Register_pymod(placeholdername) \ - void pymod_##placeholdername(py::module &m); \ - shambase::call_lambda pymod_class_obj_##placeholdername([]() { \ - register_pybind_init_func(pymod_##placeholdername); \ - }); \ - void pymod_##placeholdername(py::module &m) + Register_pymod_int(pymod_##placeholdername, pymod_class_obj_##placeholdername) -#define Register_pymodsubmodule(placeholdername, path) \ - py::module pymod_##placeholdername(); \ - shambase::call_lambda pymod_class_obj_##placeholdername([]() { \ - shambindings::submodules::builders().insert(path, pymod_##placeholdername); \ +#define Register_pybind() \ + Register_pymod_int(__shamrock_unique_name(pybind_), __shamrock_unique_name(pybind_class_obj_)) + +#define Register_pymodsubmodule_int(path, funcname, lambda_name) \ + py::module funcname(); \ + shambase::call_lambda lambda_name([]() { \ + shambindings::submodules::builders().insert(path, funcname); \ }); \ - py::module pymod_##placeholdername() + py::module funcname() + +#define Register_pymodsubmodule(path) \ + Register_pymodsubmodule_int( \ + path, __shamrock_unique_name(pybind_class_obj_), __shamrock_unique_name(pybind_)) diff --git a/src/shambindings/src/pybindings.cpp b/src/shambindings/src/pybindings.cpp index ec7e03925d..36849c6d75 100644 --- a/src/shambindings/src/pybindings.cpp +++ b/src/shambindings/src/pybindings.cpp @@ -148,6 +148,8 @@ namespace shambindings { return m; }); + shambindings::submodules::build_all_modules(); + if (static_init_shamrock_pybind) { for (auto fct : *static_init_shamrock_pybind) { fct(m); diff --git a/src/shampylib/src/pyShamphys.cpp b/src/shampylib/src/pyShamphys.cpp index 3b3d6ca8a1..6d10cf030b 100644 --- a/src/shampylib/src/pyShamphys.cpp +++ b/src/shampylib/src/pyShamphys.cpp @@ -37,15 +37,15 @@ #include #include -Register_pymodsubmodule(blablabla, "shamrock.phys") { +Register_pymodsubmodule("shamrock.phys") { return shambindings::submodules::modules() .get("shamrock") .def_submodule("phys", "Physics Library"); } -Register_pymod(shamphyslibinit) { +Register_pybind() {} - shambindings::submodules::build_all_modules(); +Register_pybind() { py::module &shamphys_module = shambindings::submodules::modules().get("shamrock.phys"); From 8305074340a43632c443f79fe0f8b87996308bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20David--Cl=C3=A9ris?= Date: Thu, 14 May 2026 14:04:05 +0200 Subject: [PATCH 7/8] improve unique_name_macro_testing --- .../include/shambase/unique_name_macro.hpp | 6 +++--- src/tests/shambase/unique_name_macro_test.cpp | 13 +++++-------- .../shambase/unique_name_macro_test2.cpp | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 src/tests/shambase/unique_name_macro_test2.cpp diff --git a/src/shambase/include/shambase/unique_name_macro.hpp b/src/shambase/include/shambase/unique_name_macro.hpp index 91494e60b7..19c4ec0a33 100644 --- a/src/shambase/include/shambase/unique_name_macro.hpp +++ b/src/shambase/include/shambase/unique_name_macro.hpp @@ -17,9 +17,9 @@ */ /// Utility to concatenate two tokens -#define internal_macro_sham_CONCAT2(a, b) a##b +#define sham_CONCAT2(a, b) a##b /// Utility to expand a macro with two tokens -#define internal_macro_sham_EXPAND2(a, b) internal_macro_sham_CONCAT2(a, b) +#define sham_EXPAND2(a, b) sham_CONCAT2(a, b) /** * @fn __shamrock_unique_name @@ -29,4 +29,4 @@ * @note The `__LINE__` fallback is not unique for multiple uses on the same line. */ -#define __shamrock_unique_name(base_name) internal_macro_sham_EXPAND2(base_name, __LINE__) +#define __shamrock_unique_name(base_name) sham_EXPAND2(base_name, __LINE__) diff --git a/src/tests/shambase/unique_name_macro_test.cpp b/src/tests/shambase/unique_name_macro_test.cpp index aadccae398..d9ab5b39e5 100644 --- a/src/tests/shambase/unique_name_macro_test.cpp +++ b/src/tests/shambase/unique_name_macro_test.cpp @@ -9,11 +9,8 @@ #include "shambase/unique_name_macro.hpp" -namespace { - int __shamrock_unique_name(test_var) = 0; - int __shamrock_unique_name(test_var) = 0; - int __shamrock_unique_name(test_var) = 0; - int __shamrock_unique_name(test_var) = 0; - int __shamrock_unique_name(test_var) = 0; - int __shamrock_unique_name(test_var) = 0; -} // namespace +static int __shamrock_unique_name(test_var) = 0; +static int __shamrock_unique_name(test_var) = 0; + +static void __shamrock_unique_name(test_func)(){}; +static void __shamrock_unique_name(test_func)(){}; diff --git a/src/tests/shambase/unique_name_macro_test2.cpp b/src/tests/shambase/unique_name_macro_test2.cpp new file mode 100644 index 0000000000..ec1a2f2188 --- /dev/null +++ b/src/tests/shambase/unique_name_macro_test2.cpp @@ -0,0 +1,19 @@ +// -------------------------------------------------------// +// +// SHAMROCK code for hydrodynamics +// Copyright (c) 2021-2026 Timothée David--Cléris +// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1 +// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information +// +// -------------------------------------------------------// + +#include "shambase/unique_name_macro.hpp" + +static int __shamrock_unique_name(test_var) = 0; +static int __shamrock_unique_name(test_var) = 0; + +static void __shamrock_unique_name(test_func)(){}; +static void __shamrock_unique_name(test_func)(){}; + +// This file duplicates the content of unique_name_macro_test.cpp to test that using the same macro +// as the same spot does not provide linker errors From e5968dff84f396b517d304df76c8b23c725a0d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20David--Cl=C3=A9ris?= Date: Thu, 14 May 2026 14:04:48 +0200 Subject: [PATCH 8/8] bla --- src/shambase/include/shambase/call_lambda.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shambase/include/shambase/call_lambda.hpp b/src/shambase/include/shambase/call_lambda.hpp index 42d3d3a0aa..72e7b80d9f 100644 --- a/src/shambase/include/shambase/call_lambda.hpp +++ b/src/shambase/include/shambase/call_lambda.hpp @@ -10,7 +10,7 @@ #pragma once /** - * @file print.hpp + * @file call_lambda.hpp * @author Timothée David--Cléris (tim.shamrock@proton.me) * @brief Call a lambda at static or local scope construction time */