Skip to content

Commit c3587f5

Browse files
authored
sync up integrators (#1513)
also fix a bug with the retry tolerances in the Strang RKC
1 parent 834938b commit c3587f5

7 files changed

+281
-184
lines changed

integration/BackwardEuler/actual_integrator.H

+71-26
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
#ifndef actual_integrator_H
22
#define actual_integrator_H
33

4+
#include <iomanip>
5+
6+
#include <network.H>
7+
#include <burn_type.H>
8+
49
#include <be_type.H>
510
#include <be_integrator.H>
611

712
template <typename BurnT>
813
AMREX_GPU_HOST_DEVICE AMREX_INLINE
9-
void actual_integrator (BurnT& state, const Real dt, bool is_retry=false)
14+
void actual_integrator (BurnT& state, const amrex::Real dt, bool is_retry=false)
1015
{
1116
constexpr int int_neqs = integrator_neqs<BurnT>();
1217

@@ -29,7 +34,7 @@ void actual_integrator (BurnT& state, const Real dt, bool is_retry=false)
2934
}
3035

3136
// set the Jacobian type
32-
if (is_retry && retry_swap_jacobian) {
37+
if (is_retry && integrator_rp::retry_swap_jacobian) {
3338
be.jacobian_type = (jacobian == 1) ? 2 : 1;
3439
} else {
3540
be.jacobian_type = jacobian;
@@ -71,13 +76,13 @@ void actual_integrator (BurnT& state, const Real dt, bool is_retry=false)
7176
// Save the initial composition, temperature, and energy for our later diagnostics.
7277

7378
#ifndef AMREX_USE_GPU
74-
Real xn_in[NumSpec];
79+
amrex::Real xn_in[NumSpec];
7580
for (int n = 0; n < NumSpec; ++n) {
7681
xn_in[n] = state.xn[n];
7782
}
78-
Real T_in = state.T;
83+
const amrex::Real T_in = state.T;
7984
#endif
80-
Real e_in = state.e;
85+
const amrex::Real e_in = state.e;
8186

8287
// Call the integration routine.
8388

@@ -88,15 +93,28 @@ void actual_integrator (BurnT& state, const Real dt, bool is_retry=false)
8893

8994
integrator_to_burn(be, state);
9095

96+
#ifdef NSE
97+
// compute the temperature based on the energy release -- we need
98+
// this in case we failed in our burn here because we entered NSE
99+
100+
#ifdef AUX_THERMO
101+
// need to sync the auxiliary data up with the new mass fractions
102+
set_aux_comp_from_X(state);
103+
#endif
104+
if (call_eos_in_rhs) {
105+
eos(eos_input_re, state);
106+
}
107+
#endif
108+
91109
// Subtract off the initial energy if the application codes expect
92110
// to get back only the generated energy during the burn.
93-
if (subtract_internal_energy) {
111+
if (integrator_rp::subtract_internal_energy) {
94112
state.e -= e_in;
95113
}
96114

97115
// Normalize the final abundances.
98116

99-
if (!use_number_densities) {
117+
if (! integrator_rp::use_number_densities) {
100118
normalize_abundances_burn(state);
101119
}
102120

@@ -106,10 +124,28 @@ void actual_integrator (BurnT& state, const Real dt, bool is_retry=false)
106124
state.n_jac = be.n_jac;
107125
state.n_step = be.n_step;
108126

127+
// BE does not always fail even though it can lead to unphysical states.
128+
// Add some checks that indicate a burn fail even if VODE thinks the
129+
// integration was successful.
130+
109131
if (istate != IERR_SUCCESS) {
110132
state.success = false;
111133
}
112134

135+
for (int n = 1; n <= NumSpec; ++n) {
136+
if (be.y(n) < -species_failure_tolerance) {
137+
state.success = false;
138+
}
139+
140+
// Don't enforce a max if we are evolving number densities
141+
142+
if (! integrator_rp::use_number_densities) {
143+
if (be.y(n) > 1.0_rt + species_failure_tolerance) {
144+
state.success = false;
145+
}
146+
}
147+
}
148+
113149
#ifndef AMREX_USE_GPU
114150
if (burner_verbose) {
115151
// Print out some integration statistics, if desired.
@@ -124,27 +160,36 @@ void actual_integrator (BurnT& state, const Real dt, bool is_retry=false)
124160
// If we failed, print out the current state of the integration.
125161

126162
if (!state.success) {
163+
if (istate != IERR_ENTERED_NSE) {
127164
#ifndef AMREX_USE_GPU
128-
std::cout << Font::Bold << FGColor::Red << "[ERROR] integration failed in net" << ResetDisplay << std::endl;
129-
std::cout << "istate = " << istate << std::endl;
130-
std::cout << "zone = (" << state.i << ", " << state.j << ", " << state.k << ")" << std::endl;
131-
std::cout << "time = " << be.t << std::endl;
132-
std::cout << "dt = " << std::setprecision(16) << dt << std::endl;
133-
std::cout << "temp start = " << std::setprecision(16) << T_in << std::endl;
134-
std::cout << "xn start = ";
135-
for (int n = 0; n < NumSpec; ++n) {
136-
std::cout << std::setprecision(16) << xn_in[n] << " ";
137-
}
138-
std::cout << std::endl;
139-
std::cout << "dens current = " << std::setprecision(16) << state.rho << std::endl;
140-
std::cout << "temp current = " << std::setprecision(16) << state.T << std::endl;
141-
std::cout << "xn current = ";
142-
for (int n = 0; n < NumSpec; ++n) {
143-
std::cout << std::setprecision(16) << state.xn[n] << " ";
144-
}
145-
std::cout << std::endl;
146-
std::cout << "energy generated = " << state.e << std::endl;
165+
std::cout << Font::Bold << FGColor::Red << "[ERROR] integration failed in net" << ResetDisplay << std::endl;
166+
std::cout << "istate = " << istate << std::endl;
167+
if (istate == IERR_SUCCESS) {
168+
std::cout << " BE exited successfully, but a check on the data values failed" << std::endl;
169+
}
170+
std::cout << "zone = (" << state.i << ", " << state.j << ", " << state.k << ")" << std::endl;
171+
std::cout << "time = " << be.t << std::endl;
172+
std::cout << "dt = " << std::setprecision(16) << dt << std::endl;
173+
std::cout << "temp start = " << std::setprecision(16) << T_in << std::endl;
174+
std::cout << "xn start = ";
175+
for (const auto X: xn_in) {
176+
std::cout << std::setprecision(16) << X << " ";
177+
}
178+
std::cout << std::endl;
179+
std::cout << "dens current = " << std::setprecision(16) << state.rho << std::endl;
180+
std::cout << "temp current = " << std::setprecision(16) << state.T << std::endl;
181+
std::cout << "xn current = ";
182+
for (const auto X: state.xn) {
183+
std::cout << std::setprecision(16) << X << " ";
184+
}
185+
std::cout << std::endl;
186+
std::cout << "energy generated = " << state.e << std::endl;
187+
#endif
188+
} else {
189+
#ifndef AMREX_USE_GPU
190+
std::cout << "burn entered NSE during integration (after " << state.n_step << " steps), zone = (" << state.i << ", " << state.j << ", " << state.k << ")" << std::endl;
147191
#endif
192+
}
148193
}
149194
}
150195

integration/BackwardEuler/actual_integrator_sdc.H

+78-52
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
template <typename BurnT>
1212
AMREX_GPU_HOST_DEVICE AMREX_INLINE
13-
void actual_integrator (BurnT& state, const Real dt, bool is_retry=false)
13+
void actual_integrator (BurnT& state, const amrex::Real dt, bool is_retry=false)
1414
{
1515
constexpr int int_neqs = integrator_neqs<BurnT>();
1616

@@ -26,7 +26,7 @@ void actual_integrator (BurnT& state, const Real dt, bool is_retry=false)
2626
be.tout = dt;
2727

2828
// set the Jacobian type
29-
if (is_retry && retry_swap_jacobian) {
29+
if (is_retry && integrator_rp::retry_swap_jacobian) {
3030
be.jacobian_type = (jacobian == 1) ? 2 : 1;
3131
} else {
3232
be.jacobian_type = jacobian;
@@ -39,30 +39,30 @@ void actual_integrator (BurnT& state, const Real dt, bool is_retry=false)
3939
// Save the initial composition and temperature for our later diagnostics.
4040

4141
#ifndef AMREX_USE_GPU
42-
Real xn_in[NumSpec];
42+
amrex::Real xn_in[NumSpec];
4343
for (int n = 0; n < NumSpec; ++n) {
4444
xn_in[n] = state.y[SFS+n] / state.y[SRHO];
4545
}
4646
// we are assuming that the temperature was valid on input
47-
Real T_in = state.T;
47+
amrex::Real T_in = state.T;
4848
#ifdef AUX_THERMO
49-
Real aux_in[NumAux];
49+
amrex::Real aux_in[NumAux];
5050
for (int n = 0; n < NumAux; ++n) {
5151
aux_in[n] = state.y[SFX+n] / state.y[SRHO];
5252
}
5353
#endif
54-
Real rhoe_in = state.y[SEINT];
54+
amrex::Real rhoe_in = state.y[SEINT];
5555
#endif
5656

5757

5858
// Set the tolerances.
5959

60-
Real sdc_tol_fac = std::pow(sdc_burn_tol_factor, state.num_sdc_iters - state.sdc_iter - 1);
60+
amrex::Real sdc_tol_fac = std::pow(integrator_rp::sdc_burn_tol_factor, state.num_sdc_iters - state.sdc_iter - 1);
6161

6262
// we use 1-based indexing inside of BackwardEuler, so we need to shift the
6363
// indices SRHO, SFS, etc by 1
6464

65-
Real sdc_min_density = amrex::min(state.rho, state.rho_orig + state.ydot_a[SRHO] * dt);
65+
amrex::Real sdc_min_density = amrex::min(state.rho, state.rho_orig + state.ydot_a[SRHO] * dt);
6666

6767
if (!is_retry) {
6868

@@ -115,7 +115,7 @@ void actual_integrator (BurnT& state, const Real dt, bool is_retry=false)
115115
// we only evolved (rho e), not (rho E), so we need to update the
116116
// total energy now to ensure we are conservative
117117

118-
Real rho_Sdot = 0.0_rt;
118+
amrex::Real rho_Sdot = 0.0_rt;
119119
if (state.time > 0) {
120120
rho_Sdot = (state.y[SEINT] - state.rhoe_orig) / state.time - state.ydot_a[SEINT];
121121
}
@@ -134,10 +134,28 @@ void actual_integrator (BurnT& state, const Real dt, bool is_retry=false)
134134

135135
normalize_abundances_sdc_burn(state);
136136

137+
// BE does not always fail even though it can lead to unphysical states.
138+
// Add some checks that indicate a burn fail even if VODE thinks the
139+
// integration was successful.
140+
137141
if (istate != IERR_SUCCESS) {
138142
state.success = false;
139143
}
140144

145+
if (state.y[SEINT] < 0.0_rt) {
146+
state.success = false;
147+
}
148+
149+
for (int n = 0; n < NumSpec; ++n) {
150+
if (state.y[SFS+n] / state.rho < -species_failure_tolerance) {
151+
state.success = false;
152+
}
153+
154+
if (state.y[SFS+n] / state.rho > 1.0_rt + species_failure_tolerance) {
155+
state.success = false;
156+
}
157+
}
158+
141159

142160
#ifndef AMREX_USE_GPU
143161
if (burner_verbose) {
@@ -153,59 +171,67 @@ void actual_integrator (BurnT& state, const Real dt, bool is_retry=false)
153171
// If we failed, print out the current state of the integration.
154172

155173
if (!state.success) {
174+
if (istate != IERR_ENTERED_NSE) {
156175
#ifndef AMREX_USE_GPU
157-
std::cout << Font::Bold << FGColor::Red << "[ERROR] integration failed in net" << ResetDisplay << std::endl;
158-
std::cout << "istate = " << istate << std::endl;
159-
std::cout << "zone = (" << state.i << ", " << state.j << ", " << state.k << ")" << std::endl;
160-
std::cout << "time = " << state.time << std::endl;
161-
std::cout << "dt = " << std::setprecision(16) << dt << std::endl;
162-
std::cout << "dens start = " << std::setprecision(16) << state.rho_orig << std::endl;
163-
std::cout << "temp start = " << std::setprecision(16) << T_in << std::endl;
164-
std::cout << "rhoe start = " << std::setprecision(16) << rhoe_in << std::endl;
165-
std::cout << "xn start = ";
166-
for (int n = 0; n < NumSpec; ++n) {
167-
std::cout << std::setprecision(16) << xn_in[n] << " ";
168-
}
169-
std::cout << std::endl;
176+
std::cout << Font::Bold << FGColor::Red << "[ERROR] integration failed in net" << ResetDisplay << std::endl;
177+
std::cout << "istate = " << istate << std::endl;
178+
if (istate == IERR_SUCCESS) {
179+
std::cout << " BE exited successfully, but a check on the data values failed" << std::endl;
180+
}
181+
std::cout << "zone = (" << state.i << ", " << state.j << ", " << state.k << ")" << std::endl;
182+
std::cout << "time = " << state.time << std::endl;
183+
std::cout << "dt = " << std::setprecision(16) << dt << std::endl;
184+
std::cout << "dens start = " << std::setprecision(16) << state.rho_orig << std::endl;
185+
std::cout << "temp start = " << std::setprecision(16) << T_in << std::endl;
186+
std::cout << "rhoe start = " << std::setprecision(16) << rhoe_in << std::endl;
187+
std::cout << "xn start = ";
188+
for (const auto X : xn_in) {
189+
std::cout << std::setprecision(16) << X << " ";
190+
}
191+
std::cout << std::endl;
170192
#ifdef AUX_THERMO
171-
std::cout << "aux start = ";
172-
for (int n = 0; n < NumAux; ++n) {
173-
std::cout << std::setprecision(16) << aux_in[n] << " ";
174-
}
175-
std::cout << std::endl;
193+
std::cout << "aux start = ";
194+
for (const auto aux : aux_in) {
195+
std::cout << std::setprecision(16) << aux << " ";
196+
}
197+
std::cout << std::endl;
176198
#endif
177-
std::cout << "dens current = " << std::setprecision(16) << state.rho << std::endl;
178-
std::cout << "temp current = " << std::setprecision(16) << state.T << std::endl;
179-
std::cout << "xn current = ";
180-
for (int n = 0; n < NumSpec; ++n) {
181-
std::cout << std::setprecision(16) << state.xn[n] << " ";
182-
}
183-
std::cout << std::endl;
199+
std::cout << "dens current = " << std::setprecision(16) << state.rho << std::endl;
200+
std::cout << "temp current = " << std::setprecision(16) << state.T << std::endl;
201+
std::cout << "xn current = ";
202+
for (int n = 0; n < NumSpec; ++n) {
203+
std::cout << std::setprecision(16) << state.xn[n] << " ";
204+
}
205+
std::cout << std::endl;
184206
#ifdef AUX_THERMO
185-
std::cout << "aux current = ";
186-
for (int n = 0; n < NumAux; ++n) {
187-
std::cout << std::setprecision(16) << state.aux[n] << " ";
188-
}
189-
std::cout << std::endl;
207+
std::cout << "aux current = ";
208+
for (int n = 0; n < NumAux; ++n) {
209+
std::cout << std::setprecision(16) << state.aux[n] << " ";
210+
}
211+
std::cout << std::endl;
190212
#endif
191-
std::cout << "A(rho) = " << std::setprecision(16) << state.ydot_a[SRHO] << std::endl;
192-
std::cout << "A(rho e) = " << std::setprecision(16) << state.ydot_a[SEINT] << std::endl;
193-
std::cout << "A(rho X_k) = ";
194-
for (int n = 0; n < NumSpec; n++) {
195-
std::cout << std::setprecision(16) << state.ydot_a[SFS+n] << " ";
196-
}
197-
std::cout << std::endl;
213+
std::cout << "A(rho) = " << std::setprecision(16) << state.ydot_a[SRHO] << std::endl;
214+
std::cout << "A(rho e) = " << std::setprecision(16) << state.ydot_a[SEINT] << std::endl;
215+
std::cout << "A(rho X_k) = ";
216+
for (int n = 0; n < NumSpec; n++) {
217+
std::cout << std::setprecision(16) << state.ydot_a[SFS+n] << " ";
218+
}
219+
std::cout << std::endl;
198220
#ifdef AUX_THERMO
199-
std::cout << "A(rho aux_k) = ";
200-
for (int n = 0; n < NumAux; n++) {
201-
std::cout << std::setprecision(16) << state.ydot_a[SFX+n] << " ";
202-
}
203-
std::cout << std::endl;
221+
std::cout << "A(rho aux_k) = ";
222+
for (int n = 0; n < NumAux; n++) {
223+
std::cout << std::setprecision(16) << state.ydot_a[SFX+n] << " ";
224+
}
225+
std::cout << std::endl;
226+
#endif
204227
#endif
228+
} else {
229+
#ifndef AMREX_USE_GPU
230+
std::cout << "burn entered NSE during integration (after " << state.n_step << " steps), zone = (" << state.i << ", " << state.j << ", " << state.k << ")" << std::endl;
205231
#endif
232+
}
206233
}
207234

208-
209235
}
210236

211237
#endif

0 commit comments

Comments
 (0)