-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make sure that DensityEnergyFromPressureTemperature works for all equations of state #449
Changes from 43 commits
4a210b5
50c08e7
acd9def
608a772
0bdead9
0a4b61a
f1d1fc4
c5f75a5
838b720
365dd65
376223f
9b083fa
c3182ff
1034b38
d6e80ee
5f79307
0e61f98
cc8db8f
58bc9c9
99aa6cd
1e72ff5
26dd8f5
be2f5b9
44e738b
fed072a
8cc2508
6dc8cae
bc5f10e
813e773
e0e587c
cf286de
2cdcc08
1d1873f
ceec265
8424efc
7d9c90a
ee5e374
38bba46
a74bd26
5f8e8e0
74ee377
9e4f844
1cd2f9d
6967e55
144b90b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,4 +36,4 @@ jobs: | |
.. | ||
make -j4 | ||
make install | ||
make test | ||
ctest --output-on-failure | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,4 +36,4 @@ jobs: | |
.. | ||
make -j4 | ||
make install | ||
make test | ||
ctest --output-on-failure |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1143,18 +1143,75 @@ quantities as outputs. | |
Methods Used for Mixed Cell Closures | ||
-------------------------------------- | ||
|
||
Several methods were developed in support of mixed cell closures. In particular: | ||
Several methods were developed in support of mixed cell closures. In particular the function | ||
|
||
.. cpp:function:: Real MinimumDensity() const; | ||
|
||
and | ||
the function | ||
|
||
.. cpp:function:: Real MinimumTemperature() const; | ||
|
||
and the function | ||
|
||
.. cpp:function:: Real MaximumDensity() const; | ||
|
||
provide bounds for valid inputs into a table, which can be used by a | ||
root finder to meaningful bound the root search. Similarly, | ||
root finder to meaningful bound the root search. | ||
|
||
.. warning:: | ||
|
||
For unbounded equations of state, ``MinimumDensity`` and | ||
``MinimumTemperature`` will return zero, while ``MaximumDensity`` | ||
will return a very large finite number. Which number you get, | ||
however, is not guaranteed. You may wish to apply more sensible | ||
bounds in your own code. | ||
|
||
Similarly, | ||
|
||
.. cpp:function:: Real RhoPmin(const Real temp) const; | ||
|
||
returns the density at which pressure is minimized for a given | ||
temperature. This is again useful for root finds. | ||
temperature. The function | ||
|
||
.. cpp:function:: Real MinimumPressure() const; | ||
|
||
provides the minimum pressure an equation of state supports, which may | ||
be the most negative tension state. The function | ||
|
||
.. cpp:function:: Real MaximumPressureFromTemperature() const; | ||
|
||
provides a maximum possible pressure an equation of state | ||
supports. (Most models are unbounded in pressure.) This is again | ||
useful for root finds. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you're modeling this off of what I did in the Gruneisen EOS, this isn't correct. This gives the maximum pressure at a given temperature. If you increase the temperature, the maximum pressure will increase. For a sesame table, this would simply be I know our convention is to use "From" in our lookup functions, but I'd argue this is subtly different and should be "At" instead. I'd argue our lookups are saying "Return a quantity given the provided state" ("Given" would be more accurate in the naming, but I'm not proposing it here). By contrast, this function does not take a complete thermodynamic state, instead taking a single variable and returning the information to form a complete state. Temperature by itself is not a complete thermodynamic state. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I completely agree--I change the name. For the tabulated equations of state, I actually do pull it out and record it now (thinking ahead), but I let this float as the table interpolation does extrapolate off the top of the table. It's not particularly trustworthy, but it's not a hard limit. Only Gruneisen currently reports a maximum pressure bound. On the other hand, I do have each table report the minimum pressure, which is important. |
||
|
||
The function | ||
|
||
.. code-block:: cpp | ||
|
||
template <typename Indexer_t = Real*> | ||
void DensityEnergyFromPressureTemperature(const Real press, const Real temp, | ||
Indexer_t &&lambda, Real &rho, Real &sie) const; | ||
|
||
is designed for working in Pressure-Temperature space. Given a | ||
pressure ``press`` and temperature ``temp``, it sets a density ``rho`` | ||
and specific internal energy ``sie``. | ||
|
||
.. note:: | ||
|
||
Note that ``lambda`` must be passed in, whether or not a given | ||
equation of state requires one. You may pass in ``nullptr`` safely, | ||
however. | ||
Yurlungur marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Typically this operation requires a root find. You may pass in an | ||
initial guess for the density ``rho`` in-place and most EOS models | ||
will use it. | ||
|
||
.. warning:: | ||
|
||
Pressure is not necessarily monotone in density and it may be double | ||
valued. Thus you are not guaranteed to find the correct root and the | ||
value of your initial guess may determine correctness. The fact that | ||
``rho`` may be used as an initial guess means you **must** pass in | ||
an initialized variable, even if it is zero-initialized. Do not pass | ||
uninitialized memory into this function! | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,11 +16,14 @@ | |
#define _SINGULARITY_EOS_EOS_EOS_BASE_ | ||
|
||
#include <cstring> | ||
#include <limits> | ||
#include <string> | ||
|
||
#include <ports-of-call/portability.hpp> | ||
#include <ports-of-call/portable_errors.hpp> | ||
#include <singularity-eos/base/constants.hpp> | ||
#include <singularity-eos/base/robust_utils.hpp> | ||
#include <singularity-eos/base/root-finding-1d/root_finding.hpp> | ||
#include <singularity-eos/base/variadic_utils.hpp> | ||
|
||
namespace singularity { | ||
|
@@ -781,6 +784,25 @@ class EosBase { | |
PORTABLE_FORCEINLINE_FUNCTION | ||
Real MinimumTemperature() const { return 0; } | ||
|
||
// Report maximum value of density. Default is unbounded. | ||
// JMM: Should we use actual infinity, the largest real, or just a | ||
// big number? For comparisons, actual infinity is better. It also | ||
// has the advantage of being projective with modifiers that modify | ||
// the max. On the other hand, it's more fraught if someone tries to | ||
// put it into a formula without guarding against it. | ||
PORTABLE_FORCEINLINE_FUNCTION | ||
Real MaximumDensity() const { return 1e100; } | ||
|
||
// These are for the PT space PTE solver to bound the iterations in | ||
// a safe range. | ||
PORTABLE_FORCEINLINE_FUNCTION | ||
Real MinimumPressure() const { return 0; } | ||
// Gruneisen EOS's often have a maximum density, which implies a maximum pressure. | ||
PORTABLE_FORCEINLINE_FUNCTION | ||
Real MaximumPressureFromTemperature([[maybe_unused]] const Real T) const { | ||
return 1e100; | ||
} | ||
|
||
PORTABLE_INLINE_FUNCTION | ||
Real RhoPmin(const Real temp) const { return 0.0; } | ||
|
||
|
@@ -836,6 +858,50 @@ class EosBase { | |
PORTABLE_ALWAYS_THROW_OR_ABORT(msg); | ||
} | ||
|
||
// JMM: This method is often going to be overloaded for special cases. | ||
template <typename Indexer_t = Real *> | ||
PORTABLE_INLINE_FUNCTION void | ||
DensityEnergyFromPressureTemperature(const Real press, const Real temp, | ||
Indexer_t &&lambda, Real &rho, Real &sie) const { | ||
Comment on lines
+859
to
+863
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This default implementation is usually not optimal but does seem to work if a given EOS doesn't need special cases. In general, though, an EOS should overload and implement its own. |
||
using RootFinding1D::findRoot; // more robust but slower. Better default. | ||
using RootFinding1D::Status; | ||
|
||
// Pressure is not monotone in density at low densities, which can | ||
// prevent convergence. We want to approach tension from above, | ||
// not below. Choose close to, but above, normal density for a | ||
// metal like copper. | ||
constexpr Real DEFAULT_RHO_GUESS = 12; | ||
|
||
CRTP copy = *(static_cast<CRTP const *>(this)); | ||
|
||
// P(rho) not monotone. When relevant, bound rhopmin. | ||
Real rhomin = std::max(copy.RhoPmin(temp), copy.MinimumDensity()); | ||
Real rhomax = copy.MaximumDensity(); | ||
PORTABLE_REQUIRE(rhomax > rhomin, "max bound > min bound"); | ||
|
||
auto PofRT = [&](const Real r) { | ||
return copy.PressureFromDensityTemperature(r, temp, lambda); | ||
}; | ||
Real rhoguess = rho; // use input density | ||
if ((rhoguess <= rhomin) || (rhoguess >= rhomax)) { // avoid edge effects | ||
if ((rhomin < DEFAULT_RHO_GUESS) && (DEFAULT_RHO_GUESS < rhomax)) { | ||
rhoguess = DEFAULT_RHO_GUESS; | ||
} else { | ||
rhoguess = 0.5 * (rhomin + rhomax); | ||
} | ||
} | ||
auto status = findRoot(PofRT, press, rhoguess, rhomin, rhomax, robust::EPS(), | ||
robust::EPS(), rho); | ||
// JMM: This needs to not fail and instead return something sane. | ||
// If root find failed to converge, density will at least be | ||
// within bounds. | ||
if (status != Status::SUCCESS) { | ||
PORTABLE_WARN("DensityEnergyFromPressureTemperature failed to find root\n"); | ||
} | ||
sie = copy.InternalEnergyFromDensityTemperature(rho, temp, lambda); | ||
return; | ||
} | ||
|
||
// Serialization | ||
/* | ||
The methodology here is there are *three* size methods all EOS's provide: | ||
|
Yurlungur marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd like to leave this permanently. You still get a summary out at the end, but here we can see what went wrong with a test. Useful for debugging, especially when the CI machine and your laptop disagree...