Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
6829cde
Add mass fraction table to sesame2spiner
adamdempsey90 Jan 12, 2026
909776e
Add table existence check to eospac_wrapper. Return a bool from eosMa…
adamdempsey90 Jan 15, 2026
a8a9804
Move getting of phase names and number of phases to eospac_wrapper an…
adamdempsey90 Jan 15, 2026
698b245
Merge remote-tracking branch 'origin/main' into dempsey/mass_frac
adamdempsey90 Feb 11, 2026
1fddda8
Merge remote-tracking branch 'origin/main' into dempsey/mass_frac # P…
adamdempsey90 Feb 23, 2026
afdb537
safe hdf5 string read
adamdempsey90 Feb 24, 2026
5672fc8
Add MassFractionsFromDensity* to spiner eos
adamdempsey90 Feb 24, 2026
1da4ba3
Add multiphase spiner unit test for tin
adamdempsey90 Feb 24, 2026
82fd328
void function
adamdempsey90 Feb 24, 2026
d150684
Format
adamdempsey90 Feb 24, 2026
dabb27b
semicolon after fence;
adamdempsey90 Feb 25, 2026
7dd80e6
remove unused
adamdempsey90 Feb 25, 2026
73f8eed
Properly use host/device eos
adamdempsey90 Feb 25, 2026
ef919f7
Add some todos
adamdempsey90 Feb 26, 2026
c028f7b
h5_safe_read_string -> h5_safe_read_attr_string
adamdempsey90 Feb 26, 2026
50d4d7f
Support Lambdas in the mass fractions
adamdempsey90 Mar 1, 2026
4736b26
modify lambda mass fractions to work with indexable types. Required e…
jonahm-LANL Mar 2, 2026
6cf5c20
docs
jonahm-LANL Mar 2, 2026
9ba04d0
bya -> by a
jonahm-LANL Mar 2, 2026
c20334d
phase_names is not an allocated string. Treated in same way as DataBo…
adamdempsey90 Mar 2, 2026
53ea472
merge
jonahm-LANL Mar 2, 2026
ad8b160
return the allocated string and use malloc/free
adamdempsey90 Mar 2, 2026
714abf2
Oops
adamdempsey90 Mar 2, 2026
83aa198
Make sure to always return something
adamdempsey90 Mar 2, 2026
f2b1874
fix test and add portable inline function declaration
jonahm-LANL Mar 2, 2026
6e4f995
Merge branch 'dempsey/mass_frac' into jmm/mass_frac
Yurlungur Mar 2, 2026
f92fe3a
come on... stupid namespace alias
jonahm-LANL Mar 2, 2026
afaff0e
Merge branch 'jmm/mass_frac' of github.com:lanl/singularity-eos into …
jonahm-LANL Mar 2, 2026
0f61964
oops . -> ::
jonahm-LANL Mar 3, 2026
9cf0494
debug
jonahm-LANL Mar 3, 2026
7f39303
oops ordering
jonahm-LANL Mar 3, 2026
81d068c
more debugging
jonahm-LANL Mar 3, 2026
dd9f46d
wrong function...
jonahm-LANL Mar 3, 2026
dc38448
OOH its the other test
jonahm-LANL Mar 3, 2026
46011d7
merge main
jonahm-LANL Mar 3, 2026
fb8b915
Merge remote-tracking branch 'origin/main' into dempsey/mass_frac
adamdempsey90 Mar 3, 2026
c7787dd
Create sesameFilesDirs.txt before running sesame2spiner
adamdempsey90 Mar 3, 2026
0101203
Merge remote-tracking branch 'origin/dempsey/mass_frac' into jmm/mass…
adamdempsey90 Mar 3, 2026
6a5fdda
Changelog for mass fractions
adamdempsey90 Mar 3, 2026
518b10f
Merge pull request #606 from lanl/jmm/mass_frac
Yurlungur Mar 3, 2026
75b49e1
format
adamdempsey90 Mar 4, 2026
3b5bc93
Merge remote-tracking branch 'origin/main' into dempsey/mass_frac
adamdempsey90 Mar 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .kessel/workflows/cmake.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def test(self, args):
self.exec(f"""
pushd {self.build_dir}
if [[ -f sesame2spiner/sesame2spiner ]]; then
echo "/usr/projects/data/eos/eos-developmental/Sn2162/v01/sn2162-v01.bin" > sesameFilesDir.txt
sesame2spiner/sesame2spiner -s materials.sp5 ../sesame2spiner/examples/unit_tests/*.dat
sesame2spiner/sesame2spiner -s duplicates.sp5 ../sesame2spiner/examples/duplicate-test/*.dat
fi
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Current develop

### Added (new features/APIs/variables/...)
- [[PR600]](https://github.com/lanl/singularity-eos/pull/600) Added mass fractions for multiphase tables to sesame2spiner and added MassFractionsFromDensityTemperture/InternalEnergy to the SpinerDependsRhoSIE and SpinerDependsRhoT equations of state.
- [[PR589]](https://github.com/lanl/singularity-eos/pull/589) InternalEnergyFromDensityPressure

### Fixed (Repair bugs, etc)
Expand Down
33 changes: 33 additions & 0 deletions doc/sphinx/src/models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1720,6 +1720,39 @@ constructor for ``SpinerEOSDependsRhoSie`` is identical.
``SpinerEOS`` model does **not** support the
``MeanAtomicProperties`` struct.

Additionally Spiner EOS models support mass fraction lookups of the form

.. code-block:: cpp

template <typename Indexer_t>
PORTABLE_INLINE_FUNCTION
void SpinerEOSDependsRhoT::MassFractionsFromDensityTemperature(
const Real rho, const Real temp, Real *mass_fracs, Indexer_t &&lambda) const;

template <typename Indexer_t>
PORTABLE_INLINE_FUNCTION void
SpinerEOSDependsRhoT::MassFractionsFromDensityInternalEnergy(
const Real rho, const Real sie, Real *mass_fracs, Indexer_t &&lambda) const;

which sets the members of the ``*mass_fracs`` array the mass fractions of multiple phases as a function of density and either temperature or internal energy in a table if they are available. If they are not available, the ``mass_fracs`` array is assumed to be of at least length 1 and is set to unity. Alternatively, the functions

.. code-block:: cpp

template <typename Indexer_t>
PORTABLE_INLINE_FUNCTION
void SpinerEOSDependsRhoT::MassFractionsFromDensityTemperature(
const Real rho, const Real temp, Indexer_t &&lambda) const;

template <typename Indexer_t>
PORTABLE_INLINE_FUNCTION
void SpinerEOSDependsRhoT::MassFractionsFromDensityInternalEnergy(
const Real rho, const Real sie, Indexer_t &&lambda) const;

assume the mass fractions array is contained in the lambda indexer and
set them accordingly. They are assumed to be indexable via the
``MassFractions`` indexable type, discussed above, or to be appended
at the end of the lambda after ``nlambda()`` elements.

``sp5`` files and ``sesame2spiner``
`````````````````````````````````````

Expand Down
85 changes: 81 additions & 4 deletions doc/sphinx/src/using-eos.rst
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,29 @@ The available types currently supported by default are:
struct singularity::IndexableTypes::MeanAtomicNumber;
struct singularity::IndexableTypes::ElectronFraction;

However if you are not limited to these types. Any type will do and
Additionally, indexable types may be "vector" quantities. The type

.. code-block:: cpp

struct singularity::IndexableTypes::MassFractions;

must be constructed with an index, e.g.,

.. code-block:: cpp

eos.MassFractionsFromDensityTemperature(rho, T, lambda);
x0 = lambda[MassFractions(0)];

and the default constructor is not supported. Finally, the structs

.. code-block:: cpp

struct singularity::RootStatus;
struct singularity::TableStatus;

are mostly used for internal/debugging purposes.

However you are not limited to these types. Any type will do and
you can define your own as you like. For example:

.. code-block::
Expand Down Expand Up @@ -736,17 +758,48 @@ which might be used as

where ``MeanIonizationState`` is shorthand for index 2, since you
defined that overload. Note that the ``operator[]`` must be marked
``const``. To more easily enable mixing and matching integer-based
``const``. "Vectorized" types such as ``MassFractions`` are expected
to expose a public member field named ``n``, which can be utilized by a
custom indexer class. For example:

.. code-block:: cpp

class MyLambda_t {
public:
constexpr static bool is_type_indexable = true;
MyLambda_t() = default;
PORTABLE_FORCEINLINE_FUNCTION
Real &operator[](const MeanIonizationState &zbar) const {
return data_[0];
}
// x.n used as on offset within the underlying container
PORTABLE_FORCEINLINE_FUNCTION
Real &operator[](const MassFractions &x) const {
return data_[1 + x.n];
}
private:
std::array<Real, 3> data_;
};

To more easily enable mixing and matching integer-based
indexing with type-based indexing, the functions

.. code-block:: cpp

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
bool SafeGet(Indexer_t const &lambda, const T &t, std::size_t const idx, Real &out);

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
bool SafeGet(Indexer_t const &lambda, std::size_t const idx, Real &out);

.. code-block:: cpp

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
bool SafeGet(Indexer_t const &lambda, const T &t, Real &out);

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
bool SafeGet(Indexer_t const &lambda, Real &out);
Expand All @@ -755,13 +808,21 @@ indexing with type-based indexing, the functions

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
Real SafeMustGet(Indexer_t const &lambda, std::size_t const idx)
Real SafeMustGet(Indexer_t const &lambda, const T &t, std::size_t const idx);

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
Real SafeMustGet(Indexer_t const &lambda, std::size_t const idx);

.. code-block:: cpp

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
Real SafeMustGet(Indexer_t const &lambda)
Real SafeMustGet(Indexer_t const &lambda, const T &t);

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
Real SafeMustGet(Indexer_t const &lambda);

will update the value of ``out`` with the value at either the appropriate
type-based index, ``T``, or the numerical index, ``idx``, if the ``Indexer_t``
Expand All @@ -788,24 +849,40 @@ Similarly, the functions

.. code-block:: cpp

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
inline bool SafeSet(Indexer_t &lambda, const T &t, std::size_t const idx, Real const in);

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
inline bool SafeSet(Indexer_t &lambda, std::size_t const idx, Real const in);

.. code-block:: cpp

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
inline bool SafeSet(Indexer_t &lambda, const T &t, Real const in)

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
inline bool SafeSet(Indexer_t &lambda, Real const in)

.. code-block:: cpp

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
inline bool SafeMustSet(Indexer_t &lambda, const T &t, std::size_t const idx, Real const in);

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
inline bool SafeMustSet(Indexer_t &lambda, std::size_t const idx, Real const in);

.. code-block:: cpp

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
inline bool SafeMustSet(Indexer_t &lambda, const T &t, Real const in)

template <typename T, typename Indexer_t>
PORTABLE_FORCEINLINE_FUNCTION
inline bool SafeMustSet(Indexer_t &lambda, Real const in)
Expand Down
33 changes: 33 additions & 0 deletions eospac-wrapper/eospac_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,14 @@ void eosSafeTableCmnts(EOS_INTEGER *table, EOS_CHAR *comments, Verbosity eospacW
eosCheckError(errorCode, "eos_GetTableCmnts", eospacWarn);
}

void eosSafeTableMetaData(EOS_INTEGER *table, EOS_INTEGER infoItem, EOS_CHAR *infoString,
Verbosity eospacWarn) {
EOS_INTEGER errorCode = EOS_OK;
EOS_INTEGER infoTypes[1] = {infoItem};
eos_GetTableMetaData(table, infoTypes, infoString, &errorCode);
eosCheckError(errorCode, "eos_GetTableMetaData", eospacWarn);
}

void eosCheckError(EOS_INTEGER errorCode, const std::string &name, Verbosity eospacWarn) {
EOS_CHAR errorMessage[EOS_MaxErrMsgLen];
if (errorCode != EOS_OK && eospacWarn != Verbosity::Quiet) {
Expand All @@ -343,6 +351,31 @@ void eosCheckError(EOS_INTEGER errorCode, const std::string &name, Verbosity eos
}
}

int eosCheckTableExistence(EOS_INTEGER tableType_, int matid_, Verbosity eospacWarn) {
// Note this opens and closes the table
int exists = 1;
int NT = 1;
EOS_INTEGER matid[1] = {matid_};
EOS_INTEGER tableType[1] = {tableType_};
EOS_INTEGER tableHandle[1];
EOS_INTEGER errorCode = EOS_OK;

eos_CreateTables(&NT, tableType, matid, tableHandle, &errorCode);
eosCheckError(errorCode, "eos_CreateTables", eospacWarn);
eos_LoadTables(&NT, &tableHandle[0], &errorCode);
if (errorCode != EOS_OK) {
if (eosErrorCodesEqual(EOS_NO_DATA_TABLE, errorCode)) {
exists = 0;
} else {
// something else happended
eosCheckError(errorCode, "eos_LoadTables", eospacWarn);
exists = -1;
}
}
eosSafeDestroy(NT, tableHandle, eospacWarn);
return exists;
}

std::string eosErrorString(EOS_INTEGER errorCode) {
// Algorithmicallly generated by parsing the EOSPAC docs
// I'm sorry. It's gross. ~JMM
Expand Down
5 changes: 3 additions & 2 deletions eospac-wrapper/eospac_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,14 @@ void eosSafeTableInfo(EOS_INTEGER *table, EOS_INTEGER numInfoItems,
EOS_INTEGER infoItems[], EOS_REAL infoVals[], Verbosity eospacWarn);

void eosSafeTableCmnts(EOS_INTEGER *table, EOS_CHAR *comments, Verbosity eospacWarn);

void eosSafeTableMetaData(EOS_INTEGER *table, EOS_INTEGER infoItem, EOS_CHAR *infoString,
Verbosity eospacWarn);
void eosCheckError(EOS_INTEGER errorCode, const std::string &name, Verbosity eospacWarn);
std::string eosErrorString(EOS_INTEGER errorCode);
void eosSafeDestroy(int ntables, EOS_INTEGER tableHandles[], Verbosity eospacWarn);
std::string getName(std::string comment);
bool eosErrorCodesEqual(EOS_INTEGER lhs, EOS_INTEGER rhs);

int eosCheckTableExistence(EOS_INTEGER tableType_, int matid_, Verbosity eospacWarn);
} // namespace EospacWrapper

#endif // _EOSPAC_WRAPPER_EOSPAC_WRAPPER_HPP_
18 changes: 18 additions & 0 deletions sesame2spiner/examples/unit_tests/tin.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# ======================================================================
# Example input deck for sesame2spiner,
# a tool for converting eospac to spiner
# © 2026. Triad National Security, LLC. All rights reserved. This
# program was produced under U.S. Government contract 89233218CNA000001
# for Los Alamos National Laboratory (LANL), which is operated by Triad
# National Security, LLC for the U.S. Department of Energy/National
# Nuclear Security Administration. All rights in the program are
# reserved by Triad National Security, LLC, and the U.S. Department of
# Energy/National Nuclear Security Administration. The Government is
# granted for itself and others acting on its behalf a nonexclusive,
# paid-up, irrevocable worldwide license in this material to reproduce,
# prepare derivative works, distribute copies to the public, perform
# publicly and display publicly, and to permit others to do so.
# ======================================================================

matid=2162
name=tin
21 changes: 20 additions & 1 deletion sesame2spiner/generate_files.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ herr_t saveMaterial(hid_t loc, const SesameMetadata &metadata, const Bounds &lRh
std::string sMatid = std::to_string(matid);

herr_t status = 0;
hid_t matGroup, lTGroup, leGroup, coldGroup;
hid_t matGroup, lTGroup, leGroup, coldGroup, mfGroup;

matGroup = H5Gcreate(loc, sMatid.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
status += H5Lcreate_soft(sMatid.c_str(), loc, name.c_str(), H5P_DEFAULT, H5P_DEFAULT);
Expand Down Expand Up @@ -116,6 +116,25 @@ herr_t saveMaterial(hid_t loc, const SesameMetadata &metadata, const Bounds &lRh
// status += transitionMask.saveHDF(coldGroup, SP5::Fields::transitionMask);
}

{
DataBox mf, mask;
Bounds nphBounds;
std::string phase_names;

if (eosMassFraction(matid, lRhoBounds, lTBounds, nphBounds, mf, mask, phase_names,
eospacWarn)) {
mfGroup = H5Gcreate(matGroup, SP5::Depends::massFrac, H5P_DEFAULT, H5P_DEFAULT,
H5P_DEFAULT);

status += mf.saveHDF(mfGroup, SP5::Fields::massFrac);
const int numphases = mf.dim(1);
status += H5LTset_attribute_int(mfGroup, ".", "numphases", &numphases, 1);
status +=
H5LTset_attribute_string(mfGroup, ".", "phase names", phase_names.c_str());
status += H5Gclose(mfGroup);
}
}

if (addSubtables) {
int i = 0;
std::vector<TableSplit> splits = {TableSplit::ElectronOnly, TableSplit::IonCold};
Expand Down
Loading