From 3a22792fd127fc5b1f6f4a7715ab28ffbc34c4e3 Mon Sep 17 00:00:00 2001 From: Emily Boudreaux Date: Mon, 20 Apr 2026 12:37:53 -0400 Subject: [PATCH] fix(GridFire): changes based on ref report --- .gitignore | 1 + README.md | 34 +--- build-config/sundials/cvode/meson.build | 3 +- build-config/sundials/kinsol/meson.build | 3 +- .../scratchpads/engine_adaptive_scratchpad.h | 1 + .../engine_multiscale_scratchpad.h | 3 + .../gridfire/io/generative/generative.h | 3 +- src/include/gridfire/io/generative/mesa.h | 17 ++ src/include/gridfire/utils/meson.build | 2 +- src/lib/engine/views/engine_multiscale.cpp | 7 +- src/lib/io/generative/mesa.cpp | 155 ++++++++++++++++++ src/lib/policy/stellar_policy.cpp | 29 +--- src/meson.build | 1 + tests/graphnet_sandbox/main.cpp | 99 +++++++++++ tests/meson.build | 1 + validation/ManuscriptFigures/BBN/run.py | 0 .../Stiffness/estimate_stiffness.py | 0 17 files changed, 291 insertions(+), 68 deletions(-) create mode 100644 tests/graphnet_sandbox/main.cpp create mode 100644 validation/ManuscriptFigures/BBN/run.py create mode 100644 validation/ManuscriptFigures/Stiffness/estimate_stiffness.py diff --git a/.gitignore b/.gitignore index 1151fff2..c3bb36ce 100644 --- a/.gitignore +++ b/.gitignore @@ -132,3 +132,4 @@ meson-boost-test/ cross/python_includes *.whl +*.pdf diff --git a/README.md b/README.md index 10a3faff..833f8561 100644 --- a/README.md +++ b/README.md @@ -152,25 +152,6 @@ the same for the other shared object file (make sure to count the duplicate rpat We also include a script at `pip_install_mac_patch.sh` which will do this automatically for you. ## Automatic Build and Installation -### Script Build and Installation Instructions - -The easiest way to build GridFire is using the `install.sh` or `install-tui.sh` -scripts in the root directory. To use these scripts, simply run: - -```bash -./install.sh -# or -./install-tui.sh -``` -The regular installation script will select a standard "ideal" set of build -options for you. If you want more control over the build options, you can use -the `install-tui.sh` script, which will provide a text-based user interface to -select the build options you want. - -Generally, both are intended to be easy to use and will prompt you -automatically to install any missing dependencies. - - ### Currently, known good platforms The installation script has been tested and found to work on clean installations of the following platforms: @@ -179,11 +160,6 @@ installations of the following platforms: - Ubuntu 25.04 (aarch64) - Ubuntu 22.04 (X86_64) -> **Note:** On Ubuntu 22.04 the user needs to install boost libraries manually -> as the versions in the Ubuntu repositories -> are too old. The installer automatically detects this and will instruct the -> user in how to do this. - ## Manual Build Instructions ### Prerequisites @@ -197,8 +173,6 @@ These only need to be manually installed if the user is not making use of the - CMake 3.20 or newer - ninja 1.10.0 or newer - Python packages: `meson-python>=0.15.0` -- Boost libraries (>= 1.83.0) installed system-wide (or at least findable by - meson with pkg-config) #### Optional - dialog (used by the `install.sh` script, not needed if using pip or meson @@ -206,15 +180,10 @@ These only need to be manually installed if the user is not making use of the - pip (used by the `install.sh` script or by calling pip directly, not needed if using meson directly) -> **Note:** Boost is the only external library dependency used by GridFire directly. - > **Note:** Windows is not supported at this time and *there are no plans to > support it in the future*. Windows users are encouraged to use WSL2 or a > Linux VM. -> **Note:** If `install-tui.sh` is not able to find a usable version of boost -> it will provide directions to fetch, compile, and install a usable version. - ### Install Scripts GridFire ships with an installer (`install.sh`) which is intended to make the process of installation both easier and more repeatable. @@ -447,7 +416,6 @@ likely to be one of adding new `EngineViews`. | View Name | Purpose | Algorithm / Reference | When to Use | |----------------------------------|-----------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------| -| AdaptiveEngineView | Dynamically culls low-flow species and reactions during runtime | Iterative flux thresholding to remove reactions below a flow threshold | Large networks to reduce computational cost | | DefinedEngineView | Restricts the network to a user-specified subset of species and reactions | Static network masking based on user-provided species/reaction lists | Targeted pathway studies or code-to-code comparisons | | FileDefinedEngineView | Load a defined engine view from a file using some parser | Same as DefinedEngineView but loads from a file | Same as DefinedEngineView | | MultiscalePartitioningEngineView | Partitions the network into fast and slow subsets based on reaction timescales | Network partitioning following Hix & Thielemann Silicon Burning I & II (DOI:10.1086/177016,10.1086/306692) | Stiff, multi-scale networks requiring tailored integration | @@ -523,7 +491,7 @@ A `NetOut` struct contains - The total specific energy lost to neutrinos while evolving to `tMax` (`NetOut::total_neutrino_loss`) [erg/g] - The total flux of neutrinos while evolving to `tMax` (`NetOut::total_neutrino_flux`) -### CVODESolverStrategy +### PointSolver We use the CVODE module from [SUNDIALS](https://computing.llnl.gov/projects/sundials/cvode) as our primary numerical solver. Specifically we use the BDF linear multistep method from that which includes advanced adaptive timestepping. diff --git a/build-config/sundials/cvode/meson.build b/build-config/sundials/cvode/meson.build index 90596bf9..6ffb7ad3 100644 --- a/build-config/sundials/cvode/meson.build +++ b/build-config/sundials/cvode/meson.build @@ -8,7 +8,8 @@ cvode_cmake_options.add_cmake_defines({ 'BUILD_STATIC_LIBS' : 'ON', 'EXAMPLES_ENABLE_C' : 'OFF', 'CMAKE_POSITION_INDEPENDENT_CODE': true, - 'CMAKE_PLATFORM_NO_VERSIONED_SONAME': 'ON' + 'CMAKE_PLATFORM_NO_VERSIONED_SONAME': 'ON', + 'SUNDIALS_LOGGING_LEVEL': 1 }) diff --git a/build-config/sundials/kinsol/meson.build b/build-config/sundials/kinsol/meson.build index fd795ef2..0926f1b8 100644 --- a/build-config/sundials/kinsol/meson.build +++ b/build-config/sundials/kinsol/meson.build @@ -9,7 +9,8 @@ kinsol_cmake_options.add_cmake_defines({ 'BUILD_STATIC_LIBS' : 'ON', 'EXAMPLES_ENABLE_C' : 'OFF', 'CMAKE_POSITION_INDEPENDENT_CODE': true, - 'CMAKE_PLATFORM_NO_VERSIONED_SONAME': 'ON' + 'CMAKE_PLATFORM_NO_VERSIONED_SONAME': 'ON', + 'SUNDIALS_LOGGING_LEVEL': 1 }) kinsol_cmake_options.add_cmake_defines({ diff --git a/src/include/gridfire/engine/scratchpads/engine_adaptive_scratchpad.h b/src/include/gridfire/engine/scratchpads/engine_adaptive_scratchpad.h index a9a9317b..2c4cbe81 100644 --- a/src/include/gridfire/engine/scratchpads/engine_adaptive_scratchpad.h +++ b/src/include/gridfire/engine/scratchpads/engine_adaptive_scratchpad.h @@ -70,6 +70,7 @@ struct AdaptiveEngineViewScratchPad final : AbstractScratchPad { /// @brief Flag indicating whether the scratchpad has been initialized. bool has_initialized = false; + /// @brief Vector of species currently active in the adaptive network. std::vector active_species; diff --git a/src/include/gridfire/engine/scratchpads/engine_multiscale_scratchpad.h b/src/include/gridfire/engine/scratchpads/engine_multiscale_scratchpad.h index 6a203d7f..4ebf5956 100644 --- a/src/include/gridfire/engine/scratchpads/engine_multiscale_scratchpad.h +++ b/src/include/gridfire/engine/scratchpads/engine_multiscale_scratchpad.h @@ -103,6 +103,9 @@ struct MultiscalePartitioningEngineViewScratchPad final : AbstractScratchPad { /// @brief Flag indicating whether the scratchpad has been initialized. bool has_initialized = false; + /// @breif User configurable parameter to control flux coupling threshold used + double flux_coupling_threshold = 5.0; + /// @brief Vector of QSE groups representing equilibrium clusters. std::vector qse_groups; diff --git a/src/include/gridfire/io/generative/generative.h b/src/include/gridfire/io/generative/generative.h index 9341af10..0f5e9eb5 100644 --- a/src/include/gridfire/io/generative/generative.h +++ b/src/include/gridfire/io/generative/generative.h @@ -1,3 +1,4 @@ #pragma once -#include "gridfire/io/generative/python.h" \ No newline at end of file +#include "gridfire/io/generative/python.h" +#include "gridfire/io/generative/mesa.h" \ No newline at end of file diff --git a/src/include/gridfire/io/generative/mesa.h b/src/include/gridfire/io/generative/mesa.h index e69de29b..da85fc87 100644 --- a/src/include/gridfire/io/generative/mesa.h +++ b/src/include/gridfire/io/generative/mesa.h @@ -0,0 +1,17 @@ +#pragma once +#include "fourdst/atomic/atomicSpecies.h" +#include "gridfire/reaction/reaction.h" +#include "gridfire/engine/engine_abstract.h" + +#include + +namespace gridfire::io::generative { + std::string get_mesa_iso_name(const fourdst::atomic::Species& species); + + bool is_proton(const fourdst::atomic::Species& species); + bool is_alpha(const fourdst::atomic::Species& species); + bool is_neutron(const fourdst::atomic::Species& species); + + std::string get_mesa_reaction_name(const reaction::Reaction& reaction); + std::string export_engine_to_mesa_net(const engine::DynamicEngine& engine, engine::scratch::StateBlob& ctx, bool skip_weak); +} diff --git a/src/include/gridfire/utils/meson.build b/src/include/gridfire/utils/meson.build index a3a75de7..f013464e 100644 --- a/src/include/gridfire/utils/meson.build +++ b/src/include/gridfire/utils/meson.build @@ -37,5 +37,5 @@ configure_file( output : 'config.h', configuration : conf_data, install : do_install_version_file, - install_dir : get_option('includedir') / '/gridfire/utils' + install_dir : get_option('includedir') / 'gridfire/utils' ) \ No newline at end of file diff --git a/src/lib/engine/views/engine_multiscale.cpp b/src/lib/engine/views/engine_multiscale.cpp index 80499101..bffbc382 100644 --- a/src/lib/engine/views/engine_multiscale.cpp +++ b/src/lib/engine/views/engine_multiscale.cpp @@ -1337,7 +1337,8 @@ namespace gridfire::engine { const double rho, const QSEGroup &group ) const { - constexpr double FLUX_RATIO_THRESHOLD = 5; + auto* state = scratch::get_state(ctx); + double FLUX_RATIO_THRESHOLD = state->flux_coupling_threshold; const std::unordered_set algebraic_group_members( group.algebraic_species.begin(), @@ -1484,8 +1485,8 @@ namespace gridfire::engine { const double diff_total = std::abs(total_prod - total_dest); bool total_balanced = (mean_total > 0) && ((diff_total / mean_total) < 0.05); - // Check 2: Charged-Particle Balance (The "Neutron-Exclusion" Check) - // Only valid if there IS charged flow (avoid 0/0 success) + // Check 2: Charged-Particle Balance + // Only valid if there IS charged flow const double mean_charged = (charged_prod + charged_dest) / 2.0; const double diff_charged = std::abs(charged_prod - charged_dest); bool charged_balanced = (mean_charged > 0) && ((diff_charged / mean_charged) < 0.05); diff --git a/src/lib/io/generative/mesa.cpp b/src/lib/io/generative/mesa.cpp index e69de29b..81754a9d 100644 --- a/src/lib/io/generative/mesa.cpp +++ b/src/lib/io/generative/mesa.cpp @@ -0,0 +1,155 @@ +#include "gridfire/io/generative/mesa.h" + +#include "gridfire/engine/engine_abstract.h" +#include "gridfire/reaction/reaction.h" +#include "fourdst/atomic/atomicSpecies.h" +#include "gridfire/utils/config.h" + +#include +#include +#include +#include +#include +#include + +namespace gridfire::io::generative { + std::string get_mesa_iso_name(const fourdst::atomic::Species& species) { + auto name = std::string(species.name()); + std::ranges::transform(name, name.begin(), ::tolower); + + name.erase(std::ranges::remove(name, '-').begin(), name.end()); + + if (name == "p") return "h1"; + if (name == "n" || name == "n1") return "neut"; + if (name == "d") return "h2"; + if (name == "t") return "h3"; + if (name == "a") return "he4"; + + return name; + } + + bool is_proton(const fourdst::atomic::Species& s) { return get_mesa_iso_name(s) == "h1"; } + bool is_alpha(const fourdst::atomic::Species& s) { return get_mesa_iso_name(s) == "he4"; } + bool is_neutron(const fourdst::atomic::Species& s) { return get_mesa_iso_name(s) == "neut"; } + + + std::string get_mesa_reaction_name(const reaction::Reaction& reaction) { + std::vector react_sorted = reaction.reactants(); + std::vector prod_sorted = reaction.products(); + + auto sort_species = [](std::vector& list) { + std::ranges::sort(list, [](const auto& a, const auto& b) { + if (a.z() != b.z()) return a.z() < b.z(); + return a.a() < b.a(); + }); + }; + + sort_species(react_sorted); + sort_species(prod_sorted); + + if (react_sorted.size() == 1 && prod_sorted.size() == 1) { + if (reaction.type() == reaction::ReactionType::WEAK || + reaction.type() == reaction::ReactionType::REACLIB_WEAK || + reaction.type() == reaction::ReactionType::LOGICAL_REACLIB_WEAK) { + return "r_" + get_mesa_iso_name(react_sorted[0]) + "_wk_" + get_mesa_iso_name(prod_sorted[0]); + } + } + + if (react_sorted.size() == 2 && prod_sorted.size() == 1) { + std::string x, cap; + if (is_proton(react_sorted[0]) || is_proton(react_sorted[1])) { + cap = "pg"; + x = is_proton(react_sorted[0]) ? get_mesa_iso_name(react_sorted[1]) : get_mesa_iso_name(react_sorted[0]); + } + else if (is_alpha(react_sorted[0]) || is_alpha(react_sorted[1])) { + cap = "ag"; + x = is_alpha(react_sorted[0]) ? get_mesa_iso_name(react_sorted[1]) : get_mesa_iso_name(react_sorted[0]); + } + else if (is_neutron(react_sorted[0]) || is_neutron(react_sorted[1])) { + cap = "ng"; + x = is_neutron(react_sorted[0]) ? get_mesa_iso_name(react_sorted[1]) : get_mesa_iso_name(react_sorted[0]); + } + + if (!cap.empty()) return "r_" + x + "_" + cap + "_" + get_mesa_iso_name(prod_sorted[0]); + } + + if (react_sorted.size() == 1 && prod_sorted.size() == 2) { + std::string x, em; + if (is_proton(prod_sorted[0]) || is_proton(prod_sorted[1])) { + em = "gp"; + x = is_proton(prod_sorted[0]) ? get_mesa_iso_name(prod_sorted[1]) : get_mesa_iso_name(prod_sorted[0]); + } + else if (is_alpha(prod_sorted[0]) || is_alpha(prod_sorted[1])) { + em = "ga"; + x = is_alpha(prod_sorted[0]) ? get_mesa_iso_name(prod_sorted[1]) : get_mesa_iso_name(prod_sorted[0]); + } + else if (is_neutron(prod_sorted[0]) || is_neutron(prod_sorted[1])) { + em = "gn"; + x = is_neutron(prod_sorted[0]) ? get_mesa_iso_name(prod_sorted[1]) : get_mesa_iso_name(prod_sorted[0]); + } + + if (!em.empty()) return "r_" + get_mesa_iso_name(react_sorted[0]) + "_" + em + "_" + x; + } + + if (react_sorted.size() == 2 && prod_sorted.size() == 2) { + int r_p = -1, r_a = -1, r_n = -1; + int p_p = -1, p_a = -1, p_n = -1; + + for(int i=0; i<2; ++i) { + if(is_proton(react_sorted[i])) r_p = i; + if(is_alpha(react_sorted[i])) r_a = i; + if(is_neutron(react_sorted[i])) r_n = i; + + if(is_proton(prod_sorted[i])) p_p = i; + if(is_alpha(prod_sorted[i])) p_a = i; + if(is_neutron(prod_sorted[i])) p_n = i; + } + + std::string x, y, exc; + if (r_a != -1 && p_p != -1) { exc = "ap"; x = get_mesa_iso_name(react_sorted[1-r_a]); y = get_mesa_iso_name(prod_sorted[1-p_p]); } + else if (r_p != -1 && p_a != -1) { exc = "pa"; x = get_mesa_iso_name(react_sorted[1-r_p]); y = get_mesa_iso_name(prod_sorted[1-p_a]); } + else if (r_n != -1 && p_p != -1) { exc = "np"; x = get_mesa_iso_name(react_sorted[1-r_n]); y = get_mesa_iso_name(prod_sorted[1-p_p]); } + else if (r_p != -1 && p_n != -1) { exc = "pn"; x = get_mesa_iso_name(react_sorted[1-r_p]); y = get_mesa_iso_name(prod_sorted[1-p_n]); } + else if (r_n != -1 && p_a != -1) { exc = "na"; x = get_mesa_iso_name(react_sorted[1-r_n]); y = get_mesa_iso_name(prod_sorted[1-p_a]); } + else if (r_a != -1 && p_n != -1) { exc = "an"; x = get_mesa_iso_name(react_sorted[1-r_a]); y = get_mesa_iso_name(prod_sorted[1-p_n]); } + + if (!exc.empty()) return "r_" + x + "_" + exc + "_" + y; + } + + std::string fallback = "r"; + for (const auto& s : react_sorted) fallback += "_" + get_mesa_iso_name(s); + fallback += "_to"; + for (const auto& s : prod_sorted) fallback += "_" + get_mesa_iso_name(s); + + return fallback; + } + + std::string export_engine_to_mesa_net(const engine::DynamicEngine& engine, engine::scratch::StateBlob& ctx, bool skip_weak) { + std::stringstream ss; + ss << "! Auto-generated MESA .net file from GridFire\n"; + ss << "! Generated by GridFire version: " << version().toString() << "\n"; + ss << "! Generated on " << std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()) << "\n\n"; + + ss << "add_isos(\n"; + for (const auto& species : engine.getNetworkSpecies(ctx)) { + ss << " " << get_mesa_iso_name(species) << "\n"; + } + ss << ")\n\n"; + + ss << "add_reactions(\n"; + const auto& reactions = engine.getNetworkReactions(ctx); + + for (const auto& reaction_ptr : reactions) { + if (skip_weak && (reaction_ptr->type() == reaction::ReactionType::WEAK || + reaction_ptr->type() == reaction::ReactionType::REACLIB_WEAK || + reaction_ptr->type() == reaction::ReactionType::LOGICAL_REACLIB_WEAK)) { + continue; + } + ss << " " << get_mesa_reaction_name(*reaction_ptr) << "\n"; + } + ss << ")\n"; + + return ss.str(); + } + +} diff --git a/src/lib/policy/stellar_policy.cpp b/src/lib/policy/stellar_policy.cpp index 56dbeec5..c7400ce9 100644 --- a/src/lib/policy/stellar_policy.cpp +++ b/src/lib/policy/stellar_policy.cpp @@ -61,14 +61,7 @@ namespace gridfire::policy { std::make_unique(m_initializing_composition, *m_partition_function, engine::NetworkBuildDepth::ThirdOrder, engine::NetworkConstructionFlags::DEFAULT) ); - m_network_stack.emplace_back( - std::make_unique(*m_network_stack.back().get()) - ); - m_network_stack.emplace_back( - std::make_unique(*m_network_stack.back().get()) - ); - - std::unique_ptr scratch_blob = get_stack_scratch_blob(); + std::unique_ptr scratch_blob = m_network_stack.back()->constructStateBlob(nullptr); m_status = NetworkPolicyStatus::INITIALIZED_UNVERIFIED; m_status = check_status(*scratch_blob); @@ -110,8 +103,6 @@ namespace gridfire::policy { std::vector MainSequencePolicy::get_engine_types_stack() const { return { engine::EngineTypes::GRAPH_ENGINE, - engine::EngineTypes::MULTISCALE_PARTITIONING_ENGINE_VIEW, - engine::EngineTypes::ADAPTIVE_ENGINE_VIEW }; } @@ -125,32 +116,14 @@ namespace gridfire::policy { } auto blob = std::make_unique(); blob->enroll(); - blob->enroll(); - blob->enroll(); - const engine::GraphEngine* graph_engine = dynamic_cast(m_network_stack.front().get()); if (!graph_engine) { throw exceptions::PolicyError("Cannot get stack scratch blob from MainSequencePolicy: The base engine is not a GraphEngine. This indicates a serious internal inconsistency and should be reported to the GridFire developers, thank you."); } - const engine::MultiscalePartitioningEngineView* multiscale_engine = dynamic_cast(m_network_stack[1].get()); - if (!multiscale_engine) { - throw exceptions::PolicyError("Cannot get stack scratch blob from MainSequencePolicy: The middle engine is not a MultiscalePartitioningEngineView. This indicates a serious internal inconsistency and should be reported to the GridFire developers, thank you."); - } - - const engine::AdaptiveEngineView* adaptive_engine = dynamic_cast(m_network_stack.back().get()); - if (!adaptive_engine) { - throw exceptions::PolicyError("Cannot get stack scratch blob from MainSequencePolicy: The top engine is not an AdaptiveEngineView. This indicates a serious internal inconsistency and should be reported to the GridFire developers, thank you."); - } - - auto* graph_engine_state = engine::scratch::get_state(*blob); graph_engine_state->initialize(*graph_engine); - auto* multiscale_engine_state = engine::scratch::get_state(*blob); - multiscale_engine_state->initialize(); - auto* adaptive_engine_state = engine::scratch::get_state(*blob); - adaptive_engine_state->initialize(*adaptive_engine); return blob; } diff --git a/src/meson.build b/src/meson.build index 2e8cc35d..0f4439c4 100644 --- a/src/meson.build +++ b/src/meson.build @@ -17,6 +17,7 @@ gridfire_sources = files( 'lib/reaction/weak/weak_interpolator.cpp', 'lib/io/network_file.cpp', 'lib/io/generative/python.cpp', + 'lib/io/generative/mesa.cpp', 'lib/solver/strategies/PointSolver.cpp', 'lib/solver/strategies/GridSolver.cpp', 'lib/solver/strategies/triggers/engine_partitioning_trigger.cpp', diff --git a/tests/graphnet_sandbox/main.cpp b/tests/graphnet_sandbox/main.cpp new file mode 100644 index 00000000..ade7d44b --- /dev/null +++ b/tests/graphnet_sandbox/main.cpp @@ -0,0 +1,99 @@ +// ReSharper disable CppUnusedIncludeDirective +#include +#include +#include +#include +#include + +#include // Required for parallel_setup + +#include "fourdst/logging/logging.h" +#include "fourdst/atomic/species.h" +#include "fourdst/composition/utils.h" + +#include "quill/Logger.h" +#include "quill/Backend.h" +#include "CLI/CLI.hpp" + +#include + +#include "gridfire/gridfire.h" +#include "fourdst/composition/composition.h" +#include "gridfire/utils/gf_omp.h" + +#include +#include +#include + + +static std::terminate_handler g_previousHandler = nullptr; +void quill_terminate_handler(); + +gridfire::NetIn init(const double temp, const double rho, const double tMax) { + std::setlocale(LC_ALL, ""); + g_previousHandler = std::set_terminate(quill_terminate_handler); + quill::Logger* logger = fourdst::logging::LogManager::getInstance().getLogger("log"); + logger->set_log_level(quill::LogLevel::Info); + + using namespace gridfire; + const std::vector X = {0.7081145999999999, 2.94e-5, 0.276, 0.003, 0.0011, 9.62e-3, 1.62e-3, 5.16e-4}; + const std::vector symbols = {"H-1", "He-3", "He-4", "C-12", "N-14", "O-16", "Ne-20", "Mg-24"}; + + + const fourdst::composition::Composition composition = fourdst::composition::buildCompositionFromMassFractions(symbols, X); + + NetIn netIn; + netIn.composition = composition; + netIn.temperature = temp; + netIn.density = rho; + netIn.energy = 0; + + netIn.tMax = tMax; + netIn.dt0 = 1e-12; + + return netIn; +} + + +void quill_terminate_handler() +{ + quill::Backend::stop(); + if (g_previousHandler) + g_previousHandler(); + else + std::abort(); +} + +int main(int argc, char* argv[]) { + using namespace gridfire; + + double temp = 1.5e7; + double rho = 1.6e2; + double tMax = 3e17; + double coupling_ratio = 5.0; + std::string output_filename = "coupling.dat"; + + CLI::App app("GridFire Test Coupling"); + app.add_option("--temperature", temp, "Temperature in degrees")->default_val(std::format("{:5.2E}", temp)); + app.add_option("--density", rho, "Density in Kg")->default_val(std::format("{:5.2E}", rho)); + app.add_option("--tmax", tMax, "Maximum time in seconds")->default_val(std::format("{:5.2E}", tMax)); + app.add_option("--coupling_ratio", coupling_ratio, "Coupling ratio for multiscale partitioning")->default_val(std::format("{:.2f}", coupling_ratio)); + app.add_option("--output", output_filename, "Output filename for intermediate results")->default_val("coupling.dat"); + + CLI11_PARSE(app, argc, argv); + + const NetIn netIn = init(temp, rho, tMax); + + auto base_engine = std::make_unique(netIn.composition, 3); + auto base_blob = base_engine->constructStateBlob(); + auto qse_engine = std::make_unique(*base_engine); + auto blob = qse_engine->constructStateBlob(base_blob.get()); + + auto* state = engine::scratch::get_state(*blob); + + const solver::PointSolver localSolver(*base_engine); + solver::PointSolverContext solverCtx(*base_blob); + + auto result = localSolver.evaluate(solverCtx, netIn, false, false); + +} \ No newline at end of file diff --git a/tests/meson.build b/tests/meson.build index 5f17b7ab..5fac0d4b 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -5,4 +5,5 @@ # Subdirectories for unit and integration tests subdir('graphnet_sandbox') +subdir('flux_coupling') subdir('extern') diff --git a/validation/ManuscriptFigures/BBN/run.py b/validation/ManuscriptFigures/BBN/run.py new file mode 100644 index 00000000..e69de29b diff --git a/validation/ManuscriptFigures/Stiffness/estimate_stiffness.py b/validation/ManuscriptFigures/Stiffness/estimate_stiffness.py new file mode 100644 index 00000000..e69de29b