Skip to content
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

Merged
merged 45 commits into from
Jan 9, 2025

Conversation

Yurlungur
Copy link
Collaborator

@Yurlungur Yurlungur commented Dec 24, 2024

PR Summary

The easiest way to get the Jacobian for the PT-space PTE solver we are building is to ensure that the DensityEnergyFromPressureTemperature call works consistently for all equations of state. This MR makes sure thats the case and threads this call through all the tests.

To ease this process, I added a base class implementation. However, I think most classes will want their own implementations, and I added them when appropriate.

PR Checklist

  • Adds a test for any bugs fixed. Adds tests for new features.
  • Format your changes by using the make format command after configuring with cmake.
  • Document any new features, update documentation for changes made.
  • Make sure the copyright notice on any files you modified is up to date.
  • After creating a pull request, note it in the CHANGELOG.md file.
  • LANL employees: make sure tests pass both on the github CI and on the Darwin CI

If preparing for a new release, in addition please check the following:

  • Update the version in cmake.
  • Move the changes in the CHANGELOG.md file under a new header for the new release, and reset the categories.
  • Ensure that any when='@main' dependencies are updated to the release version in the package.py

@Yurlungur Yurlungur added bug Something isn't working enhancement New feature or request Testing Additions/changes to the testing infrastruture Robustness Ensures that existing features work as intended labels Dec 24, 2024
@Yurlungur Yurlungur self-assigned this Dec 24, 2024
@@ -36,4 +36,4 @@ jobs:
..
make -j4
make install
make test
ctest --output-on-failure
Copy link
Collaborator Author

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...

Comment on lines +841 to +845
// 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 {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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.

Comment on lines 870 to 874
// JMM: This needs to not fail and instead return something sane
if (status != Status::SUCCESS) {
PORTABLE_WARN("DensityEnergyFromPressureTemperature failed to find root\n");
rho = rhoguess;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a function that may be passed data and I see it as similar to a PTE solve. Even if it fails out, something reasonable must be done.

singularity-eos/eos/eos_helmholtz.hpp Show resolved Hide resolved
Comment on lines 132 to 139
PORTABLE_FORCEINLINE_FUNCTION
Real MaximumDensity() const {
if (_s > 1) {
return 0.99 * robust::ratio(_s * _rho0, _s - 1);
} else { // for s <= 1, no maximum, but we need to pick something.
return 1e3 * _rho0;
}
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the conditions where the reference isotherm is a positive temperature.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly the $s &lt; 0$ case implies that the fundamental shock derivative is negative and the EOS is no longer convex, so it's not a very useful EOS. I think what you picked is as good as any for that case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I will add a comment to this effect.

Comment on lines 129 to 130
PORTABLE_FORCEINLINE_FUNCTION
Real MinimumDensity() const { return 10 * robust::EPS(); }
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the reference isotherm scales as _rho0/rho, the EOS diverges at zero density. This bounds it at least to some degree.

Comment on lines +667 to +669
auto lPofRT = [&](Real lR) { return lP_.interpToReal(Ye, lT, lR); };
auto status = regula_falsi(lPofRT, lP, lrguess, lRhoMin_, lRhoMax_, ROOT_THRESH,
ROOT_THRESH, lrguess);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the EOS is tabulated in logrho, use logrho for the root find.

@@ -131,6 +131,10 @@ class Vinet : public EosBase<Vinet> {
ValuesAtReferenceState(Real &rho, Real &temp, Real &sie, Real &press, Real &cv,
Real &bmod, Real &dpde, Real &dvdt,
Indexer_t &&lambda = static_cast<Real *>(nullptr)) const;

PORTABLE_FORCEINLINE_FUNCTION
Real MinimumDensity() const { return std::cbrt(10 * robust::EPS()) * _rho0; }
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EOS depends on $\left(\frac{\rho_0}{\rho}\right)^{1/3}$ so a reasonable bound before the EOS will become ill behaved is this.

Comment on lines -155 to -159
// Density/Energy from P/T not unique, if used will give error
template <typename Indexer_t = Real *>
PORTABLE_INLINE_FUNCTION void
DensityEnergyFromPressureTemperature(const Real press, const Real temp,
Indexer_t &&lambda, Real &rho, Real &sie) const;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use the default in the base class

Comment on lines +147 to +150
template <typename EOS, typename Indexer_t = Real *>
PORTABLE_INLINE_FUNCTION bool
CheckRhoSieFromPT(EOS eos, Real rho, Real T,
Indexer_t &&lambda = static_cast<Real *>(nullptr)) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Convenience function to let me test the functionality more easily

@Yurlungur
Copy link
Collaborator Author

Ok that was finicky but tests on github now seem to be passing. re-git tests appear to be having some network issues. Ping @rbberger for after the holidays. :)

singularity-eos/eos/eos_base.hpp Outdated Show resolved Hide resolved
singularity-eos/eos/eos_helmholtz.hpp Show resolved Hide resolved
Comment on lines 132 to 139
PORTABLE_FORCEINLINE_FUNCTION
Real MaximumDensity() const {
if (_s > 1) {
return 0.99 * robust::ratio(_s * _rho0, _s - 1);
} else { // for s <= 1, no maximum, but we need to pick something.
return 1e3 * _rho0;
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly the $s &lt; 0$ case implies that the fundamental shock derivative is negative and the EOS is no longer convex, so it's not a very useful EOS. I think what you picked is as good as any for that case.

singularity-eos/eos/eos_mgusup.hpp Outdated Show resolved Hide resolved
singularity-eos/eos/eos_mgusup.hpp Show resolved Hide resolved
@Yurlungur
Copy link
Collaborator Author

OK... that took longer than I thought it would. All tests now passing once again and the machinery is more flexible and robust. @jhp-lanl please re-review when you get the chance. I believe I've addressed all your concerns.

I also noticed that the DensityEnergyFromPressureTemperature function wasn't documented. It's documented now.

@Yurlungur
Copy link
Collaborator Author

Ping @jhp-lanl

@jhp-lanl
Copy link
Collaborator

jhp-lanl commented Jan 8, 2025

Ping @jhp-lanl

I'll try to re-review that by the end of today.

@Yurlungur
Copy link
Collaborator Author

Snuck in introspection for pressure into this MR as well.

@Yurlungur Yurlungur mentioned this pull request Jan 8, 2025
13 tasks
Copy link
Collaborator

@jhp-lanl jhp-lanl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving because none of my comments are really blocking. That said, I do think the name change to MaximumPressureAtTemperature() would be preferable. I also think the documentation should be changed to indicate that there could be a temperature dependence for the maximum pressure if an EOS supports it.

Comment on lines 1181 to 1185
.. 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.
Copy link
Collaborator

Choose a reason for hiding this comment

The 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 $P(\rho_\mathrm{max}, T)$ assuming that $\rho_\mathrm{max}$ is not inside the vapor dome for some strange reason.

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.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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.

doc/sphinx/src/using-eos.rst Outdated Show resolved Hide resolved
singularity-eos/eos/eos_eospac.hpp Outdated Show resolved Hide resolved
singularity-eos/eos/eos_variant.hpp Outdated Show resolved Hide resolved
@Yurlungur
Copy link
Collaborator Author

Thanks for the review, @jhp-lanl ! Agree with your comments and have addressed them. Will merge once tests pass on re-git.

@Yurlungur Yurlungur merged commit 3f78b83 into main Jan 9, 2025
8 checks passed
@Yurlungur Yurlungur deleted the jmm/pt-of-re-everywhere branch January 9, 2025 17:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request Robustness Ensures that existing features work as intended Testing Additions/changes to the testing infrastruture
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants