Skip to content

Commit 72ac3ba

Browse files
Preallocate some buffers for local solve
1 parent 7d7e574 commit 72ac3ba

4 files changed

Lines changed: 35 additions & 29 deletions

File tree

src/modeling/functions.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ struct QuasiStaticFunction{I <: NonlinearIntegrator, DH <: Ferrite.AbstractDofHa
9292
end
9393

9494
solution_size(f::QuasiStaticFunction) = ndofs(f.dh)+ndofs(f.lvh)
95+
function local_function_size(f::QuasiStaticFunction)
96+
length(f.lvh.dh.subdofhandlers) == 0 && return 0
97+
return sum(Ferrite.n_components.(f.lvh.dh.subdofhandlers[1].field_interpolations); init=0)
98+
end
9599
function default_initial_condition!(u::AbstractVector, f::QuasiStaticFunction)
96100
fill!(u, 0.0)
97101
ndofs(f.lvh) == 0 && return # no internal variable

src/modeling/solid/materials.jl

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ setup_internal_cache(material_model::Union{<:ElastodynamicsModel{<:ActiveStressM
223223

224224
# TODO this actually belongs to the multi-level newton file :)
225225
# Dual (global cache and element-level cache) use for now to make it non-allocating.
226-
struct GenericFirstOrderRateIndependentCondensationMaterialStateCache{LocalModelType, LocalModelCacheType, QType, QType2, T, LVH} <: RateIndependentCondensationMaterialStateCache
226+
struct GenericFirstOrderRateIndependentCondensationMaterialStateCache{LocalModelType, LocalModelCacheType, LocalSolverType, QType, QType2, T, LVH} <: RateIndependentCondensationMaterialStateCache
227227
# The actual model
228228
model::LocalModelType
229229
model_cache::LocalModelCacheType
@@ -233,7 +233,7 @@ struct GenericFirstOrderRateIndependentCondensationMaterialStateCache{LocalModel
233233
Qprev::QType
234234
# t - tprev
235235
Δt::T
236-
# local_solver::...?
236+
local_solver_cache::LocalSolverType
237237
lvh::LVH
238238
# These are used locally
239239
localQ::QType2
@@ -274,24 +274,23 @@ function solve_local_constraint(F::Tensor{2,dim}, coefficients, material_model::
274274
function local_residual!(R, Q, λ, dλdt)
275275
dQ = zeros(eltype(Q), length(Q)) # TODO preallocate during setup
276276
sarcomere_rhs!(dQ, Q, λ, dλdt, Ca, time, material_model.contraction_model)
277-
R .= (Q .- Qprev) ./ state_cache.Δt .- dQ
277+
@.. R = (Q - Qprev) / state_cache.Δt - dQ
278278
return nothing
279279
end
280280

281281
function local_residual_jac_wrap!(R, Q)
282282
return local_residual!(R, Q, λ, dλdt)
283283
end
284284

285-
# TODO preallocate during setup
286-
R = zeros(length(Q))
287-
J = zeros(length(Q),length(Q))
288-
for newton_iter in 1:10
285+
R = state_cache.local_solver_cache.residual
286+
J = state_cache.local_solver_cache.J
287+
for newton_iter in 1:state_cache.local_solver_cache.params.max_iters
289288
ForwardDiff.jacobian!(J, local_residual_jac_wrap!, R, Q)
290289
local_residual!(R, Q, λ, dλdt)
291290
ΔQ = J \ R
292291
Q .-= ΔQ
293292
# @info qp.i, norm(R), norm(ΔQ)
294-
if norm(R) < 1e-16
293+
if norm(R) < state_cache.local_solver_cache.params.tol
295294
break
296295
elseif newton_iter == 10
297296
error("Local Newton did not converge")
@@ -307,23 +306,16 @@ function solve_local_constraint(F::Tensor{2,dim}, coefficients, material_model::
307306
_store_local_state!(state_cache, geometry_cache, qp)
308307

309308
# Solve corrector problem
310-
# function local_residual_rhs_wrap!(R, λ)
311-
# dQ = zeros(eltype(λ), 20) # TODO preallocate during setup
312-
# sarcomere_rhs!(dQ, Q, λ, dλdt, Ca, time, material_model.contraction_model)
313-
# # R .= (Q .- Qprev) .- dQ
314-
# R .= (Q .- Qprevflat) .- dQ
315-
# return nothing
316-
# end
317-
function local_residual_rhs_wrap(λ)
309+
function local_residual_rhs_wrap!(R, λ)
318310
dQ = zeros(eltype(λ), length(Q)) # TODO preallocate during setup
319311
sarcomere_rhs!(dQ, Q, λ, dλdt, Ca, time, material_model.contraction_model)
320-
# R .= (Q .- Qprev) .- dQ
321-
return (Q .- Qprevflat) ./ state_cache.Δt .- dQ
312+
@.. R = (Q - Qprevflat) / state_cache.Δt - dQ
322313
return nothing
323314
end
324-
∂fₗ∂λ = zeros(length(Q))
325-
ForwardDiff.derivative!(∂fₗ∂λ, local_residual_rhs_wrap, λ)
326-
dQdλ = - J \ ∂fₗ∂λ
315+
R = state_cache.local_solver_cache.residual
316+
∂fₗ∂λ = state_cache.local_solver_cache.rhs_corrector
317+
ForwardDiff.derivative!(∂fₗ∂λ, local_residual_rhs_wrap!, R, λ)
318+
dQdλ = J \ -∂fₗ∂λ
327319

328320
return Q, _solve_local_sarcomere_dQdF(dQdλ, dλdF, λ, F, coefficients, material_model.active_stress_model, material_model.contraction_model)
329321
end

src/solver/nonlinear/multilevel_newton_raphson.jl

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

4-
struct GenericLocalNonlinearSolverCache{JacobianType, ResidualType, CorrectorType}
6+
struct GenericLocalNonlinearSolverCache{JacobianType, ResidualType, CorrectorRhsType}
7+
params::GenericLocalNonlinearSolver
58
J::JacobianType
69
residual::ResidualType
7-
corrector_rhs::CorrectorType
8-
corrector::CorrectorType
10+
rhs_corrector::CorrectorRhsType
911
end
1012

1113
"""

src/solver/time/euler.jl

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ mutable struct BackwardEulerStageFunctionWrapper{F,U,T,S, LVH} <: AbstractTimeDi
172172
const u::U
173173
const uprev::U
174174
Δt::T
175-
const inner_solver::S
175+
const local_solver_cache::S
176176
const lvh::LVH
177177
end
178178

@@ -193,6 +193,14 @@ end
193193
@unpack volume_model, face_model = integrator
194194
@unpack local_solver, newton = solver
195195

196+
singleQsize = local_function_size(f)
197+
local_solver_cache = GenericLocalNonlinearSolverCache(
198+
solver.local_solver,
199+
zeros(singleQsize, singleQsize),
200+
zeros(singleQsize),
201+
zeros(singleQsize),
202+
)
203+
196204
# Extract condensable parts
197205
Q = @view wrapper.u[(ndofs(dh)+1):end]
198206
Qprev = @view wrapper.uprev[(ndofs(dh)+1):end]
@@ -201,7 +209,7 @@ end
201209
volume_model,
202210
Q, Qprev,
203211
0.0,
204-
nothing, # inner_solver_cache.local_solver_cache,
212+
local_solver_cache,
205213
f.lvh,
206214
)
207215
face_wrapper = BackwardEulerStageFunctionWrapper(
@@ -231,9 +239,8 @@ end
231239
newton_cache = NewtonRaphsonSolverCache(op, residual, newton, inner_cache, T[], 0)
232240

233241
return MultiLevelNewtonRaphsonSolverCache(
234-
# FIXME global_f and local_f :)
235242
newton_cache, # setup_solver_cache(G, solver.newton),
236-
nothing, #setup_solver_cache(L, solver.local_newton), # FIXME pass
243+
local_solver_cache, #setup_solver_cache(L, solver.local_newton), # FIXME pass
237244
)
238245
end
239246

@@ -315,6 +322,7 @@ function setup_internal_cache(wrapper::BackwardEulerStageFunctionWrapper{<:Quasi
315322
wrapper.u,
316323
wrapper.uprev,
317324
wrapper.Δt,
325+
wrapper.local_solver_cache,
318326
wrapper.lvh,
319327
zeros(n_ivs_per_qp),
320328
zeros(n_ivs_per_qp),

0 commit comments

Comments
 (0)