Skip to content

Commit 7f78872

Browse files
committed
Overhaul steepest descent solver for EMS (WIP)
1 parent e9319d5 commit 7f78872

File tree

9 files changed

+28
-152
lines changed

9 files changed

+28
-152
lines changed

examples/ems/awful-cube/awful-cube.yaml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
type: single
22
input mesh file: awful-cube.g
33
output mesh file: awful-cube.e
4-
Exodus output interval: 10
5-
CSV output interval: 10
4+
Exodus output interval: 1
65
model:
76
type: mesh smoothing
87
smooth reference: max
@@ -19,12 +18,8 @@ model:
1918
time integrator:
2019
type: quasi static
2120
initial time: 0.0
22-
final time: 1.0e-00
23-
time step: 1.0e-04
24-
maximum time step: 1.0e-4
25-
minimum time step: 1.0e-15
26-
increase factor: 1.1
27-
decrease factor: 0.5
21+
final time: 10.0
22+
time step: 1.0
2823
boundary conditions:
2924
Dirichlet:
3025
- node set: nsx-
@@ -49,7 +44,12 @@ solver:
4944
type: steepest descent
5045
step: steepest descent
5146
minimum iterations: 1
52-
maximum iterations: 16
47+
maximum iterations: 64
5348
relative tolerance: 1.0e-12
5449
absolute tolerance: 1.0e-08
55-
step length: 1.0e-8
50+
step length: 1.0e-3
51+
use line search: true
52+
line search backtrack factor: 0.5
53+
line search decrease factor: 1.0e-04
54+
line search maximum iterations: 16
55+

examples/single/implicit-dynamic-solid/cube/cube-matrix-free.yaml

Lines changed: 0 additions & 34 deletions
This file was deleted.

examples/single/static-solid/cube/cube-steepest-descent.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,12 @@ boundary conditions:
3535
solver:
3636
type: steepest descent
3737
step: steepest descent
38-
step length: 1.0
38+
step length: 1.0e-01
39+
use line search: true
40+
line search backtrack factor: 0.5
41+
line search decrease factor: 1.0e-04
42+
line search maximum iterations: 64
3943
minimum iterations: 1
40-
maximum iterations: 1024
44+
maximum iterations: 64
4145
relative tolerance: 1.0e-15
4246
absolute tolerance: 1.0e-08

src/model.jl

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,10 @@ function SolidMechanics(params::Parameters)
195195
end
196196
strain_energy = 0.0
197197
stiffness = spzeros(0, 0)
198-
diag_stiffness = Float64[]
199198
mass = spzeros(0, 0)
200199
lumped_mass = Float64[]
201200
body_force = Float64[]
202201
compute_stiffness = true
203-
compute_diag_stiffness = true
204202
compute_mass = true
205203
compute_lumped_mass = true
206204
mesh_smoothing = get(params, "mesh smoothing", false)
@@ -223,14 +221,12 @@ function SolidMechanics(params::Parameters)
223221
stored_energy,
224222
strain_energy,
225223
stiffness,
226-
diag_stiffness,
227224
mass,
228225
lumped_mass,
229226
body_force,
230227
free_dofs,
231228
time,
232229
compute_stiffness,
233-
compute_diag_stiffness,
234230
compute_mass,
235231
compute_lumped_mass,
236232
failed,
@@ -534,14 +530,6 @@ function add_internal_force!(Fi::MVector{M,T}, grad_op::SMatrix{9,M,T}, stress::
534530
@einsum Fi[i] += grad_op[j, i] * stress[j] * dV
535531
end
536532

537-
function add_diag_stiff!(K::MVector{M,T}, grad_op::SMatrix{9,M,T}, C::SMatrix{9,9,T}, dV::T) where {M,T}
538-
@inbounds for i in 1:M
539-
g = grad_op[:, i]
540-
K[i] += dV * dot(g, C * g)
541-
end
542-
return nothing
543-
end
544-
545533
function add_lumped_mass!(M::MVector{R,T}, Nξ::SVector{N,T}, density::T, dV::T) where {R,N,T}
546534
@assert R == 3N
547535
s = sum(Nξ)
@@ -565,11 +553,9 @@ function compute_flags(model::SolidMechanics, integrator::TimeIntegrator, solver
565553
is_implicit = is_implicit_dynamic || is_implicit_static
566554
is_hessian_opt = solver isa HessianMinimizer
567555
is_matrix_free = solver isa SteepestDescent
568-
need_diag_stiffness = is_implicit && is_matrix_free
569556
need_lumped_mass = is_explicit_dynamic || (is_implicit_dynamic && is_matrix_free)
570557
need_stiffness = is_implicit && is_hessian_opt
571558
need_mass = is_dynamic && is_hessian_opt
572-
compute_diag_stiffness = need_diag_stiffness && model.compute_diag_stiffness
573559
compute_lumped_mass = need_lumped_mass && model.compute_lumped_mass
574560
compute_stiffness = need_stiffness && model.compute_stiffness
575561
compute_mass = need_mass && model.compute_mass
@@ -580,11 +566,9 @@ function compute_flags(model::SolidMechanics, integrator::TimeIntegrator, solver
580566
is_implicit,
581567
is_hessian_opt,
582568
is_matrix_free,
583-
need_diag_stiffness,
584569
need_lumped_mass,
585570
need_stiffness,
586571
need_mass,
587-
compute_diag_stiffness,
588572
compute_lumped_mass,
589573
compute_stiffness,
590574
compute_mass,
@@ -598,11 +582,6 @@ function create_threadlocal_arrays(model::SolidMechanics, flags::EvaluationFlags
598582
energy = zeros(nthreads())
599583
internal_force = create_threadlocal_coo_vectors(num_dofs)
600584

601-
diag_stiffness = create_threadlocal_coo_vectors(flags.compute_diag_stiffness ? num_dofs : 0)
602-
if flags.compute_diag_stiffness && model.kinematics == Infinitesimal
603-
model.compute_diag_stiffness = false
604-
end
605-
606585
lumped_mass = create_threadlocal_coo_vectors(flags.compute_lumped_mass ? num_dofs : 0)
607586
if flags.compute_lumped_mass
608587
model.compute_lumped_mass = false
@@ -623,19 +602,18 @@ function create_threadlocal_arrays(model::SolidMechanics, flags::EvaluationFlags
623602
if flags.compute_mass
624603
model.compute_mass = false
625604
end
626-
return SMThreadLocalArrays(energy, internal_force, diag_stiffness, lumped_mass, stiffness, mass)
605+
return SMThreadLocalArrays(energy, internal_force, lumped_mass, stiffness, mass)
627606
end
628607

629608
function create_element_threadlocal_arrays(num_element_nodes::Int64, flags::EvaluationFlags)
630609
valN = Val(num_element_nodes)
631610
energy = zeros(nthreads())
632611
dofs = create_threadlocal_element_vectors(Int64, valN)
633612
internal_force = create_threadlocal_element_vectors(Float64, valN)
634-
diag_stiffness = create_threadlocal_element_vectors(Float64, flags.compute_diag_stiffness ? valN : Val(0))
635613
lumped_mass = create_threadlocal_element_vectors(Float64, flags.compute_lumped_mass ? valN : Val(0))
636614
stiffness = create_threadlocal_element_matrices(Float64, flags.compute_stiffness ? valN : Val(0))
637615
mass = create_threadlocal_element_matrices(Float64, flags.compute_mass ? valN : Val(0))
638-
return SMElementThreadLocalArrays(energy, dofs, internal_force, diag_stiffness, lumped_mass, stiffness, mass)
616+
return SMElementThreadLocalArrays(energy, dofs, internal_force, lumped_mass, stiffness, mass)
639617
end
640618

641619
function reset_element_threadlocal_arrays!(
@@ -651,9 +629,6 @@ function reset_element_threadlocal_arrays!(
651629
element_arrays_tl.dofs[t] = reshape(3 .* node_indices' .- [2, 1, 0], :)
652630
element_arrays_tl.energy[t] = 0.0
653631
fill!(element_arrays_tl.internal_force[t], 0.0)
654-
if flags.compute_diag_stiffness == true
655-
fill!(element_arrays_tl.diag_stiffness[t], 0.0)
656-
end
657632
if flags.compute_lumped_mass == true
658633
fill!(element_arrays_tl.lumped_mass[t], 0.0)
659634
end
@@ -682,10 +657,6 @@ function compute_element_threadlocal_arrays!(
682657
stress = SVector{9,Float64}(P)
683658
element_arrays_tl.energy[t] += W * dvol
684659
add_internal_force!(element_arrays_tl.internal_force[t], grad_op, stress, dvol)
685-
if flags.compute_diag_stiffness == true
686-
moduli = second_from_fourth(AA)
687-
add_diag_stiff!(element_arrays_tl.diag_stiffness[t], grad_op, moduli, dvol)
688-
end
689660
if flags.compute_lumped_mass == true
690661
add_lumped_mass!(element_arrays_tl.lumped_mass[t], Np, density, dvol)
691662
end
@@ -709,9 +680,6 @@ function assemble_element_threadlocal_arrays!(
709680
t = threadid()
710681
arrays_tl.energy[t] += element_arrays_tl.energy[t]
711682
assemble!(arrays_tl.internal_force[t], element_arrays_tl.internal_force[t], element_arrays_tl.dofs[t])
712-
if flags.compute_diag_stiffness == true
713-
assemble!(arrays_tl.diag_stiffness[t], element_arrays_tl.diag_stiffness[t], element_arrays_tl.dofs[t])
714-
end
715683
if flags.compute_lumped_mass == true
716684
assemble!(arrays_tl.lumped_mass[t], element_arrays_tl.lumped_mass[t], element_arrays_tl.dofs[t])
717685
end
@@ -729,9 +697,6 @@ function merge_threadlocal_arrays(
729697
)
730698
model.strain_energy = sum(arrays_tl.energy)
731699
model.internal_force = merge_threadlocal_coo_vectors(arrays_tl.internal_force, num_dofs)
732-
if flags.compute_diag_stiffness == true
733-
model.diag_stiffness = merge_threadlocal_coo_vectors(arrays_tl.diag_stiffness, num_dofs)
734-
end
735700
if flags.compute_lumped_mass == true
736701
model.lumped_mass = merge_threadlocal_coo_vectors(arrays_tl.lumped_mass, num_dofs)
737702
end
@@ -787,7 +752,6 @@ function evaluate(model::SolidMechanics, integrator::TimeIntegrator, solver::Sol
787752
J = det(F)
788753
if J 0.0 || isfinite(J) == false
789754
model.failed = true
790-
model.compute_stiffness = model.compute_diag_stiffness = true
791755
model.compute_mass = model.compute_lumped_mass = true
792756
norma_log(0, :error, "Non-positive Jacobian detected! This may indicate element distortion.")
793757
norma_logf(4, :warning, "det(F) = %.3e", J)

src/model_types.jl

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,9 @@ struct EvaluationFlags
3434
is_implicit::Bool
3535
is_hessian_opt::Bool
3636
is_matrix_free::Bool
37-
need_diag_stiffness::Bool
3837
need_lumped_mass::Bool
3938
need_stiffness::Bool
4039
need_mass::Bool
41-
compute_diag_stiffness::Bool
4240
compute_lumped_mass::Bool
4341
compute_stiffness::Bool
4442
compute_mass::Bool
@@ -48,17 +46,15 @@ end
4846
struct SMThreadLocalArrays{V,M}
4947
energy::Vector{Float64}
5048
internal_force::Vector{V}
51-
diag_stiffness::Vector{V}
5249
lumped_mass::Vector{V}
5350
stiffness::Vector{M}
5451
mass::Vector{M}
5552
end
5653

57-
struct SMElementThreadLocalArrays{T,DOFV,IFV,DSV,LMV,SM,MM}
54+
struct SMElementThreadLocalArrays{T,DOFV,IFV,LMV,SM,MM}
5855
energy::Vector{T}
5956
dofs::Vector{DOFV}
6057
internal_force::Vector{IFV}
61-
diag_stiffness::Vector{DSV}
6258
lumped_mass::Vector{LMV}
6359
stiffness::Vector{SM}
6460
mass::Vector{MM}
@@ -78,14 +74,12 @@ mutable struct SolidMechanics <: Model
7874
stored_energy::Vector{Vector{Float64}}
7975
strain_energy::Float64
8076
stiffness::SparseMatrixCSC{Float64,Int64}
81-
diag_stiffness::Vector{Float64}
8277
mass::SparseMatrixCSC{Float64,Int64}
8378
lumped_mass::Vector{Float64}
8479
body_force::Vector{Float64}
8580
free_dofs::BitVector
8681
time::Float64
8782
compute_stiffness::Bool
88-
compute_diag_stiffness::Bool
8983
compute_mass::Bool
9084
compute_lumped_mass::Bool
9185
failed::Bool

src/solver.jl

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ function SteepestDescent(params::Parameters, model::Model)
8282
relative_error = 0.0
8383
value = 0.0
8484
gradient = zeros(num_dof)
85-
lumped_hessian = zeros(num_dof)
8685
solution = zeros(num_dof)
8786
initial_norm = 0.0
8887
converged = false
@@ -105,7 +104,6 @@ function SteepestDescent(params::Parameters, model::Model)
105104
relative_error,
106105
value,
107106
gradient,
108-
lumped_hessian,
109107
solution,
110108
initial_norm,
111109
converged,
@@ -496,10 +494,8 @@ function evaluate(integrator::QuasiStatic, solver::MatrixFree, model::SolidMecha
496494
external_force = model.body_force + model.boundary_force
497495
if model.inclined_support == true
498496
solver.gradient = model.global_transform * (model.internal_force - external_force)
499-
solver.lumped_hessian = model.global_transform * model.diag_stiffness
500497
else
501498
solver.gradient = model.internal_force - external_force
502-
solver.lumped_hessian = model.diag_stiffness
503499
end
504500
return nothing
505501
end
@@ -530,32 +526,6 @@ function evaluate(integrator::Newmark, solver::HessianMinimizer, model::SolidMec
530526
return nothing
531527
end
532528

533-
function evaluate(integrator::Newmark, solver::MatrixFree, model::SolidMechanics)
534-
evaluate(model, integrator, solver)
535-
if model.failed == true
536-
return nothing
537-
end
538-
integrator.stored_energy = model.strain_energy
539-
β = integrator.β
540-
Δt = integrator.time_step
541-
inertial_force = model.lumped_mass .* integrator.acceleration
542-
kinetic_energy = 0.5 * model.lumped_mass (integrator.velocity .* integrator.velocity)
543-
integrator.kinetic_energy = kinetic_energy
544-
internal_force = model.internal_force
545-
external_force = model.body_force + model.boundary_force
546-
diag_stiffness = model.diag_stiffness
547-
if model.inclined_support == true
548-
global_transform = model.global_transform
549-
internal_force = global_transform * internal_force
550-
external_force = global_transform * external_force
551-
diag_stiffness = global_transform * diag_stiffness
552-
end
553-
solver.lumped_hessian = diag_stiffness + model.lumped_mass / β / Δt / Δt
554-
solver.gradient = internal_force - external_force + inertial_force
555-
solver.value = model.strain_energy - external_force integrator.displacement + kinetic_energy
556-
return nothing
557-
end
558-
559529
function evaluate(integrator::CentralDifference, solver::ExplicitSolver, model::SolidMechanics)
560530
evaluate(model, integrator, solver)
561531
if model.failed == true
@@ -607,7 +577,8 @@ function backtrack_line_search(
607577
copy_solution_source_targets(solver, model, integrator)
608578
evaluate(integrator, solver, model)
609579
if model.failed == true
610-
return step
580+
step_length *= backtrack_factor
581+
continue
611582
end
612583
resid = solver.gradient[free]
613584
merit = 0.5 * dot(resid, resid)
@@ -640,7 +611,7 @@ end
640611

641612
function compute_step(integrator::TimeIntegrator, model::SolidMechanics, solver::MatrixFree, _::SteepestDescentStep)
642613
free = model.free_dofs
643-
direction = -solver.gradient[free] ./ solver.lumped_hessian[free]
614+
direction = LinearAlgebra.normalize(-solver.gradient[free])
644615
return backtrack_line_search(integrator, solver, model, direction)
645616
end
646617

src/solver_types.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ mutable struct SteepestDescent <: MatrixFree
6060
relative_error::Float64
6161
value::Float64
6262
gradient::Vector{Float64}
63-
lumped_hessian::Vector{Float64}
6463
solution::Vector{Float64}
6564
initial_norm::Float64
6665
converged::Bool

0 commit comments

Comments
 (0)