Optimization
Three optimization algorithms are available for iterative reconstruction. All use Armijo backtracking line search.
See the Mathematical Reference for update rule equations.
Problem Context
Sentinel.ForwardProblemContext Type
ForwardProblemContextBundles all immutable problem data needed to evaluate the objective function and gradient. Passed to line search and optimizer routines to avoid long argument lists.
Fields
grid: Ferrite Griddh: DofHandlercv_disp: CellValues for displacement interpolationcv_press: CellValues for pressure (ornothing)model: AbstractMaterialModel singletongp2mtrs: vector of GP2Mtr per material meshmeshes: vector of MaterialMeshbcs: BoundaryConditionsmeas: measured Displacementω: angular frequency [rad/s]ρ: density [kg/m³]regularizations: vector of AbstractRegularization (ornothing)solver: linear solver backendnumdispsets: number of displacement/excitation setsfiber_field: per-element fiber direction vectors (ornothing)
Sentinel.ConvergenceHistory Type
ConvergenceHistoryRecords iteration-by-iteration progress of an optimization run.
Fields
iterations: number of iterations completedobjective: objective function values per iterationdisp_error: displacement-only error per iterationmat_epsilon: relative material change per iterationconverged: whether the optimizer declared convergence
Helper Functions
Sentinel.copy_material Function
copy_material(mat::Material) -> MaterialDeep-copy a Material struct, duplicating all SingleProperty arrays.
sourceSentinel.apply_material_update! Function
apply_material_update!(material::Material, delta_theta::AbstractVector,
alpha::Float64, grad::MaterialGradient)Update material property values: θ += α·Δθ/scalar, using the gradient's realparam2prop reverse mapping to write each element of delta_theta back to the correct rvalue or ivalue entry.
The division by scalar matches Fortran's incrementmaterial (FEmaterial.f90): realinc = direction%rvalue(direcind) / origmaterial%prop(ii)%scalar(iii) This converts the step from physical units (produced by CG gradient scaling) back to normalized parameter units.
Sentinel.evaluate_objective! Function
evaluate_objective!(calc::Displacement, K::SparseMatrixCSC{ComplexF64},
f_work::Vector{ComplexF64},
ctx::ForwardProblemContext, material::Material;
iteration::Int=1) -> Float64Run the forward solve for all displacement sets and compute the objective.
Assemble stiffness from current material
For each dispset: apply BCs, solve, store in
calcReturn
compute_objective(calc, meas, material, regularizations)
Sentinel.compute_full_gradient! Function
compute_full_gradient!(grad::MaterialGradient, calc::Displacement,
adjnt::Displacement,
K::SparseMatrixCSC{ComplexF64},
ctx::ForwardProblemContext, material::Material;
iteration::Int=1)Compute the full gradient including adjoint solves and regularization.
For each dispset: adjoint_solve!
zero!(grad), compute_gradient! (adjoint contribution)
add_gradient! for each regularization term
Sentinel.apply_postprocessing! Function
apply_postprocessing!(material::Material, regularizations)Apply all post-processing regularizations (Van Houten, Spatial Filter, McGarry bounds) in sequence.
sourceConjugate Gradient
Polak-Ribiere+ nonlinear CG:
Sentinel.conjugate_gradient! Function
conjugate_gradient!(material::Material, ctx::ForwardProblemContext;
max_iter::Int=50, tol::Float64=1e-6,
alpha_init::Float64=1.0,
cg_threshold::Float64=0.0,
cg_scalar_weights::Union{Matrix{Float64}, Nothing}=nothing,
iteration_offset::Int=0) -> (Material, ConvergenceHistory)Run nonlinear conjugate gradient iterations to minimize the objective.
Arguments
material: initial material estimate (modified in-place on convergence)ctx: forward problem contextmax_iter: maximum number of CG iterationstol: convergence tolerance onmaterial_epsilonalpha_init: initial line search step sizecg_threshold: if > 0, cap relative material change per step viacg_update_scalecg_scalar_weights: (numprop, 2) matrix of per-property CG scalar weights for gradient direction scaling. If provided, scales the gradient so the average step for each property equalsweight * avg_property_value. Ports regind(7) from Fortran.iteration_offset: offset for regularization weight schedule evaluation
Returns
(material, history): updated material and convergence history
Gauss-Newton
Diagonal Hessian preconditioned descent:
Sentinel.gauss_newton! Function
gauss_newton!(material::Material, ctx::ForwardProblemContext;
max_iter::Int=20, tol::Float64=1e-6,
alpha_init::Float64=1.0,
hessian_floor::Float64=1e-30,
iteration_offset::Int=0) -> (Material, ConvergenceHistory)Run Gauss-Newton iterations to minimize the objective.
Arguments
material: initial material estimate (modified in-place)ctx: forward problem context (regularizations should include Hessian-contributing regs)max_iter: maximum iterationstol: convergence tolerance onmaterial_epsilonalpha_init: initial line search step sizehessian_floor: minimum diagonal value to prevent division by zeroiteration_offset: offset for regularization weight schedules
Returns
(material, history): updated material and convergence history
L-BFGS
Limited-memory BFGS with two-loop recursion and initial scaling
Sentinel.quasi_newton! Function
quasi_newton!(material::Material, ctx::ForwardProblemContext;
max_iter::Int=50, tol::Float64=1e-6,
memory::Int=5, alpha_init::Float64=1.0,
iteration_offset::Int=0) -> (Material, ConvergenceHistory)Run L-BFGS quasi-Newton iterations to minimize the objective.
Arguments
material: initial material estimate (modified in-place)ctx: forward problem contextmax_iter: maximum iterationstol: convergence tolerance onmaterial_epsilonmemory: number of L-BFGS curvature pairs to store (default 5)alpha_init: initial line search step sizeiteration_offset: offset for regularization weight schedules
Returns
(material, history): updated material and convergence history
Line Search
Armijo backtracking: reduce
Sentinel.line_search Function
line_search(ctx::ForwardProblemContext, material::Material,
grad::MaterialGradient, direction::AbstractVector{Float64},
obj_current::Float64;
alpha_init::Float64=1.0, c1::Float64=1e-4,
rho::Float64=0.5, max_iter::Int=20,
iteration::Int=1) -> (Float64, Float64, Material)Backtracking line search with Armijo sufficient decrease condition.
Arguments
ctx: forward problem contextmaterial: current material stategrad: current gradient (must be initialized, withrvaluepopulated)direction: search direction vector (same length asgrad.rvalue)obj_current: current objective value Φ(θ_k)alpha_init: initial step size (default 1.0)c1: sufficient decrease parameter (default 1e-4)rho: backtracking reduction factor (default 0.5)max_iter: maximum number of backtracking steps (default 20)iteration: current optimizer iteration (for regularization weight schedules)
Returns
(alpha, obj_new, mat_new): step size, new objective value, updated material If no decrease is found, returns(0.0, obj_current, copy_material(material)).