Skip to content

Commit 6abd221

Browse files
authored
add fallback to finite diff Jacobian (#2008)
In the Rosenbrock integrator, add a fall back to the FD Jacobian if the analytic Jacobian produces a NaN or Inf value.
1 parent 34b1204 commit 6abd221

2 files changed

Lines changed: 23 additions & 2 deletions

File tree

integration/Rosenbrock/rosenbrock_integrator.H

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,13 +194,29 @@ amrex::Real yass_change_norm (const rosenbrock_t<int_neqs>& rstate)
194194
return max_change / integrator_rp::yass_epsilon;
195195
}
196196

197+
template <typename MatrixType, int int_neqs>
198+
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
199+
bool matrix_is_finite (const MatrixType& matrix)
200+
{
201+
for (int j = 1; j <= int_neqs; ++j) {
202+
for (int i = 1; i <= int_neqs; ++i) {
203+
const amrex::Real value = matrix(i, j);
204+
if (std::isnan(value) || std::isinf(value)) {
205+
return false;
206+
}
207+
}
208+
}
209+
210+
return true;
211+
}
212+
197213
template <int int_neqs>
198214
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
199215
bool valid_integrator_state (const amrex::Array1D<amrex::Real, 1, int_neqs>& y)
200216
{
201217
for (int n = 1; n <= int_neqs; ++n) {
202218
const amrex::Real yn = y(n);
203-
if (yn != yn || std::abs(yn) == std::numeric_limits<amrex::Real>::infinity()) {
219+
if (std::isnan(yn) || std::isinf(yn)) {
204220
return false;
205221
}
206222
}
@@ -236,7 +252,10 @@ void evaluate_jacobian (BurnT& state, rosenbrock_t<int_neqs>& rstate, const amre
236252
if (rstate.jacobian_type == 1) {
237253
jac(time, state, rstate, rstate.jac);
238254
rstate.n_jac += 1;
239-
return;
255+
256+
if (matrix_is_finite<decltype(rstate.jac), int_neqs>(rstate.jac)) {
257+
return;
258+
}
240259
}
241260

242261
constexpr amrex::Real UROUND = std::numeric_limits<amrex::Real>::epsilon();

integration/integrator_setup_strang.H

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ void integrator_cleanup (IntegratorT& int_state, BurnT& state,
146146
state.n_jac = int_state.n_jac;
147147
state.n_step = int_state.n_step;
148148

149+
state.error_code = static_cast<short>(istate);
150+
149151
// The integrator may not always fail even though it can lead to
150152
// unphysical states. Add some checks that indicate a burn fail
151153
// even if the integrator thinks the integration was successful.

0 commit comments

Comments
 (0)