From 2b258e403a3d452fbdd324f899f2faa37eb870d1 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 10 Dec 2024 19:50:26 -0700 Subject: [PATCH 01/39] ideal gas electron EOS implemented. Still need to add zsplit and documentation --- CMakeLists.txt | 4 + singularity-eos/CMakeLists.txt | 1 + singularity-eos/eos/eos_electrons.hpp | 262 ++++++++++++++++++++++++++ singularity-eos/eos/eos_models.hpp | 1 + test/test_eos_ideal.cpp | 39 +++- 5 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 singularity-eos/eos/eos_electrons.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ab5d62bd02..6429fc358f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -560,6 +560,10 @@ target_compile_options( -use_fast_math > # release > # cuda + + # Suppresses annoying ABI notes. See: + # https://stackoverflow.com/questions/52020305/what-exactly-does-gccs-wpsabi-option-do-what-are-the-implications-of-supressi + $<$:-Wno-psabi> ) if (SINGULARITY_STRICT_WARNINGS) target_compile_options(singularity-eos_Interface INTERFACE diff --git a/singularity-eos/CMakeLists.txt b/singularity-eos/CMakeLists.txt index 4f0c5e3220..f800a90cf3 100644 --- a/singularity-eos/CMakeLists.txt +++ b/singularity-eos/CMakeLists.txt @@ -64,6 +64,7 @@ register_headers( eos/singularity_eos_init_utils.hpp eos/variant_utils.hpp eos/eos_carnahan_starling.hpp + eos/eos_electrons.hpp ) if (SINGULARITY_BUILD_CLOSURE) diff --git a/singularity-eos/eos/eos_electrons.hpp b/singularity-eos/eos/eos_electrons.hpp new file mode 100644 index 0000000000..0e667509d6 --- /dev/null +++ b/singularity-eos/eos/eos_electrons.hpp @@ -0,0 +1,262 @@ +//------------------------------------------------------------------------------ +// © 2024. 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. +//------------------------------------------------------------------------------ + +#ifndef _SINGULARITY_EOS_EOS_ELECTRONS +#define _SINGULARITY_EOS_EOS_ELECTRONS + +#include + +// Ports-of-call +#include +#include + +// Base stuff +#include +#include +#include + +namespace singularity { +using namespace eos_base; + +/* + An ideal gas class designed specifically for electrons in a 3T + framework. The overall structure of the EOS is still identical to an + ideal gas: + + P = (gamma - 1) rho_i sie + sie = Cv T + + but with some caviats. + 1. gamma = 5./3. as for a gas with only 3 translational degrees of freedom + 2. rho_i is the ION mass density. Electron mass density is assumed + to be negligible. + 3. As such, + + Cv = kb / ((gamma -1) mp) + + where is the average ionization state of the gas and is the + mean atomic mass of the underlying atomic nuclei. + + is read in at initialization. is passed in via the lambda. + */ +class IdealElectrons : public EosBase { + public: + struct Lambda { // Lambda index is ionization state Zi + enum Index { Zi = 0 }; + }; + static constexpr const Real kb = 1.3806505e-16; // Boltzmann's constant. In ergs/K + static constexpr const Real mp = 1.67262171e-24; // proton mass, in g. + + IdealElectrons() = default; + PORTABLE_INLINE_FUNCTION + IdealElectrons(const MeanAtomicProperties &AZbar) + : _AZbar(AZbar), _Cvbase(robust::ratio(kb, _gm1 * _AZbar.Abar * mp)) { + CheckParams(); + } + + IdealElectrons GetOnDevice() { return *this; } + + PORTABLE_INLINE_FUNCTION void CheckParams() const { + _AZbar.CheckParams(); + return; + } + + template + PORTABLE_INLINE_FUNCTION Real TemperatureFromDensityInternalEnergy( + const Real rho, const Real sie, + Indexer_t &&lambda = static_cast(nullptr)) const { + return std::max(0.0, sie / _Cv(lambda)); + } + template + PORTABLE_INLINE_FUNCTION Real InternalEnergyFromDensityTemperature( + const Real rho, const Real temperature, + Indexer_t &&lambda = static_cast(nullptr)) const { + return std::max(0.0, _Cv(lambda) * temperature); + } + template + PORTABLE_INLINE_FUNCTION Real PressureFromDensityTemperature( + const Real rho, const Real temperature, + Indexer_t &&lambda = static_cast(nullptr)) const { + return std::max(0.0, _gm1 * rho * _Cv(lambda) * temperature); + } + template + PORTABLE_INLINE_FUNCTION Real PressureFromDensityInternalEnergy( + const Real rho, const Real sie, + Indexer_t &&lambda = static_cast(nullptr)) const { + return std::max(0.0, _gm1 * rho * sie); + } + template + PORTABLE_INLINE_FUNCTION Real MinInternalEnergyFromDensity( + const Real rho, Indexer_t &&lambda = static_cast(nullptr)) const { + return 0.0; + }; + + template + PORTABLE_INLINE_FUNCTION Real + EntropyFromDensityTemperature(const Real rho, const Real temperature, + Indexer_t &&lambda = static_cast(nullptr)) const { + // TODO(JMM): Is this good enough? + const Real cv = _Cv(lambda); + return cv * std::log(robust::ratio(temperature, _T0)) + + _gm1 * cv * std::log(robust::ratio(_rho0, rho)); + } + template + PORTABLE_INLINE_FUNCTION Real EntropyFromDensityInternalEnergy( + const Real rho, const Real sie, + Indexer_t &&lambda = static_cast(nullptr)) const { + const Real temp = TemperatureFromDensityInternalEnergy(rho, sie, lambda); + return EntropyFromDensityTemperature(rho, temp, lambda); + } + + template + PORTABLE_INLINE_FUNCTION Real SpecificHeatFromDensityTemperature( + const Real rho, const Real temperature, + Indexer_t &&lambda = static_cast(nullptr)) const { + return _Cv(lambda); + } + template + PORTABLE_INLINE_FUNCTION Real SpecificHeatFromDensityInternalEnergy( + const Real rho, const Real sie, + Indexer_t &&lambda = static_cast(nullptr)) const { + return _Cv(lambda); + } + template + PORTABLE_INLINE_FUNCTION Real BulkModulusFromDensityTemperature( + const Real rho, const Real temperature, + Indexer_t &&lambda = static_cast(nullptr)) const { + return std::max(0.0, (_gm1 + 1) * _gm1 * rho * _Cv(lambda) * temperature); + } + template + PORTABLE_INLINE_FUNCTION Real BulkModulusFromDensityInternalEnergy( + const Real rho, const Real sie, + Indexer_t &&lambda = static_cast(nullptr)) const { + return std::max(0.0, (_gm1 + 1) * _gm1 * rho * sie); + } + template + PORTABLE_INLINE_FUNCTION Real GruneisenParamFromDensityTemperature( + const Real rho, const Real temperature, + Indexer_t &&lambda = static_cast(nullptr)) const { + return _gm1; + } + template + PORTABLE_INLINE_FUNCTION Real GruneisenParamFromDensityInternalEnergy( + const Real rho, const Real sie, + Indexer_t &&lambda = static_cast(nullptr)) const { + return _gm1; + } + + template + PORTABLE_INLINE_FUNCTION void + DensityEnergyFromPressureTemperature(const Real press, const Real temp, + Indexer_t &&lambda, Real &rho, Real &sie) const { + sie = std::max(0.0, _Cv(lambda) * temp); + rho = std::max(0.0, press / (_gm1 * sie)); + } + + template + PORTABLE_INLINE_FUNCTION void + ValuesAtReferenceState(Real &rho, Real &temp, Real &sie, Real &press, Real &cv, + Real &bmod, Real &dpde, Real &dvdt, + Indexer_t &&lambda = static_cast(nullptr)) const { + // use STP: 1 atmosphere, room temperature + const Real Cv = _Cv(lambda); + rho = _rho0; + temp = _T0; + sie = Cv * temp; + press = _P0; + cv = Cv; + bmod = BulkModulusFromDensityTemperature(rho, temp, lambda); + dpde = _dpde0; + dvdt = _dvdt0; + } + + template + PORTABLE_INLINE_FUNCTION void + FillEos(Real &rho, Real &temp, Real &energy, Real &press, Real &cv, Real &bmod, + const unsigned long output, + Indexer_t &&lambda = static_cast(nullptr)) const; + + // Generic functions provided by the base class. These contain + // e.g. the vector overloads that use the scalar versions declared + // here + SG_ADD_DEFAULT_MEAN_ATOMIC_FUNCTIONS(_AZbar) + SG_ADD_BASE_CLASS_USINGS(IdealElectrons) + PORTABLE_INLINE_FUNCTION + int nlambda() const noexcept { return 1; } + static constexpr unsigned long PreferredInput() { return _preferred_input; } + static inline unsigned long scratch_size(std::string method, unsigned int nelements) { + return 0; + } + static inline unsigned long max_scratch_size(unsigned int nelements) { return 0; } + PORTABLE_INLINE_FUNCTION void PrintParams() const { + printf("Ideal Electrons Parameters:\n"); + _AZbar.PrintParams(); + } + inline void Finalize() {} + static std::string EosType() { return std::string("IdealElectrons"); } + static std::string EosPyType() { return EosType(); } + + private: + template + PORTABLE_INLINE_FUNCTION Real _Cv(Indexer_t &&lambda) const { + const Real Z = std::max(lambda[Lambda::Zi], static_cast(0.0)); + return _Cvbase * Z; + } + + // TODO(JMM): Change gamma if needed + static constexpr const Real _gm1 = (5. / 3.) - 1; // 3 translational DOF + static constexpr const Real _rho0 = 1.0; + static constexpr const Real _T0 = ROOM_TEMPERATURE; + static constexpr const Real _P0 = ATMOSPHERIC_PRESSURE; + static constexpr const Real _dpde0 = _gm1 * _rho0; + static constexpr const Real _dvdt0 = 1. / (_rho0 * _T0); + static constexpr const unsigned long _preferred_input = + thermalqs::density | thermalqs::specific_internal_energy; + MeanAtomicProperties _AZbar; + Real _Cvbase; // cv / where Zi is ionization state +}; + +template +PORTABLE_INLINE_FUNCTION void IdealElectrons::FillEos(Real &rho, Real &temp, Real &sie, + Real &press, Real &cv, Real &bmod, + const unsigned long output, + Indexer_t &&lambda) const { + if (output & thermalqs::density && output & thermalqs::specific_internal_energy) { + if (output & thermalqs::pressure || output & thermalqs::temperature) { + UNDEFINED_ERROR; + } + DensityEnergyFromPressureTemperature(press, temp, lambda, rho, sie); + } + if (output & thermalqs::pressure && output & thermalqs::specific_internal_energy) { + if (output & thermalqs::density || output & thermalqs::temperature) { + UNDEFINED_ERROR; + } + sie = InternalEnergyFromDensityTemperature(rho, temp, lambda); + } + if (output & thermalqs::temperature && output & thermalqs::specific_internal_energy) { + sie = press / (_gm1 * rho); + } + if (output & thermalqs::pressure) + press = PressureFromDensityInternalEnergy(rho, sie, lambda); + if (output & thermalqs::temperature) + temp = TemperatureFromDensityInternalEnergy(rho, sie, lambda); + if (output & thermalqs::bulk_modulus) + bmod = BulkModulusFromDensityInternalEnergy(rho, sie, lambda); + if (output & thermalqs::specific_heat) + cv = SpecificHeatFromDensityInternalEnergy(rho, sie, lambda); +} + +} // namespace singularity + +#endif // _SINGULARITY_EOS_EOS_ELECTRONS diff --git a/singularity-eos/eos/eos_models.hpp b/singularity-eos/eos/eos_models.hpp index 306de6fb28..3f75a442fa 100644 --- a/singularity-eos/eos/eos_models.hpp +++ b/singularity-eos/eos/eos_models.hpp @@ -18,6 +18,7 @@ // EOS models #include #include +#include #include #include #include diff --git a/test/test_eos_ideal.cpp b/test/test_eos_ideal.cpp index dafc287b73..b24a94bb3f 100644 --- a/test/test_eos_ideal.cpp +++ b/test/test_eos_ideal.cpp @@ -29,9 +29,10 @@ #include +using singularity::IdealElectrons; using singularity::IdealGas; using singularity::MeanAtomicProperties; -using EOS = singularity::Variant; +using EOS = singularity::Variant; SCENARIO("Ideal gas entropy", "[IdealGas][Entropy][GibbsFreeEnergy]") { GIVEN("Parameters for an ideal gas with entropy reference states") { @@ -248,3 +249,39 @@ SCENARIO("Ideal gas serialization", "[IdealGas][Serialization]") { eos_variant.Finalize(); } } + +SCENARIO("Ideal electron gas", "[IdealGas][IdealEelctrons]") { + GIVEN("An ideal electron gas from partially ionized iron") { + constexpr Real Abar = 26; + constexpr Real Zbar = 55.8; + constexpr Real rho = 1; + constexpr Real T = 4000; + + MeanAtomicProperties AZbar(Abar, Zbar); + EOS eos = IdealElectrons(AZbar); + + THEN("The gruneisen coefficient is for 3 DOF") { + Real gm1 = eos.GruneisenParamFromDensityTemperature(rho, T); + Real gamma = gm1 + 1; + REQUIRE(isClose(gamma, 5. / 3., 1e-12)); + } + + WHEN("We evaluate the specific heat for different partial ionizations") { + Real lambda[1] = {1}; + const Real cv1 = eos.SpecificHeatFromDensityTemperature(rho, T, lambda); + int nwrong = 0; + constexpr int N = 55; + portableReduce( + "Check Cv vs Z", 2, N, + PORTABLE_LAMBDA(const int i, int &nw) { + Real ll[1] = {static_cast(i)}; + Real Cv = eos.SpecificHeatFromDensityTemperature(rho, T, ll); + if (!isClose(Cv, i * cv1, 1e-12)) nw += 1; + }, + nwrong); + THEN("The specific heat should scale linearly with the ionization state") { + REQUIRE(nwrong == 0); + } + } + } +} From 6167b75cbdf3ad41430213f9b0f0fc968434ec66 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Mon, 16 Dec 2024 10:29:31 -0700 Subject: [PATCH 02/39] zsplit mostly implemented --- singularity-eos/CMakeLists.txt | 1 + singularity-eos/eos/eos_base.hpp | 4 +- singularity-eos/eos/eos_models.hpp | 1 + .../eos/modifiers/eos_unitsystem.hpp | 1 + singularity-eos/eos/modifiers/ramps_eos.hpp | 1 + .../eos/modifiers/relativistic_eos.hpp | 1 + singularity-eos/eos/modifiers/scaled_eos.hpp | 12 +- singularity-eos/eos/modifiers/shifted_eos.hpp | 1 + singularity-eos/eos/modifiers/zsplit_eos.hpp | 214 ++++++++++++++++++ 9 files changed, 234 insertions(+), 2 deletions(-) create mode 100644 singularity-eos/eos/modifiers/zsplit_eos.hpp diff --git a/singularity-eos/CMakeLists.txt b/singularity-eos/CMakeLists.txt index f800a90cf3..3d6b932cb7 100644 --- a/singularity-eos/CMakeLists.txt +++ b/singularity-eos/CMakeLists.txt @@ -57,6 +57,7 @@ register_headers( eos/modifiers/ramps_eos.hpp eos/modifiers/shifted_eos.hpp eos/modifiers/eos_unitsystem.hpp + eos/modifiers/zsplit_eos.hpp eos/eos_base.hpp eos/eos_eospac.hpp eos/eos_noble_abel.hpp diff --git a/singularity-eos/eos/eos_base.hpp b/singularity-eos/eos/eos_base.hpp index 8122925f2a..f455872735 100644 --- a/singularity-eos/eos/eos_base.hpp +++ b/singularity-eos/eos/eos_base.hpp @@ -111,7 +111,9 @@ char *StrCat(char *destination, const char *source) { } \ constexpr bool AllDynamicMemoryIsShareable() const { \ return t_.AllDynamicMemoryIsShareable(); \ - } \ + } + +#define SG_ADD_MODIFIER_MEAN_METHODS(t_) \ PORTABLE_INLINE_FUNCTION \ Real MeanAtomicMass() const { return t_.MeanAtomicMass(); } \ PORTABLE_INLINE_FUNCTION \ diff --git a/singularity-eos/eos/eos_models.hpp b/singularity-eos/eos/eos_models.hpp index 3f75a442fa..f0ce27612c 100644 --- a/singularity-eos/eos/eos_models.hpp +++ b/singularity-eos/eos/eos_models.hpp @@ -38,5 +38,6 @@ #include #include #include +#include #endif // _SINGULARITY_EOS_EOS_EOS_MODELS_HPP_ diff --git a/singularity-eos/eos/modifiers/eos_unitsystem.hpp b/singularity-eos/eos/modifiers/eos_unitsystem.hpp index 957aa5eed6..2e7519f750 100644 --- a/singularity-eos/eos/modifiers/eos_unitsystem.hpp +++ b/singularity-eos/eos/modifiers/eos_unitsystem.hpp @@ -441,6 +441,7 @@ class UnitSystem : public EosBase> { } SG_ADD_MODIFIER_METHODS(T, t_); + SG_ADD_MODIFIER_MEAN_METHODS(t_) private: T t_; diff --git a/singularity-eos/eos/modifiers/ramps_eos.hpp b/singularity-eos/eos/modifiers/ramps_eos.hpp index f316c57dec..fb072f7d7d 100644 --- a/singularity-eos/eos/modifiers/ramps_eos.hpp +++ b/singularity-eos/eos/modifiers/ramps_eos.hpp @@ -467,6 +467,7 @@ class BilinearRampEOS : public EosBase> { } SG_ADD_MODIFIER_METHODS(T, t_); + SG_ADD_MODIFIER_MEAN_METHODS(t_) private: T t_; diff --git a/singularity-eos/eos/modifiers/relativistic_eos.hpp b/singularity-eos/eos/modifiers/relativistic_eos.hpp index 8729c30a83..f497e35924 100644 --- a/singularity-eos/eos/modifiers/relativistic_eos.hpp +++ b/singularity-eos/eos/modifiers/relativistic_eos.hpp @@ -196,6 +196,7 @@ class RelativisticEOS : public EosBase> { } SG_ADD_MODIFIER_METHODS(T, t_); + SG_ADD_MODIFIER_MEAN_METHODS(t_) private: T t_; diff --git a/singularity-eos/eos/modifiers/scaled_eos.hpp b/singularity-eos/eos/modifiers/scaled_eos.hpp index 9576c306c4..31cee21ae6 100644 --- a/singularity-eos/eos/modifiers/scaled_eos.hpp +++ b/singularity-eos/eos/modifiers/scaled_eos.hpp @@ -342,11 +342,21 @@ class ScaledEOS : public EosBase> { return t_.MinimumTemperature(); } + PORTABLE_INLINE_FUNCTION + Real MeanAtomicMass() const { + return inv_scale_*t_.MeanAtomicMass(); + } + PORTABLE_INLINE_FUNCTION + Real MeanAtomicNumber() const { + return t_.MeanAtomicNumber(); + } + template PORTABLE_INLINE_FUNCTION Real MeanAtomicMassFromDensityTemperature( const Real rho, const Real temperature, Indexer_t &&lambda = static_cast(nullptr)) const { - return t_.MeanAtomicMassFromDensityTemperature(scale_ * rho, temperature, lambda); + return inv_scale_ * + t_.MeanAtomicMassFromDensityTemperature(scale_ * rho, temperature, lambda); } template PORTABLE_INLINE_FUNCTION Real MeanAtomicNumberFromDensityTemperature( diff --git a/singularity-eos/eos/modifiers/shifted_eos.hpp b/singularity-eos/eos/modifiers/shifted_eos.hpp index c943bec517..f42003a412 100644 --- a/singularity-eos/eos/modifiers/shifted_eos.hpp +++ b/singularity-eos/eos/modifiers/shifted_eos.hpp @@ -366,6 +366,7 @@ class ShiftedEOS : public EosBase> { } SG_ADD_MODIFIER_METHODS(T, t_); + SG_ADD_MODIFIER_MEAN_METHODS(t_) private: T t_; diff --git a/singularity-eos/eos/modifiers/zsplit_eos.hpp b/singularity-eos/eos/modifiers/zsplit_eos.hpp new file mode 100644 index 0000000000..f73c66be81 --- /dev/null +++ b/singularity-eos/eos/modifiers/zsplit_eos.hpp @@ -0,0 +1,214 @@ +//------------------------------------------------------------------------------ +// © 2024. 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. +//------------------------------------------------------------------------------ + +#ifndef _SINGULARITY_EOS_EOS_ZSPLIT_EOS_ +#define _SINGULARITY_EOS_EOS_ZSPLIT_EOS_ + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace singularity { + +using namespace eos_base; + +enum class ZSplitComponent { Electrons, Ions }; + +// TODO(JMM): Separate type? Or runtime? +template +class ZSplit : public EosBase> { + public: + using BaseType = T; + static constexpr const ZSplitComponent zsplit_type = ztype; + SG_ADD_BASE_CLASS_USINGS(ZSplit); + + static std::string EosType() { + std::string ts = (ztype == Electrons) ? "Electrons, " : "Ions, "; + return std::string("ZSplit<") + ts + T::EosType() + std::string(">"); + } + std::string ts = (ztype == Electrons) ? "Electrons" : "Ions"; + static std::string EosPyType() { return std::string("ZSplit") + ts + T::EosPyType(); } + + ZSplit() = default; + PORTABLE_INLINE_FUNCTION + ZSplit(T &&t) : t_(std::forward(t)); + {} + + PORTABLE_INLINE_FUNCTION void CheckParams() const { t_.CheckParams(); } + auto GetOnDevice() { return ZSplit(t_.GetOnDevice()); } + inline void Finalize() { t_.Finalize(); } + + template + PORTABLE_FUNCTION Real TemperatureFromDensityInternalEnergy( + const Real rho, const Real sie, Indexer_t &&lambda = nullptr) const { + const Real iscale = GetInvScale_(lambda); + return t_.TemperatureFromDensityInternalEnergy(rho, sie * iscale, lambda); + } + template + PORTABLE_FUNCTION Real InternalEnergyFromDensityTemperature( + const Real rho, const Real temperature, Indexer_t &&lambda = nullptr) const { + const Real scale = GetScale_(lambda); + const Real et = t_.InternalEnergyFromDensityTemperature(rho, temperature, lambda); + return scale * et; + } + + template + PORTABLE_FUNCTION Real PressureFromDensityTemperature( + const Real rho, const Real temperature, Indexer_t &&lambda = nullptr) const { + const Real scale = GetScale_(lambda); + const Real Pt = t_.PressureFromDensityTemperature(rho, temperature, lambda); + return scale * Pt; + } + template + PORTABLE_INLINE_FUNCTION Real PressureFromDensityInternalEnergy( + const Real rho, const Real sie, + Indexer_t &&lambda = static_cast(nullptr)) const { + const Real iscale = GetInvScale_(lambda); + const Real scale = GetScale_(lambda); + const Real Pt = t_.PressureFromDensityInternalEnergy(rho, iscale * sie, lambda); + return scale * Pt; + } + + template + PORTABLE_FUNCTION Real + MinInternalEnergyFromDensity(const Real rho, Indexer_t &&lambda = nullptr) const { + const Real scale = GetScale_(lambda); + const Real et = t_.MinInternalEnergyFromDensity(rho, lambda); + return scale * et; + } + template + PORTABLE_INLINE_FUNCTION Real + EntropyFromDensityTemperature(const Real rho, const Real temperature, + Indexer_t &&lambda = static_cast(nullptr)) const { + const Real scale = GetScale_(lambda); + return scale * t_.EntropyFromDensityTemperature(rho, temperature, lambda); + } + template + PORTABLE_FUNCTION Real EntropyFromDensityInternalEnergy( + const Real rho, const Real sie, Indexer_t &&lambda = nullptr) const { + const Real scale = GetScale_(lambda); + const Real iscale = GetInvScale_(lambda); + return scale * t_.EntropyFromDensityInternalEnergy(rho, iscale * sie, lambda); + } + + template + PORTABLE_INLINE_FUNCTION Real SpecificHeatFromDensityTemperature( + const Real rho, const Real temperature, + Indexer_t &&lambda = static_cast(nullptr)) const { + const Real scale = GetScale_(lambda); + return scale * t_.SpecificHeatFromDensityTemperature(rho, temperature, lambda); + } + template + PORTABLE_INLINE_FUNCTION Real SpecificHeatFromDensityInternalEnergy( + const Real rho, const Real sie, + Indexer_t &&lambda = static_cast(nullptr)) const { + const Real scale = GetScale_(lambda); + const Real iscale = GetInvScale_(lambda); + return scale * t_.SpecificHeatFromDensityInternalEnergy(rho, iscale * sie, lambda); + } + + template + PORTABLE_INLINE_FUNCTION Real BulkModulusFromDensityTemperature( + const Real rho, const Real temperature, + Indexer_t &&lambda = static_cast(nullptr)) const { + const Real scale = GetScale_(lambda); + return scale * t_.BulkModulusFromDensityTemperature(rho, temperature, lambda); + } + template + PORTABLE_INLINE_FUNCTION Real BulkModulusFromDensityInternalEnergy( + const Real rho, const Real sie, + Indexer_t &&lambda = static_cast(nullptr)) const { + const Real scale = GetScale_(lambda); + const Real iscale = GetInvScale_(lambda); + return scale * t_.BulkModulusFromDensityInternalEnergy(rho, iscale * sie, lambda); + } + + + + PORTABLE_INLINE_FUNCTION + int nlambda() const noexcept { return NL + t_.nlambda(); } + static constexpr unsigned long PreferredInput() { return T::PreferredInput(); } + static inline unsigned long scratch_size(std::string method, unsigned int nelements) { + return T::scratch_size(method, nelements); + } + static inline unsigned long max_scratch_size(unsigned int nelements) { + return T::max_scratch_size(nelements); + } + PORTABLE_FUNCTION void PrintParams() const { t_.PrintParams(); } + + PORTABLE_FORCEINLINE_FUNCTION Real MinimumDensity() const { + return t_.MinimumDensity(); + } + PORTABLE_FORCEINLINE_FUNCTION Real MinimumTemperature() const { + return t_.MinimumTemperature(); + } + + template + PORTABLE_INLINE_FUNCTION Real MeanAtomicMassFromDensityTemperature( + const Real rho, const Real temperature, + Indexer_t &&lambda = static_cast(nullptr)) const { + return t_.MeanAtomicMassFromDensityTemperature(rho, temperature, lambda); + } + template + PORTABLE_INLINE_FUNCTION Real MeanAtomicNumberFromDensityTemperature( + const Real rho, const Real temperature, + Indexer_t &&lambda = static_cast(nullptr)) const { + return t_.MeanAtomicNumberFromDensityTemperature(rho, temperature, lambda); + } + + SG_ADD_MODIFIER_METHODS(T, t_); + SG_ADD_MODIFIER_MEAN_METHODS(t_) + + private: + static constexpr const int NL = 1; + template + PORTABLE_FORCEINLINE_FUNCTION Real GetIonizationState_(const Indexer_t &&lambda) const { + return std::max(0.0, lambda[t_.nlambda()]); + } + template + PORTABLE_INLINE_FUNCTION Real GetScale_(const Indexer_t &&lambda) const { + Real Z = GetIonizationState_(lambda); + if constexpr (ztype == ZSplitComponent::Electrons) { + return robust::ratio(Z, Z + 1); + } else { + return robust::ratio(1.0, Z + 1); + } + } + template + PORTABLE_INLINE_FUNCTION Real GetInvScale_(const Indexer_t &&lambda) const { + Real Z = GetIonizationState_(lambda); + if constexpr (ztype == ZSplitComponent::Electrons) { + return robust::ratio(Z + 1, Z); + } else { + return Z + 1; + } + } + T t_; +}; + +template +using ZSplitE = ZSplit; + +template +using ZSplitI = ZSplit; + +} // namespace singularity + +#endif // _SINGULARITY_EOS_EOS_ZSPLIT_EOS_ From 4b4a2fa3cda7849e18cdc12eea19342ffc72fe90 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Mon, 16 Dec 2024 10:48:11 -0700 Subject: [PATCH 03/39] zsplit compiles --- singularity-eos/eos/eos_base.hpp | 35 ++++----- singularity-eos/eos/modifiers/scaled_eos.hpp | 8 +-- singularity-eos/eos/modifiers/zsplit_eos.hpp | 75 ++++++++++++++++++-- 3 files changed, 88 insertions(+), 30 deletions(-) diff --git a/singularity-eos/eos/eos_base.hpp b/singularity-eos/eos/eos_base.hpp index f455872735..5ca9ed928e 100644 --- a/singularity-eos/eos/eos_base.hpp +++ b/singularity-eos/eos/eos_base.hpp @@ -66,23 +66,24 @@ char *StrCat(char *destination, const char *source) { // VECTOR functionality to overload the scalar implementations in the derived // classes. Do not add functions here that are not overloads of derived class features. // TODO(JMM): Should we have more macros that capture just some of these? -#define SG_ADD_BASE_CLASS_USINGS(EOSDERIVED) \ - using EosBase::TemperatureFromDensityInternalEnergy; \ - using EosBase::InternalEnergyFromDensityTemperature; \ - using EosBase::PressureFromDensityTemperature; \ - using EosBase::PressureFromDensityInternalEnergy; \ - using EosBase::MinInternalEnergyFromDensity; \ - using EosBase::SpecificHeatFromDensityTemperature; \ - using EosBase::SpecificHeatFromDensityInternalEnergy; \ - using EosBase::BulkModulusFromDensityTemperature; \ - using EosBase::BulkModulusFromDensityInternalEnergy; \ - using EosBase::GruneisenParamFromDensityTemperature; \ - using EosBase::GruneisenParamFromDensityInternalEnergy; \ - using EosBase::FillEos; \ - using EosBase::EntropyFromDensityTemperature; \ - using EosBase::EntropyFromDensityInternalEnergy; \ - using EosBase::GibbsFreeEnergyFromDensityTemperature; \ - using EosBase::GibbsFreeEnergyFromDensityInternalEnergy; +// JMM: Use VA_ARGS to capture more complex template types +#define SG_ADD_BASE_CLASS_USINGS(...) \ + using EosBase<__VA_ARGS__>::TemperatureFromDensityInternalEnergy; \ + using EosBase<__VA_ARGS__>::InternalEnergyFromDensityTemperature; \ + using EosBase<__VA_ARGS__>::PressureFromDensityTemperature; \ + using EosBase<__VA_ARGS__>::PressureFromDensityInternalEnergy; \ + using EosBase<__VA_ARGS__>::MinInternalEnergyFromDensity; \ + using EosBase<__VA_ARGS__>::SpecificHeatFromDensityTemperature; \ + using EosBase<__VA_ARGS__>::SpecificHeatFromDensityInternalEnergy; \ + using EosBase<__VA_ARGS__>::BulkModulusFromDensityTemperature; \ + using EosBase<__VA_ARGS__>::BulkModulusFromDensityInternalEnergy; \ + using EosBase<__VA_ARGS__>::GruneisenParamFromDensityTemperature; \ + using EosBase<__VA_ARGS__>::GruneisenParamFromDensityInternalEnergy; \ + using EosBase<__VA_ARGS__>::FillEos; \ + using EosBase<__VA_ARGS__>::EntropyFromDensityTemperature; \ + using EosBase<__VA_ARGS__>::EntropyFromDensityInternalEnergy; \ + using EosBase<__VA_ARGS__>::GibbsFreeEnergyFromDensityTemperature; \ + using EosBase<__VA_ARGS__>::GibbsFreeEnergyFromDensityInternalEnergy; // This macro adds these methods to a derived class. Due to scope, // these can't be implemented in the base class, unless we make diff --git a/singularity-eos/eos/modifiers/scaled_eos.hpp b/singularity-eos/eos/modifiers/scaled_eos.hpp index 31cee21ae6..60d522026f 100644 --- a/singularity-eos/eos/modifiers/scaled_eos.hpp +++ b/singularity-eos/eos/modifiers/scaled_eos.hpp @@ -343,13 +343,9 @@ class ScaledEOS : public EosBase> { } PORTABLE_INLINE_FUNCTION - Real MeanAtomicMass() const { - return inv_scale_*t_.MeanAtomicMass(); - } + Real MeanAtomicMass() const { return inv_scale_ * t_.MeanAtomicMass(); } PORTABLE_INLINE_FUNCTION - Real MeanAtomicNumber() const { - return t_.MeanAtomicNumber(); - } + Real MeanAtomicNumber() const { return t_.MeanAtomicNumber(); } template PORTABLE_INLINE_FUNCTION Real MeanAtomicMassFromDensityTemperature( diff --git a/singularity-eos/eos/modifiers/zsplit_eos.hpp b/singularity-eos/eos/modifiers/zsplit_eos.hpp index f73c66be81..d8730bfcca 100644 --- a/singularity-eos/eos/modifiers/zsplit_eos.hpp +++ b/singularity-eos/eos/modifiers/zsplit_eos.hpp @@ -40,16 +40,17 @@ class ZSplit : public EosBase> { SG_ADD_BASE_CLASS_USINGS(ZSplit); static std::string EosType() { - std::string ts = (ztype == Electrons) ? "Electrons, " : "Ions, "; + std::string ts = (ztype == ZSplitComponent::Electrons) ? "Electrons, " : "Ions, "; return std::string("ZSplit<") + ts + T::EosType() + std::string(">"); } - std::string ts = (ztype == Electrons) ? "Electrons" : "Ions"; - static std::string EosPyType() { return std::string("ZSplit") + ts + T::EosPyType(); } + static std::string EosPyType() { + std::string ts = (ztype == ZSplitComponent::Electrons) ? "Electrons" : "Ions"; + return std::string("ZSplit") + ts + T::EosPyType(); + } ZSplit() = default; PORTABLE_INLINE_FUNCTION - ZSplit(T &&t) : t_(std::forward(t)); - {} + ZSplit(T &&t) : t_(std::forward(t)) {} PORTABLE_INLINE_FUNCTION void CheckParams() const { t_.CheckParams(); } auto GetOnDevice() { return ZSplit(t_.GetOnDevice()); } @@ -140,7 +141,66 @@ class ZSplit : public EosBase> { return scale * t_.BulkModulusFromDensityInternalEnergy(rho, iscale * sie, lambda); } + template + PORTABLE_INLINE_FUNCTION Real GruneisenParamFromDensityTemperature( + const Real rho, const Real temperature, + Indexer_t &&lambda = static_cast(nullptr)) const { + // (1/rho) (dP/de). Scale cancels in P and e + return t_.GruneisenParameterFromDensityTemperature(rho, temperature, lambda); + } + template + PORTABLE_INLINE_FUNCTION Real GruneisenParamFromDensityInternalEnergy( + const Real rho, const Real sie, + Indexer_t &&lambda = static_cast(nullptr)) const { + const Real iscale = GetInvScale_(lambda); + return t_.GruneisenParameterFromDensityInternalEnergy(rho, iscale * sie, lambda); + } + template + PORTABLE_INLINE_FUNCTION void + FillEos(Real &rho, Real &temp, Real &energy, Real &press, Real &cv, Real &bmod, + const unsigned long output, + Indexer_t &&lambda = static_cast(nullptr)) const { + const Real scale = GetScale_(lambda); + const Real iscale = GetInvScale_(lambda); + + const bool sie_output = (output & thermalqs::specific_internal_energy); + const bool sie_input = !sie_output; + + const bool press_output = (output & thermalqs::pressure); + const bool press_input = !press_output; + + const bool cv_output = (output & thermalqs::specific_heat); + const bool bmod_output = (output & thermalqs::bulk_modulus); + + if (sie_input) energy *= iscale; + if (press_input) press *= iscale; + + t_.FillEos(rho, temp, energy, press, cv, output, lambda); + + // do it to undo if it was input. do it because you need to if + // output + energy *= scale; + press *= scale; + // These aren't input + if (cv_output) cv *= scale; + if (bmod_output) bmod *= scale; + } + + template + PORTABLE_INLINE_FUNCTION void + ValuesAtReferenceState(Real &rho, Real &temp, Real &sie, Real &press, Real &cv, + Real &bmod, Real &dpde, Real &dvdt, + Indexer_t &&lambda = static_cast(nullptr)) const { + const Real scale = GetScale_(lambda); + const Real iscale = GetInvScale_(lambda); + t_.ValuesAtReferenceState(rho, temp, sie, press, cv, bmod, dpde, dvdt); + sie *= scale; + press *= scale; + cv *= scale; + bmod *= scale; + // dvdt, dpde unchanged + } PORTABLE_INLINE_FUNCTION int nlambda() const noexcept { return NL + t_.nlambda(); } @@ -182,8 +242,9 @@ class ZSplit : public EosBase> { PORTABLE_FORCEINLINE_FUNCTION Real GetIonizationState_(const Indexer_t &&lambda) const { return std::max(0.0, lambda[t_.nlambda()]); } + // TODO(JMM): Runtime? template - PORTABLE_INLINE_FUNCTION Real GetScale_(const Indexer_t &&lambda) const { + PORTABLE_FORCEINLINE_FUNCTION Real GetScale_(const Indexer_t &&lambda) const { Real Z = GetIonizationState_(lambda); if constexpr (ztype == ZSplitComponent::Electrons) { return robust::ratio(Z, Z + 1); @@ -192,7 +253,7 @@ class ZSplit : public EosBase> { } } template - PORTABLE_INLINE_FUNCTION Real GetInvScale_(const Indexer_t &&lambda) const { + PORTABLE_FORCEINLINE_FUNCTION Real GetInvScale_(const Indexer_t &&lambda) const { Real Z = GetIonizationState_(lambda); if constexpr (ztype == ZSplitComponent::Electrons) { return robust::ratio(Z + 1, Z); From 3d18cae364f9a7fc316ff230fe8b43d910c03b86 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Mon, 16 Dec 2024 12:10:58 -0700 Subject: [PATCH 04/39] tests work --- singularity-eos/eos/modifiers/zsplit_eos.hpp | 12 ++++++------ test/CMakeLists.txt | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/singularity-eos/eos/modifiers/zsplit_eos.hpp b/singularity-eos/eos/modifiers/zsplit_eos.hpp index d8730bfcca..227fa857e0 100644 --- a/singularity-eos/eos/modifiers/zsplit_eos.hpp +++ b/singularity-eos/eos/modifiers/zsplit_eos.hpp @@ -238,13 +238,13 @@ class ZSplit : public EosBase> { private: static constexpr const int NL = 1; - template - PORTABLE_FORCEINLINE_FUNCTION Real GetIonizationState_(const Indexer_t &&lambda) const { + template + PORTABLE_FORCEINLINE_FUNCTION Real GetIonizationState_(Indexer_t &&lambda) const { return std::max(0.0, lambda[t_.nlambda()]); } // TODO(JMM): Runtime? - template - PORTABLE_FORCEINLINE_FUNCTION Real GetScale_(const Indexer_t &&lambda) const { + template + PORTABLE_FORCEINLINE_FUNCTION Real GetScale_(Indexer_t &&lambda) const { Real Z = GetIonizationState_(lambda); if constexpr (ztype == ZSplitComponent::Electrons) { return robust::ratio(Z, Z + 1); @@ -252,8 +252,8 @@ class ZSplit : public EosBase> { return robust::ratio(1.0, Z + 1); } } - template - PORTABLE_FORCEINLINE_FUNCTION Real GetInvScale_(const Indexer_t &&lambda) const { + template + PORTABLE_FORCEINLINE_FUNCTION Real GetInvScale_(Indexer_t &&lambda) const { Real Z = GetIonizationState_(lambda); if constexpr (ztype == ZSplitComponent::Electrons) { return robust::ratio(Z + 1, Z); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 318f469387..77ffc4183c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -24,6 +24,7 @@ add_executable( test_eos_vinet.cpp test_eos_mgusup.cpp test_eos_powermg.cpp + test_eos_zsplit.cpp ) add_executable( From 7fba185fa4619870bf283e40707138276aa76c27 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Mon, 16 Dec 2024 13:09:18 -0700 Subject: [PATCH 05/39] add test for zsplits --- test/test_eos_zsplit.cpp | 133 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 test/test_eos_zsplit.cpp diff --git a/test/test_eos_zsplit.cpp b/test/test_eos_zsplit.cpp new file mode 100644 index 0000000000..e75ed01478 --- /dev/null +++ b/test/test_eos_zsplit.cpp @@ -0,0 +1,133 @@ +//------------------------------------------------------------------------------ +// © 2024. 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. +//------------------------------------------------------------------------------ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifndef CATCH_CONFIG_FAST_COMPILE +#define CATCH_CONFIG_FAST_COMPILE +#include +#endif + +#include + +using singularity::IdealElectrons; +using singularity::IdealGas; +using singularity::MeanAtomicProperties; +using singularity::ZSplitE; +using singularity::ZSplitI; + +using EOS = + singularity::Variant, ZSplitE>; + +SCENARIO("ZSplit of Ideal Gas", "[ZSplit][IdealGas][IdealElectrons]") { + GIVEN("An ideal gas EOS") { + constexpr Real gm1 = (5. / 3.) - 1.; + + constexpr Real Abar = 26; // Iron + constexpr Real Zbar = 55.845; + const MeanAtomicProperties azbar(Abar, Zbar); + + constexpr Real Cv = + (Zbar + 1) * IdealElectrons::kb / (gm1 * Abar * IdealElectrons::mp); + + EOS eos_t_h = IdealGas(gm1, Cv, azbar); + EOS eos_ze_h = eos_t_h.Modify(); + EOS eos_zi_h = eos_t_h.Modify(); + EOS eos_ie_h = IdealElectrons(azbar); + + auto eos_t = eos_t_h.GetOnDevice(); + auto eos_ze = eos_ze_h.GetOnDevice(); + auto eos_zi = eos_zi_h.GetOnDevice(); + auto eos_ie = eos_ie_h.GetOnDevice(); + WHEN("We evaluate at fixed density and temperature for several ionization states") { + constexpr Real rho = 1.0; + constexpr Real temp = 1e3; + constexpr Real zmin = 0; + constexpr Real zmax = Zbar; + constexpr std::size_t NZ = 1000; + constexpr Real dz = (zmax - zmin) / (NZ - 1); + + int nwrong = 0; + portableReduce( + "Zsplit check P and sie", 0, NZ, + PORTABLE_LAMBDA(const int i, int &nw) { + Real Z = zmin + dz * i; + Real lambda[1] = {Z}; + + Real Pt = eos_t.PressureFromDensityTemperature(rho, temp, lambda); + Real Pi = eos_zi.PressureFromDensityTemperature(rho, temp, lambda); + Real Pe = eos_ze.PressureFromDensityTemperature(rho, temp, lambda); + if (!isClose(Pt, Pi + Pe, 1e-12)) { + printf("Bad P Sum! %d %.14e %.14e %.14e\n", i, Pt, Pi, Pe); + nw += 1; + } + + Real et = eos_t.InternalEnergyFromDensityTemperature(rho, temp, lambda); + Real ei = eos_zi.InternalEnergyFromDensityTemperature(rho, temp, lambda); + Real ee = eos_ze.InternalEnergyFromDensityTemperature(rho, temp, lambda); + if (!isClose(et, ei + ee, 1e-12)) { + printf("Bad sie Sum! %d %.14e %.14e %.14e\n", i, et, ei, ee); + nw += 1; + } + }, + nwrong); + THEN("Pe + Pi = Pt") { REQUIRE(nwrong == 0); } + + WHEN("Ideal electrons are fully ionized") { + constexpr Real rho = 1.0; + constexpr Real Tmin = 3e3; + constexpr Real Tmax = 3e5; + constexpr int NT = 1000; + constexpr Real dt = (Tmax - Tmin) / (NT - 1); + + int nwrong = 0; + portableReduce( + "Ideal electrons check full ionization", 0, NT, + PORTABLE_LAMBDA(const int i, int &nw) { + const Real T = Tmin + i * dt; + Real lambda[1] = {Zbar}; + + Real P_fi = eos_ze.PressureFromDensityTemperature(rho, T, lambda); + Real P_ie = eos_ie.PressureFromDensityTemperature(rho, T, lambda); + if (!isClose(P_fi, P_ie, 1e-12)) { + printf("Bad P ionized! %d %.14e %.14e\n", i, P_fi, P_ie); + nw += 1; + } + + Real e_fi = eos_ze.InternalEnergyFromDensityTemperature(rho, T, lambda); + Real e_ie = eos_ie.InternalEnergyFromDensityTemperature(rho, T, lambda); + if (!isClose(e_fi, e_ie, 1e-12)) { + printf("Bad P ionized! %d %.14e %.14e\n", i, e_fi, e_ie); + nw += 1; + } + }, + nwrong); + THEN("Pe_fi == PE_ie") { REQUIRE(nwrong == 0); } + } + + eos_t.Finalize(); + eos_ze.Finalize(); + eos_zi.Finalize(); + eos_ie.Finalize(); + } + } +} From 251224991290affe3b50aafba1df5a2edc4625ee Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Mon, 16 Dec 2024 13:19:09 -0700 Subject: [PATCH 06/39] messages --- test/test_eos_zsplit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_eos_zsplit.cpp b/test/test_eos_zsplit.cpp index e75ed01478..aeaff8c18c 100644 --- a/test/test_eos_zsplit.cpp +++ b/test/test_eos_zsplit.cpp @@ -116,7 +116,7 @@ SCENARIO("ZSplit of Ideal Gas", "[ZSplit][IdealGas][IdealElectrons]") { Real e_fi = eos_ze.InternalEnergyFromDensityTemperature(rho, T, lambda); Real e_ie = eos_ie.InternalEnergyFromDensityTemperature(rho, T, lambda); if (!isClose(e_fi, e_ie, 1e-12)) { - printf("Bad P ionized! %d %.14e %.14e\n", i, e_fi, e_ie); + printf("Bad sie ionized! %d %.14e %.14e\n", i, e_fi, e_ie); nw += 1; } }, From 8085e6162cc9042c52af15beddc4cb5204f42099 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Mon, 16 Dec 2024 18:42:53 -0700 Subject: [PATCH 07/39] Add discussion of lambdas, add discussion of 3T, add discussion of ZSplit and IdealElectron modles --- doc/sphinx/src/models.rst | 120 +++++++++++++++++++++++++++++++++++ doc/sphinx/src/modifiers.rst | 111 +++++++++++++++++++++++++++++--- doc/sphinx/src/using-eos.rst | 12 ++++ 3 files changed, 235 insertions(+), 8 deletions(-) diff --git a/doc/sphinx/src/models.rst b/doc/sphinx/src/models.rst index 5f3b914856..410d372011 100644 --- a/doc/sphinx/src/models.rst +++ b/doc/sphinx/src/models.rst @@ -164,6 +164,61 @@ functional forms for :math:`\Gamma` and the reference curves, the task of calculating a **thermodynamically consistent** temperature becomes more complicated. +The 3T Model +`````````````` + +In high-energy denisty physics, the so-called three-temperature (or +3T) model is often employed. In this model, a material is fully or +partially ionized. Due to the separation in masses between electrons +and atomic nuclei, electrons come into thermal equilibrium and ions +come into thermal equilibrium, but the two populations are not in +thermal equilibrium with each other. This introduces separate electron +and ion temperatures. The third temperature is potentially a radiation +temperature. + +By convention in 3T physics, density :math:`\rho` is always the mass +density of the ions. The electron number density may then be computed +as + +.. math:: + + n = \left\langle Z \right\rangle \frac{\rho}{\left\langle A\right\rangle m_p} + +where here :math:`\left\langle Z\right\rangle` is the average number +of electrons contributed per atom, also called mean ionization state, +:math:`\rho` is the ion mass density, :math:`\bar{A}` is the mean +atomic mass (in grams per mole) of a given material and :math:`m_p` is +the proton mass. + +.. note:: + + Note that there is notational ambiguity between the average + ionization state and the average atomic number, as the symbol for + both is :math:`Z`. To disambiguate in ``singularity-eos``, we use + overbars to reference mean atomic properties such as mean atomic + mass :math:`\bar{A}` and mean atomic number :math:`\bar{Z}` while we + use :math:`\left\langle Z\right\rangle` to denote mean ionizaiton + state. + +Also by convention, the specific internal energy carried by electrons +:math:`\varepsilon_e` is specific with respect to the *ion* mass. In +particular: + +.. math:: + + u_e = \varepsilon_e \rho + +where here :math:`u_e` is the internal energy per unit volume carried +by electrons and, as discussed above, :math:`\rho` is ion mass +density. + +``singularity-eos`` assumes that, when 3T physics is active, electrons +and ions are each described by a separate equation of state +object. Several models are specifically designed to represent, e.g., +the electron equation of state or ion equation of state. The tabulated +models may also support loading tables specifically for electron or +ion equations of state. + Available EOS Information and Nomenclature ------------------------------------------ @@ -469,6 +524,71 @@ the atomic mass and number as a final optional parameter, e.g., IdealGas(Real gm1, Real Cv, MeanAtomicProperties(Abar, Zbar)); IdealGas(Real gm1, Real Cv, Real EntropyT0, Real EntropyRho0, MeanAtomicProperties(Abar, Zbar)); +Ideal Electron Gas +``````````````````` + +The ideal electron gas equation of state is designed for use with 3T +physics. It is an ideal Boltzmann gas of electrons. As such, each +electron is assumed to have three translational degrees of freedom +:math:`f`, such that + +.. math:: + + \Gamma = \frac{2}{f} = \frac{2}{3} + +and + +.. math:: + + \gamma = \Gamma + 1 = \frac{5}{3}. + +The pressure is given by the number density of electrons times +:math:`k_b T` for Boltzmann constant :math:`k_b` and temperature +:math:`T`: + +.. math:: + + P = \frac{\rho}{m_p \bar{A}}\left\langle Z \right\rangle k_b T + +The specific heat is then + +.. math:: + + C_V = \frac{\left\langle Z \right\rangle k_b}{\Gamma m_p \bar{A}} + +so that + +.. math:: + + P = \Gamma \rho C_V T + +as expected. + +The constructor takes only the ``MeanAtomicProperties`` struct, which +is a required input: + +.. code-block::cpp + + IdealElectrons(const MeanAtomicProperties &AZbar); + +Optionally reference values may be provided for the entropy +calculation, which is computed in the same way as the standard ideal +gas. + +Calls to compute state variables require the mean ionization state, +which must be passed in the ``lambda`` parameter, e.g., + +.. code-block:: cpp + + Real lambda[1] = {Z}; + Real P = eos.PressureFromDensityTemperature(rho, T, lambda); + +.. note:: + + For now, the ideal electron gas is not in the default variant + provided by singularity-eos. If you would like to use it, you must + implement your own custom variant. + Stiffened Gas ````````````` diff --git a/doc/sphinx/src/modifiers.rst b/doc/sphinx/src/modifiers.rst index 75e11310af..678bd80c83 100644 --- a/doc/sphinx/src/modifiers.rst +++ b/doc/sphinx/src/modifiers.rst @@ -8,14 +8,16 @@ Equation of State Modifiers provides some internal transformation on inputs and outputs. For example the ``ShiftedEOS`` modifier changes the zero point energy of a given EOS model by shifting all energies up or down. Modifiers can be -used to, for example, production-harden a model. Only certain -combinations of ``EOS`` and ``modifier`` are permitted by the defualt -``Variant``. For example, only ``IdealGas``, ``SpinerEOS``, and -``StellarCollapse`` support the ``RelativisticEOS`` and ``UnitSystem`` -modifiers. All models support the ``ShiftedEOS`` and ``ScaledEOS`` -modifiers. However, note that modifiers do not commute, and only one -order is supported. The ordering, inside-out, is ``UnitSystem`` or -``RelativisticEOS``, then ``ScaledEOS``, then ``ShiftedEOS``. +used to, for example, production-harden a model. + +Only certain combinations of ``EOS`` and ``modifier`` are permitted by +the defualt ``Variant``. For example, only ``IdealGas``, +``SpinerEOS``, and ``StellarCollapse`` support the ``RelativisticEOS`` +and ``UnitSystem`` modifiers. All models support the ``ShiftedEOS`` +and ``ScaledEOS`` modifiers. However, note that modifiers do not +commute, and only one order is supported. The ordering, inside-out, is +``UnitSystem`` or ``RelativisticEOS``, then ``ScaledEOS``, then +``ShiftedEOS``. We list below the available modifiers and their constructors. @@ -187,6 +189,99 @@ internal energy, and temperature. On the other hand, specifies the unit system by specifying units for time, mass, length, and temperature. +Z-Split EOS +------------- + +For 3T physics (as described in the models section) it is often +desirable to have a separate equation of state for electrons and a +separate equation of state for ions. The Z-split model takes a total +equation of state and splits it into electron and ion components. The +"Z" here signifies mean ionization state, or the average number of +free electrons contributed per atomic nucleus, which is the mean +atomic number in the case of full ionization, but could be smaller in +the case of partial ionization. (It is zero for an unionized gas.) The +physical model of Z-split can be derived from an ideal gas equation of +state. For an ideal gas made up of electrons and ions, where all +molecular bonds have been broken, the total pressure is given by + +.. math:: + + P_t = (\left\langle Z\right\rangle + 1) \frac{\rho}{m_p \bar{A}} k_b T + +where :math:`\left\langle Z\right\rangle` is the mean ionization +state, :math:`rho` is the ion mass density (the electron ion mass +density is negligible), :math:`m_p` is the proton mass, +:math:`\bar{A}` is the mean atomic mass, :math:`k_b` is Boltzmann's +constant, and :math:`T` is temperature. The contribution from +electrons is proportional to :math:`\left\langle Z\right\rangle`. + +The split simply splits the total pressure into normalized +contributions for the electrons: + +.. math:: + + P_e = \frac{\left\langle Z\right\rangle}{1 + \left\langle Z\right\rangle} P_t(\rho, T_e) + +and ions: + +.. math:: + + P_i = \frac{1}{1 + \left\langle Z\right\rangle} P_t(\rho, T_i) + +where here :math:`T_e` is the electron temperature and :math:`T_i` the +ion temperature such that, when the temperatures are equal, + +.. math:: + + P_e + P_i = P_t + +The same split is applied to the specific internal energy: + +.. math:: + + \varepsilon_e = \frac{\left\langle Z\right\rangle}{1 + \left\langle Z\right\rangle} \varepsilon_t(\rho, T_e)\\ + \varepsilon_i = \frac{1}{1 + \left\langle Z\right\rangle} \varepsilon_t(\rho, T_i) + +and the remaining state variables and thermodynamic derivatives can be +derived from these relations. + +In ``singularity-eos``, the z-split is implemented as the templated class + +.. code-block:: cpp + + template + class ZSplit + +where ``ZSPlitComponent`` may either be ``ZSplitComponent::Electrons`` +or ``ZSplitComponent::Ions``. As syntactic sugar, ``ZSplitE`` and +``ZSplitI`` are available. The Z-split constructor does not require +any additional parameters, so you may construct one as, e.g., + +.. code-block:: cpp + + using namespace singularity + auto ion_eos = ZSPlitI(IdealGas(gm1, Cv); + +and similarly for electrons, + +.. code-block:: cpp + + auto electron_eos = ZSPlitE(IdealGas(gm1, Cv); + +The Z-split modifier takes the ionization state as an additional +parameter via the lambda. For example: + +.. code-block:: cpp + + Real lambda[1] = {Z}; + Real Pe = electron_eos.PressureFromDensityTemperature(rho, temperature, lambda); + +.. note:: + + For now, the Z-split EOS is not in the default variant provided by + singularity-eos. If you would like to use it, you must implement + your own custom variant. + Composing Modifiers -------------------- diff --git a/doc/sphinx/src/using-eos.rst b/doc/sphinx/src/using-eos.rst index e9a2ecf848..e9bed5ddfb 100644 --- a/doc/sphinx/src/using-eos.rst +++ b/doc/sphinx/src/using-eos.rst @@ -737,6 +737,18 @@ For more details on modifiers, see the :ref:`modifiers` section. If you need a combination of modifiers not supported by default, we recommend building a custom variant as described above. +Modifiers and Lambdas +----------------------- + +Modifiers may require lambdas. When this is the case, the lambda +required by the modifier is appended to the end of the lambda +indexer. For example, the ``StellarCollapse`` EOS model requires +``nlambda=2``. The ``ZSplitI`` modifier rquires +``nlambda=1``. Together, ``ZSplitI`` requires a +lambda indexer of length 3, an the ordering is two parameters for +``StellarCollapse`` first, and then the parameter required by +``ZSplitI``. + Preferred Inputs ----------------- From 7e9a7ec0e4c19be0e4b1c88c696522dc0edf39e2 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 09:09:16 -0700 Subject: [PATCH 08/39] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f04083d0b..7e75ccc12d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Current develop ### Added (new features/APIs/variables/...) +- [[PR444]](https://github.com/lanl/singularity-eos/pull/444) Add Z split modifier and electron ideal gas EOS ### Fixed (Repair bugs, etc) - [[PR439]](https://github.com/lanl/singularity-eos/pull/439) Add mean atomic mass and number to EOS API From aaa57cc72c68e672dfd1dcc3dd3707e4022f61dc Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 09:12:33 -0700 Subject: [PATCH 09/39] clang format 12 stay around please --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index bd05a1cf88..8980bb5325 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -15,7 +15,7 @@ permissions: jobs: docs: name: build and deploy docs - runs-on: ubuntu-latest + runs-on: ubuntu-noble steps: - name: Checkout code From 0dfef593274e1d9d41a64c9ebee947c46928becc Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 09:12:57 -0700 Subject: [PATCH 10/39] latest for docs, noble for formatting --- .github/workflows/docs.yml | 2 +- .github/workflows/formatting.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 8980bb5325..bd05a1cf88 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -15,7 +15,7 @@ permissions: jobs: docs: name: build and deploy docs - runs-on: ubuntu-noble + runs-on: ubuntu-latest steps: - name: Checkout code diff --git a/.github/workflows/formatting.yml b/.github/workflows/formatting.yml index b14b07af30..ef7fb71d26 100644 --- a/.github/workflows/formatting.yml +++ b/.github/workflows/formatting.yml @@ -9,7 +9,7 @@ on: jobs: formatting: name: Check Formatting - runs-on: ubuntu-latest + runs-on: ubuntu-noble steps: - name: Checkout code From a0a806920e4a1a3ff4f28fe28efc3c660280dfd9 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 09:17:11 -0700 Subject: [PATCH 11/39] try updating to latest catch2 release --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6429fc358f..4e2bce0efe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -441,7 +441,7 @@ if(SINGULARITY_BUILD_TESTS) Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git # or later is fine too - GIT_TAG v3.0.1) + GIT_TAG v3.7.1) FetchContent_MakeAvailable(Catch2) list(APPEND CMAKE_MODULE_PATH ${Catch2_SOURCE_DIR}/contrib) endif() From c692221a8fa14cf4afe8bfd3e782a736031ce5a6 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 09:21:01 -0700 Subject: [PATCH 12/39] unused variable --- CMakeLists.txt | 2 +- singularity-eos/eos/modifiers/zsplit_eos.hpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e2bce0efe..09c4435794 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -440,7 +440,7 @@ if(SINGULARITY_BUILD_TESTS) FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git - # or later is fine too + # jmm: updated Dec 17, 2024 to avoid build errors on modern gcc GIT_TAG v3.7.1) FetchContent_MakeAvailable(Catch2) list(APPEND CMAKE_MODULE_PATH ${Catch2_SOURCE_DIR}/contrib) diff --git a/singularity-eos/eos/modifiers/zsplit_eos.hpp b/singularity-eos/eos/modifiers/zsplit_eos.hpp index 227fa857e0..3ef20a8496 100644 --- a/singularity-eos/eos/modifiers/zsplit_eos.hpp +++ b/singularity-eos/eos/modifiers/zsplit_eos.hpp @@ -193,7 +193,6 @@ class ZSplit : public EosBase> { Real &bmod, Real &dpde, Real &dvdt, Indexer_t &&lambda = static_cast(nullptr)) const { const Real scale = GetScale_(lambda); - const Real iscale = GetInvScale_(lambda); t_.ValuesAtReferenceState(rho, temp, sie, press, cv, bmod, dpde, dvdt); sie *= scale; press *= scale; From 98fb4446e7d77ae61b596f2e6e6d7a1e102702a9 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 10:03:09 -0700 Subject: [PATCH 13/39] typo and also try to make wno-psabi only for C++ --- doc/sphinx/src/models.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/sphinx/src/models.rst b/doc/sphinx/src/models.rst index 410d372011..5d377ac026 100644 --- a/doc/sphinx/src/models.rst +++ b/doc/sphinx/src/models.rst @@ -167,7 +167,7 @@ complicated. The 3T Model `````````````` -In high-energy denisty physics, the so-called three-temperature (or +In high-energy density physics, the so-called three-temperature (or 3T) model is often employed. In this model, a material is fully or partially ionized. Due to the separation in masses between electrons and atomic nuclei, electrons come into thermal equilibrium and ions @@ -567,7 +567,7 @@ as expected. The constructor takes only the ``MeanAtomicProperties`` struct, which is a required input: -.. code-block::cpp +.. code-block:: cpp IdealElectrons(const MeanAtomicProperties &AZbar); From 08172b2e42b8421124c4c0d970d8f74a9d583ff8 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 10:13:23 -0700 Subject: [PATCH 14/39] try to fix cuda errors for static members --- CMakeLists.txt | 2 +- singularity-eos/eos/eos_electrons.hpp | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 09c4435794..8c4e918a97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -563,7 +563,7 @@ target_compile_options( # Suppresses annoying ABI notes. See: # https://stackoverflow.com/questions/52020305/what-exactly-does-gccs-wpsabi-option-do-what-are-the-implications-of-supressi - $<$:-Wno-psabi> + $<$,$>:-Wno-psabi> ) if (SINGULARITY_STRICT_WARNINGS) target_compile_options(singularity-eos_Interface INTERFACE diff --git a/singularity-eos/eos/eos_electrons.hpp b/singularity-eos/eos/eos_electrons.hpp index 0e667509d6..0da6da4f44 100644 --- a/singularity-eos/eos/eos_electrons.hpp +++ b/singularity-eos/eos/eos_electrons.hpp @@ -59,7 +59,6 @@ class IdealElectrons : public EosBase { static constexpr const Real mp = 1.67262171e-24; // proton mass, in g. IdealElectrons() = default; - PORTABLE_INLINE_FUNCTION IdealElectrons(const MeanAtomicProperties &AZbar) : _AZbar(AZbar), _Cvbase(robust::ratio(kb, _gm1 * _AZbar.Abar * mp)) { CheckParams(); @@ -215,12 +214,15 @@ class IdealElectrons : public EosBase { } // TODO(JMM): Change gamma if needed - static constexpr const Real _gm1 = (5. / 3.) - 1; // 3 translational DOF - static constexpr const Real _rho0 = 1.0; - static constexpr const Real _T0 = ROOM_TEMPERATURE; - static constexpr const Real _P0 = ATMOSPHERIC_PRESSURE; - static constexpr const Real _dpde0 = _gm1 * _rho0; - static constexpr const Real _dvdt0 = 1. / (_rho0 * _T0); + // JMM: For some reason some cuda/HIP implementations don't like + // static constexpr vars. They are not getting properly translated to + // device, even with --expt-relaxed-constexpr + const Real _gm1 = (5. / 3.) - 1; // 3 translational DOF + const Real _rho0 = 1.0; + const Real _T0 = ROOM_TEMPERATURE; + const Real _P0 = ATMOSPHERIC_PRESSURE; + const Real _dpde0 = _gm1 * _rho0; + const Real _dvdt0 = 1. / (_rho0 * _T0); static constexpr const unsigned long _preferred_input = thermalqs::density | thermalqs::specific_internal_energy; MeanAtomicProperties _AZbar; From 95c60cdead0fb18bbcf7f3c4186bb8127686f0b3 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 10:21:07 -0700 Subject: [PATCH 15/39] No GCC. You are wrong and I am right. --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c4e918a97..ac97fbc5aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -564,6 +564,9 @@ target_compile_options( # Suppresses annoying ABI notes. See: # https://stackoverflow.com/questions/52020305/what-exactly-does-gccs-wpsabi-option-do-what-are-the-implications-of-supressi $<$,$>:-Wno-psabi> + # `-Wclass-memaccess now default with -Wall but we explicitly + # manage this ourselves in our serialization routines. + $<$,$>:-Wno-class-memaccess> ) if (SINGULARITY_STRICT_WARNINGS) target_compile_options(singularity-eos_Interface INTERFACE From 3b030b1965a8634f9e79c3141ac958c40dc642de Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 10:51:03 -0700 Subject: [PATCH 16/39] disable some EOSs from default variant --- .github/workflows/tests.yml | 1 + CMakeLists.txt | 7 +++++++ singularity-eos/eos/eos_type_lists.hpp | 5 ++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d31ea2b6f1..08d5bf3c42 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -38,6 +38,7 @@ jobs: -DSINGULARITY_USE_HELMHOLTZ=ON \ -DSINGULARITY_TEST_HELMHOLTZ=ON \ -DSINGULARITY_FORCE_SUBMODULE_MODE=ON \ + -DSINGULARITY_USE_V_AND_V_EOS=OFF \ -DSINGULARITY_PLUGINS=$(pwd)/../example/plugin \ .. #-DSINGULARITY_TEST_PYTHON=ON \ diff --git a/CMakeLists.txt b/CMakeLists.txt index ac97fbc5aa..b538630ac5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,13 @@ cmake_dependent_option( SINGULARITY_USE_HELMHOLTZ "Include Helmholtz equation of state" OFF "SINGULARITY_USE_SPINER;SINGULARITY_USE_SPINER_WITH_HDF5" OFF) +# Enables polynomial, carnahan starling, and NobleAbel in variant. +# Off by default, as they are not in the default python bindings or used +# by default in downstream codes. +option(SINGULARITY_USE_V_AND_V_EOS + "Add analytic EOSs for V&V to the variant" + OFF) + # testing options option(SINGULARITY_BUILD_TESTS "Compile tests" OFF) diff --git a/singularity-eos/eos/eos_type_lists.hpp b/singularity-eos/eos/eos_type_lists.hpp index c0429fa77e..f5435bf128 100644 --- a/singularity-eos/eos/eos_type_lists.hpp +++ b/singularity-eos/eos/eos_type_lists.hpp @@ -50,7 +50,10 @@ using singularity::variadic_utils::transform_variadic_list; // all eos's static constexpr const auto full_eos_list = tl Date: Tue, 17 Dec 2024 15:12:46 -0700 Subject: [PATCH 17/39] shrink the default variant --- CMakeLists.txt | 3 ++ singularity-eos/eos/eos_type_lists.hpp | 37 ++++++++----------------- singularity-eos/eos/singularity_eos.cpp | 18 ++++++++++++ 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b538630ac5..0ed05aa7ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -339,6 +339,9 @@ endif() if(SINGULARITY_USE_HELMHOLTZ) target_compile_definitions(singularity-eos_Interface INTERFACE SINGULARITY_USE_HELMHOLTZ) endif() +if (SINGULARITY_USE_V_AND_V_EOS) + target_compile_definitions(singularity-eos_Interface INTERFACE SINGULARITY_USE_V_AND_V_EOS) +endif() if(SINGULARITY_USE_SPINER_WITH_HDF5) target_compile_definitions(singularity-eos_Interface INTERFACE SINGULARITY_USE_SPINER_WITH_HDF5) endif() diff --git a/singularity-eos/eos/eos_type_lists.hpp b/singularity-eos/eos/eos_type_lists.hpp index f5435bf128..8b8f776ffc 100644 --- a/singularity-eos/eos/eos_type_lists.hpp +++ b/singularity-eos/eos/eos_type_lists.hpp @@ -50,8 +50,9 @@ using singularity::variadic_utils::transform_variadic_list; // all eos's static constexpr const auto full_eos_list = tl{}; -// eos's that get relativistic modifier -static constexpr const auto relativistic_eos_list = - tl{}; // eos's that get unit system modifier static constexpr const auto unit_system_eos_list = tl{}; // variadic list of UnitSystem's static constexpr const auto unit_system = transform_variadic_list(unit_system_eos_list, al{}); -// variadic list of Relativistic's -static constexpr const auto relativistic = - transform_variadic_list(relativistic_eos_list, al{}); // variadic list of eos's with shifted or scaled modifiers static constexpr const auto shifted_1 = transform_variadic_list(full_eos_list, al{}); static constexpr const auto scaled_1 = transform_variadic_list(full_eos_list, al{}); -// relativistic and unit system modifiers -static constexpr const auto unit_or_rel = - singularity::variadic_utils::concat(unit_system, relativistic); -// variadic list of eos with shifted, relativistic or unit system modifiers -static constexpr const auto shifted_of_unit_or_rel = - transform_variadic_list(unit_or_rel, al{}); +// variadic list of eos with shifted or unit system modifiers +static constexpr const auto shifted_of_unit = + transform_variadic_list(unit_system, al{}); // combined list of all shifted EOS static constexpr const auto shifted = - singularity::variadic_utils::concat(shifted_1, shifted_of_unit_or_rel); -// variadic list of eos with scaled, relativistic or unit system modifiers -static constexpr const auto scaled_of_unit_or_rel = - transform_variadic_list(unit_or_rel, al{}); + singularity::variadic_utils::concat(shifted_1, shifted_of_unit); +// variadic list of eos with scaled or unit system modifiers +static constexpr const auto scaled_of_unit = + transform_variadic_list(unit_system, al{}); // variadic list of Scaled>'s static constexpr const auto scaled_of_shifted = transform_variadic_list(shifted, al{}); // combined list of all scaled EOS -static constexpr const auto scaled = singularity::variadic_utils::concat( - scaled_1, scaled_of_unit_or_rel, scaled_of_shifted); +static constexpr const auto scaled = + singularity::variadic_utils::concat(scaled_1, scaled_of_unit, scaled_of_shifted); // create combined list static constexpr const auto combined_list_1 = - singularity::variadic_utils::concat(full_eos_list, shifted, scaled, unit_or_rel); + singularity::variadic_utils::concat(full_eos_list, shifted, scaled, unit_system); // make a ramped eos of everything static constexpr const auto ramped_all = transform_variadic_list(combined_list_1, al{}); diff --git a/singularity-eos/eos/singularity_eos.cpp b/singularity-eos/eos/singularity_eos.cpp index 4a03fba455..95a549cb8c 100644 --- a/singularity-eos/eos/singularity_eos.cpp +++ b/singularity-eos/eos/singularity_eos.cpp @@ -144,6 +144,7 @@ int init_sg_SAP_Polynomial(const int matindex, EOS *eos, const double rho0, const double b1, const double b2c, const double b2e, const double b3, int const *const enabled, double *const vals) { +#if SINGULARITY_USE_V_AND_V_EOS assert(matindex >= 0); EOS eosi = SGAPPLYMODSIMPLE(SAP_Polynomial(rho0, a0, a1, a2c, a2e, a3, b0, b1, b2c, b2e, b3)); @@ -154,6 +155,11 @@ int init_sg_SAP_Polynomial(const int matindex, EOS *eos, const double rho0, EOS eos_ = SGAPPLYMOD(SAP_Polynomial(rho0, a0, a1, a2c, a2e, a3, b0, b1, b2c, b2e, b3)); eos[matindex] = eos_.GetOnDevice(); return 0; +#else + PORTABLE_THROW_OR_ABORT("SAP Polynomial not currently supported. Please build with " + "-DSINGULARITY_USE_V_AND_V_EOS"); + return 1; +#endif // SINGULARITY_USE_V_AND_V_EOS } int init_sg_StiffGas(const int matindex, EOS *eos, const double gm1, const double Cv, @@ -178,6 +184,7 @@ int init_sg_StiffGas(const int matindex, EOS *eos, const double gm1, const doubl int init_sg_NobleAbel(const int matindex, EOS *eos, const double gm1, const double Cv, const double bb, const double qq, int const *const enabled, double *const vals) { +#if SINGULARITY_USE_V_AND_V_EOS assert(matindex >= 0); EOS eosi = SGAPPLYMODSIMPLE(NobleAbel(gm1, Cv, bb, qq)); if (enabled[3] == 1) { @@ -187,6 +194,11 @@ int init_sg_NobleAbel(const int matindex, EOS *eos, const double gm1, const doub EOS eos_ = SGAPPLYMOD(NobleAbel(gm1, Cv, bb, qq)); eos[matindex] = eos_.GetOnDevice(); return 0; +#else + PORTABLE_THROW_OR_ABORT("NobleAbel not currently supported. Please build with " + "-DSINGULARITY_USE_V_AND_V_EOS"); + return 1; +#endif // SINGULARITY_USE_V_AND_V_EOS } int init_sg_NobleAbel(const int matindex, EOS *eos, const double gm1, const double Cv, @@ -197,6 +209,7 @@ int init_sg_NobleAbel(const int matindex, EOS *eos, const double gm1, const doub int init_sg_CarnahanStarling(const int matindex, EOS *eos, const double gm1, const double Cv, const double bb, const double qq, int const *const enabled, double *const vals) { +#if SINGULARITY_USE_V_AND_V_EOS assert(matindex >= 0); EOS eosi = SGAPPLYMODSIMPLE(CarnahanStarling(gm1, Cv, bb, qq)); if (enabled[3] == 1) { @@ -206,6 +219,11 @@ int init_sg_CarnahanStarling(const int matindex, EOS *eos, const double gm1, EOS eos_ = SGAPPLYMOD(CarnahanStarling(gm1, Cv, bb, qq)); eos[matindex] = eos_.GetOnDevice(); return 0; +#else + PORTABLE_THROW_OR_ABORT("Carnahan Starling not currently supported. Please build with " + "-DSINGULARITY_USE_V_AND_V_EOS"); + return 1; +#endif // SINGULARITY_USE_V_AND_V_EOS } int init_sg_CarnahanStarling(const int matindex, EOS *eos, const double gm1, From dc803ed9a1c1bba12ef04bc366eee2ce1eebf42f Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 15:20:21 -0700 Subject: [PATCH 18/39] Disable python build in github tests as it now takes an incredibly long time, for unclear reasons --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 08d5bf3c42..59deb6f887 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,7 +33,7 @@ jobs: -DSINGULARITY_USE_SPINER=ON \ -DSINGULARITY_BUILD_TESTS=ON \ -DSINGULARITY_BUILD_EXAMPLES=ON \ - -DSINGULARITY_BUILD_PYTHON=ON \ + -DSINGULARITY_BUILD_PYTHON=OFF \ -DSINGULARITY_TEST_SESAME=OFF \ -DSINGULARITY_USE_HELMHOLTZ=ON \ -DSINGULARITY_TEST_HELMHOLTZ=ON \ From a0f00c456913579bb98cfafe515e87f337cbe7ff Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 15:23:36 -0700 Subject: [PATCH 19/39] update build to be parallel --- .github/workflows/tests.yml | 2 +- .github/workflows/tests_minimal.yml | 2 +- .github/workflows/tests_minimal_kokkos.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 59deb6f887..3037535941 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -44,6 +44,6 @@ jobs: #-DSINGULARITY_TEST_PYTHON=ON \ #-DSINGULARITY_TEST_STELLAR_COLLAPSE=ON \ #.. - make + make -j4 make install ctest --output-on-failure diff --git a/.github/workflows/tests_minimal.yml b/.github/workflows/tests_minimal.yml index d7e951e2b7..781802b3e9 100644 --- a/.github/workflows/tests_minimal.yml +++ b/.github/workflows/tests_minimal.yml @@ -34,6 +34,6 @@ jobs: -DSINGULARITY_FORCE_SUBMODULE_MODE=ON \ -DSINGULARITY_USE_KOKKOS=OFF \ .. - make + make -j4 make install make test diff --git a/.github/workflows/tests_minimal_kokkos.yml b/.github/workflows/tests_minimal_kokkos.yml index 5c84e43531..b966613845 100644 --- a/.github/workflows/tests_minimal_kokkos.yml +++ b/.github/workflows/tests_minimal_kokkos.yml @@ -34,6 +34,6 @@ jobs: -DSINGULARITY_FORCE_SUBMODULE_MODE=ON \ -DSINGULARITY_USE_KOKKOS=ON \ .. - make + make -j4 make install make test From c43afccc5dadf483189190652540abdd753b5e75 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 15:24:24 -0700 Subject: [PATCH 20/39] try enabling python build now again with parallel builds --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3037535941..58523c7fff 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,7 +33,7 @@ jobs: -DSINGULARITY_USE_SPINER=ON \ -DSINGULARITY_BUILD_TESTS=ON \ -DSINGULARITY_BUILD_EXAMPLES=ON \ - -DSINGULARITY_BUILD_PYTHON=OFF \ + -DSINGULARITY_BUILD_PYTHON=ON \ -DSINGULARITY_TEST_SESAME=OFF \ -DSINGULARITY_USE_HELMHOLTZ=ON \ -DSINGULARITY_TEST_HELMHOLTZ=ON \ From d282d091d4b777442cbae642e18bb0e069edaa45 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 15:29:56 -0700 Subject: [PATCH 21/39] undo removal of relativistic EOS --- singularity-eos/eos/eos_type_lists.hpp | 37 +++++++++++++++++--------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/singularity-eos/eos/eos_type_lists.hpp b/singularity-eos/eos/eos_type_lists.hpp index 8b8f776ffc..f5435bf128 100644 --- a/singularity-eos/eos/eos_type_lists.hpp +++ b/singularity-eos/eos/eos_type_lists.hpp @@ -50,9 +50,8 @@ using singularity::variadic_utils::transform_variadic_list; // all eos's static constexpr const auto full_eos_list = tl{}; +// eos's that get relativistic modifier +static constexpr const auto relativistic_eos_list = + tl{}; // eos's that get unit system modifier static constexpr const auto unit_system_eos_list = tl{}; // variadic list of UnitSystem's static constexpr const auto unit_system = transform_variadic_list(unit_system_eos_list, al{}); +// variadic list of Relativistic's +static constexpr const auto relativistic = + transform_variadic_list(relativistic_eos_list, al{}); // variadic list of eos's with shifted or scaled modifiers static constexpr const auto shifted_1 = transform_variadic_list(full_eos_list, al{}); static constexpr const auto scaled_1 = transform_variadic_list(full_eos_list, al{}); -// variadic list of eos with shifted or unit system modifiers -static constexpr const auto shifted_of_unit = - transform_variadic_list(unit_system, al{}); +// relativistic and unit system modifiers +static constexpr const auto unit_or_rel = + singularity::variadic_utils::concat(unit_system, relativistic); +// variadic list of eos with shifted, relativistic or unit system modifiers +static constexpr const auto shifted_of_unit_or_rel = + transform_variadic_list(unit_or_rel, al{}); // combined list of all shifted EOS static constexpr const auto shifted = - singularity::variadic_utils::concat(shifted_1, shifted_of_unit); -// variadic list of eos with scaled or unit system modifiers -static constexpr const auto scaled_of_unit = - transform_variadic_list(unit_system, al{}); + singularity::variadic_utils::concat(shifted_1, shifted_of_unit_or_rel); +// variadic list of eos with scaled, relativistic or unit system modifiers +static constexpr const auto scaled_of_unit_or_rel = + transform_variadic_list(unit_or_rel, al{}); // variadic list of Scaled>'s static constexpr const auto scaled_of_shifted = transform_variadic_list(shifted, al{}); // combined list of all scaled EOS -static constexpr const auto scaled = - singularity::variadic_utils::concat(scaled_1, scaled_of_unit, scaled_of_shifted); +static constexpr const auto scaled = singularity::variadic_utils::concat( + scaled_1, scaled_of_unit_or_rel, scaled_of_shifted); // create combined list static constexpr const auto combined_list_1 = - singularity::variadic_utils::concat(full_eos_list, shifted, scaled, unit_system); + singularity::variadic_utils::concat(full_eos_list, shifted, scaled, unit_or_rel); // make a ramped eos of everything static constexpr const auto ramped_all = transform_variadic_list(combined_list_1, al{}); From 090559e594ed2e2dd782a0e7031f9b3745a6e0bb Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 15:30:27 -0700 Subject: [PATCH 22/39] fix type list comma --- singularity-eos/eos/eos_type_lists.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/singularity-eos/eos/eos_type_lists.hpp b/singularity-eos/eos/eos_type_lists.hpp index f5435bf128..7f5fac724d 100644 --- a/singularity-eos/eos/eos_type_lists.hpp +++ b/singularity-eos/eos/eos_type_lists.hpp @@ -50,8 +50,9 @@ using singularity::variadic_utils::transform_variadic_list; // all eos's static constexpr const auto full_eos_list = tl Date: Tue, 17 Dec 2024 15:36:23 -0700 Subject: [PATCH 23/39] add parallel builds for the docs build --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index bd05a1cf88..0ea5fa525f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -40,7 +40,7 @@ jobs: -DSINGULARITY_USE_SPINER_WITH_HDF5=OFF \ -DSINGULARITY_FORCE_SUBMODULE_MODE=ON \ -B build . - cmake --build build + cmake --build build --parallel 4 sudo cmake --install build - name: build docs run: | From 780fbd439dfe4f97428a9b5250d48a6a5403450e Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 15:41:31 -0700 Subject: [PATCH 24/39] WHY IS IT DYING WITHOUT AN ERROR MESSAGE --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 58523c7fff..6fd375d412 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -44,6 +44,6 @@ jobs: #-DSINGULARITY_TEST_PYTHON=ON \ #-DSINGULARITY_TEST_STELLAR_COLLAPSE=ON \ #.. - make -j4 + VERBOSE=1 make -j4 make install ctest --output-on-failure From af1e70a634708eea7904b19f105ea067de06790d Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 15:56:38 -0700 Subject: [PATCH 25/39] turn off IPO to see if this fixes the memory problems with the linker --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6fd375d412..2d1582b335 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -40,6 +40,7 @@ jobs: -DSINGULARITY_FORCE_SUBMODULE_MODE=ON \ -DSINGULARITY_USE_V_AND_V_EOS=OFF \ -DSINGULARITY_PLUGINS=$(pwd)/../example/plugin \ + -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF \ .. #-DSINGULARITY_TEST_PYTHON=ON \ #-DSINGULARITY_TEST_STELLAR_COLLAPSE=ON \ From ed6622f1fa69d5c4bd8ecc7c8af3875d0e669146 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 15:57:13 -0700 Subject: [PATCH 26/39] no need for verbose output --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2d1582b335..2e1944b6b9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -45,6 +45,6 @@ jobs: #-DSINGULARITY_TEST_PYTHON=ON \ #-DSINGULARITY_TEST_STELLAR_COLLAPSE=ON \ #.. - VERBOSE=1 make -j4 + make -j4 make install ctest --output-on-failure From 39990f8c78d72da8e0d94ee46947851389f31021 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 16:14:51 -0700 Subject: [PATCH 27/39] switch to ld.gold linker --- .github/workflows/tests.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2e1944b6b9..e88574dd94 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,7 +21,7 @@ jobs: - name: install dependencies run: | sudo apt-get update -y -qq - sudo apt-get install -y --allow-downgrades --allow-remove-essential --allow-change-held-packages -qq build-essential gfortran libhdf5-serial-dev + sudo apt-get install -y --allow-downgrades --allow-remove-essential --allow-change-held-packages -qq build-essential gfortran libhdf5-serial-dev binutils-gold pip install numpy pip install h5py - name: build and run tests @@ -40,7 +40,9 @@ jobs: -DSINGULARITY_FORCE_SUBMODULE_MODE=ON \ -DSINGULARITY_USE_V_AND_V_EOS=OFF \ -DSINGULARITY_PLUGINS=$(pwd)/../example/plugin \ + # These options here are to reduce linker memory footprint -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF \ + -DCMAKE_LINKER=ld.gold \ .. #-DSINGULARITY_TEST_PYTHON=ON \ #-DSINGULARITY_TEST_STELLAR_COLLAPSE=ON \ From 6f6b6f87091657a534a130fff651d3d67bfeddeb Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 16:17:14 -0700 Subject: [PATCH 28/39] huh... --- .github/workflows/tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e88574dd94..1519a9c2d7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -40,7 +40,6 @@ jobs: -DSINGULARITY_FORCE_SUBMODULE_MODE=ON \ -DSINGULARITY_USE_V_AND_V_EOS=OFF \ -DSINGULARITY_PLUGINS=$(pwd)/../example/plugin \ - # These options here are to reduce linker memory footprint -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF \ -DCMAKE_LINKER=ld.gold \ .. From 830bb5ef838622a08b2c836862c62722533d6d08 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 16:17:59 -0700 Subject: [PATCH 29/39] disabling intraprocedural optimization seems to way slow down the build --- .github/workflows/tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1519a9c2d7..78eb1d06e9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -40,7 +40,6 @@ jobs: -DSINGULARITY_FORCE_SUBMODULE_MODE=ON \ -DSINGULARITY_USE_V_AND_V_EOS=OFF \ -DSINGULARITY_PLUGINS=$(pwd)/../example/plugin \ - -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF \ -DCMAKE_LINKER=ld.gold \ .. #-DSINGULARITY_TEST_PYTHON=ON \ From d0dcacd4b69bd989ba65564858fd2f75b03b4845 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 16:23:57 -0700 Subject: [PATCH 30/39] extend memory limits on system, use release build to remove debug symbols --- .github/workflows/tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 78eb1d06e9..28ea411ffe 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -28,6 +28,8 @@ jobs: run: | mkdir -p bin cd bin + ulimit -m unlimited + ulimit -v unlimited mkdir -p ${HOME}/install cmake -DCMAKE_INSTALL_PREFIX=${HOME}/install \ -DSINGULARITY_USE_SPINER=ON \ @@ -41,6 +43,7 @@ jobs: -DSINGULARITY_USE_V_AND_V_EOS=OFF \ -DSINGULARITY_PLUGINS=$(pwd)/../example/plugin \ -DCMAKE_LINKER=ld.gold \ + -DCMAKE_BUILD_TYPE=Release \ .. #-DSINGULARITY_TEST_PYTHON=ON \ #-DSINGULARITY_TEST_STELLAR_COLLAPSE=ON \ From bc721f8a85c5a7196b6f32a62320036aeaf73f7c Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 16:50:31 -0700 Subject: [PATCH 31/39] runner not available for ubuntu-noble now. Try older version string? --- .github/workflows/formatting.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/formatting.yml b/.github/workflows/formatting.yml index ef7fb71d26..2db899f0d6 100644 --- a/.github/workflows/formatting.yml +++ b/.github/workflows/formatting.yml @@ -9,7 +9,7 @@ on: jobs: formatting: name: Check Formatting - runs-on: ubuntu-noble + runs-on: ubuntu-22.04 steps: - name: Checkout code From fc3ee770023bd5c47b63b130682fe0986c147731 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 17:10:20 -0700 Subject: [PATCH 32/39] add doc info --- doc/sphinx/src/building.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/sphinx/src/building.rst b/doc/sphinx/src/building.rst index 2567f1f266..92e8361014 100644 --- a/doc/sphinx/src/building.rst +++ b/doc/sphinx/src/building.rst @@ -119,6 +119,7 @@ The main CMake options to configure building are in the following table: ``SINGULARITY_NQT_ORDER_1`` OFF For fast logs, use the less accurate but faster 1st-order version. ``SINGULARITY_NQT_PORTABLE`` OFF For fast logs, use the slower but endianness-independent implementation. ``SINGULARITY_STRICT_WARNINGS`` OFF For testing. Adds -Wall and -Werror to builds. + ``SINGULARITY_USE_V_AND_V_EOS`` OFF Enables several additional EOS models and adds them to the default variant ====================================== ======= =========================================== More options are available to modify only if certain other options or From 0e9f910b3a1630f07ba93ef1fa32c34c6c8b4ce7 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 17:12:13 -0700 Subject: [PATCH 33/39] add v&v EOS option to spackage --- spack-repo/packages/singularity-eos/package.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spack-repo/packages/singularity-eos/package.py b/spack-repo/packages/singularity-eos/package.py index 2bde1a8f57..101dce6398 100644 --- a/spack-repo/packages/singularity-eos/package.py +++ b/spack-repo/packages/singularity-eos/package.py @@ -79,6 +79,7 @@ class SingularityEos(CMakePackage, CudaPackage, ROCmPackage): variant("closure", default=True, description="Build closure module") variant("shared", default=False, description="Build shared libs") + variant("vandv", default=False, description="Enable V&V EOSs in default Singularity::Variant") plugins = {} @@ -211,6 +212,7 @@ def cmake_args(self): self.define_from_variant("SINGULARITY_USE_SPINER", "spiner"), self.define_from_variant("SINGULARITY_USE_SPINER_WITH_HDF5", "hdf5"), self.define_from_variant("BUILD_SHARED_LIBS", "shared"), + self.define_from_variant("SINGULARITY_USE_V_AND_V_EOS", "vandv"), self.define("SINGULARITY_BUILD_TESTS", self.run_tests), self.define( "SINGULARITY_BUILD_SESAME2SPINER", "sesame" in self.spec.variants["build_extra"].value From 2c013c30bf62fe090b50c5898f8f798f2137353a Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 17:13:08 -0700 Subject: [PATCH 34/39] spackage should have vandv set to true --- spack-repo/packages/singularity-eos/package.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spack-repo/packages/singularity-eos/package.py b/spack-repo/packages/singularity-eos/package.py index 101dce6398..de60ca00c3 100644 --- a/spack-repo/packages/singularity-eos/package.py +++ b/spack-repo/packages/singularity-eos/package.py @@ -79,7 +79,7 @@ class SingularityEos(CMakePackage, CudaPackage, ROCmPackage): variant("closure", default=True, description="Build closure module") variant("shared", default=False, description="Build shared libs") - variant("vandv", default=False, description="Enable V&V EOSs in default Singularity::Variant") + variant("vandv", default=True, description="Enable V&V EOSs in default Singularity::Variant") plugins = {} From 7368490bcca8c752698b3e6d061e45749c582bb5 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Tue, 17 Dec 2024 17:14:25 -0700 Subject: [PATCH 35/39] document spackage change --- doc/sphinx/src/building.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/sphinx/src/building.rst b/doc/sphinx/src/building.rst index 92e8361014..8b3c914c67 100644 --- a/doc/sphinx/src/building.rst +++ b/doc/sphinx/src/building.rst @@ -730,6 +730,9 @@ supports a number of relevant variants: +-----------------------------+-----------------+-----------------------------+ | tests [off] | on, off | Build tests | +-----------------------------+-----------------+-----------------------------+ +| vandv [on] | on, off | Add some V&V EOS's to the | +| | | Singularity::Variant | ++-----------------------------+-----------------+-----------------------------+ Developing ``singularity-eos`` using Spack ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 4e93e122228f09dcf353ace3b9b1c48f5fd1e77f Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Wed, 18 Dec 2024 12:01:17 -0700 Subject: [PATCH 36/39] Sam jones comments --- doc/sphinx/src/models.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/sphinx/src/models.rst b/doc/sphinx/src/models.rst index 5d377ac026..7472c9a47d 100644 --- a/doc/sphinx/src/models.rst +++ b/doc/sphinx/src/models.rst @@ -200,7 +200,8 @@ the proton mass. use :math:`\left\langle Z\right\rangle` to denote mean ionizaiton state. -Also by convention, the specific internal energy carried by electrons +Also, since the electron mass is negligible compared to the ion mass, +the specific internal energy carried by electrons :math:`\varepsilon_e` is specific with respect to the *ion* mass. In particular: @@ -562,7 +563,10 @@ so that P = \Gamma \rho C_V T -as expected. +as expected. (Note that the total mass per nucleus isn't exactly +:math:`\left\langle A\right\rangle m_p`, as protons and neutrons are +not exactly the same mass. However, it's close enough for all intents +and purposes.) The constructor takes only the ``MeanAtomicProperties`` struct, which is a required input: From 551fc3e69c4b1b65ec12d431da4ad169f1a191d7 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Wed, 18 Dec 2024 12:32:28 -0700 Subject: [PATCH 37/39] Update doc/sphinx/src/modifiers.rst Co-authored-by: Jeff Peterson <83598606+jhp-lanl@users.noreply.github.com> --- doc/sphinx/src/modifiers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/sphinx/src/modifiers.rst b/doc/sphinx/src/modifiers.rst index 678bd80c83..f2f1f57b62 100644 --- a/doc/sphinx/src/modifiers.rst +++ b/doc/sphinx/src/modifiers.rst @@ -200,8 +200,8 @@ equation of state and splits it into electron and ion components. The free electrons contributed per atomic nucleus, which is the mean atomic number in the case of full ionization, but could be smaller in the case of partial ionization. (It is zero for an unionized gas.) The -physical model of Z-split can be derived from an ideal gas equation of -state. For an ideal gas made up of electrons and ions, where all +physical model of Z-split can be derived by approximating the +material as an ideal gas. For an ideal gas made up of electrons and ions, where all molecular bonds have been broken, the total pressure is given by .. math:: From 6e255b9bcc42ddcd6ba12aae15db6961fc9ee005 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Wed, 18 Dec 2024 12:32:43 -0700 Subject: [PATCH 38/39] Update doc/sphinx/src/modifiers.rst Co-authored-by: Jeff Peterson <83598606+jhp-lanl@users.noreply.github.com> --- doc/sphinx/src/modifiers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sphinx/src/modifiers.rst b/doc/sphinx/src/modifiers.rst index f2f1f57b62..b6e5237c89 100644 --- a/doc/sphinx/src/modifiers.rst +++ b/doc/sphinx/src/modifiers.rst @@ -209,7 +209,7 @@ molecular bonds have been broken, the total pressure is given by P_t = (\left\langle Z\right\rangle + 1) \frac{\rho}{m_p \bar{A}} k_b T where :math:`\left\langle Z\right\rangle` is the mean ionization -state, :math:`rho` is the ion mass density (the electron ion mass +state, :math:`\rho` is the ion mass density (the electron ion mass density is negligible), :math:`m_p` is the proton mass, :math:`\bar{A}` is the mean atomic mass, :math:`k_b` is Boltzmann's constant, and :math:`T` is temperature. The contribution from From 5042643b5b858ccc106ad39c5a5e034d32a998b7 Mon Sep 17 00:00:00 2001 From: Jonah Miller Date: Wed, 18 Dec 2024 12:52:02 -0700 Subject: [PATCH 39/39] hjhp and pdmullen comments --- doc/sphinx/src/models.rst | 32 +++++++++++++++----- doc/sphinx/src/modifiers.rst | 25 +++++++++++++-- singularity-eos/eos/modifiers/zsplit_eos.hpp | 11 +++++++ 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/doc/sphinx/src/models.rst b/doc/sphinx/src/models.rst index 7472c9a47d..4fa44a29ef 100644 --- a/doc/sphinx/src/models.rst +++ b/doc/sphinx/src/models.rst @@ -164,6 +164,8 @@ functional forms for :math:`\Gamma` and the reference curves, the task of calculating a **thermodynamically consistent** temperature becomes more complicated. +.. _3T-Model: + The 3T Model `````````````` @@ -182,11 +184,11 @@ as .. math:: - n = \left\langle Z \right\rangle \frac{\rho}{\left\langle A\right\rangle m_p} + n = \left\langle Z \right\rangle \frac{\rho}{\overline{A} m_p} where here :math:`\left\langle Z\right\rangle` is the average number of electrons contributed per atom, also called mean ionization state, -:math:`\rho` is the ion mass density, :math:`\bar{A}` is the mean +:math:`\rho` is the ion mass density, :math:`\overline{A}` is the mean atomic mass (in grams per mole) of a given material and :math:`m_p` is the proton mass. @@ -196,7 +198,7 @@ the proton mass. ionization state and the average atomic number, as the symbol for both is :math:`Z`. To disambiguate in ``singularity-eos``, we use overbars to reference mean atomic properties such as mean atomic - mass :math:`\bar{A}` and mean atomic number :math:`\bar{Z}` while we + mass :math:`\overline{A}` and mean atomic number :math:`\overline{Z}` while we use :math:`\left\langle Z\right\rangle` to denote mean ionizaiton state. @@ -549,13 +551,13 @@ The pressure is given by the number density of electrons times .. math:: - P = \frac{\rho}{m_p \bar{A}}\left\langle Z \right\rangle k_b T + P = \frac{\rho}{m_p \overline{A}}\left\langle Z \right\rangle k_b T -The specific heat is then +for proton mass :math:`m_p`. The specific heat is then .. math:: - C_V = \frac{\left\langle Z \right\rangle k_b}{\Gamma m_p \bar{A}} + C_V = \frac{\left\langle Z \right\rangle k_b}{\Gamma m_p \overline{A}} so that @@ -564,7 +566,7 @@ so that P = \Gamma \rho C_V T as expected. (Note that the total mass per nucleus isn't exactly -:math:`\left\langle A\right\rangle m_p`, as protons and neutrons are +:math:`\overline{A} m_p`, as protons and neutrons are not exactly the same mass. However, it's close enough for all intents and purposes.) @@ -579,6 +581,22 @@ Optionally reference values may be provided for the entropy calculation, which is computed in the same way as the standard ideal gas. +.. note:: + + Since the mean ionization state is built into the heat capacity, the + entropy is zero until the material is ionized. This is physically + consistent, if there are no electrons, the total electron entropy + should be zero. + +.. note:: + + The electron entropy reference should probably be chosen to be + consistent with the chosen ionization model, such as a reference + temperature where ionization begins. This is about :math:`10^4` + Kelvin but will depend on the model and the material. This means + that the entropy reference temperature may be very different between + ions and electrons. + Calls to compute state variables require the mean ionization state, which must be passed in the ``lambda`` parameter, e.g., diff --git a/doc/sphinx/src/modifiers.rst b/doc/sphinx/src/modifiers.rst index 678bd80c83..ce0ad3e849 100644 --- a/doc/sphinx/src/modifiers.rst +++ b/doc/sphinx/src/modifiers.rst @@ -192,7 +192,7 @@ and temperature. Z-Split EOS ------------- -For 3T physics (as described in the models section) it is often +For 3T physics (as described in the :ref:`models section<3T-Model>`) it is often desirable to have a separate equation of state for electrons and a separate equation of state for ions. The Z-split model takes a total equation of state and splits it into electron and ion components. The @@ -206,12 +206,12 @@ molecular bonds have been broken, the total pressure is given by .. math:: - P_t = (\left\langle Z\right\rangle + 1) \frac{\rho}{m_p \bar{A}} k_b T + P_t = (\left\langle Z\right\rangle + 1) \frac{\rho}{m_p \overline{A}} k_b T where :math:`\left\langle Z\right\rangle` is the mean ionization state, :math:`rho` is the ion mass density (the electron ion mass density is negligible), :math:`m_p` is the proton mass, -:math:`\bar{A}` is the mean atomic mass, :math:`k_b` is Boltzmann's +:math:`\overline{A}` is the mean atomic mass, :math:`k_b` is Boltzmann's constant, and :math:`T` is temperature. The contribution from electrons is proportional to :math:`\left\langle Z\right\rangle`. @@ -268,6 +268,14 @@ and similarly for electrons, auto electron_eos = ZSPlitE(IdealGas(gm1, Cv); +.. note:: + + The Z-split modifier uses the mean atomic properties methods + provided by the underlying equation of state to pick, e.g., the + total number of nuclei per unit mass. This means you must specify + ``MeanAtomicProperties`` when constructing the underlying equation + of state. If you don't specify anything, hydrogen is assumed. + The Z-split modifier takes the ionization state as an additional parameter via the lambda. For example: @@ -276,6 +284,17 @@ parameter via the lambda. For example: Real lambda[1] = {Z}; Real Pe = electron_eos.PressureFromDensityTemperature(rho, temperature, lambda); +.. warning:: + + Several thermodynamic properties are approximated in the z-split + model due to incomplete information. Notably, the specific heat and + bulk modulus should depend on the electron chemical potential and + the ionization model: how much does the ionization state change with + respect to temperature? However, the ionization model is typically + decoupled from the equation of state and treated separately. As + such, this dependence is neglected here. This treatment may be + extended in the future. + .. note:: For now, the Z-split EOS is not in the default variant provided by diff --git a/singularity-eos/eos/modifiers/zsplit_eos.hpp b/singularity-eos/eos/modifiers/zsplit_eos.hpp index 3ef20a8496..eb9d68313c 100644 --- a/singularity-eos/eos/modifiers/zsplit_eos.hpp +++ b/singularity-eos/eos/modifiers/zsplit_eos.hpp @@ -109,6 +109,11 @@ class ZSplit : public EosBase> { return scale * t_.EntropyFromDensityInternalEnergy(rho, iscale * sie, lambda); } + // TODO(JMM): Formally, this should be d/dT (scale * sie_base) but + // we don't have access to d/dT scale, as it depends on d/dT + // which depends on the ionization model. In principle, we could + // request a derivative in the lambda or do something more + // sophisticated. We should keep that in mind going forward. template PORTABLE_INLINE_FUNCTION Real SpecificHeatFromDensityTemperature( const Real rho, const Real temperature, @@ -125,6 +130,12 @@ class ZSplit : public EosBase> { return scale * t_.SpecificHeatFromDensityInternalEnergy(rho, iscale * sie, lambda); } + // TODO(JMM): Formally this may also depend on the derivative of the + // ionization state with respect to volume along an + // isentrope. However, this cannot be included without more + // information from the ionization model. As with Cv we could in + // principle request a derivative in the lambda or do something more + // sophisticated. We should keep that in mind going forward. template PORTABLE_INLINE_FUNCTION Real BulkModulusFromDensityTemperature( const Real rho, const Real temperature,