Equation of State Unit
Introduction
The Eos
unit implements the equation of state needed by the
hydrodynamics and nuclear burning solvers. The function
physics/Eos/Eos
provides the interface for operating on a
single data point. A macro (eos_args
) is defined to provide a list
of arguments. It is highly recommended using this macro in both, the
the declaration section of the caller and in the call to the function
itself. This recommendation stems from the possibility of the
interface needing to change in future if other variants of Eos are
introduced. This function can be
used to find the thermodynamic quantities either from the density,
temperature, and composition or from the density, internal energy, and
composition.
For user’s convenience, two wrapper functions are
provided. (physics/Eos/Eos_vector
) takes in a two dimensional
array of data points where the first dimension is the length of the
vector, and the second dimension is for the physical
quantities, both input and output. The index of each physical quantity for the second
dimension is included in Eos.h
. In FLASH all interfaces of Eos
used a single-dimensional vector and one had to find the offset for
the desired physical quantity. Use of two-dimensional array has
obviated the need for this additional step. The second wrapper
function is physics/Eos/Eos_multiDim
which takes a pointer to a multidimensional array of data,
computes kinetic energy if velocities are included in the data, and
converts the data to the two-dimension vector format. It then calls
the physics/Eos/Eos_vector
function, and upon return from
the function, it translates the returned data back to the same
mutidimensional array..
Two implementations of the (Eos
) unit are available in the
Flash-X distribution, and a third can be imported if desired (see the
Readme at the top level of the source for instructions to import). The
two that are included in the distribution are:
Gamma
which implements a perfect-gas equation of
state; and Helmholtz
which uses a fast Helmholtz free-energy table
interpolation to handle degenerate/relativistic electrons/positrons
and includes radiation pressure and ions (via the perfect gas
approximation). For WeakLib
, the imported implementation, the
necessary functions to make the calls compatible with Flash-X’s API
are included in the distribution. A hybrid implementation that can
call either the Helmholtz
or the WeakLib
version depending on
the state of the matter is also included in the distribution.
As described in previous sections, Flash-X evolves the Euler equations for compressible, inviscid flow. This system of equations must be closed by an additional equation that provides a relation between the thermodynamic quantities of the gas. This relationship is known as the equation of state for the material, and its structure and properties depend on the composition of the gas.
It is common to call an equation of state (henceforth EOS) routine more than \(10^9\) times during a two-dimensional simulation and more than \(10^{11}\) times during the course of a three-dimensional simulation of stellar phenomena. Thus, it is very desirable to have an EOS that is as efficient as possible, yet accurately represents the relevant physics. While Flash-X is capable of using any general equation of state, we discuss here the two primary versions that are supplied: an ideal-gas or gamma-law EOS, and a tabular Helmholtz free energy EOS appropriate for stellar interiors. The gamma-law EOS consists of simple analytic expressions that make for a very fast EOS routine in the case of a single gas. The Helmholtz EOS includes much more physics and relies on a table look-up scheme for performance.
Gamma Law
Flash-X uses the method of Colella & Glaz (1985) to handle general equations of state. General equations of state contain 4 adiabatic indices (Chandrasekhar 1939), but the method of Colella & Glaz parameterizes the EOS and requires only two of the adiabatic indices The first is necessary to calculate the adiabatic sound speed and is given by
The second relates the pressure to the energy and is given by
These two adiabatic indices are stored as the mesh-based variables
GAMC_VAR
and GAME_VAR
. All EOS routines must return
\(\gamma_1\), and \(\gamma_4\) is calculated from
[Eqn:game].
The gamma-law EOS models a simple ideal gas with a constant adiabatic index \(\gamma\). Here we have dropped the subscript on \(\gamma\), because for an ideal gas, all adiabatic indices are equal. The relationship between pressure \(P\), density \(\rho\), and specific internal energy \(\epsilon\) is
We also have an expression relating pressure to the temperature \(T\)
where \(N_a\) is the Avogadro number, \(k\) is the Boltzmann constant, and \(\bar{A}\) is the average atomic mass, defined as
where \(X_i\) is the mass fraction of the \(i\)th element. Equating these expressions for pressure yields an expression for the specific internal energy as a function of temperature
We note that the analytic expressions apply to both the forward (internal energy as a function of density, temperature, and composition) and backward (temperature as a function of density, internal energy and composition) relations. Because the backward relation requires no iteration in order to obtain the temperature, this EOS is quite inexpensive to evaluate. Despite its fast performance, use of the gamma-law EOS is limited, due to its restricted range of applicability for astrophysical problems.
In the current distribution of Flash-X we have excluded the multigamma version because of lack of use-cases. It will be included in future distributions.
Helmholtz
The Helmholtz EOS provided with the Flash-X distribution contains more physics and is appropriate for addressing astrophysical phenomena in which electrons and positrons may be relativistic and/or degenerate and in which radiation may significantly contribute to the thermodynamic state. Full details of the Helmholtz equation of state are provided in Timmes & Swesty (1999). This EOS includes contributions from radiation, completely ionized nuclei, and degenerate/relativistic electrons and positrons. The pressure and internal energy are calculated as the sum over the components
Here the subscripts “rad,” “ion,” “ele,” “pos,” and “coul” represent the contributions from radiation, nuclei, electrons, positrons, and corrections for Coulomb effects, respectively. The radiation portion assumes a blackbody in local thermodynamic equilibrium, the ion portion (nuclei) is treated as an ideal gas with \(\gamma \, = \, 5/3\), and the electrons and positrons are treated as a non-interacting Fermi gas.
The blackbody pressure and energy are calculated as
where \(a\) is related to the Stephan-Boltzmann constant \(\sigma_B \, = \, a c/4\), and \(c\) is the speed of light. The ion portion of each routine is the ideal gas of () with \(\gamma \, = \, 5/3\). The number densities of free electrons \(N_{\rm ele}\) and positrons \(N_{\rm pos}\) in the noninteracting Fermi gas formalism are given by
where \(h\) is Planck’s constant, \(m_{\rm e}\) is the electron rest mass, \(\beta \: = \: k T / (m_{\rm e} c^2)\) is the relativity parameter, \(\eta \: = \: \mu / k T\) is the normalized chemical potential energy \(\mu\) for electrons, and \(F_{k}(\eta,\beta)\) is the Fermi-Dirac integral
Because the electron rest mass is not included in the chemical potential, the positron chemical potential must have the form \(\eta_{{\rm pos}} \, = \, -\eta - 2/\beta\). For complete ionization, the number density of free electrons in the matter is
and charge neutrality requires
Solving this equation with a standard one-dimensional root-finding algorithm determines \(\eta\). Once \(\eta\) is known, the Fermi-Dirac integrals can be evaluated, giving the pressure, specific thermal energy, and entropy due to the free electrons and positrons. From these, other thermodynamic quantities such as \(\gamma_1\) and \(\gamma_4\) are found. Full details of this formalism may be found in Fryxell et al. (2000) and references therein.
The above formalism requires many complex calculations to evaluate the thermodynamic quantities, and routines for these calculations typically are designed for accuracy and thermodynamic consistency at the expense of speed. The Helmholtz EOS in Flash-X provides a table of the Helmholtz free energy (hence the name) and makes use of a thermodynamically consistent interpolation scheme obviating the need to perform the complex calculations required of the above formalism during the course of a simulation. The interpolation scheme uses a bi-quintic Hermite interpolant resulting in an accurate EOS that performs reasonably well.
The Helmholtz free energy,
is the appropriate thermodynamic potential for use when the temperature and density are the natural thermodynamic variables. The free energy table distributed with Flash-X was produced from the Timmes EOS (Timmes & Arnett 1999). The Timmes EOS evaluates the Fermi-Dirac integrals [Eqn:eos7] and their partial derivatives with respect to \(\eta\) and \(\beta\) to machine precision with the efficient quadrature schemes of Aparicio (1998) and uses a Newton-Raphson iteration to obtain the chemical potential of [Eqn:eos9]. All partial derivatives of the pressure, entropy, and internal energy are formed analytically. Searches through the free energy table are avoided by computing hash indices from the values of any given \((T,\rho \bar{Z}/\bar{A})\) pair. No computationally expensive divisions are required in interpolating from the table; all of them can be computed and stored the first time the EOS routine is called.
We note that the Helmholtz free energy table is constructed for only the electron-positron plasma, and it is a 2-dimensional function of density and temperature, i.e. \(F(\rho,{\rm T})\). It is made with \({\bar {\rm A}} \, = \, {\bar {\rm Z}} = 1\) (pure hydrogen), with an electron fraction \(Y_{\rm e} \, = \, 1\). One reason for not including contributions from photons and ions in the table is that these components of the Helmholtz EOS are very simple (), and one doesn’t need fancy table look-up schemes to evaluate simple analytical functions. A more important reason for only constructing an electron-positron EOS table with \(Y_{\rm e} \, = \, 1\) is that the 2-dimensional table is valid for any composition. Separate planes for each \(Y_{\rm e}\) are not necessary (or desirable), since simple multiplication by \(Y_{\rm e}\) in the appropriate places gives the desired composition scaling. If photons and ions were included in the table, then this valuable composition independence would be lost, and a 3-dimensional table would be necessary.
The Helmholtz EOS has been subjected to considerable analysis and testing (Timmes & Swesty 2000), and particular care was taken to reduce the numerical error introduced by the thermodynamical models below the formal accuracy of the hydrodynamics algorithm (Fryxell, et al. 2000; Timmes & Swesty 2000). The physical limits of the Helmholtz EOS are \(10^{-10}\,<\,\rho\,<\,10^{11}~({\rm g~cm}^{-3})\) and \(10^{4}\,<\,T\,<\,10^{11}\) (K). As with the gamma-law EOS, the Helmholtz EOS provides both forward and backward relations. In the case of the forward relation (\(\rho, T\), given along with the composition) the table lookup scheme and analytic formulae directly provide relevant thermodynamic quantities. In the case of the backward relation (\(\rho, \epsilon\), and composition given), the routine performs a Newton-Rhaphson iteration to determine temperature. It is possible for the input variables to be changed in the iterative modes since the solution is not exact. The returned quantities are thermodynamically consistent.
Usage
Initialization
The initialization function of the Eos unit physics/Eos/Eos_init
is
fairly simple for theideal gas gamma law implementation included.
It gathers the runtime parameters and the physical constants needed by
the equation of state and stores them in the data module. The Helmholtz
EOS physics/Eos/Eos_init
routine is a little more complex. The
Helmholtz
EOS requires an input file helm_table.dat
that
contains the lookup table for the electron contributions. This table is
currently stored in ASCII for portability purposes. When the table is
first read in, a binary version called helm_table.bdat
is created.
This binary format can be used for faster subsequent restarts on the
same machine but may not be portable across platforms. The Eos_init
routine reads in the table data on processor 0 and broadcasts it to all
other processors.
Runtime Parameters
Runtime parameters for the Gamma
unit require the user to set the
thermodynamic properties for the single gas. Eos/gamma
,
Eos/eos_singleSpeciesA
, Eos/eos_singleSpeciesZ
set the ratio of
specific heats and the nucleon and proton numbers for the gas.
For the Helmholtz equation of state, the table-lookup algorithm requires
a given temperature and density. When temperature or internal energy are
supplied as the input parameter, an iterative solution is found.
Therefore, no matter what mode is selected for Helmholtz
input, the
best initial value of temperature should be provided to speed
convergence of the iterations. The iterative solver is controlled by two
vruntime parameters Eos/eos_maxNewton
and Eos/eos_tolerance
which
define the maximum number of iterations and convergence tolerance. An
additional runtime parameter for Helmholtz
, Eos/eos_coulumbMult
,
indicates whether or not to apply Coulomb corrections. In some regions
of the \(\rho\)-\(T\) plane, the approximations made in the
Coulomb corrections may be invalid and result in negative pressures.
When the parameter eos_coulombMult
is set to zero, the Coulomb
corrections are not applied.
Direct and Wrapped Calls
The primary function in the Eos
unit operates on a single data point, taking
density, composition, and either temperature, internal energy, or
pressure as input, and returning \(\gamma_1\), and either the
pressure, temperature or internal energy (whichever was not used as
input). This equation of state interface is particularly useful for initializing an
application instance. The user is given direct control over the input and output,
since everything is passed through the argument list. Certain optional quantities such
electron pressure, degeneracy parameter, and thermodynamic derivatives
can be calculated by the physics/Eos/Eos
function if needed. They
are computed if an optional argument derivs
is present in the call.
The hydrodynamic and burning computations repeatedly call the Eos
function to update pressure and temperature during the course of their
calculation. Typically, values in all the cells of the block need of be
updated in these calls. Additionally, the kinetic energy in the system
should be taken into account for accuracy. The single point interface
is not aware of velocities, and therefore cannot consider the effects
of kinetic energey directly. For user convenience several interfaces
are provided to make the invocation of Eos more convenient.
The interface physics/Eos/Eos_fillEosData
convert data coming in as a
multidimensional array of grid data into a two dimensional data
structure and physics/Eos/Eos_getFromEosData
does the reverse. It
puts the updated values returned in the two dimensional array into the
multidimensional grid data.
The interface physics/Eos/Eos_vector
applies EOS to the two
dimensional vectorised data points given to it. Similar to the
physics/Eos/Eos
, this interface does not have access to the
velocity and other grid data values. It assumes that the calling
routine will have either invoked physics/Eos/Eos_fillEosData
or
otherwise accounted for kinetice energy if it is desired before
calling this routine. Similarly it expects an invocation of
physics/Eos/Eos_getFromEosData
by the
calling routine afterwards if those same effects are to be accounted
for. The difference between physics/Eos/Eos
and
physics/Eos/Eos_vector
is that the former works on a single data
point while the latter works on a vector of data point.
An additional interface physics/Eos/Eos_multiDim
provides a means by which the
details of translating the data from block to vector and back, and
accounting for kinetic energy are hidden
from the calling unit. This interface permits the caller to
define a multidimensional collection of cells along each their lower
and upper bounds. These are typically either a whole block or a
section of block. The Eos_multiDim
returns updated values in the
same multidimensional array where the input values were provided. The
internal mechanisms for manipulating the data are transparent to the
user. The main implementation of this routine calls
physics/Eos/Eos_fillEosData
, physics/Eos/Eos_vector
and
physics/Eos/Eos_getFromEosData
in that order.
This wrapper routine does not calculate the optional derivative
quantities. If they are needed, one needs to call either point-wise of
vector based interfaces with the optional arguement derivs
in the argument list of the invoking call..
Unit Test
The unit test of the Eos function can exercise all the
implementations. Because the Gamma law allows only one species, the
setup required for each implementations is specific. To invoke any
three-dimensional Eos
unit test, the command is:
./setup unitTest/Eos/
implementation-auto -3d
where implementation is one of Gamma
, Helmholtz
, or
Hybrid/Helmholtz_Weaklib
. The Eos
unit test works on the assumption that if the
four physical variables in question (density, pressure, energy and
temperature) are in thermal equilibrium with one another, then applying
the equation of state to any two of them should leave the other two
completely unchanged. Hence, if we initialize density and temperature
with some arbitrary values, and apply the equation of state to them in
MODE_DENS_TEMP
, then we should get pressure and energy values that
are thermodynamically consistent with density and temperature. Now after
saving the original temperature value, we apply the equation of state to
density and newly calculated pressure. The new value of the temperature
should be identical to the saved original value. This verifies that the
Eos
unit is computing correctly in MODE_DENS_PRES
mode. By
repeating this process for the remaining two modes, we can say with
great confidence that the Eos
unit is functioning normally.
In our implementation of the Eos unit test, the initial conditions applied to the domain create a gradient for density along the \(x\) axis and gradients for temperature and pressure along the \(y\) axis. If the test is being run for the Helmholtz implementation, then the species are initialized to have gradients along the \(z\) axis. The initial conditions for the Hybrid unit test make sure that physical conditions are generated that would cause one set of cells to call the Helmholtz implementation, another set to call the Weaklib implementation and yet another set to call both.