From 05614f8070132bc0a5c0af1d22cc27e63f0abbb5 Mon Sep 17 00:00:00 2001 From: Miles Buechler Date: Wed, 8 Apr 2026 08:52:12 -0600 Subject: [PATCH 01/35] Add a SpinerEosDependsRhoSie constructor that takes an existing eos and an object representing grid parameters --- SPINER_CONSTRUCTOR_PLAN.md | 485 ++++++++++++++++ singularity-eos/eos/eos_spiner_rho_sie.hpp | 630 +++++++++++++++++++++ test/CMakeLists.txt | 1 + test/test_eos_spiner_constructor.cpp | 223 ++++++++ 4 files changed, 1339 insertions(+) create mode 100644 SPINER_CONSTRUCTOR_PLAN.md create mode 100644 test/test_eos_spiner_constructor.cpp diff --git a/SPINER_CONSTRUCTOR_PLAN.md b/SPINER_CONSTRUCTOR_PLAN.md new file mode 100644 index 00000000000..fb221aa710c --- /dev/null +++ b/SPINER_CONSTRUCTOR_PLAN.md @@ -0,0 +1,485 @@ +# Plan: SpinerEOS Constructor from Generic EOS + +## Goal + +Add a new constructor to `SpinerEOSDependsRhoSie` that can create Spiner tables from any EOS object (analytic or otherwise) that provides the necessary thermodynamic methods. This allows users to tabulate any equation of state into the high-performance Spiner format. + +## Overview + +The constructor will: +1. Take a source EOS object (template parameter for flexibility) +2. Take grid parameters (mimicking sesame2spiner options) +3. Evaluate the source EOS on a grid to populate all required Spiner DataBox tables +4. Handle offsets automatically for negative values (especially sie) +5. Compute derivatives (either from source EOS or via finite differences) +6. Create a fully-functional in-memory SpinerEOS object + +**Note on persistence**: The constructed SpinerEOS exists in memory and can be used immediately. While the underlying DataBox objects have `saveHDF()` methods, a convenience method to save the entire SpinerEOS to an HDF5 file in the correct SP5 format would be a useful future enhancement (see Future Enhancements section). + +## New Data Structures + +### SpinerTableGridParams + +Located in: `singularity-eos/eos/eos_spiner_rho_sie.hpp` (or possibly a separate header) + +```cpp +struct SpinerTableGridParams { + // Density bounds + Real rhoMin, rhoMax; + int numRho = -1; // -1 means use numRhoPerDecade + int numRhoPerDecade = 350; // PPD_DEFAULT_RHO from sesame2spiner + Real shrinklRhoBounds = 0.0; // shrink log bounds by fraction + + // Temperature bounds + Real TMin, TMax; + int numT = -1; // -1 means use numTPerDecade + int numTPerDecade = 100; // PPD_DEFAULT_T + Real shrinklTBounds = 0.0; + + // SIE bounds (energy can be negative!) + Real sieMin, sieMax; + int numSie = -1; // -1 means use numSiePerDecade + int numSiePerDecade = 100; + Real shrinkleBounds = 0.0; + + // Offset control (usually automatic, but allow override) + // Set to -1 for auto-compute (default behavior) + Real rhoOffset = -1.0; + Real TOffset = -1.0; + Real sieOffset = -1.0; + + // Enforce positive minimums (like sesame2spiner does for rho/T) + // Set to <= 0 to disable enforcement + Real strictlyPositiveMinRho = 1e-8; // STRICTLY_POS_MIN_RHO + Real strictlyPositiveMinT = 1e-2; // STRICTLY_POS_MIN_T + Real strictlyPositiveMinSie = -1.0; // disabled for sie (can be negative) + + // Material properties + int matid = 0; + Real Abar = std::numeric_limits::signaling_NaN(); + Real Zbar = std::numeric_limits::signaling_NaN(); + Real rhoNormal = std::numeric_limits::signaling_NaN(); + + // Piecewise grid options (advanced - follow sesame2spiner defaults) + bool piecewiseRho = true; + bool piecewiseT = true; + bool piecewiseSie = true; + Real rhoCoarseFactorLo = 3.0; // COARSE_FACTOR_DEFAULT_RHO_LO + Real rhoCoarseFactorHi = 5.0; // COARSE_FACTOR_DEFAULT_RHO_HI + Real TCoarseFactor = 1.5; // COARSE_FACTOR_DEFAULT_T + Real sieCoarseFactor = 1.5; + Real rhoFineDiameterDecades = 1.5; // RHO_FINE_DIAMETER_DEFAULT + Real TSplitPoint = 1e4; // T_SPLIT_POINT_DEFAULT + + // Optional: fine grid bounds override (advanced use) + Real rhoFineMin = -1.0; // -1 means use diameter + Real rhoFineMax = -1.0; +}; +``` + +## Constructor Signature + +```cpp +template