Skip to content

Commit

Permalink
Merge pull request #279 from lanl/bjm/noble-abel
Browse files Browse the repository at this point in the history
Bjm/noble abel
  • Loading branch information
jhp-lanl authored Aug 10, 2023
2 parents 984e6d0 + 8522a9f commit c95e6fa
Show file tree
Hide file tree
Showing 11 changed files with 923 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- [[PR232]](https://github.com/lanl/singularity-eos/pull/228) Fixed uninitialized cmake path variables

### Added (new features/APIs/variables/...)
- [[PR279]](https://github.com/lanl/singularity-eos/pull/279) added noble-abel EoS
- [[PR274]](https://github.com/lanl/singularity-eos/pull/274) added a stiffened gas EoS
- [[PR254]](https://github.com/lanl/singularity-eos/pull/254) added ability to peel off modifiers as needed
- [[PR250]](https://github.com/lanl/singularity-eos/pull/250) added mass fraction output to stellar collapse eos
Expand Down
60 changes: 60 additions & 0 deletions doc/sphinx/src/models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

.. _WillsThermo: https://www.osti.gov/biblio/1561015

.. _NobleAbel: https://doi.org/10.1063/5.0079187

.. _StiffGas: https://doi.org/10.1016/j.ijthermalsci.2003.09.002


Expand Down Expand Up @@ -482,6 +484,64 @@ these values are not set, they will be the same as those returned by the
conditions are given, the return values of the :code:`ValuesAtReferenceState()`
function will not be the same.

Noble-Abel
``````````

The implementation here was influenced by the reference `NobleAbel`_. The Noble-Abel (aka Clausius I or Hirn) model in ``singularity-eos`` takes
the form

.. math::
P = \frac{ \rho (e-q) (\gamma-1) }{ 1 - b \rho }
.. math::
e = C_V T + q,
where quantities are similar to the ideal gas law with the exception of covolume (:math:`b`) and offset internal energy (:math:`q`).
It should be noted that covolume is physically significant as it represents the maximum compressibility of the gas, and as a result it should be non-negative.

The entropy for the Noble-Abel EoS is given by

.. math::
S = C_V \ln\left(\frac{T}{T_0}\right) + C_V (\gamma-1) \ln\left(\frac{v - b}
{v_0 - b}\right) + q',
where :math:`S(\rho_0,T_0)=q'`. By default, :math:`T_0 = 298` K and the
reference density is given by

.. math::
\rho_0 = \frac{P_0}{C_V T_0(\gamma-1) + bP_0},
where :math:`P_0` is by default 1 bar.

The settable parameters for this EOS are :math:`\gamma-1`, specific
heat capacity (:math:`C_V`), covolume (:math:`b`) and offset internal energy (:math:`q`). Optionally, the reference state for the entropy calculation can
be provided by setting the reference temperature, pressure, and entropy offset.

The ``NobleAbel`` EOS constructor has four arguments: ``gm1``, which is :math:`\gamma-1`; ``Cv``, the
specific heat :math:`C_V`; :math:`b`, the covolume; and :math:`q`, the internal energy offset.

.. code-block:: cpp
NobleAbel(Real gm1, Real Cv, Real b, Real q)
Optionally, the reference state for the entropy calculation,
can be provided in the constructor via ``qp``, ``T0`` and ``P0``:

.. code-block:: cpp
NobleAbel(Real gm1, Real Cv, Real b, Real q, Real qp, Real T0, Real P0)
Note that these parameters are provided solely for the entropy calculation. When
these values are not set, they will be the same as those returned by the
:code:`ValuesAtReferenceState()` function. However, if the entropy reference
conditions are given, the return values of the :code:`ValuesAtReferenceState()`
function will not be the same.

Gruneisen EOS
`````````````

Expand Down
2 changes: 2 additions & 0 deletions singularity-eos/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ set(EOS_HEADERS
eos/modifiers/eos_unitsystem.hpp
eos/eos_base.hpp
eos/eos_eospac.hpp
eos/eos_noble_abel.hpp
eos/eos_stiff.hpp
)

set(EOS_SRCS
Expand Down
3 changes: 2 additions & 1 deletion singularity-eos/eos/eos.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <singularity-eos/eos/eos_gruneisen.hpp>
#include <singularity-eos/eos/eos_ideal.hpp>
#include <singularity-eos/eos/eos_jwl.hpp>
#include <singularity-eos/eos/eos_noble_abel.hpp>
#include <singularity-eos/eos/eos_sap_polynomial.hpp>
#include <singularity-eos/eos/eos_spiner.hpp>
#include <singularity-eos/eos/eos_stellar_collapse.hpp>
Expand Down Expand Up @@ -66,7 +67,7 @@ using singularity::detail::transform_variadic_list;
// all eos's
static constexpr const auto full_eos_list =
tl<IdealGas, Gruneisen, Vinet, JWL, DavisReactants, DavisProducts, StiffGas,
SAP_Polynomial
SAP_Polynomial, NobleAbel
#ifdef SINGULARITY_USE_SPINER_WITH_HDF5
,
SpinerEOSDependsRhoT, SpinerEOSDependsRhoSie, StellarCollapse
Expand Down
210 changes: 210 additions & 0 deletions singularity-eos/eos/eos_noble_abel.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
//------------------------------------------------------------------------------
// © 2021-2023. 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_EOS_NOBLE_ABEL_HPP_
#define _SINGULARITY_EOS_EOS_EOS_NOBLE_ABEL_HPP_

// stdlib
#include <cmath>
#include <cstdio>
#include <string>

// Ports-of-call
#include <ports-of-call/portability.hpp>

// Base stuff
#include <singularity-eos/base/constants.hpp>
#include <singularity-eos/base/eos_error.hpp>
#include <singularity-eos/base/robust_utils.hpp>
#include <singularity-eos/eos/eos_base.hpp>

namespace singularity {

using namespace eos_base;

class NobleAbel : public EosBase<NobleAbel> {
public:
NobleAbel() = default;
PORTABLE_INLINE_FUNCTION NobleAbel(Real gm1, Real Cv, Real bb, Real qq)
: _Cv(Cv), _gm1(gm1), _bb(bb), _qq(qq), _T0(ROOM_TEMPERATURE),
_P0(ATMOSPHERIC_PRESSURE), _qp(0.0),
_rho0(robust::ratio(_P0, gm1 * Cv * _T0 + bb * _P0)),
_vol0(robust::ratio(gm1 * Cv * _T0 + bb * _P0, _P0)), _sie0(Cv * _T0 + qq),
_bmod0(robust::ratio(_rho0 * Cv * _T0 * gm1 * (gm1 + 1.0),
(1.0 - bb * _rho0) * (1.0 - bb * _rho0))),
_dpde0(robust::ratio(_rho0 * gm1, 1.0 - bb * _rho0)) {
checkParams();
}
PORTABLE_INLINE_FUNCTION NobleAbel(Real gm1, Real Cv, Real bb, Real qq, Real qp,
Real T0, Real P0)
: _Cv(Cv), _gm1(gm1), _bb(bb), _qq(qq), _T0(T0), _P0(P0), _qp(qp),
_rho0(robust::ratio(P0, gm1 * Cv * T0 + bb * P0)),
_vol0(robust::ratio(gm1 * Cv * T0 + bb * P0, P0)), _sie0(Cv * T0 + qq),
_bmod0(robust::ratio(_rho0 * Cv * T0 * gm1 * (gm1 + 1.0),
(1.0 - bb * _rho0) * (1.0 - bb * _rho0))),
_dpde0(robust::ratio(_rho0 * gm1, 1.0 - bb * _rho0)) {
checkParams();
}
NobleAbel GetOnDevice() { return *this; }
PORTABLE_INLINE_FUNCTION Real TemperatureFromDensityInternalEnergy(
const Real rho, const Real sie, Real *lambda = nullptr) const {
return std::max(robust::SMALL(), (sie - _qq) / _Cv);
}
PORTABLE_INLINE_FUNCTION void checkParams() const {
PORTABLE_ALWAYS_REQUIRE(_Cv > 0, "Heat capacity must be positive");
PORTABLE_ALWAYS_REQUIRE(_gm1 >= 0, "Gruneisen parameter must be positive");
PORTABLE_ALWAYS_REQUIRE(_bb >= 0, "Covolume must be positive");
}
PORTABLE_INLINE_FUNCTION Real InternalEnergyFromDensityTemperature(
const Real rho, const Real temperature, Real *lambda = nullptr) const {
return std::max(_qq, _Cv * temperature + _qq);
}
PORTABLE_INLINE_FUNCTION Real PressureFromDensityTemperature(
const Real rho, const Real temperature, Real *lambda = nullptr) const {
return std::max(robust::SMALL(),
robust::ratio(_gm1 * rho * _Cv * temperature, 1.0 - _bb * rho));
}
PORTABLE_INLINE_FUNCTION Real PressureFromDensityInternalEnergy(
const Real rho, const Real sie, Real *lambda = nullptr) const {
return std::max(robust::SMALL(),
robust::ratio(_gm1 * rho * (sie - _qq), 1.0 - _bb * rho));
}
PORTABLE_INLINE_FUNCTION Real EntropyFromDensityTemperature(
const Real rho, const Real temperature, Real *lambda = nullptr) const {
const Real vol = robust::ratio(1.0, rho);
return _Cv * std::log(robust::ratio(temperature, _T0) + robust::SMALL()) +
_gm1 * _Cv *
std::log(robust::ratio(vol - _bb, _vol0 - _bb) + robust::SMALL()) +
_qp;
}
PORTABLE_INLINE_FUNCTION Real EntropyFromDensityInternalEnergy(
const Real rho, const Real sie, Real *lambda = nullptr) const {
const Real vol = robust::ratio(1.0, rho);
return _Cv * std::log(robust::ratio(sie - _qq, _sie0 - _qq) + robust::SMALL()) +
_gm1 * _Cv *
std::log(robust::ratio(vol - _bb, _vol0 - _bb) + robust::SMALL()) +
_qp;
}
PORTABLE_INLINE_FUNCTION Real SpecificHeatFromDensityTemperature(
const Real rho, const Real temperature, Real *lambda = nullptr) const {
return _Cv;
}
PORTABLE_INLINE_FUNCTION Real SpecificHeatFromDensityInternalEnergy(
const Real rho, const Real sie, Real *lambda = nullptr) const {
return _Cv;
}
PORTABLE_INLINE_FUNCTION Real BulkModulusFromDensityTemperature(
const Real rho, const Real temperature, Real *lambda = nullptr) const {
return std::max(robust::SMALL(),
robust::ratio(_gm1 * (_gm1 + 1.0) * rho * _Cv * temperature,
(1.0 - _bb * rho) * (1.0 - _bb * rho)));
}
PORTABLE_INLINE_FUNCTION Real BulkModulusFromDensityInternalEnergy(
const Real rho, const Real sie, Real *lambda = nullptr) const {
return std::max(robust::SMALL(),
robust::ratio(_gm1 * (_gm1 + 1.0) * rho * (sie - _qq),
(1.0 - _bb * rho) * (1.0 - _bb * rho)));
}
PORTABLE_INLINE_FUNCTION Real GruneisenParamFromDensityTemperature(
const Real rho, const Real temperature, Real *lambda = nullptr) const {
return robust::ratio(_gm1, (1.0 - _bb * rho));
}
PORTABLE_INLINE_FUNCTION Real GruneisenParamFromDensityInternalEnergy(
const Real rho, const Real sie, Real *lambda = nullptr) const {
return robust::ratio(_gm1, (1.0 - _bb * rho));
}
PORTABLE_INLINE_FUNCTION void FillEos(Real &rho, Real &temp, Real &energy, Real &press,
Real &cv, Real &bmod, const unsigned long output,
Real *lambda = nullptr) const;
PORTABLE_INLINE_FUNCTION
void ValuesAtReferenceState(Real &rho, Real &temp, Real &sie, Real &press, Real &cv,
Real &bmod, Real &dpde, Real &dvdt,
Real *lambda = nullptr) const {
// use STP: 1 atmosphere, room temperature
rho = _rho0;
temp = _T0;
sie = _sie0;
press = _P0;
cv = _Cv;
bmod = _bmod0;
dpde = _dpde0;
}
// Generic functions provided by the base class. These contain e.g. the vector
// overloads that use the scalar versions declared here
SG_ADD_BASE_CLASS_USINGS(NobleAbel)
PORTABLE_INLINE_FUNCTION
int nlambda() const noexcept { return 0; }
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("Noble-Abel Parameters:\nGamma = %g\nCv = %g\nb = %g\nq = "
"%g\n",
_gm1 + 1.0, _Cv, _bb, _qq);
}
PORTABLE_INLINE_FUNCTION void
DensityEnergyFromPressureTemperature(const Real press, const Real temp, Real *lambda,
Real &rho, Real &sie) const {
sie = std::max(_qq, _Cv * temp + _qq);
rho =
std::max(robust::SMALL(), robust::ratio(press, _gm1 * _Cv * temp + _bb * press));
}
inline void Finalize() {}
static std::string EosType() { return std::string("NobleAbel"); }
static std::string EosPyType() { return EosType(); }

private:
Real _Cv, _gm1, _bb, _qq;
// optional reference state variables
Real _T0, _P0, _qp;
// reference values
Real _rho0, _vol0, _sie0, _bmod0, _dpde0;
// static constexpr const Real _T0 = ROOM_TEMPERATURE;
// static constexpr const Real _P0 = ATMOSPHERIC_PRESSURE;
static constexpr const unsigned long _preferred_input =
thermalqs::density | thermalqs::specific_internal_energy;
};

PORTABLE_INLINE_FUNCTION
void NobleAbel::FillEos(Real &rho, Real &temp, Real &sie, Real &press, Real &cv,
Real &bmod, const unsigned long output, Real *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 * (1.0 - _bb * rho) / _gm1 + _qq;
}
if (output & thermalqs::pressure) press = PressureFromDensityInternalEnergy(rho, sie);
if (output & thermalqs::temperature)
temp = TemperatureFromDensityInternalEnergy(rho, sie);
if (output & thermalqs::bulk_modulus)
bmod = BulkModulusFromDensityInternalEnergy(rho, sie);
if (output & thermalqs::specific_heat)
cv = SpecificHeatFromDensityInternalEnergy(rho, sie);
}

} // namespace singularity

#endif // _SINGULARITY_EOS_EOS_EOS_NOBLE_ABEL_HPP_
20 changes: 20 additions & 0 deletions singularity-eos/eos/singularity_eos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,27 @@ int init_sg_StiffGas(const int matindex, EOS *eos, const double gm1, const doubl
return init_sg_StiffGas(matindex, eos, gm1, Cv, Pinf, qq, def_en, def_v);
}

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) {
assert(matindex >= 0);
EOS eosi = SGAPPLYMODSIMPLE(NobleAbel(gm1, Cv, bb, qq));
if (enabled[3] == 1) {
singularity::pAlpha2BilinearRampParams(eosi, vals[2], vals[3], vals[4], vals[2],
vals[3], vals[4], vals[5]);
}
EOS eos_ = SGAPPLYMOD(NobleAbel(gm1, Cv, bb, qq));
eos[matindex] = eos_.GetOnDevice();
return 0;
}

int init_sg_NobleAbel(const int matindex, EOS *eos, const double gm1, const double Cv,
const double bb, const double qq) {
return init_sg_NobleAbel(matindex, eos, gm1, Cv, bb, qq, def_en, def_v);
}

#ifdef SINGULARITY_USE_SPINER_WITH_HDF5

int init_sg_SpinerDependsRhoT(const int matindex, EOS *eos, const char *filename,
const int matid, int const *const enabled,
double *const vals) {
Expand Down
27 changes: 27 additions & 0 deletions singularity-eos/eos/singularity_eos.f90
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module singularity_eos
init_sg_JWL_f,&
init_sg_DavisProducts_f,&
init_sg_DavisReactants_f,&
init_sg_NobleAbel_f,&
init_sg_SAP_Polynomial_f,&
init_sg_StiffGas_f,&
init_sg_SpinerDependsRhoT_f,&
Expand Down Expand Up @@ -123,6 +124,19 @@ end function init_sg_DavisProducts
end function init_sg_DavisReactants
end interface

interface
integer(kind=c_int) function &
init_sg_NobleAbel(matindex, eos, gm1, Cv, bb, qq, sg_mods_enabled, &
sg_mods_values) &
bind(C, name='init_sg_NobleAbel')
import
integer(c_int), value, intent(in) :: matindex
type(c_ptr), value, intent(in) :: eos
real(kind=c_double), value, intent(in) :: gm1, Cv, bb, qq
type(c_ptr), value, intent(in) :: sg_mods_enabled, sg_mods_values
end function init_sg_NobleAbel
end interface

interface
integer(kind=c_int) function &
init_sg_StiffGas(matindex, eos, gm1, Cv, Pinf, qq, sg_mods_enabled, &
Expand Down Expand Up @@ -400,6 +414,19 @@ integer function init_sg_StiffGas_f(matindex, eos, gm1, Cv, &
err = init_sg_StiffGas(matindex-1, eos%ptr, gm1, Cv, Pinf, qq, &
c_loc(sg_mods_enabled), c_loc(sg_mods_values))
end function init_sg_StiffGas_f

integer function init_sg_NobleAbel_f(matindex, eos, gm1, Cv, &
bb, qq, &
sg_mods_enabled, sg_mods_values) &
result(err)
integer(c_int), value, intent(in) :: matindex
type(sg_eos_ary_t), intent(in) :: eos
real(kind=8), value, intent(in) :: gm1, Cv, bb, qq
integer(kind=c_int), dimension(:), target, intent(inout) :: sg_mods_enabled
real(kind=8), dimension(:), target, intent(inout) :: sg_mods_values
err = init_sg_NobleAbel(matindex-1, eos%ptr, gm1, Cv, bb, qq, &
c_loc(sg_mods_enabled), c_loc(sg_mods_values))
end function init_sg_NobleAbel_f

integer function init_sg_SpinerDependsRhoT_f(matindex, eos, filename, id, &
sg_mods_enabled, &
Expand Down
Loading

0 comments on commit c95e6fa

Please sign in to comment.