◆ FORGE Suite
GitHubMechanical Neuroimaging Lab · Univ. of Delaware
Skip to content

Inverse Solver ​

The inverse solver computes gradients of the objective function with respect to material parameters using the adjoint method. See the Mathematical Reference for the full derivation.

Objective Function ​

The data-misfit objective is Φ(θ)=12∥ucalc−umeas∥2, optionally augmented with regularization penalties.

Sentinel.compute_objective Function
julia
compute_objective(calc::Displacement, meas::Displacement) -> Float64

Compute the displacement-only objective function value (L2 misfit): Φ = ½‖u_calc − u_meas‖²

This calls displacement_error! internally to compute the misfit and returns calc.abserror.

source
julia
compute_objective(calc::Displacement, meas::Displacement,
                  material::Material, regularizations;
                  iteration::Int=1) -> Float64

Compute the total objective function value including regularization penalties.

Stores displacement error in material.disperror, per-regularization errors in material.regerror, and the total in material.totalerror.

source

Gradient Initialization ​

The gradient structure maps material parameters to a flat index vector for optimization. Each entry corresponds to a specific (property, real/imaginary, value index) triple.

Sentinel.init_gradient! Function
julia
init_gradient!(grad::MaterialGradient, material::Material;
               realparamind::Union{AbstractMatrix{Bool}, Nothing}=nothing)

Initialize the MaterialGradient struct from a Material, building the index mapping from (property, real/imag, value_index) to a flat gradient vector offset.

Ports initmtrlgrad + propparamindices from FEmaterial.f90.

Arguments

  • grad: MaterialGradient to initialize in-place

  • material: Material struct with property definitions

  • realparamind: optional (2*numprop, max_nvpp) Bool matrix selecting which parameter groups are active. nothing → all active.

Index layout

For each property iprop (1-based) and value index jprop (1-based):

  • Row 2*(iprop-1)+1 → real part

  • Row 2*(iprop-1)+2 → imaginary part

realprop2param[row, jprop] gives the starting 1-based index in grad.rvalue for the flattened gradient entries of that parameter group. realparam2prop[k, :] = [iprop, jprop, iii] is the reverse mapping (iii=1 for real, 2 for imaginary).

source

Gradient Computation ​

The adjoint gradient is:

∂Φ∂θm=−Re[∑e∑gpwgpλ―eT∂Ke∂θmue]

Dispatched per material model type for model-specific ∂K/∂θ derivatives.

Sentinel.compute_gradient! Function
julia
compute_gradient!(grad::MaterialGradient,
                  dh::DofHandler, cv_disp::CellValues,
                  calc::Displacement, adjnt::Displacement,
                  model::IsotropicIncompressible,
                  material::Material,
                  gp2mtrs::Vector{GP2Mtr},
                  meshes::Vector{MaterialMesh},
                  ω::Float64; numdispsets::Int=1)

Compute the adjoint gradient for the IsotropicIncompressible model (Model 1).

Ports isoadjointgrad_multimesh from FEgradient.f90 (lines 126–416).

The gradient formula for parameter θ_m at material mesh node m is:

∂Φ/∂θ_m = -Σ_dispsets Re[ Σ_elem Σ_gp  wght · (∂K/∂θ)_ij · λᵢ · uⱼ ]

where wght = basis_m (hex8 shape function at material mesh node m).

Three property derivatives for Model 1:

  • ∂K/∂μ: deviatoric stiffness (9 terms per node pair)

  • ∂K/∂ρ: mass matrix diagonal (-ω²·Nᵢ·Nⱼ)

  • ∂K/∂κ: pressure-pressure block ((1/κ²)·ψ_p·ψ_q)

Arguments

  • grad: initialized MaterialGradient (from init_gradient!)

  • dh: DofHandler with vector field Lagrange{RefHexahedron, 2}()^3

  • cv_disp: CellValues for scalar Lagrange{RefHexahedron, 2}()

  • calc: calculated displacement (forward solution)

  • adjnt: adjoint displacement

  • model: IsotropicIncompressible() singleton

  • material: Material with properties μ, ρ, κ

  • gp2mtrs: vector of GP2Mtr (one per material mesh)

  • meshes: vector of MaterialMesh

  • ω: angular frequency rad/s

  • numdispsets: number of displacement sets (default 1)

source

Gradient Type ​

Sentinel.MaterialGradient Type
julia
MaterialGradient

Stores the adjoint gradient of the objective function with respect to all real material parameter values. Corresponds to the Fortran mtrlgrad derived type.

Fields

  • numprop: number of material properties

  • npr: per-property count of real parameter points

  • npi: per-property count of imaginary parameter points

  • nvpp: per-property values per point

  • numrealparam: total number of distinct real parameter groups (including real+imag parts)

  • totnumrealparam: total flattened gradient vector length

  • realprop2param: maps (2*iprop-1/2, ival) → starting index in rvalue

  • realparam2prop: maps gradient index → (iprop, ival, 1=real/2=imag)

  • nreg: number of regularization terms

  • toterrinit: initial total error

  • totalerror: complete error including regularization

  • disperror: displacement misfit only

  • regerror: per-regularization-term error, length nreg

  • rvalue: gradient values, length totnumrealparam

source

Full Inverse Problem ​

The full inverse solver orchestrates multi-zone inversion using Zone Decomposition to partition the domain and solve subproblems independently. See the Optimization API for ForwardProblemContext, evaluate_objective!, compute_full_gradient!, and material operation utilities.