Skip to content

Commit 2c439d4

Browse files
Add solver info communication
1 parent 72ac3ba commit 2c439d4

3 files changed

Lines changed: 40 additions & 10 deletions

File tree

src/modeling/solid/materials.jl

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,12 @@ function _solve_local_sarcomere_dQdF(dQdλ, dλdF, λ, F, coefficients, active_t
255255
end
256256

257257
function 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

src/solver/nonlinear/multilevel_newton_raphson.jl

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
Base.@kwdef struct GenericLocalNonlinearSolver <: AbstractNonlinearSolver
22
max_iters::Int = 10
3-
tol::Float64 = 1e-16
3+
tol::Float64 = 1e-4
44
end
55

6-
struct GenericLocalNonlinearSolverCache{JacobianType, ResidualType, CorrectorRhsType}
7-
params::GenericLocalNonlinearSolver
8-
J::JacobianType
9-
residual::ResidualType
10-
rhs_corrector::CorrectorRhsType
6+
Base.@kwdef mutable struct GenericLocalNonlinearSolverCache{JacobianType, ResidualType, CorrectorRhsType}
7+
const params::GenericLocalNonlinearSolver
8+
const J::JacobianType
9+
const residual::ResidualType
10+
const rhs_corrector::CorrectorRhsType
11+
outer_tol::Float64 = Inf
12+
retcode::SciMLBase.ReturnCode.T = SciMLBase.ReturnCode.Default
1113
end
1214

1315
"""
@@ -37,14 +39,21 @@ function nlsolve!(u::AbstractVector, f::AbstractSemidiscreteFunction, mlcache::M
3739
residualnormprev = 0.0
3840
Θ1prev = length(Θks) > 0 ? first(Θks) : 0.0
3941
resize!(Θks, 0)
42+
mlcache.local_solver_cache.outer_tol = Inf
4043
while true
4144
cache.iter += 1
4245
residual .= 0.0
4346
@timeit_debug "update operator" update_linearization!(op, residual, u, t)
47+
# Check if local solve failed
48+
if mlcache.local_solver_cache.retcode (SciMLBase.ReturnCode.Default, SciMLBase.ReturnCode.Success)
49+
@debug "Some local newton did not converge. Aborting. ||r|| = $residualnorm" _group=:nlsolve
50+
return false
51+
end
4452
@timeit_debug "elimination" eliminate_constraints_from_linearization!(cache, f)
4553
linear_solver_cache.isfresh = true # Notify linear solver that we touched the system matrix
4654

4755
residualnorm = residual_norm(cache, f)
56+
mlcache.local_solver_cache.outer_tol = residualnorm
4857
if residualnorm < cache.parameters.tol && cache.iter > 1 # Do at least two iterations to get a sane convergence estimate
4958
break
5059
elseif cache.iter > cache.parameters.max_iter

src/solver/time/euler.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ end
199199
zeros(singleQsize, singleQsize),
200200
zeros(singleQsize),
201201
zeros(singleQsize),
202+
Inf,
203+
SciMLBase.ReturnCode.Default,
202204
)
203205

204206
# Extract condensable parts

0 commit comments

Comments
 (0)