diff options
author | Anton Khirnov <anton@khirnov.net> | 2018-04-09 10:13:44 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2018-04-09 10:13:44 +0200 |
commit | 975abbee31abe7f8299c3cc4583f76214f699671 (patch) | |
tree | 82888c4e615803ef1ff6da8f1590274c79998078 | |
parent | 90381f1d94c437e58d233edeb43d0a1bb5c923f8 (diff) |
nlsolve: faster abort on divergence
-rw-r--r-- | init.c | 10 | ||||
-rw-r--r-- | nlsolve.c | 6 | ||||
-rw-r--r-- | nlsolve.h | 2 |
3 files changed, 11 insertions, 7 deletions
@@ -284,7 +284,7 @@ int td_solve(TDContext *td, double *coeffs_init[3]) if (td->solution_branch == 0 || coeffs_init) { // direct solve with default (flat space) or user-provided initial guess ret = tdi_nlsolve_solve(s->solver, teukolsky_constraint_eval, NULL, - &td->amplitude, s->coeffs); + &td->amplitude, s->coeffs, 0); if (ret < 0) { tdi_log(&s->logger, 0, "tdi_nlsolve_solve() failed: %d", ret); return ret; @@ -301,11 +301,11 @@ int td_solve(TDContext *td, double *coeffs_init[3]) int dir; ret = tdi_nlsolve_solve(s->solver, teukolsky_constraint_eval, NULL, - &a0, s->coeffs); + &a0, s->coeffs, 0); if (ret < 0) return ret; ret = tdi_nlsolve_solve(s->solver, teukolsky_constraint_eval, NULL, - &a1, s->coeffs_tmp); + &a1, s->coeffs_tmp, 0); if (ret < 0) return ret; @@ -314,7 +314,7 @@ int td_solve(TDContext *td, double *coeffs_init[3]) // obtain solution for a1 in the upper branch ret = tdi_nlsolve_solve(s->solver, teukolsky_constraint_eval, NULL, - &a1, s->coeffs); + &a1, s->coeffs, 0); if (ret < 0) { tdi_log(&s->logger, 0, "Failed to get into the upper branch\n"); return ret; @@ -335,7 +335,7 @@ int td_solve(TDContext *td, double *coeffs_init[3]) tdi_log(&s->logger, 2, "Trying amplitude %g\n", new_amplitude); memcpy(s->coeffs_tmp, s->coeffs, sizeof(*s->coeffs) * N); ret = tdi_nlsolve_solve(s->solver, teukolsky_constraint_eval, NULL, - &new_amplitude, s->coeffs_tmp); + &new_amplitude, s->coeffs_tmp, 1); if (ret == -EDOM) { inverse_step = 0.5 * inverse_step; if (fabs(inverse_step) < 1e-2) @@ -100,7 +100,7 @@ struct NLSolvePriv { }; int tdi_nlsolve_solve(NLSolveContext *ctx, NLEqCallback eq_eval, - NLEqJacobianCallback eq_jac_eval, void *opaque, double *coeffs) + NLEqJacobianCallback eq_jac_eval, void *opaque, double *coeffs, int fast_abort) { NLSolvePriv *s = ctx->priv; int64_t start, totaltime_start; @@ -209,6 +209,10 @@ int tdi_nlsolve_solve(NLSolveContext *ctx, NLEqCallback eq_eval, it, s->delta[max_idx], ctx->atol); ret = 0; goto finish; + } else if ((fast_abort && fabs(s->delta[max_idx]) > 1e6) || + s->delta[max_idx] > 1e18) { + tdi_log(&ctx->logger, 2, "max(delta) %g, aborting\n", s->delta[max_idx]); + return -EDOM; } cblas_daxpy(s->solve_order, 1.0, s->delta, 1, coeffs, 1); @@ -101,7 +101,7 @@ void tdi_nlsolve_context_free(NLSolveContext **ctx); int tdi_nlsolve_solve(NLSolveContext *ctx, NLEqCallback eq_eval, NLEqJacobianCallback eq_jac_eval, - void *opaque, double *coeffs); + void *opaque, double *coeffs, int fast_abort); void tdi_nlsolve_print_stats(NLSolveContext *ctx); |