@@ -255,6 +255,12 @@ function _solve_local_sarcomere_dQdF(dQdλ, dλdF, λ, F, coefficients, active_t
255255end
256256
257257function solve_local_constraint (F:: Tensor{2,dim} , coefficients, material_model:: ActiveStressModel , state_cache:: GenericFirstOrderRateIndependentCondensationMaterialStateCache , geometry_cache, qp, time) where dim
258+ # Early out if any of the previous local solves failed
259+ if state_cache. local_solver_cache. retcode ∉ (SciMLBase. ReturnCode. Default, SciMLBase. ReturnCode. Success)
260+ Qflat, _ = _query_local_state (state_cache, geometry_cache, qp)
261+ return Qflat, zero (Tensor{4 ,dim,Float64,4 ^ dim})
262+ end
263+
258264 function computeλ (F)
259265 f = F ⋅ coefficients. f
260266 return √ (f ⋅ f)
@@ -284,24 +290,37 @@ function solve_local_constraint(F::Tensor{2,dim}, coefficients, material_model::
284290
285291 R = state_cache. local_solver_cache. residual
286292 J = state_cache. local_solver_cache. J
293+ rtol = min (state_cache. local_solver_cache. params. tol, state_cache. local_solver_cache. outer_tol)
287294 for newton_iter in 1 : state_cache. local_solver_cache. params. max_iters
288295 ForwardDiff. jacobian! (J, local_residual_jac_wrap!, R, Q)
289296 local_residual! (R, Q, λ, dλdt)
290297 ΔQ = J \ R
291298 Q .- = ΔQ
292- # @info qp.i, norm(R), norm(ΔQ )
293- if norm (R) < state_cache. local_solver_cache. params. tol
299+ residualnorm = norm (R)
300+ if residualnorm < state_cache. local_solver_cache. params. tol
294301 break
295- elseif newton_iter == 10
296- error (" Local Newton did not converge" )
302+ elseif newton_iter == state_cache. local_solver_cache. params. max_iters
303+ state_cache. local_solver_cache. retcode = SciMLBase. ReturnCode. MaxIters
304+ @debug " Reached maximum local Newton iterations at cell $(cellid (geometry_cache)) qp $(qp. i) . Aborting. ||r|| = $(residualnorm) " _group= :nlsolve
305+ return Q, J
306+ elseif isnan (residualnorm)
307+ state_cache. local_solver_cache. retcode = SciMLBase. ReturnCode. ConvergenceFailure
308+ @debug " Newton-Raphson diverged. Aborting. ||r|| = $residualnorm " _group= :nlsolve
309+ return Q, J
297310 end
298311 end
299312 ForwardDiff. jacobian! (J, local_residual_jac_wrap!, R, Q)
313+ state_cache. local_solver_cache. retcode = SciMLBase. ReturnCode. Success
300314 return Q, J
301315 end
302316
303317 Qflat, Qprevflat = _query_local_state (state_cache, geometry_cache, qp)
304318 Q, J = solve_internal_timestep (material_model, state_cache, λ, dλdt, Qflat, Qprevflat)
319+ # Abort if local solve failed
320+ if state_cache. local_solver_cache. retcode ∉ (SciMLBase. ReturnCode. Default, SciMLBase. ReturnCode. Success)
321+ Qflat, _ = _query_local_state (state_cache, geometry_cache, qp)
322+ return Qflat, zero (Tensor{4 ,dim,Float64,4 ^ dim})
323+ end
305324 Qflat .= Q
306325 _store_local_state! (state_cache, geometry_cache, qp)
307326
0 commit comments