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

Fix Bug in PTE Solver and Several Code Quality Improvements #383

Merged
merged 72 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from 66 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
ef88154
Simplify line search and add comments
jhp-lanl Jun 27, 2024
8b99c75
Make sure the scale that comes out is the minimum over all checks
jhp-lanl Jun 27, 2024
896c205
Merge branch 'jhp/get_sg_introspection' into jhp/robust_pte
jhp-lanl Jun 27, 2024
f60e4b4
Remove commented variable and add clarifying comment
jhp-lanl Jun 27, 2024
f501b2a
Clang format
jhp-lanl Jun 27, 2024
9cb3627
Merge branch 'jhp/get_sg_introspection' into jhp/robust_pte
jhp-lanl Jun 27, 2024
2afe06e
Merge branch 'jhp/get_sg_introspection' into jhp/robust_pte
jhp-lanl Jun 27, 2024
ca3d16a
Change behavior to assume small mass fraction materials are at the ce…
jhp-lanl Jun 28, 2024
a853cbc
Clang format
jhp-lanl Jun 28, 2024
2c9ecac
Merge branch 'main' of github.com:lanl/singularity-eos into jhp/robus…
jhp-lanl Jul 1, 2024
e885113
min not needed since scales are checked sequentially _after_ being mo…
jhp-lanl Jul 2, 2024
71250a5
Add sanity check that initial volume fractions add up to 1 or less
jhp-lanl Jul 2, 2024
a4e1f0c
Add more asserts and label what is going on if an assert is tripped
jhp-lanl Jul 2, 2024
5e947cd
Remove volume fraction sum check since it's really not relevant and p…
jhp-lanl Jul 2, 2024
9b3f900
Clang format
jhp-lanl Jul 2, 2024
3538048
Add comment about ScaleDx
jhp-lanl Jul 2, 2024
1916267
Add mass fraction cutoff argument
jhp-lanl Jul 4, 2024
bb61c27
Add closure unit test
jhp-lanl Jul 4, 2024
1e2952b
Change TestUpdate() to take an argument to reset the cached variables…
jhp-lanl Jul 4, 2024
52de0c4
Move #endif to be in proper place
jhp-lanl Jul 4, 2024
ac21c03
Fix another misplaced #endif
jhp-lanl Jul 4, 2024
6dd5411
Clang format
jhp-lanl Jul 4, 2024
bf28497
Expliclty depend on ports-of-call1.6.0 for new printf
jhp-lanl Jul 9, 2024
f017752
Fix typo in scale update and skip update if appropriate
jhp-lanl Jul 11, 2024
f913f97
Link Catch2 to closure
jhp-lanl Jul 11, 2024
d834c84
Add PORTABLE_FREE and change check condition temporarily
jhp-lanl Jul 11, 2024
724639e
Missing semicolon
jhp-lanl Jul 11, 2024
33269a4
Add back in a couple free statements
jhp-lanl Jul 11, 2024
ae40f6a
Fix bug in other PTE solvers
jhp-lanl Jul 11, 2024
b994fdf
Remove requirements on volume fractions within iteration since there'…
jhp-lanl Jul 11, 2024
af9e22a
Add check to ensure step size is always less than or equal to Newton …
jhp-lanl Jul 11, 2024
ddb1969
Add PTE solver bug
jhp-lanl Jul 11, 2024
1c5d5b7
Change singularity version for updated POC
jhp-lanl Jul 11, 2024
21a67ad
Merge branch 'main' of github.com:lanl/singularity-eos into jhp/robus…
jhp-lanl Jul 11, 2024
65788e5
Remove debug checks from inside the PTE solver iteration
jhp-lanl Jul 11, 2024
49fbd27
Add PORTABLE_FREE and finalize... this should work but doesn't
jhp-lanl Jul 11, 2024
0974b11
Fix memory allocation
jhp-lanl Jul 11, 2024
aab092a
Merge branch 'main' into jhp/robust_pte
Yurlungur Jul 12, 2024
1a048ad
Break out parts of tests into functions
jhp-lanl Jul 16, 2024
92cde1c
Merge branch 'jhp/robust_pte' of github.com:lanl/singularity-eos into…
jhp-lanl Jul 16, 2024
3a67f5b
Merge branch 'main' of github.com:lanl/singularity-eos into jhp/robus…
jhp-lanl Jul 16, 2024
b03cb44
Remove portable copy and instead just output GetOnDevice() to device …
jhp-lanl Jul 16, 2024
843057c
add missing header
jhp-lanl Jul 16, 2024
ae688b8
Consolidate ifdef statements
jhp-lanl Jul 16, 2024
50edd22
Get on device and _then_ copy EOS array to device. Also free each lam…
jhp-lanl Jul 16, 2024
10fb97a
Remove using namespace singularity and instead explicitly bring thing…
jhp-lanl Jul 16, 2024
a9edf92
Clang format
jhp-lanl Jul 16, 2024
8e89d45
Make PTE call on device
jhp-lanl Jul 16, 2024
a27eecb
Clang format
jhp-lanl Jul 16, 2024
a825f1e
Change type of iteration variable
jhp-lanl Jul 16, 2024
5e89dd3
Add copper material for closure unit test
jhp-lanl Jul 17, 2024
14a5303
Allocate lambda memory all at once and then use accessor to index int…
jhp-lanl Jul 17, 2024
73b6ea4
Clang format
jhp-lanl Jul 17, 2024
200531e
fix typo
jhp-lanl Jul 17, 2024
592c2d3
Free lambda memory, not the struct itself
jhp-lanl Jul 17, 2024
b68f524
Ensure Finalize() is called from the host and combine tests
jhp-lanl Jul 17, 2024
e59140f
Clang format
jhp-lanl Jul 17, 2024
53f4198
Fix silly bugs
jhp-lanl Jul 17, 2024
e9db000
Switch to using SINGULARITY_USE_SPINER_WITH_HDF5 for closure test
jhp-lanl Jul 18, 2024
e9dbf6e
Make parameter constexpr
jhp-lanl Jul 18, 2024
3adea33
Clang format
jhp-lanl Jul 18, 2024
f32ca90
Enforce convention that '*_TEST_*' variables are defined in the test …
jhp-lanl Jul 18, 2024
4588d76
Make comments more descriptive
jhp-lanl Jul 19, 2024
7d35c43
Don't call GetOnDevice() twice
jhp-lanl Jul 19, 2024
fd07bdd
Fix array out of bounds issues when confusing num_pte and num_eos
jhp-lanl Jul 20, 2024
6de9259
Remove unused num_eos
jhp-lanl Jul 20, 2024
5910eab
Merge branch 'main' into jhp/robust_pte
Yurlungur Jul 22, 2024
8a8ac4e
Update copyright
jhp-lanl Jul 22, 2024
a3c4d6e
Update copyright
jhp-lanl Jul 22, 2024
9666c32
Merge branch 'jhp/robust_pte' of github.com:lanl/singularity-eos into…
jhp-lanl Jul 22, 2024
454039a
Remove asserts in Ideal calculation in favor of a positive temperatur…
jhp-lanl Jul 22, 2024
ff35cea
Merge branch 'main' into jhp/robust_pte
Yurlungur Jul 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
- [[PR356]](https://github.com/lanl/singularity-eos/pull/356) Update CMake for proper Kokkos linking in Fortran interface
- [[PR373]](https://github.com/lanl/singularity-eos/pull/373) Initialize cache in `get_sg_eos*` functions
- [[PR374]](https://github.com/lanl/singularity-eos/pull/374) Make the Davis EOS more numerically robust
- [[PR383]](https://github.com/lanl/singularity-eos/pull/383) Fix bug in step scaling for PTE solver

### Changed (changing behavior/API/variables/...)
- [[PR363]](https://github.com/lanl/singularity-eos/pull/363) Template lambda values for scalar calls
Expand Down
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,6 @@ if(SINGULARITY_USE_HIGH_RISK_MATH)
target_compile_definitions(singularity-eos_Interface
INTERFACE SINGULARITY_USE_HIGH_RISK_MATH)
endif()

if(SINGULARITY_TEST_SESAME)
target_compile_definitions(singularity-eos_Interface INTERFACE SINGULARITY_TEST_SESAME)
endif()
Expand All @@ -268,6 +267,9 @@ endif()
if(SINGULARITY_USE_HELMHOLTZ)
target_compile_definitions(singularity-eos_Interface INTERFACE SINGULARITY_USE_HELMHOLTZ)
endif()
if(SINGULARITY_USE_SPINER_WITH_HDF5)
target_compile_definitions(singularity-eos_Interface INTERFACE SINGULARITY_USE_SPINER_WITH_HDF5)
endif()

# ------------------------------------------------------------------------------#
# Handle dependencies
Expand Down
20 changes: 20 additions & 0 deletions sesame2spiner/examples/unit_tests/copper.dat
jhp-lanl marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# ======================================================================
# Example input deck for sesame2spiner,
# a tool for converting eospac to spiner
# Author: Jonah Miller ([email protected])
# © 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.
# ======================================================================

matid=3337
name=copper
rhomin=0.
93 changes: 68 additions & 25 deletions singularity-eos/closure/mixed_cell_models.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ class PTESolverBase {
PORTABLE_INLINE_FUNCTION
virtual void Fixup() const {
Real vsum = 0;
for (int m = 0; m < nmat; ++m)
for (int m = 0; m < nmat; ++m) {
vsum += vfrac[m];
PORTABLE_REQUIRE(vsum > 0., "Volume fraction sum is non-positive");
pdmullen marked this conversation as resolved.
Show resolved Hide resolved
}
for (int m = 0; m < nmat; ++m)
vfrac[m] *= robust::ratio(vfrac_total, vsum);
}
Expand All @@ -182,7 +182,6 @@ class PTESolverBase {
void Finalize() {
for (int m = 0; m < nmat; m++) {
temp[m] *= Tnorm;
PORTABLE_REQUIRE(temp[m] >= 0., "Non-positive temperature returned");
u[m] *= uscale;
press[m] *= uscale;
}
Expand Down Expand Up @@ -219,8 +218,9 @@ class PTESolverBase {
// material m averaged over the full PTE volume
rho_total = 0.0;
for (int m = 0; m < nmat; ++m) {
PORTABLE_REQUIRE(vfrac[m] > 0., "Non-positive volume fraction");
PORTABLE_REQUIRE(rho[m] > 0., "Non-positive density");
PORTABLE_REQUIRE(vfrac[m] > 0.,
"Non-positive volume fraction provided to PTE solver");
PORTABLE_REQUIRE(rho[m] > 0., "Non-positive density provided to PTE solver");
Yurlungur marked this conversation as resolved.
Show resolved Hide resolved
rhobar[m] = rho[m] * vfrac[m];
rho_total += rhobar[m];
}
Expand Down Expand Up @@ -353,12 +353,12 @@ class PTESolverBase {
Asum += vfrac[m] * robust::ratio(press[m], temp[m]);
rhoBsum += rho[m] * vfrac[m] * robust::ratio(sie[m], temp[m]);
}
PORTABLE_REQUIRE(Tnorm > 0., "Non-positive temperature guess");
PORTABLE_REQUIRE(Tnorm > 0., "Non-positive Ideal PTE temperature guess");
Asum *= uscale / Tnorm;
rhoBsum /= Tnorm;
PORTABLE_REQUIRE(rhoBsum > 0., "Non-positive energy density");
PORTABLE_REQUIRE(rhoBsum > 0., "Non-positive Ideal PTE energy density guess");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this only for ideal gas? Because non-ideal gas EOS's can have non-positive energies and it's totally expected/fine.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The next line is

Tideal = uscale / rhoBsum / Tnorm;

This would imply a negative temperature guess, so no, this code cannot admit a negative energy density. I think this is probably part of why it's not useful outside of gas mixtures.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah ok. I just want to make sure this is only used for ideal gas, as tabulated EOSs definitely support negative energy.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yep! I think this is a good reason not to use this guess for tabular EOS. You could also imagine a reacting system where the reaction products is represented by a shifted ideal gas with a negative energy. I think this guess isn't really used, but I figured it might be good to put guardrails on it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This function is called in the Init for PTESolverRhoU which I believe is supposed to handle non-ideal EOS.

Notice that TryIdealPTE is commented out from PTESolverRhoT with the following comment:

    // Leave this in for now, but comment out because I'm not sure it's a good idea
    // TryIdealPTE(this);
    // Set the current guess for the equilibrium temperature.  Note that this is already
    // scaled.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I unresolved this conversation because I was concerned that PTESolverRhoU now no longer works for non-ideal EOS wherein u can be less than 0. Any thoughts here?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I suggest that we floor the energy/temperature inside the solver, as it's only used for guesses

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 unresolved this conversation because I was concerned that PTESolverRhoU now no longer works for non-ideal EOS wherein u can be less than 0. Any thoughts here?

If PTESolverRhoU relies on a negative temperature guess, I'd argue that it never worked for non-ideal EOS that can have negative energies and that the guess infrastructure should be re-worked for that solver.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah I misread the above. I forgot that TryIdealPTE() is separate from GetIdealPTE(). So these error checks being located in GetIdealPTE() is a mistake since TryIdealPTE() will check the results of GetIdealPTE() and see if the results are sane.

Even though these changes are highlighted just because I changed the message and not because they were added here, I'll move them to the TryIdealPTE() function.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Actually, I ended up getting rid of all the GetIdealPTE asserts and instead I added a check in TryIdealPTE() to make sure the temperature guess is actually positive.

Tideal = uscale / rhoBsum / Tnorm;
PORTABLE_REQUIRE(vfrac_total > 0., "Non-positive volume fraction sum");
PORTABLE_REQUIRE(vfrac_total > 0., "Non-positive Ideal PTE volume fraction sum");
Pideal = robust::ratio(Tnorm * Tideal * Asum, uscale * vfrac_total);
}

Expand Down Expand Up @@ -671,6 +671,7 @@ class PTESolverRhoT : public mix_impl::PTESolverBase<EOSIndexer, RealIndexer> {
PORTABLE_INLINE_FUNCTION
Real ScaleDx() const {
using namespace mix_params;
// Each check reduces the scale further if necessary
Real scale = 1.0;
// control how big of a step toward vfrac = 0 is allowed
for (int m = 0; m < nmat; ++m) {
Expand All @@ -684,8 +685,15 @@ class PTESolverRhoT : public mix_impl::PTESolverBase<EOSIndexer, RealIndexer> {
const Real rho_min =
std::max(eos[m].RhoPmin(Tnorm * Tequil), eos[m].RhoPmin(Tnorm * Tnew));
const Real alpha_max = robust::ratio(rhobar[m], rho_min);
if (alpha_max < vfrac[m]) {
// Despite our best efforts, we're already in the unstable regime (i.e.
// dPdV_T > 0) so we would actually want to *increase* the step instead
// of decreasing it. As a result, this code doesn't work as intended and
// should be skipped.
continue;
}
if (scale * dx[m] > 0.5 * (alpha_max - vfrac[m])) {
scale = robust::ratio(0.5 * alpha_max - vfrac[m], dx[m]);
scale = robust::ratio(0.5 * (alpha_max - vfrac[m]), dx[m]);
jhp-lanl marked this conversation as resolved.
Show resolved Hide resolved
}
}
// control how big of a step toward T = 0 is allowed
Expand All @@ -701,8 +709,10 @@ class PTESolverRhoT : public mix_impl::PTESolverBase<EOSIndexer, RealIndexer> {
// Update the solution and return new residual. Possibly called repeatedly with
// different scale factors as part of a line search
PORTABLE_INLINE_FUNCTION
Real TestUpdate(const Real scale) {
if (scale == 1.0) {
Real TestUpdate(const Real scale, bool const cache_state = false) {
if (cache_state) {
// Store the current state in temp variables for first iteration of line
// search
Ttemp = Tequil;
for (int m = 0; m < nmat; ++m)
vtemp[m] = vfrac[m];
Expand Down Expand Up @@ -879,6 +889,7 @@ class PTESolverFixedT : public mix_impl::PTESolverBase<EOSIndexer, RealIndexer>
PORTABLE_INLINE_FUNCTION
Real ScaleDx() const {
using namespace mix_params;
// Each check reduces the scale further if necessary
Real scale = 1.0;
// control how big of a step toward vfrac = 0 is allowed
for (int m = 0; m < nmat; ++m) {
Expand All @@ -890,6 +901,13 @@ class PTESolverFixedT : public mix_impl::PTESolverBase<EOSIndexer, RealIndexer>
for (int m = 0; m < nmat; m++) {
const Real rho_min = eos[m].RhoPmin(Tequil);
const Real alpha_max = robust::ratio(rhobar[m], rho_min);
if (alpha_max < vfrac[m]) {
// Despite our best efforts, we're already in the unstable regime (i.e.
// dPdV_T > 0) so we would actually want to *increase* the step instead
// of decreasing it. As a result, this code doesn't work as intended and
// should be skipped.
continue;
}
if (scale * dx[m] > 0.5 * (alpha_max - vfrac[m])) {
scale = robust::ratio(0.5 * (alpha_max - vfrac[m]), dx[m]);
}
Expand All @@ -903,8 +921,10 @@ class PTESolverFixedT : public mix_impl::PTESolverBase<EOSIndexer, RealIndexer>
// Update the solution and return new residual. Possibly called repeatedly with
// different scale factors as part of a line search
PORTABLE_INLINE_FUNCTION
Real TestUpdate(const Real scale) {
if (scale == 1.0) {
Real TestUpdate(const Real scale, bool const cache_state = false) {
if (cache_state) {
// Store the current state in temp variables for first iteration of line
// search
for (int m = 0; m < nmat; ++m)
vtemp[m] = vfrac[m];
}
Expand Down Expand Up @@ -1093,6 +1113,7 @@ class PTESolverFixedP : public mix_impl::PTESolverBase<EOSIndexer, RealIndexer>
PORTABLE_INLINE_FUNCTION
Real ScaleDx() const {
using namespace mix_params;
// Each check reduces the scale further if necessary
Real scale = 1.0;
// control how big of a step toward vfrac = 0 is allowed
for (int m = 0; m < nmat; ++m) {
Expand All @@ -1106,6 +1127,13 @@ class PTESolverFixedP : public mix_impl::PTESolverBase<EOSIndexer, RealIndexer>
const Real rho_min =
std::max(eos[m].RhoPmin(Tnorm * Tequil), eos[m].RhoPmin(Tnorm * Tnew));
const Real alpha_max = robust::ratio(rhobar[m], rho_min);
if (alpha_max < vfrac[m]) {
// Despite our best efforts, we're already in the unstable regime (i.e.
// dPdV_T > 0) so we would actually want to *increase* the step instead
// of decreasing it. As a result, this code doesn't work as intended and
// should be skipped.
continue;
}
if (scale * dx[m] > 0.5 * (alpha_max - vfrac[m])) {
scale = 0.5 * robust::ratio(alpha_max - vfrac[m], dx[m]);
}
Expand All @@ -1123,8 +1151,10 @@ class PTESolverFixedP : public mix_impl::PTESolverBase<EOSIndexer, RealIndexer>
// Update the solution and return new residual. Possibly called repeatedly with
// different scale factors as part of a line search
PORTABLE_INLINE_FUNCTION
Real TestUpdate(const Real scale) {
if (scale == 1.0) {
Real TestUpdate(const Real scale, bool const cache_state = false) {
if (cache_state) {
// Store the current state in temp variables for first iteration of line
// search
Ttemp = Tequil;
for (int m = 0; m < nmat; ++m)
vtemp[m] = vfrac[m];
Expand Down Expand Up @@ -1332,6 +1362,7 @@ class PTESolverRhoU : public mix_impl::PTESolverBase<EOSIndexer, RealIndexer> {
PORTABLE_INLINE_FUNCTION
Real ScaleDx() const {
using namespace mix_params;
// Each check reduces the scale further if necessary
Real scale = 1.0;
for (int m = 0; m < nmat; ++m) {
// control how big of a step toward vfrac = 0 is allowed
Expand All @@ -1348,6 +1379,13 @@ class PTESolverRhoU : public mix_impl::PTESolverBase<EOSIndexer, RealIndexer> {
std::max(eos[m].RhoPmin(Tnorm * temp[m]), eos[m].RhoPmin(Tnorm * tt));
const Real alpha_max = robust::ratio(rhobar[m], rho_min);
// control how big of a step toward rho = rho(Pmin) is allowed
if (alpha_max < vfrac[m]) {
// Despite our best efforts, we're already in the unstable regime (i.e.
// dPdV_T > 0) so we would actually want to *increase* the step instead
// of decreasing it. As a result, this code doesn't work as intended and
// should be skipped.
continue;
}
if (scale * dx[m] > 0.5 * (alpha_max - vfrac[m])) {
scale = 0.5 * robust::ratio(alpha_max - vfrac[m], dx[m]);
}
Expand All @@ -1361,8 +1399,10 @@ class PTESolverRhoU : public mix_impl::PTESolverBase<EOSIndexer, RealIndexer> {
// Update the solution and return new residual. Possibly called repeatedly with
// different scale factors as part of a line search
PORTABLE_INLINE_FUNCTION
Real TestUpdate(const Real scale) const {
if (scale == 1.0) {
Real TestUpdate(const Real scale, bool const cache_state = false) const {
if (cache_state) {
// Store the current state in temp variables for first iteration of line
// search
for (int m = 0; m < nmat; ++m) {
vtemp[m] = vfrac[m];
utemp[m] = u[m];
Expand Down Expand Up @@ -1417,25 +1457,28 @@ PORTABLE_INLINE_FUNCTION bool PTESolver(System &s) {

// possibly scale the update to stay within reasonable bounds
Real scale = s.ScaleDx();
// const Real scale_save = scale;
PORTABLE_REQUIRE(scale <= 1.0, "PTE Solver is attempting to increase the step size");
jhp-lanl marked this conversation as resolved.
Show resolved Hide resolved

// Line search
Real gradfdx = -2.0 * scale * err;
scale = 1.0;
scale = 1.0; // New scale for line search
Real err_old = err;
err = s.TestUpdate(scale);
// Test the update and reset the cache the current state
err = s.TestUpdate(scale, true /* cache_state */);
if (err > err_old + line_search_alpha * gradfdx) {
// backtrack
Real err_mid = s.TestUpdate(0.5);
// backtrack to middle of step
scale = 0.5;
Real err_mid = s.TestUpdate(scale);
if (err_mid < err && err_mid < err_old) {
// We know the half step is better than both the full step and the
// prior result, so try a pseudo parabolic fit to the error and find its
// minimum. The `scale` value is bound between 0.75 and 0.25.
scale = 0.75 + 0.5 * robust::ratio(err_mid - err, err - 2.0 * err_mid + err_old);
} else {
scale = line_search_fac;
}

for (int line_iter = 0; line_iter < line_search_max_iter; line_iter++) {
err = s.TestUpdate(scale);
if (err < err_old + line_search_alpha * scale * gradfdx) break;
// shrink the step if the error isn't reduced enough
scale *= line_search_fac;
}
}
Expand Down
19 changes: 13 additions & 6 deletions singularity-eos/eos/get_sg_eos_functors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,32 +63,37 @@ struct init_functor {

PORTABLE_INLINE_FUNCTION
void operator()(const int i, const int tid, double &mass_sum, int &npte,
const Real t_mult, const Real s_mult, const Real p_mult) const {
double &vfrac_sum, const Real t_mult, const Real s_mult,
const Real p_mult) const {
/* normalize mass fractions */
/* first find the mass sum */
/* also set idxs as the decrement of the eos offsets */
/* to take into account 1 based indexing in fortran */
for (int m = 0; m < nmat; ++m) {
mass_sum += frac_mass_v(i, m);
pte_idxs(tid, m) = eos_offsets_v(m) - 1;
frac_vol_v(i, m) = 0.0;
// Assume non-participating materials are all at cell density. PTE volumes
// will be overwritten
frac_vol_v(i, m) = frac_mass_v(i, m);
// Initialize all materials to the cell sie (if provided). PTE sie values
// will be overwritten. This also means that the sie for the PTE
// materials is the same as the cell PTE after removing small materials
frac_ie_v(i, m) = sie_v(i) * frac_mass_v(i, m) * s_mult;
}
for (int m = 0; m < nmat; ++m) {
frac_mass_v(i, m) /= mass_sum;
}
check_all_vals(i);
// count the number of participating materials and zero the inputs
// count the number of participating materials
npte = 0;
for (int m = 0; m < nmat; ++m) {
if (frac_mass_v(i, m) > mass_frac_cutoff) {
// participating materials are those with non-negligible mass fractions
pte_idxs(tid, npte) = eos_offsets_v(m) - 1;
pte_mats(tid, npte) = m;
npte += 1;
} else {
frac_ie_v(i, m) = 0.0;
}
// zero the inputs
// zero the PTE solver material inputs
vfrac_pte(tid, m) = 0.0;
sie_pte(tid, m) = 0.0;
temp_pte(tid, m) = 0.0;
Expand All @@ -98,10 +103,12 @@ struct init_functor {
// NOTE: the volume fractions and densities need to be consistent with the
// total specific volume since they are used to calculate internal
// quantities for the PTE solver
vfrac_sum = 0.;
for (int mp = 0; mp < npte; ++mp) {
const int m = pte_mats(tid, mp);
// Need to guess volume fractions
vfrac_pte(tid, mp) = frac_mass_v(i, m);
vfrac_sum += vfrac_pte(tid, mp);
// Calculate densities to be consistent with these volume fractions
rho_pte(tid, mp) = frac_mass_v(i, m) / spvol_v(i) / vfrac_pte(tid, mp);
temp_pte(tid, mp) = temp_v(i) * ev2k * t_mult;
Expand Down
5 changes: 3 additions & 2 deletions singularity-eos/eos/get_sg_eos_rho_e.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ void get_sg_eos_rho_e(const char *name, int ncell, indirection_v &offsets_v,
const int32_t tid{small_loop ? iloop : token};
double mass_sum{0.0};
int npte{0};
double vfrac_sum{0.0};
// initialize values for solver / lookup
i_func(i, tid, mass_sum, npte, 0.0, 1.0, 0.0);
i_func(i, tid, mass_sum, npte, vfrac_sum, 0.0, 1.0, 0.0);
// need to initialize the scratch before it's used to avoid undefined behavior
for (int idx = 0; idx < solver_scratch.extent(1); ++idx) {
solver_scratch(tid, idx) = 0.0;
Expand All @@ -54,7 +55,7 @@ void get_sg_eos_rho_e(const char *name, int ncell, indirection_v &offsets_v,
singularity::EOSAccessor_ eos_inx(eos_v, &pte_idxs(tid, 0));
// reset inputs
PTESolverRhoT<singularity::EOSAccessor_, Real *, Real **> method(
npte, eos_inx, 1.0, sie_v(i), &rho_pte(tid, 0), &vfrac_pte(tid, 0),
npte, eos_inx, vfrac_sum, sie_v(i), &rho_pte(tid, 0), &vfrac_pte(tid, 0),
&sie_pte(tid, 0), &temp_pte(tid, 0), &press_pte(tid, 0), cache,
&solver_scratch(tid, 0));
pte_converged = PTESolver(method);
Expand Down
9 changes: 5 additions & 4 deletions singularity-eos/eos/get_sg_eos_rho_p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ void get_sg_eos_rho_p(const char *name, int ncell, indirection_v &offsets_v,
const int32_t tid{small_loop ? iloop : token};
double mass_sum{0.0};
int npte{0};
double vfrac_sum{0.0};
// initialize values for solver / lookup
i_func(i, tid, mass_sum, npte, 0.0, 0.0, 1.0);
i_func(i, tid, mass_sum, npte, vfrac_sum, 0.0, 0.0, 1.0);
Real sie_tot_true{0.0};
// need to initialize the scratch before it's used to avoid undefined behavior
for (int idx = 0; idx < solver_scratch.extent(1); ++idx) {
Expand All @@ -54,9 +55,9 @@ void get_sg_eos_rho_p(const char *name, int ncell, indirection_v &offsets_v,
// eos accessor
singularity::EOSAccessor_ eos_inx(eos_v, &pte_idxs(tid, 0));
PTESolverFixedP<singularity::EOSAccessor_, Real *, Real *> method(
npte, eos_inx, 1.0, press_pte(tid, 0), &rho_pte(tid, 0), &vfrac_pte(tid, 0),
&sie_pte(tid, 0), &temp_pte(tid, 0), &press_pte(tid, 0), cache[0],
&solver_scratch(tid, 0));
npte, eos_inx, vfrac_sum, press_pte(tid, 0), &rho_pte(tid, 0),
&vfrac_pte(tid, 0), &sie_pte(tid, 0), &temp_pte(tid, 0), &press_pte(tid, 0),
cache[0], &solver_scratch(tid, 0));
pte_converged = PTESolver(method);
// calculate total sie
for (int mp = 0; mp < npte; ++mp) {
Expand Down
9 changes: 5 additions & 4 deletions singularity-eos/eos/get_sg_eos_rho_t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ void get_sg_eos_rho_t(const char *name, int ncell, indirection_v &offsets_v,
const int32_t tid{small_loop ? iloop : token};
double mass_sum{0.0};
int npte{0};
double vfrac_sum{0.0};
// initialize values for solver / lookup
i_func(i, tid, mass_sum, npte, 1.0, 0.0, 0.0);
i_func(i, tid, mass_sum, npte, vfrac_sum, 1.0, 0.0, 0.0);
// calculate pte condition (lookup for 1 mat cell)
Real sie_tot_true{0.0};
// need to initialize the scratch before it's used to avoid undefined behavior
Expand All @@ -55,9 +56,9 @@ void get_sg_eos_rho_t(const char *name, int ncell, indirection_v &offsets_v,
// eos accessor
singularity::EOSAccessor_ eos_inx(eos_v, &pte_idxs(tid, 0));
PTESolverFixedT<singularity::EOSAccessor_, Real *, Real **> method(
npte, eos_inx, 1.0, temp_pte(tid, 0), &rho_pte(tid, 0), &vfrac_pte(tid, 0),
&sie_pte(tid, 0), &temp_pte(tid, 0), &press_pte(tid, 0), cache,
&solver_scratch(tid, 0));
npte, eos_inx, vfrac_sum, temp_pte(tid, 0), &rho_pte(tid, 0),
&vfrac_pte(tid, 0), &sie_pte(tid, 0), &temp_pte(tid, 0), &press_pte(tid, 0),
cache, &solver_scratch(tid, 0));
pte_converged = PTESolver(method);
// calculate total internal energy
for (int mp = 0; mp < npte; ++mp) {
Expand Down
Loading
Loading