This repository implements a Data-Driven Identification (DDI) framework for recovering the viscoelastic stress field S*(t) directly from bubble radius observations R*(t) in Inertial Microcavitation Rheometry (IMR) experiments. The method avoids assuming a parametric constitutive model and instead recovers the full stress trajectory by solving a constrained optimization problem derived from the Keller-Miksis (KM) equation of bubble dynamics.
The framework is compared against a naive (model-free, derivative-based) baseline across seven constitutive models and multiple noise levels.
IMR_DDI/
├── ddi_main.m # Top-level entry point for the DDI pipeline
├── setup.m # Adds all required folders to the MATLAB path
├── core/
│ ├── ddi_inverse_solver.m # DDI inverse solve: Stage 1 + Stage 2 (main orchestrator)
│ ├── ddi_kkt_newton.m # Per-experiment KKT Newton solver (7N x 7N sparse system)
│ ├── ddi_kkt_residual.m # KKT residual evaluator (used in backtracking line search)
│ ├── ddi_differentiate.m # Differentiation schemes: Pade, WENO3, FD4
│ ├── ddi_stress_recovery.m # One-pass stress recovery from KM equation (Stage 1)
│ ├── naive_DDI_IMR.m # Naive (one-pass, no manifold) baseline solver
│ └── compute_S_gt.m # Ground-truth stress integral for seven constitutive models
├── helpers/
│ ├── ddi_load_radius_data.m # Data loader for synthetic and experimental cases
│ ├── ddi_plot_results.m # Trajectory, phase space, and convergence figures
│ └── lambda_vs_Rmax_fig.m # Fit mean Rmax and lambda from experimental datasets
├── studies/
│ ├── ddi_noise_study.m # Study 1: sweep over noise levels x centroid counts
│ ├── ddi_noise_study_new.m # Study 1 variant: alternative metric (WIP)
│ └── model_comparison.m # Study 2: DDI vs naive across all 7 constitutive models
├── data/
│ ├── synthetic/ # Pre-generated synthetic R*(t) datasets (.mat)
│ │ ├── synthetic_data_KV.mat
│ │ ├── synthetic_data_NH.mat
│ │ ├── synthetic_data_Newt.mat
│ │ ├── synthetic_data_LM.mat
│ │ ├── synthetic_data_qKV.mat
│ │ ├── synthetic_data_qNH.mat
│ │ └── synthetic_data_SLS.mat
│ ├── experimental/ # Experimental R*(t) data organized by material
│ │ ├── 10percent/ # Gelatin 10%
│ │ ├── Ag0.5/ # Agarose 0.5%
│ │ ├── Ag2.5/ # Agarose 2.5%
│ │ ├── Ag5.0/ # Agarose 5.0%
│ │ ├── PA1pt7/ # Polyacrylamide 1.7%
│ │ ├── forbenchmarks/ # PEGDA benchmark data
│ │ └── Processed_Data.mat # Preprocessed data for UM materials 1-3
│ ├── synthetic_data_gen.m # Generate synthetic data for one model
│ └── synthetic_data_gen_all.m# Generate synthetic data for all 7 models
├── archive/ # Legacy and superseded files (not part of pipeline)
├── .gitignore
└── LICENSE
Seven models are supported throughout the pipeline:
| Tag | Model | Parameters |
|---|---|---|
| Newt | Newtonian viscous | mu |
| NH | Neo-Hookean elastic | G |
| KV | Kelvin-Voigt | mu, G |
| qNH | Quasi-linear Neo-Hookean | G, alpha |
| LM | Linear Maxwell | mu, lambda1 |
| qKV | Quasi-linear Kelvin-Voigt | mu, G, alpha |
| SLS | Standard Linear Solid | mu, G, lambda1 |
- MATLAB R2021a or later
- Parallel Computing Toolbox (for parfor in noise study and model comparison)
Run this once at the start of your MATLAB session, or add to startup.m:
run('setup.m')
Alternatively, setup.m is called automatically by ddi_main so no manual path setup is needed when running the pipeline through ddi_main.
% Default: synthetic KV case, all plots enabled
results = ddi_main();
% Specify data source (0 = synthetic, 1-9 = experimental materials)
results = ddi_main(0); % synthetic
results = ddi_main(5); % experimental Ag5.0
% Validation mode (uses single centroid = all points, no manifold)
results = ddi_main(0, false, true);
% Initialize from ground truth (synthetic only, for diagnostics)
results = ddi_main(0, true, false);
In ddi_main.m, under default_settings, set:
settings.diff_scheme = 'pade'; % recommended (default)
settings.diff_scheme = 'weno'; % matches paper Algorithm 1 description
settings.diff_scheme = 'fd4'; % 4th-order explicit finite difference
% Step 1: find optimal centroid count across noise levels and models
% Saves optimal_nbar_results.mat to the working directory
cd studies
ddi_noise_study
% Step 2: compare DDI vs naive across all 7 models at optimal Nbar
% Reads optimal_nbar_results.mat, saves model_comparison_results.mat
model_comparison
Requires IMRv2 (forward KM solver) to be restored from archive/ and added to the path. Once available:
cd data
synthetic_data_gen_all % generates all 7 model datasets into data/synthetic/
| Index | Tag | Description |
|---|---|---|
| 0 | synthetic | Synthetic data (set gt_model) |
| 1 | UM1 | Loaded from Processed_Data.mat |
| 2 | UM2 | Loaded from Processed_Data.mat |
| 3 | UM3 | Loaded from Processed_Data.mat |
| 4 | UT1 | Gelatin 10% |
| 5 | Ag5.0 | Agarose 5.0% |
| 6 | Ag2.5 | Agarose 2.5% |
| 7 | Ag0.5 | Agarose 0.5% |
| 8 | PA1pt7 | Polyacrylamide 1.7% |
| 9 | PEGDA | PEGDA benchmark |
These are generated locally when you run the studies and are not tracked:
| File | Generated by |
|---|---|
| optimal_nbar_results.mat | ddi_noise_study |
| model_comparison_results.mat | model_comparison |
| noise_study_results.mat | ddi_noise_study |
| centroid_sweep_results.mat | sweep scripts |
Sanchez et al., Hierarchical Bayesian constitutive model selection for high-strain-rate soft material characterization, RSC Soft Matter, 2026.