Inversion Setup & Solve
The high-level programmatic API for describing and running an MRE inverse reconstruction: build an InversionProblem, call solve, and read the InversionResult. Configurations load and round-trip through load_inversion / save_inversion, and legacy Fortran runfiles convert with runfile_to_toml.
Problem definition
An InversionProblem is the declarative description of a reconstruction; PropertySpec describes one reconstructed material property.
Sentinel.InversionProblem Type
InversionProblem(; kwargs...)Validated, keyword-constructed description of an MRE inverse reconstruction.
Data (required)
frequency: actuation frequency (Hz, or Unitful)displacements:.dspfile path(s), ordata: a UIUC-format.matfile — the mesh and displacement files are generated automatically atsolvetime (mesh_strategyselects 1/2/3)mesh: mesh file stem ("study"→study.nod/.elm/.bnd) or a NamedTuple(nod=..., elm=..., bnd=...); required withdisplacements, omitted withdata
Physics
model = :isotropic: material model (Symbol, id, or model instance)density = 1000.0: tissue density (kg/m³, or Unitful)properties = default_properties(model; density):Vector{PropertySpec}material_mesh_resolutions: vector of 3-tuples (m), default fine/medium/coarse
Regularization
regularization = default_regularization():Vector{RegularizationSpec}const_reg_iters = 30: iterations before the scheduled regularization weights activate (weights are 0 through this iteration, then ramp initial → final); must be <max_global_iter × max_zone_iterfor ramped specs to contribute
Zones & iterations
zone_edge = 0.0195633(m),zone_overlap = 0.15max_global_iter = 20,max_zone_iter = 1global_tol = zone_tol = line_tol = 0.001(fractional)zone_structures = [(1,0,0,1), (2,0,0,2), (3,0,0,2)](CG/GN/QN/LS iters),structure_limits = [10, 150](one fewer than structures)
Execution
output = "sentinel_inv": output file stemsolver = :default::default(cached direct),:direct,:mumps,:krylov, or anAbstractLinearSolverinstanceregstack = nothing: region stack file (required bySoftPrior)initial_solution = nothing,verbose = true,calc_variance = falsemesh_strategy = 1(datamode only),mumps_procs = 1,max_ram(MB)
Sentinel.PropertySpec Type
PropertySpec(; name=:property, basis=:nodal, nvpp=1, scalars,
mesh=1, reconstruct=false)Description of one material property.
basis::nodalor:elementalnvpp: parameter values per material pointscalars:(real, imag)property scalars (native runfile units)mesh: material-mesh index, or(real_mesh, imag_mesh)reconstruct: whether to reconstruct, or(real, imag)separately
Running a solve
solve runs the reconstruction. It accepts either an InversionProblem or the path to a TOML configuration (the latter loads and solves in one step) and returns an InversionResult.
Sentinel.solve Function
solve(problem::ForwardProblem) -> DisplacementAssemble stiffness, apply Dirichlet BCs, and solve the forward problem for all displacement sets.
Returns a Displacement containing the computed displacement and pressure fields.
solve(prob::InversionProblem; basedir=".", on_iteration=nothing, kwargs...) -> InversionResultRun the inverse reconstruction described by prob and return an InversionResult.
Arguments
basedir: directory that relative input paths inprobare resolved against.on_iteration: optional callback invoked once per global iteration — after zone consolidation, before the convergence check — with the signature(giter::Int, material, state), wherematerialis the current reconstruction andstate.global_obj/state.disp_error/state.convergedare the running metrics. For monitoring only; mutatingmaterialis not supported.remaining
kwargsare forwarded torun_inverse_solve!— e.g.pmap_func,gradient_backend,cudss_batched_solver,distributed.
Side effects
Writes the fully-resolved configuration to "<output>.config.toml" (next to the outputs) for provenance. When prob reconstructs directly from a .mat data file, the generated displacement mesh is written under dirname(output)/generated_mesh/.
Example
prob = InversionProblem(data="scan.mat", frequency=60.0, model=:isotropic, output="inv/scan")
result = solve(prob; on_iteration=(g, _m, s) -> @info "global iter" g obj=s.global_obj)A convenience overload, solve(path::AbstractString; kwargs...), loads a TOML configuration with load_inversion and solves it in one step.
solve(path::AbstractString; kwargs...) -> InversionResultConvenience overload: load a TOML configuration with load_inversion and solve it in one step — equivalent to solve(load_inversion(path); basedir=dirname(abspath(path)), kwargs...). Relative paths in the file are resolved against the file's directory; kwargs are forwarded to solve (e.g. on_iteration). Returns an InversionResult.
Example
result = solve("config.toml")Result
Sentinel.InversionResult Type
InversionResultThe result of solve: the reconstructed material, the final calculated displacement, the solver state, and the handles needed to export or post-process the reconstruction.
Fields
material::Material— reconstructed properties. The per-property arraysmaterial.prop[i].rvalue/.ivalueare the normalized nodal/elemental values; multiply bymaterial.prop[i].scalar[1](real) andscalar[2](imag) to get physical units — Pa for shear/bulk, kg/m³ for density. For Model 1,prop[1]is the complex shear modulus (μ′ real part, μ″ imaginary part). (interpolate_to_gridandexport_reconpropsapply this scaling for you.)displacement::Displacement— the final calculated complex displacement field (metres) on the FE nodes.state— the solver state:state.converged::Bool,state.global_obj(the objective: displacement misfit + regularization penalties), andstate.disp_error(the displacement misfit).problem::InversionProblem— the problem exactly as solved (input provenance).setup::InverseProblemSetup— meshes, DOF handler, etc.; the handle you pass tointerpolate_to_grid/export_reconpropsfor export.
Example
result = solve(prob)
result.state.converged # did it converge?
result.state.disp_error # final displacement misfit
# physical shear modulus (Pa) on the material mesh, property 1:
p = result.material.prop[1]
mu_real = p.scalar[1] .* p.rvalue # μ′ (Pa)
mu_imag = p.scalar[2] .* p.ivalue # μ″ (Pa)See also solve, interpolate_to_grid, export_reconprops.
Configuration files
Load, save (provenance), and convert TOML / legacy .dat configurations. load_inversion reads both TOML files and legacy Fortran .dat runfiles directly, returning an InversionProblem either way.
Sentinel.load_inversion Function
load_inversion(path) -> InversionProblemRead a TOML configuration or a legacy Fortran .dat runfile and return an InversionProblem. Dispatches on the .dat extension: .dat paths are parsed with parse_inverse_runfile and raised via raise_config; any non-.dat path is treated as TOML. Unknown TOML keys raise errors (typo safety); omitted keys take the InversionProblem defaults.
Sentinel.save_inversion Function
save_inversion(path, prob::InversionProblem)Write the fully-resolved problem (all defaults made explicit) as TOML.
sourceSentinel.runfile_to_toml Function
runfile_to_toml(runfile, toml=replace(runfile, r"\.dat$" => "") * ".toml")Convert a legacy Fortran .dat runfile to the TOML format. Returns the output path.