@@ -171,17 +171,14 @@ int single_step (BurnT& state, BeT& be, const amrex::Real dt)
171171 if (! converged) {
172172
173173 if (ierr == IERR_SUCCESS) {
174-
175174 // if we didn't set another error, then we probably ran
176175 // out of iterations, so set nonconvergence
177-
178176 ierr = IERR_CORRECTOR_CONVERGENCE;
177+ }
179178
180- // reset the solution to the original
181- for (int n = 1 ; n <= int_neqs; n++) {
182- be.y (n) = y_old (n);
183- }
184-
179+ // reset the solution to the original on any failure
180+ for (int n = 1 ; n <= int_neqs; n++) {
181+ be.y (n) = y_old (n);
185182 }
186183
187184 }
@@ -206,7 +203,9 @@ int be_integrator (BurnT& state, BeT& be)
206203 // Do a single step to the final time
207204 const amrex::Real dt_single_step = be.tout - be.t ;
208205 ierr = single_step (state, be, dt_single_step);
209- be.t = be.tout ;
206+ if (ierr == IERR_SUCCESS) {
207+ be.t = be.tout ;
208+ }
210209 ++be.n_step ;
211210 return ierr;
212211 }
@@ -240,50 +239,55 @@ int be_integrator (BurnT& state, BeT& be)
240239 // our strategy is to take 2 steps at dt/2 and one at dt and
241240 // to compute the error from those
242241
243-
244- // try to take a step dt
245-
246242 // first do 2 (fine) dt/2 steps
247243
248244 amrex::Array1D<amrex::Real, 1 , int_neqs> y_fine;
249245
246+ // keep track of whether we have a valid fine solution
247+ // this means no errors from either half step
248+ bool have_fine_solution = false ;
249+
250250 ierr = single_step (state, be, dt_sub/2 );
251251 if (ierr == IERR_SUCCESS) {
252252 ierr = single_step (state, be, dt_sub/2 );
253253
254- // store the fine dt solution
255-
256- for (int n = 1 ; n <= int_neqs; ++n) {
257- y_fine (n) = be.y (n);
258- }
254+ if (ierr == IERR_SUCCESS) {
255+ // store the fine dt solution
256+ for (int n = 1 ; n <= int_neqs; ++n) {
257+ y_fine (n) = be.y (n);
258+ }
259+ have_fine_solution = true ;
259260
260- // now that single (coarse) dt step
261- // first reset the solution
262- for (int n = 1 ; n <= int_neqs; ++n) {
263- be.y (n) = y_old (n);
261+ // now do a single (coarse) dt step
262+ // first reset the solution
263+ for (int n = 1 ; n <= int_neqs; ++n) {
264+ be.y (n) = y_old (n);
265+ }
266+ ierr = single_step (state, be, dt_sub);
264267 }
265- ierr = single_step (state, be, dt_sub);
266268 }
267269
268- // define a weight for each variable to use in checking the error
270+ amrex::Real rel_error = 0 .0_rt;
271+ bool step_success = false ;
272+ if (ierr == IERR_SUCCESS && have_fine_solution) {
273+ // define a weight for each variable to use in checking the error
269274
270- amrex::Array1D<amrex::Real, 1 , int_neqs> w;
271- for (int n = 1 ; n <= NumSpec; n++) {
272- w (n) = 1 .0_rt / (be.rtol_spec * std::abs (y_fine (n)) + be.atol_spec );
273- }
274- w (net_ienuc) = 1 .0_rt / (be.rtol_enuc * std::abs (y_fine (net_ienuc)) + be.atol_enuc );
275+ amrex::Array1D<amrex::Real, 1 , int_neqs> w;
276+ for (int n = 1 ; n <= NumSpec; n++) {
277+ w (n) = 1 .0_rt / (be.rtol_spec * std::abs (y_fine (n)) + be.atol_spec );
278+ }
279+ w (net_ienuc) = 1 .0_rt / (be.rtol_enuc * std::abs (y_fine (net_ienuc)) + be.atol_enuc );
275280
276- // now look for w |y_fine - y_coarse| < 1
281+ // now look for w |y_fine - y_coarse| < 1
277282
278- amrex::Real rel_error = 0 .0_rt;
279- for (int n = 1 ; n <= NumSpec; n++) {
280- rel_error = amrex::max (rel_error, w (n) * std::abs (y_fine (n) - be.y (n)));
281- }
282- rel_error = amrex::max (rel_error, w (net_ienuc) * std::abs (y_fine (net_ienuc) - be.y (net_ienuc)));
283+ for (int n = 1 ; n <= NumSpec; n++) {
284+ rel_error = amrex::max (rel_error, w (n) * std::abs (y_fine (n) - be.y (n)));
285+ }
286+ rel_error = amrex::max (rel_error, w (net_ienuc) * std::abs (y_fine (net_ienuc) - be.y (net_ienuc)));
283287
284- bool step_success = false ;
285- if (rel_error < 1 .0_rt) {
286- step_success = true ;
288+ if (rel_error < 1 .0_rt) {
289+ step_success = true ;
290+ }
287291 }
288292
289293 if (ierr == IERR_SUCCESS && step_success) {
0 commit comments