Equation of State
Castro is written in a modular fashion so that the EOS can be supplied by the user. No equations of state are distributed with Castro, instead they are part of the separate Microphysics repository.
Most equations of state are written to take \((\rho, T, X_k)\) as input and return the needed thermodynamic quantities. For other inputs, a Newton-Raphson root find is done.
Most of the standard problem setups in Castro (such as the Sedov blast wave)
use the gamma_law
EOS. This represents a gamma law gas, with equation of state:
The gas is currently assumed to be monatomic and ideal.
Runtime Parameters
When inverting the EOS (e.g. by using eos_input_re
), an initial guess for
the temperature is required. This guess is provided by the runtime parameter
castro.T_guess
, and should be set to a sensible value for each problem
(it will vary depending on which EOS is used).
EOS Interfaces and Parameters
Each EOS should have two main routines by which it interfaces to the
rest of Castro. At the beginning of the simulation, eos_init
will perform any initialization steps and save EOS variables (mainly
smallt
, the temperature floor, and smalld
, the
density floor). Then, whenever you want to call the EOS, use:
eos (eos_input, eos_state)
The first argument specifies the inputs to the EOS. The options
that are currently available are stored in Microphysics in
interfaces/eos_type.H
, and are always a combination of two
thermodynamic quantities. For example, eos_input_rt
means
that we call the EOS with \(\rho\) (density) and \(T\) (temperature)
and we expect the EOS to return the associated thermodynamic
quantities such as internal energy \(e\) and entropy \(s\).
We note that for real (non-analytic) equations of state
in which \(\rho\), \(T\) and species are the independent variables, such
as the Helmholtz EOS, eos_input_rt
directly calls the EOS
and obtains the other thermodynamic variables. But for other inputs,
e.g. eos_input_re
, a Newton-Raphson iteration is performed
to find the density or temperature that corresponds to the given
input.
The eos_state variable is a C struct, eos_t
. It stores a complete
set of thermodynamic
variables. When calling the EOS, you should first fill the variables
that are the inputs, for example with
eos_t eos_state;
...
eos_state.rho = state(i,j,k,URHO);
eos_state.T = state(i,j,k,UTEMP);
eos_state.e = state(i,j,k,UEINT) / state(i,j,k,URHO);
for (int n = 0; n < NumSpec; ++n) {
eos_state.xn[n] = state(i,j,k,UFS+n) / state(i,j,k,URHO);
}
for (int n = 0; n < NumAux; ++n) {
eos_state.aux[n] = state(i,j,k,UFX+n) / state(i,j,k,URHO);
}
Whenever the eos_state
type is initialized, the thermodynamic
state variables are filled with unphysical numbers. If you do not
input the correct arguments to match your input quantities, the EOS
will call an error. This means that it is good practice to fill the
quantities that will be iterated over with an initial guess. Indeed,
this initial guess is typically required for equations of state that
iterate over this variable, as the values they are initialized with
will likely not converge. Usually a prior value of the temperature or
density suffices if it’s available, but if not then use T_guess
or
small_dens
.
Required Thermodynamics Quantities
Three input quantities are required of any EOS:
eos_input_re
: \(\rho\), \(e\), and \(X_k\) are inputeos_input_rt
: \(\rho\), \(T\), and \(X_k\) are inputeos_input_rp
: \(\rho\), \(P\), and \(X_k\) are input
The eos_t
derived type holds a large number of thermodynamics
quantities, but not all of these are needed for basic
Castro operation. The main quantities that any EOS in any mode needs to
supply, if they are not input, are:
eos_state.T
: the temperatureeos_state.p
: total pressureeos_state.e
: the specific energyeos_state.gam1
: the first adiabatic index, \(\Gamma_1 = d\log P / d\log \rho |_s\)
Additionally the eos_input_re
mode also needs to supply:
eos_state.cs
: the adiabatic sound speedeos_state.dpdr_e
: the derivative, \(\partial p/\partial \rho |_e\) — note that the specific internal energy, \(e\) is held constant here.eos_state.dpde
: the derivative, \(\partial p / \partial e |_\rho\)
For radiation hydro, the eos_input_rt
model needs to supply:
eos_state.cv
: the specific heat capacity.
Other quantities (e.g., entropy) might be needed for the derived variables that are optional output into the plotfiles.
Composition derivatives
A separate type, eos_xderivs_t
provides access to derivatives with respect to mass fraction.
eos_xderivs.dhdX[NumSpec]
: the derivative of the specific enthalpy with respect to mass fraction at constant \(T\) and \(p\):\[\xi_k = e_{X_k} + \frac{1}{p_\rho} \left (\frac{p}{\rho^2} - e_\rho \right ) p_{X_k}\]eos_xderivs.dpdX[NumSpec]
: the derivative of the pressure with respect to mass fraction:\[\begin{split}\begin{align} p_{X_k} &= \left .\frac{\partial p}{\partial \bar{A}} \right |_{\rho, T, \bar{Z}} \frac{\partial \bar{A}}{\partial X_k} + \left . \frac{\partial p}{\partial \bar{Z}} \right |_{\rho, T, \bar{A}} \frac{\partial \bar{Z}}{\partial X_k} \nonumber \\ &= -\frac{\bar{A}^2}{A_k} \left .\frac{\partial p}{\partial \bar{A}} \right |_{\rho, T, \bar{Z}} + \frac{\bar{A}}{A_k} \left (Z_k - \bar{Z} \right ) \left . \frac{\partial p}{\partial \bar{Z}} \right |_{\rho, T, \bar{A}} \end{align}\end{split}\]eos_xderivs.dedX[NumSpec]
: the derivative of the specific internal energy with respect to mass fraction:\[\begin{split}\begin{align} e_{X_k} &= \left . \frac{\partial e }{\partial \bar{A}} \right |_{\rho, T, \bar{Z}} \frac{\partial \bar{A}}{\partial X_k} + \left .\frac{\partial e}{\partial \bar{Z}} \right |_{\rho, T, \bar{A}} \frac{\partial \bar{Z}}{\partial X_k} \nonumber \\ &= -\frac{\bar{A}^2}{A_k} \left . \frac{\partial e }{\partial \bar{A}} \right |_{\rho, T, \bar{Z}} + \frac{\bar{A}}{A_k} \left (Z_k - \bar{Z}\right ) \left .\frac{\partial e}{\partial \bar{Z}} \right |_{\rho, T, \bar{A}} \end{align}\end{split}\]
(see [20], Appendix A).