Elasto-Plastic Models (EPM)¶
Quick Reference¶
Use when: Spatially-resolved modeling of amorphous solids, plastic avalanches, shear banding
Parameters: 6 (\(\mu, \sigma_{c,\text{mean}}, \sigma_{c,\text{std}}, \tau_{\text{pl}}\), L, dt)
Key equation: \(\partial_t \sigma_{ij} = \mu \dot{\gamma}(t) - \mu \dot{\gamma}^{pl}_{ij} + \sum_{kl} \mathcal{G}_{ij,kl} \dot{\gamma}^{pl}_{kl}\)
Test modes: flow_curve, startup, relaxation, creep, oscillation
Material examples: Metallic glasses, colloidal gels, pastes, dense granular suspensions, foams
Overview¶
The Elasto-Plastic Model (EPM) is a mesoscopic lattice-based framework for modeling the rheology of amorphous solids (glasses, gels, pastes, dense suspensions). Unlike mean-field models (like Hébraud-Lequeux or Soft Glassy Rheology), EPMs explicitly resolve spatial heterogeneity, plastic avalanches, and non-local stress redistribution.
This implementation leverages JAX for high-performance FFT-based computations on GPU/TPU.
Notation Guide¶
Symbol |
Units |
Description |
|---|---|---|
\(\sigma\) |
Pa |
Local shear stress at lattice site |
\(\dot{\gamma}\) |
1/s |
Macroscopic applied shear rate |
\(\dot{\gamma}^p\) |
1/s |
Local plastic strain rate at yielded sites |
\(\sigma_c\) |
Pa |
Local yield stress threshold (varies spatially) |
\(\mu\) |
Pa |
Shear modulus of elastic matrix |
\(\tau_{pl}\) |
s |
Plastic relaxation time for yielded blocks |
\(\mathcal{G}(\mathbf{r})\) |
— |
Eshelby propagator (stress redistribution kernel) |
\(L\) |
— |
Lattice size (\(L \times L\) grid) |
Discrete State Variables¶
The scalar EPM discretizes the material on a \(d\)-dimensional periodic lattice (typically \(d=2\)) with \(N = L_x \times L_y\) sites indexed by \(i\).
At each site \(i\):
Local shear stress: \(\sigma_i(t)\)
Local plastic strain: \(\varepsilon_i^{pl}(t)\)
Local yield threshold: \(\sigma_{y,i}\) (constant or disordered)
Local elastic modulus: \(\mu_i\) (often uniform \(\mu\))
(Optional) Structural variable: age \(x_i\), effective temperature \(T_i\), etc.
Elastic Loading and Stress Redistribution¶
The local stress evolves due to elastic loading from the macroscopic shear and redistribution from plastic events at other sites:
In rate form:
where:
\(\mu \dot{\gamma}\): Affine elastic loading from imposed macroscopic shear
\(G_{ij}\): Eshelby propagator (elastic kernel) discretized on the lattice
The last two terms describe stress relaxation/redistribution from plastic strain rates
Effective Kernel¶
In practice, it is common to combine terms into an effective kernel \(K_{ij}\) acting on plastic strain increments:
This form is computationally convenient since the FFT convolution directly gives the stress update from plastic strain rates.
Physical Interpretation & Assumptions¶
The Mesoscopic View¶
We discretize the material into a lattice of mesoscopic blocks of size $xi$ (the correlation length of plastic events). Each block is coarse-grained enough to be treated as a continuum element with a local stress $sigma_{ij}$ and strain $gamma_{ij}$, but small enough that plastic yielding is a discrete, local event.
The Physics of Plasticity¶
The dynamics are governed by the interplay of three mechanisms:
Elastic Loading: The entire lattice is driven by a macroscopic shear rate $dot{gamma}$. Each block accumulates elastic stress.
Local Yielding: If the local stress $|sigma_i|$ exceeds a local yield threshold $sigma_{c,i}$, the block yields. This is a “plastic event” or “Shear Transformation Zone (STZ) flip”.
Stress Redistribution: A plastic event at site $j$ releases local stress but must satisfy force balance ($nabla cdot sigma = 0$). This stress is redistributed to neighbors via the Eshelby Propagator $mathcal{G}_{ij}$.
Assumptions¶
Scalar Approximation: We model only the shear component $sigma_{xy}$.
Athermal Limit: Yielding is purely stress-driven (zero temperature), though “smooth” yielding can approximate thermal activation.
Periodic Boundary Conditions: The system is an infinite repeating lattice.
Overdamped Dynamics: Inertia is neglected.
Mathematical Formulation¶
Evolution Equation¶
The time evolution of the local stress $sigma(mathbf{r}, t)$ is given by:
where: * $mu$ is the shear modulus. * $dot{gamma}(t)$ is the macroscopic applied shear rate. * $dot{gamma}^{pl}$ is the local plastic strain rate. * $mathcal{G}$ is the elastic propagator.
Physical Foundations¶
Mesoscopic Coarse-Graining¶
The EPM operates at a length scale \(\xi\) (correlation length of plastic events, typically 10-100 particle diameters in colloidal systems). At this scale:
The material is homogeneous enough for continuum elasticity to apply
Plastic yielding is localized to discrete regions (blocks)
Spatial correlations between yielding events become important
This mesoscopic view differs from:
Microscopic models (molecular dynamics): Track individual particles
Macroscopic models (continuum plasticity): Smear plasticity into a continuous field
Stress Redistribution via Eshelby Propagator¶
When a block yields plastically, it releases local stress. However, mechanical equilibrium (∇·\(\sigma\) = 0) requires this stress to be redistributed to neighboring blocks. The Eshelby propagator describes this redistribution:
In 2D Fourier space, the propagator has characteristic quadrupolar symmetry (“four-leaf clover”):
Note
For a 2D scalar shear model, a common alternative form is:
with \(\hat{G}(\mathbf{0}) = 0\). Variants exist depending on whether you model pure shear, simple shear, or include compressibility.
Numerically, the effective kernel is defined as \(\hat{K}(\mathbf{q}) = \hat{G}(\mathbf{q}) - \mu\), and the convolution is computed via FFT:
where \(\mathcal{F}\) denotes the discrete Fourier transform.
Key properties:
\(\tilde{\mathcal{G}}(0) = 0\): Plastic events conserve total stress (controlled by boundary loading)
Long-range coupling: \(\mathcal{G}(\mathbf{r}) \sim 1/r^2\) in real space (power-law decay)
Quadrupolar structure: Stress redistribution has four lobes (compression/extension pattern)
This long-range interaction is what leads to avalanche dynamics: one yielding event can trigger neighbors to yield, creating cascades of plasticity.
Governing Equations¶
Yield Criteria¶
We implement two modes of yielding:
Hard Mode (Simulation):
\[\dot{\gamma}^{pl} = \frac{\sigma}{\tau_{pl}} \Theta(|\sigma| - \sigma_c)\]Standard threshold dynamics. Used for physical validation.
Smooth Mode (Inference):
\[\dot{\gamma}^{pl} = \frac{\sigma}{\tau_{pl}} \frac{1}{2} \left[ 1 + \tanh\left(\frac{|\sigma| - \sigma_c}{w}\right) \right]\]A differentiable approximation that allows gradients to backpropagate through the yield surface for NLSQ/HMC fitting.
Local Yield Condition¶
A site becomes unstable when the local stress exceeds its yield threshold:
Once unstable, the plastic strain rate is determined by one of two dynamics:
Plastic Event Dynamics¶
Option A: Instantaneous Flip (Quasi-Static / Event-Driven)
When unstable, site \(i\) yields and its plastic strain jumps by a fixed increment:
where \(\Delta\varepsilon_0\) may be drawn from a distribution. Stress is then updated by redistribution to all sites:
After redistribution, stability is re-checked (potentially triggering avalanches).
Option B: Finite-Rate Maxwell / Viscoplastic Rule (Continuous Time Stepping)
Introduce a plastic strain rate when the yield condition is met:
Or a simpler activated rule with fixed rate:
The finite-rate rule is convenient for LAOS and explicit time integration since it produces smooth time series.
Macroscopic Observables¶
The primary outputs from EPM simulations are spatially-averaged quantities:
Macroscopic Shear Stress:
Plastic Activity (fraction of active sites or total plastic strain rate):
Energy Dissipation Rate:
Dissipated Energy Per Cycle (for oscillatory protocols):
This integral over a complete strain cycle gives the area enclosed by the Lissajous figure, representing energy lost to plastic dissipation.
Numerical Implementation¶
Spectral Method (FFT)¶
Direct summation of the stress redistribution is $O(L^4)$ or $O(L^2)$ with a cutoff. We use Fast Fourier Transforms (FFT) to perform the convolution in $O(L^2 log L)$ time.
Compute $dot{gamma}^{pl}(mathbf{r})$.
FFT to Fourier space: $tilde{dot{gamma}}^{pl}(mathbf{q})$.
Multiply by propagator: $tilde{sigma}^{redist}(mathbf{q}) = tilde{mathcal{G}}(mathbf{q}) tilde{dot{gamma}}^{pl}(mathbf{q})$.
Inverse FFT to real space.
This allows us to simulate large systems ($L=64, 128, 256$) efficiently on GPUs.
Time Integration¶
We use a semi-implicit or explicit Euler scheme with a small time step $dt$. The yield thresholds $sigma_{c,i}$ are renewed (drawn from a Gaussian distribution) whenever a site yields, introducing the necessary quenched disorder that leads to avalanches.
Validity and Assumptions¶
Valid for:
Athermal plasticity: Yielding driven by stress, not thermal activation (T ≈ 0)
Overdamped dynamics: Inertia negligible (quasi-static or low Stokes number)
2D simple shear: Single shear component \(\sigma_xy\) (for scalar EPM)
Periodic systems: Infinite lattice (no boundary effects)
Assumptions:
Quenched disorder: Yield thresholds \(\sigma_c,i\) drawn from Gaussian, renewed upon yielding
Elastic homogeneity: Uniform shear modulus \(\mu\) throughout
Mean-field-like yield: Local yield criterion (no cooperative yielding beyond Eshelby coupling)
Not appropriate for:
Thermal systems where \(k_B T\) ~ barrier heights
High-frequency dynamics (inertial effects)
Systems where plasticity is diffusive rather than avalanche-like
What You Can Learn¶
From fitting EPM to experimental data, you can extract insights about mesoscopic plasticity, avalanche dynamics, and spatial heterogeneity in amorphous solids.
Parameter Interpretation¶
- \(\sigma_c\) (Yield Stress Threshold):
The local stress at which mesoscopic blocks yield plastically. Typically lower than macroscopic yield stress due to spatial averaging. For graduate students: \(\sigma_c\) represents the energy barrier for local plastic rearrangements in the free energy landscape. For colloidal gels, \(\sigma_c\) ~ bond strength; for glasses, \(\sigma_c\) ~ activation barrier height. For practitioners: Use \(\sigma_c\) to predict onset of yielding in processing. Lower \(\sigma_c\) = easier to flow but potentially less stable structures.
- \(\sigma_{c,\text{std}}\) (Disorder Strength):
Standard deviation of local yield thresholds across the material, quantifying microstructural heterogeneity. For graduate students: Disorder drives avalanche criticality. Larger \(\sigma_{c,\text{std}}\) → broader avalanche size distributions. In 2D lattice EPM under quasistatic loading, the avalanche exponent \(\tau \approx 1.0\text{--}1.5\) (Lin et al. PNAS 2014 measured \(\tau = 1.36 \pm 0.03\)); the mean-field value \(\tau = 3/2\) holds only under random triggering. Controls correlation length \(\xi_{\text{corr}}\) of yielding events. For practitioners: High disorder correlates with pronounced shear banding. Monitor \(\sigma_{c,\text{std}}/\sigma_c\) ratio to predict flow instabilities.
- \(\alpha\) (Disorder Parameter):
Related parameter quantifying yield threshold variability, \(\alpha = \sigma_{c,\text{std}}/\sigma_c\). For graduate students: Critical parameter in mean-field elastoplastic theory. \(\alpha\) → 0 recovers deterministic plasticity; \(\alpha\) >> 1 leads to extreme heterogeneity and arrested dynamics. For practitioners: \(\alpha\) > 0.3 indicates strong spatial heterogeneity requiring spatially-resolved models.
Material Classification¶
Parameter Range |
Material Behavior |
Typical Materials |
Processing Implications |
|---|---|---|---|
\(\sigma_c\) = 10-100 Pa, \(\alpha\) < 0.2 |
Homogeneous yielding |
Monodisperse colloids, simple gels |
Uniform flow, minimal banding |
\(\sigma_c\) = 50-500 Pa, \(\alpha\) = 0.2-0.5 |
Moderate heterogeneity |
Emulsions, pastes, polydisperse suspensions |
Possible shear banding, flow instabilities |
\(\sigma_c\) = 100-1000 Pa, \(\alpha\) > 0.5 |
Strong heterogeneity, avalanches |
Metallic glasses, dense granular media |
Shear localization, stick-slip |
\(\tau_{\text{pl}}\) < 0.1 s |
Fast plastic relaxation |
Soft colloids, concentrated emulsions |
Rapid stress relaxation, smooth flow |
\(\tau_{\text{pl}}\) > 1 s |
Slow plastic relaxation |
Glassy polymers, hard colloids |
Stress overshoots, memory effects |
Experimental Protocol Integration¶
The model supports standard rheological protocols via _predict(test_mode=...).
Below we provide the complete mathematical formulation for each protocol, using the
finite-rate plastic flow rule (Option B) unless noted otherwise.
Flow Curve (Rotation / Steady Shear)¶
Protocol:
Governing Equations:
where \(\mathcal{R}\) is the chosen plastic flow rule (finite-rate or activated).
Flow Curve Extraction:
Run to steady state and compute the time-averaged macroscopic stress:
Typical Scaling:
Many EPMs produce Herschel-Bulkley-like flow curves:
The exponent \(n\) depends on the flow rule and noise/activation:
\(n \approx 0.5\) near yield (diffusive scaling from avalanches)
\(n \to 1\) at high rates (linear viscous regime)
Start-up of Steady Shear¶
Protocol:
starting from an initial condition (often \(\varepsilon^{pl} = 0\), \(\sigma\) drawn from a narrow distribution, or an “aged” state).
Outputs:
Stress growth \(\Sigma(t)\)
Stress overshoot \(\Sigma_{\max}\) and peak strain \(\gamma_{\max}\)
Avalanche statistics (for event-driven implementation)
Transient shear banding (when spatial gradient direction is retained)
Key Physics:
Elastic rise: \(\Sigma \propto \mu \dot{\gamma}_0 t\) at early times
Overshoot: Stress peak when first system-spanning avalanches occur
Steady state: Relaxation to the flow curve plateau
Stress Relaxation (Step Strain)¶
Protocol (step strain):
Implementation:
Apply instantaneous affine loading at \(t = 0^+\):
\[\sigma_i(0^+) = \sigma_i(0^-) + \mu \gamma_0\]Then evolve at \(\dot{\gamma}(t > 0) = 0\).
Governing Equations for \(t > 0\):
Relaxation Modulus:
Physics:
Stress relaxes via “cascades”—an active site yields, triggering a neighbor, keeping the system active long after the drive stops. This leads to slow, non-exponential relaxation (power-law \(\sim t^{-\alpha}\) or logarithmic \(\sim \ln t\)).
Creep (Step Stress)¶
Protocol (step stress):
Stress-Controlled Closure:
Since EPM is naturally strain-rate driven, we determine \(\dot{\gamma}(t)\) dynamically so that:
Simple Controller:
where \(\lambda\) is the feedback gain (typically 0.1-1.0).
Creep Strain:
Behavior:
\(\Sigma_0 < \Sigma_y\): Strain rate decays to zero (arrest)
\(\Sigma_0 > \Sigma_y\): Strain rate stabilizes to finite value (flow)
Fluidization time \(t_f \sim (\Sigma_y - \Sigma_0)^{-\beta}\) with \(\beta \approx 2\text{--}3\) for athermal EPM (Ferrero et al. PRL 2022). Larger exponents \(\beta \approx 4\text{--}6\) observed in thermal creep experiments (e.g., carbopol gels)
Oscillation (SAOS and LAOS)¶
Protocol:
Governing Equations:
SAOS Moduli (Small Amplitude Oscillatory Shear, \(\gamma_0 \ll 1\)):
Extract first harmonic from the stress response:
Storage and loss moduli:
LAOS Harmonics (Large Amplitude Oscillatory Shear):
At large \(\gamma_0\), the stress response contains higher harmonics:
Higher-order moduli:
LAOS Physics:
Large \(\gamma_0\) triggers yielding cycle-by-cycle
The Eshelby propagator synchronizes these events
Complex Lissajous figures with shear-banding signatures
Intracycle yielding and strain stiffening/softening
Bayesian Inference (NLSQ → NUTS)¶
EPM models now support the full NLSQ → NUTS Bayesian inference pipeline, enabling:
Point estimates via GPU-accelerated NLSQ optimization
Posterior distributions via NumPyro’s NUTS sampler
Uncertainty quantification with credible intervals
Convergence diagnostics (R-hat, ESS, divergences)
The key requirement is the model_function() method, which provides a differentiable
forward model for both NLSQ and NumPyro.
Smooth Yielding Approximation¶
Bayesian inference requires gradients through the yield surface. EPM uses a smooth
tanh approximation (smooth=True) during fitting:
This enables backpropagation while closely approximating the hard threshold behavior.
Example: NLSQ → NUTS Pipeline¶
from rheojax.models.epm import LatticeEPM
import numpy as np
# Create model and synthetic data
model = LatticeEPM(L=32, dt=0.01)
gamma_dot = np.logspace(-2, 1, 30)
# Example experimental data
stress = 10.0 * gamma_dot**0.5 + 5.0 # Herschel-Bulkley-like
# Step 1: NLSQ fitting (fast point estimation)
model.fit(gamma_dot, stress, test_mode='flow_curve', max_iter=500)
# Step 2: Bayesian inference (warm-started from NLSQ)
result = model.fit_bayesian(
gamma_dot,
stress,
test_mode='flow_curve',
num_warmup=500,
num_samples=1000,
num_chains=4, # Multiple chains for R-hat diagnostics
seed=42,
)
# Step 3: Analyze posteriors
print(result.summary) # Parameter means, std, credible intervals
# Convergence diagnostics
print(f"R-hat: {result.diagnostics['r_hat']}")
print(f"ESS: {result.diagnostics['ess']}")
# Credible intervals
intervals = model.get_credible_intervals(result.posterior_samples, credibility=0.95)
for name, (lower, upper) in intervals.items():
print(f"{name}: [{lower:.3f}, {upper:.3f}]")
Parameters¶
Parameter |
Symbol |
Units |
Description |
|---|---|---|---|
|
\(\mu\) |
Pa |
Shear modulus of the elastic matrix |
|
\(\bar{\sigma}_c\) |
Pa |
Mean local yield stress threshold |
|
\(\delta\sigma_c\) |
Pa |
Standard deviation of local yield stress (disorder) |
|
\(\tau_{pl}\) |
s |
Plastic relaxation time for yielded blocks |
|
\(L\) |
— |
Lattice size (L × L grid) |
|
\(\Delta t\) |
s |
Time step for numerical integration |
Fitting Guidance¶
Initialization Strategy¶
Step 1: Flow curve fitting (fastest)
Start with steady-state flow curve data to constrain:
sigma_c_mean: Should approximate macroscopic yield stress (or slightly below)mu: Elastic modulus (can initialize from SAOS data if available)
Step 2: Startup shear refinement
Use transient startup data to refine:
tau_pl: Controls stress overshoot decay ratesigma_c_std: Controls overshoot magnitude and fluctuations
Step 3: Use small lattice for fitting
L = 8-16 for parameter estimation (fast, 0.5-2 min per fit)
L = 32-64 for validation and spatial analysis (10-30 min)
L = 128+ only for production simulations (hours)
Parameter Bounds and Physical Constraints¶
Parameter |
Typical Range |
Physical Constraint |
|---|---|---|
|
10-10000 Pa |
Match SAOS elastic modulus \(G'\) if available |
|
0.5-2× macroscopic \(\sigma_y\) |
Lower bound: \(\sigma_y/2\); upper bound: \(2\sigma_y\) |
|
0.1-0.5× sigma_c_mean |
Larger disorder = stronger shear banding |
|
0.01-10 s |
Should be << experimental timescale |
|
8-128 |
Fitting: 8-16; Production: 32-128 |
|
0.001-0.05 |
Must resolve \(\tau_{\text{pl}}\) (dt < \(\tau_{\text{pl}}\)/10) |
Common Fitting Issues¶
Issue |
Solution |
|---|---|
Fit converges but predictions unrealistic |
Reduce L to 8-12 for faster iteration; check dt stability |
Large NLSQ residuals |
Switch to |
Bayesian divergences > 5% |
Increase |
R-hat > 1.1 |
Run longer chains (num_samples=2000+); check for multimodality |
Predictions too smooth (no avalanches) |
Increase |
Fitting Parameters¶
EPM fitting supports these keyword arguments:
Parameter |
Default |
Description |
|---|---|---|
|
(required) |
Protocol: ‘flow_curve’, ‘startup’, ‘relaxation’, ‘creep’, ‘oscillation’ |
|
42 |
Random seed for reproducibility |
|
0.1 |
Shear rate for startup protocol |
|
0.1 |
Step strain for relaxation protocol |
|
1.0 |
Target stress for creep protocol |
|
0.01 |
Strain amplitude for oscillation |
|
1.0 |
Angular frequency for oscillation |
|
500 |
Maximum NLSQ iterations |
|
True |
Use log-space residuals (recommended) |
Convergence Tips¶
EPM models are stochastic due to the random yield thresholds. For robust inference:
Use small lattices for fitting (L=8-16): Faster and sufficient for parameter estimation
Increase warmup samples: EPM posteriors may have multimodal structure
Check divergences: >5% divergences suggests model-data mismatch
Run multiple chains: Essential for R-hat diagnostics
Expected diagnostics for well-converged EPM fits:
R-hat < 1.1 for all parameters
ESS > 400 per parameter
Divergences < 1%
Usage¶
Basic Usage¶
from rheojax.models.epm import LatticeEPM
import numpy as np
# Create model instance
model = LatticeEPM(L=16, dt=0.01)
# Fit to flow curve data
gamma_dot = np.logspace(-2, 1, 20)
stress_exp = np.array([0.5, 0.8, 1.2, 1.8, 2.5, 3.4, 4.5, 5.8, 7.3, 9.1,
11.2, 13.6, 16.3, 19.4, 22.8, 26.5, 30.6, 35.0, 39.8, 44.9])
model.fit(gamma_dot, stress_exp, test_mode='flow_curve')
# Predict stress
gamma_dot_new = np.logspace(-2, 1, 50)
sigma_pred = model.predict(gamma_dot_new, test_mode='flow_curve')
Advanced Usage Examples¶
Basic Flow Curve Fitting¶
from rheojax.models.epm import LatticeEPM
import numpy as np
# Create model with small lattice for fitting
model = LatticeEPM(L=16, dt=0.01)
# Experimental flow curve data
gamma_dot = np.logspace(-2, 1, 20)
stress_exp = np.array([0.5, 0.8, 1.2, 1.8, 2.5, 3.4, 4.5, 5.8, 7.3, 9.1,
11.2, 13.6, 16.3, 19.4, 22.8, 26.5, 30.6, 35.0, 39.8, 44.9])
# NLSQ fitting (fast)
model.fit(gamma_dot, stress_exp, test_mode='flow_curve', max_iter=500)
print(f"Fitted σ_c: {model.params.get_value('sigma_c_mean'):.2f} Pa")
print(f"Fitted disorder: {model.params.get_value('sigma_c_std'):.3f} Pa")
Startup Shear with Stress Overshoot¶
# Simulate startup at constant shear rate
t = np.linspace(0, 50, 500)
gamma_dot_startup = 0.1 # 1/s
# Predict using fitted parameters
stress_startup = model.predict(
t,
test_mode='startup',
gamma_dot=gamma_dot_startup
)
# Plot stress vs time (shows overshoot)
import matplotlib.pyplot as plt
plt.plot(t, stress_startup)
plt.xlabel("Time (s)")
plt.ylabel("Stress (Pa)")
Bayesian Inference with Uncertainty¶
# Bayesian inference (warm-started from NLSQ)
result = model.fit_bayesian(
gamma_dot,
stress_exp,
test_mode='flow_curve',
num_warmup=500,
num_samples=1000,
num_chains=4,
seed=42,
)
# Extract credible intervals
intervals = model.get_credible_intervals(
result.posterior_samples,
credibility=0.95
)
for name, (lower, upper) in intervals.items():
mean_val = result.posterior_samples[name].mean()
print(f"{name}: {mean_val:.3f} [{lower:.3f}, {upper:.3f}]")
# Check convergence
print(f"R-hat (max): {max(result.diagnostics['r_hat'].values()):.4f}")
print(f"ESS (min): {min(result.diagnostics['ess'].values()):.0f}")
Visualizing Spatial Fields¶
import numpy as np
from rheojax.visualization.epm_plots import plot_lattice_fields
# Run simulation at higher resolution for visualization
model_viz = LatticeEPM(L=64, dt=0.01)
model_viz.params = model.params.copy() # Use fitted parameters
# Time array for startup simulation
t = np.linspace(0, 50, 500)
# Simulate and extract stress field
stress_field = model_viz.predict(
t,
test_mode='startup',
gamma_dot=1.0,
return_fields=True # Returns spatial arrays
)
# Plot stress heterogeneity
plot_lattice_fields(
stress_field,
title="Stress Distribution at t=10s",
cmap="viridis"
)
API Reference¶
- class rheojax.models.epm.lattice.LatticeEPM(L=64, dt=0.01, mu=1.0, tau_pl=1.0, sigma_c_mean=1.0, sigma_c_std=0.1, n_bayesian_steps=200)[source]
Bases:
EPMBase2D Lattice Elasto-Plastic Model (EPM).
A mesoscopic model for amorphous solids (glasses, gels) that explicitly resolves spatial heterogeneity, plastic avalanches, and stress redistribution.
- Physics:
Lattice of elastoplastic blocks.
Elastic loading (affine).
Local yielding when stress > threshold.
Long-range stress redistribution via quadrupolar Eshelby propagator.
Structural renewal (disorder).
- Parameters:
mu (
float) – Shear modulus. Default 1.0.tau_pl (
float) – Plastic relaxation timescale. Default 1.0.sigma_c_mean (
float) – Mean yield threshold. Default 1.0.sigma_c_std (
float) – Disorder strength (std dev of thresholds). Default 0.1.smoothing_width (float) – Width for smooth yielding approx (inference only). Default 0.1.
- Configuration:
L (int): Lattice size (LxL). Default 64. dt (float): Time step. Default 0.01.
- __init__(L=64, dt=0.01, mu=1.0, tau_pl=1.0, sigma_c_mean=1.0, sigma_c_std=0.1, n_bayesian_steps=200)[source]
Initialize the Lattice EPM.
- rheojax.visualization.epm_plots.plot_lattice_fields(stress, thresholds, title=None, figsize=None, cmap_stress='coolwarm', cmap_thresh='viridis')[source]
Plot EPM lattice fields with auto-detection of scalar vs tensorial stress.
Automatically detects whether stress is scalar (L, L) or tensorial (3, L, L) and dispatches to the appropriate plotting function.
- Parameters:
stress (
ndarray|Array) – Either (L, L) scalar or (3, L, L) tensorial stress field.thresholds (
ndarray|Array) – 2D array of local yield thresholds (L, L).title (
str|None) – Overall figure title (auto-generated if None).figsize (
tuple[int,int] |None) – Figure size (width, height) (auto-selected if None).cmap_stress (
str) – Colormap for stress field (diverging).cmap_thresh (
str) – Colormap for threshold field (sequential).
- Return type:
- Returns:
Matplotlib Figure object.
- Raises:
ValueError – If stress shape is invalid.
Comparison: LatticeEPM vs TensorialEPM¶
RheoJAX provides two EPM implementations with different capabilities:
Feature |
LatticeEPM (Scalar) |
TensorialEPM |
|---|---|---|
Stress Components |
\(\sigma_xy\) only |
[\(\sigma_xx, \sigma_yy, \sigma_xy\)] + \(\sigma_zz\) |
Flow Curves |
✓ Fast |
✓ More accurate if \(N_1\) ≠ 0 |
Normal Stress Differences |
✗ |
✓ \(N_1, N_2\) predictions |
Yield Criteria |
Scalar threshold |
von Mises or Hill |
Anisotropic Materials |
✗ |
✓ Hill criterion |
Computational Cost |
1x (baseline) |
3-5x slower |
Memory Usage |
1x |
3x (tensor storage) |
Fitting Speed |
Fast |
Moderate |
GPU Acceleration |
✓ |
✓ |
When to Use LatticeEPM: - Pure shear rheology (flow curves, yield stress) - Fast parameter estimation - Exploratory analysis - No normal stress data available
When to Use TensorialEPM (Tensorial Elasto-Plastic Model (EPM)): - Normal stress measurements available - Anisotropic materials (fibers, liquid crystals) - Flow instabilities (shear banding, edge fracture) - Rod climbing or die swell phenomena
References¶
See Also¶
Elasto-Plastic Models (EPM) — EPM family overview and comparison
Tensorial Elasto-Plastic Model (EPM) — Full stress tensor implementation
SGR Conventional (Soft Glassy Rheology) — Handbook — Mean-field SGR (complementary theory)
Hébraud–Lequeux (HL) Model — Handbook — Mean-field HL (EPM limiting case)
Fluidity Local (Homogeneous Fluidity Model) — Handbook — Fluidity approach to plasticity
rheojax.visualization.epm_plots.plot_lattice_fields()— Visualization functions for spatial fields
JAX Implementation Utilities¶
This section provides JAX-first implementations of the core EPM components. These
utilities form the computational backbone of the LatticeEPM model.
Note
For actual usage, prefer the high-level LatticeEPM class. These utilities
are documented for advanced users and developers.
EPM Parameter Container¶
from __future__ import annotations
from dataclasses import dataclass
import jax.numpy as jnp
Array = jnp.ndarray
@dataclass(frozen=True)
class EPMParams:
"""Immutable container for EPM simulation parameters."""
Lx: int
Ly: int
mu: float = 1.0 # Shear modulus
sig_y0: float = 1.0 # Mean yield stress
eta: float = 1.0 # Viscoplastic viscosity
tau: float = 1.0 # Activated timescale
dt: float = 1e-3 # Time step
sigy_logstd: float = 0.0 # Yield stress disorder (log-normal)
Fourier Grid and Eshelby Kernel¶
def make_qgrid(Lx: int, Ly: int):
"""Create 2D wavevector grid for FFT operations."""
qx = 2 * jnp.pi * jnp.fft.fftfreq(Lx)[:, None]
qy = 2 * jnp.pi * jnp.fft.fftfreq(Ly)[None, :]
return qx, qy
def make_eshelby_kernel_hat(Lx: int, Ly: int, mu: float):
"""Construct effective kernel K̂(q) = Ĝ(q) - μ in Fourier space.
Returns
-------
Khat : Array, shape (Lx, Ly)
Effective kernel for FFT convolution
"""
qx, qy = make_qgrid(Lx, Ly)
q2 = qx * qx + qy * qy
q2_safe = jnp.where(q2 == 0.0, 1.0, q2)
# Quadrupolar Eshelby kernel: G(q) ∝ -(qx² - qy²)² / q⁴
Ghat = -((qx * qx - qy * qy) ** 2) / (q2_safe * q2_safe)
Ghat = jnp.where(q2 == 0.0, 0.0, Ghat)
# Effective kernel
Khat = Ghat - mu
return Khat
Plastic Flow Rules¶
def plastic_rate_bingham(sigma: Array, sig_y: Array, eta: float) -> Array:
"""Bingham-like viscoplastic flow rule.
ε̇ᵖˡ = (1/η) × sign(σ) × max(|σ| - σ_y, 0)
"""
sgn = jnp.sign(sigma)
overstress = jnp.maximum(jnp.abs(sigma) - sig_y, 0.0)
return (overstress / eta) * sgn
Time-Stepping Kernel¶
import jax
@jax.jit
def epm_step(
sigma: Array,
eps_pl: Array,
sig_y: Array,
gdot: float,
Khat: Array,
p: EPMParams,
) -> tuple[Array, Array]:
"""Single EPM time step with FFT-accelerated stress redistribution.
Parameters
----------
sigma : Array, shape (Lx, Ly)
Current local stress field
eps_pl : Array, shape (Lx, Ly)
Current plastic strain field
sig_y : Array, shape (Lx, Ly)
Local yield thresholds
gdot : float
Applied macroscopic shear rate
Khat : Array, shape (Lx, Ly)
Precomputed effective kernel in Fourier space
p : EPMParams
Simulation parameters
Returns
-------
sigma_new, eps_pl_new : Arrays
Updated stress and plastic strain fields
"""
# Plastic strain rate
deps_pl = plastic_rate_bingham(sigma, sig_y, p.eta)
# FFT convolution for stress redistribution
deps_pl_hat = jnp.fft.fftn(deps_pl)
conv = jnp.fft.ifftn(Khat * deps_pl_hat).real
# Stress update: elastic loading + redistribution
dsigma = p.mu * gdot + conv
sigma_new = sigma + p.dt * dsigma
eps_pl_new = eps_pl + p.dt * deps_pl
return sigma_new, eps_pl_new
Strain-Rate Controlled Simulation¶
@jax.jit
def simulate_strain_rate_control(
sigma0: Array,
eps_pl0: Array,
sig_y: Array,
gdot_t: Array,
Khat: Array,
p: EPMParams,
):
"""Run EPM simulation with prescribed strain rate history.
Uses jax.lax.scan for efficient compilation and execution.
Parameters
----------
sigma0, eps_pl0 : Arrays
Initial stress and plastic strain fields
sig_y : Array
Yield threshold field
gdot_t : Array, shape (Nt,)
Strain rate at each time step
Khat : Array
Precomputed Eshelby kernel
p : EPMParams
Simulation parameters
Returns
-------
Sigma_t : Array, shape (Nt,)
Macroscopic stress time series
sigmaT, epsT : Arrays
Final stress and plastic strain fields
"""
def body(carry, gdot):
sigma, eps_pl = carry
sigma, eps_pl = epm_step(sigma, eps_pl, sig_y, gdot, Khat, p)
Sigma = jnp.mean(sigma)
return (sigma, eps_pl), Sigma
(sigmaT, epsT), Sigma_t = jax.lax.scan(body, (sigma0, eps_pl0), gdot_t)
return Sigma_t, sigmaT, epsT
Stress-Controlled Simulation (Creep)¶
@jax.jit
def simulate_creep_stress_control(
sigma0: Array,
eps_pl0: Array,
sig_y: Array,
Sigma_target: float,
Nt: int,
Khat: Array,
p: EPMParams,
gdot0: float = 0.0,
gain: float = 0.1,
):
"""Run EPM creep simulation with stress feedback control.
Parameters
----------
Sigma_target : float
Target macroscopic stress
Nt : int
Number of time steps
gain : float
Feedback controller gain (λ in documentation)
Returns
-------
Sigma_t : Array
Macroscopic stress time series
gdot_t : Array
Strain rate time series
sigmaT, epsT : Arrays
Final fields
"""
def body(carry, _):
sigma, eps_pl, gdot = carry
Sigma = jnp.mean(sigma)
# P-controller: adjust strain rate
gdot = gdot + gain * (Sigma_target - Sigma)
sigma, eps_pl = epm_step(sigma, eps_pl, sig_y, gdot, Khat, p)
return (sigma, eps_pl, gdot), (Sigma, gdot)
(sigmaT, epsT, gdotT), (Sigma_t, gdot_t) = jax.lax.scan(
body, (sigma0, eps_pl0, gdot0), xs=None, length=Nt
)
return Sigma_t, gdot_t, sigmaT, epsT
Quasi-Static Avalanche Relaxation¶
For event-driven (quasi-static) simulations, use iterative relaxation:
def avalanche_relax(
sigma: Array,
sig_y: Array,
Khat: Array,
Delta_eps0: float,
max_iters: int = 256,
):
"""Relax unstable sites via iterative yielding until stable.
All unstable sites yield simultaneously per sub-iteration (JAX-friendly).
Parameters
----------
Delta_eps0 : float
Fixed plastic strain increment per yield event
Returns
-------
sigma : Array
Relaxed (stable) stress field
"""
def one_iter(sigma, _):
unstable = jnp.abs(sigma) >= sig_y
deps = Delta_eps0 * jnp.sign(sigma) * unstable
deps_hat = jnp.fft.fftn(deps)
conv = jnp.fft.ifftn(Khat * deps_hat).real
sigma = sigma + conv
return sigma, None
sigma, _ = jax.lax.scan(one_iter, sigma, xs=jnp.arange(max_iters))
return sigma
Field Initialization¶
import jax.random
def init_sigy(key, p: EPMParams):
"""Initialize yield threshold field with optional log-normal disorder."""
if p.sigy_logstd <= 0:
return p.sig_y0 * jnp.ones((p.Lx, p.Ly))
z = jax.random.normal(key, (p.Lx, p.Ly))
return p.sig_y0 * jnp.exp(p.sigy_logstd * z)
def init_fields(p: EPMParams):
"""Initialize stress and plastic strain fields to zero."""
sigma0 = jnp.zeros((p.Lx, p.Ly))
eps0 = jnp.zeros((p.Lx, p.Ly))
return sigma0, eps0
Advanced Physics¶
This section covers advanced theoretical aspects of EPM plasticity, connecting the lattice model to broader statistical physics concepts.
Avalanche Dynamics¶
One of the defining features of EPM is its ability to capture plastic avalanches— cascades of yielding events triggered by stress redistribution.
Avalanche Definition¶
An avalanche is a sequence of plastic events (block yieldings) triggered by a single driving event. The avalanche terminates when no more blocks exceed their yield thresholds.
Detection algorithm:
Identify primary yield event (block exceeds \(\sigma_c\))
Propagate stress via Eshelby (FFT convolution)
Count secondary yields (blocks pushed over threshold by redistribution)
Repeat until no new yields occur
Total yield count = avalanche size S
Code example:
def detect_avalanches(model, stress_time_series, sigma_c):
"""Detect avalanches from stress time series.
Parameters
----------
stress_time_series : ndarray, shape (T, L, L)
Spatiotemporal stress field
sigma_c : ndarray, shape (L, L)
Local yield thresholds
Returns
-------
avalanche_sizes : list
Sizes of detected avalanches
"""
yielded = jnp.abs(stress_time_series) > sigma_c
# Count connected yield events per timestep
avalanche_sizes = []
for t in range(len(yielded) - 1):
new_yields = yielded[t+1] & ~yielded[t]
if new_yields.sum() > 0:
avalanche_sizes.append(int(new_yields.sum()))
return avalanche_sizes
Avalanche Size Distribution¶
In the critical regime near yielding, avalanche sizes follow a power-law distribution:
where:
\(\tau\) ≈ 1.0-1.5 (2D quasistatic): Lin et al. PNAS 2014 measured \(\tau = 1.36 \pm 0.03\) in 2D. Mean-field \(\tau = 3/2\) applies under random triggering only
S_c: Finite-size cutoff scaling with lattice size L
d_f ≈ 2: Fractal dimension of avalanches in 2D
Key observations:
Well below yield (\(\sigma < \sigma_y\)): Exponentially distributed (no criticality)
At yield (\(\sigma \approx \sigma_y\)): Power-law distribution (critical behavior)
Above yield (\(\sigma > \sigma_y\)): Flowing state, continuous plastic activity
Duration-size scaling:
Avalanche duration T scales with size S:
This scaling connects to the dynamical exponent z = 2 for overdamped dynamics.
References: Lin et al. PNAS 2014 [5], Budrikis et al. Nat. Commun. 2017 [10]
Yielding Transition Physics¶
The yielding transition in EPM exhibits critical point behavior, analogous to absorbing phase transitions in statistical physics.
Critical Behavior¶
Near the macroscopic yield stress \(\sigma_y\), several quantities diverge or vanish:
Correlation length:
where \(\nu\) is the correlation length exponent (\(\nu\) ≈ 1 in mean-field).
Relaxation time:
with dynamical exponent z ≈ 2.
Mean-field exponents:
Exponent |
Value |
Physical Meaning |
|---|---|---|
\(\tau\) (avalanche) |
3/2 |
Avalanche size distribution \(P(S) \sim S^{-\tau}\) |
\(\nu\) (correlation) |
1 |
Correlation length \(\xi \sim (\sigma-\sigma_y)^{-\nu}\) |
\(\beta\) (order param) |
1 |
Plastic rate \(\dot{\gamma}_{\text{pl}} \sim (\sigma-\sigma_y)^{\beta}\) |
z (dynamical) |
2 |
Relaxation time \(\tau \sim \xi^z\) |
Disorder corrections:
Strong disorder (\(\sigma_{c,\text{std}}/\sigma_{c,\text{mean}}\) > 0.3) modifies these exponents:
\(\tau\) increases toward 2.0 (broader avalanche distribution)
\(\nu\) decreases (shorter correlations)
Dynamical Heterogeneity¶
Near yielding, the material exhibits dynamical heterogeneity: coexisting regions with different local plastic activity. This is quantified by:
Four-point correlator:
where \(\Delta(t)\) is the fraction of sites that have yielded by time t.
\(\chi_4\) peaks at the characteristic relaxation time, measuring the size of correlated rearranging regions.
Connection to absorbing phase transitions:
The yielding transition maps onto the directed percolation universality class in the athermal limit, or conserved directed percolation for stress-controlled protocols.
References: Nicolas et al. Rev. Mod. Phys. 2018 §IV [2], Martens et al. PRL 2011 [3]
Shear Banding Mechanisms¶
EPM naturally captures shear banding—the localization of plastic flow into narrow bands separated by solid-like regions.
Localization Criteria¶
Shear banding in EPM arises from two mechanisms:
Disorder-driven localization: High disorder (\(\alpha = \sigma_{c,\text{std}}/\sigma_{c,\text{mean}}\) > 0.3) leads to heterogeneous yield thresholds. Regions with low \(\sigma_c\) yield first, creating stress concentrations that nucleate bands.
Stress redistribution feedback: The Eshelby propagator’s quadrupolar symmetry creates positive feedback—plastic events along the flow direction destabilize neighboring regions.
Banding criterion:
Band width:
where \(\xi_{\text{corr}}\) is the correlation length of plastic events.
Detection Methods¶
From velocity profile:
def detect_shear_band(velocity_profile, y_positions, threshold=0.1):
"""Detect shear banding from velocity profile.
Parameters
----------
velocity_profile : ndarray
Velocity v_x as function of y
y_positions : ndarray
y coordinates
threshold : float
Relative gradient threshold
Returns
-------
band_width : float
Width of the shear band (or NaN if no banding)
"""
grad_v = jnp.gradient(velocity_profile, y_positions)
max_grad = jnp.max(jnp.abs(grad_v))
# Banding if localized high shear region
high_shear = jnp.abs(grad_v) > threshold * max_grad
band_width = jnp.sum(high_shear) * (y_positions[1] - y_positions[0])
return band_width
From stress gradients:
Shear bands correlate with large spatial gradients in the stress field:
Transient vs steady-state banding:
Transient bands: Appear during startup, may homogenize at long times
Steady-state bands: Persist indefinitely; require strong disorder or thixotropy
References: Talamali et al. CR Mécanique 2012 [9], Nicolas et al. Soft Matter 2014 [7]
Connections to Other Models¶
EPM connects to several other rheological frameworks, providing physical insight and enabling model selection.
Soft Glassy Rheology (SGR)¶
SGR and EPM describe similar physics from different perspectives:
Aspect |
SGR |
EPM |
|---|---|---|
Approach |
Mean-field trap model |
Spatially resolved lattice |
Noise temperature |
x (thermal + mechanical) |
\(\sigma_{c,\text{std}}\) (quenched disorder) |
Yielding |
Thermally activated escape |
Stress-driven (athermal) |
Avalanches |
Implicit (\(x < 1\)) |
Explicit cascades |
Correlations |
None (mean-field) |
Quadrupolar (Eshelby) |
Mapping:
The effective noise temperature x in SGR corresponds to disorder strength:
SGR’s glass transition (x = 1) maps to the EPM critical disorder threshold.
Fluidity Models¶
Fluidity models describe plastic flow via a kinetic fluidity field \(\phi(r\), t).
Connection:
The local plastic strain rate in EPM maps to fluidity:
High \(\phi\) → flowing (high plastic activity)
Low \(\phi\) → arrested (solid-like)
Fluidity diffusion in nonlocal models corresponds to Eshelby stress redistribution in the mean-field limit.
Shear Transformation Zone (STZ) Theory¶
STZ theory views plastic events as activated transitions of local structural zones.
Connection:
Each EPM lattice block represents a mesoscopic ensemble of STZs. The yield threshold \(\sigma_c\) corresponds to the activation barrier, and the plastic relaxation time \(\tau_{\text{pl}}\) to the STZ flip rate.
where n_STZ is STZ density, \(\nu_flip\) is flip rate, and \(\gamma_0\) is elementary strain.
Hébraud-Lequeux Mean-Field Limit¶
The Hébraud-Lequeux (HL) model is the mean-field limit of EPM:
Replace Eshelby propagator with uniform redistribution
All sites feel average stress, not local heterogeneity
Exact solution possible, faster computation
EPM → HL when:
L → ∞ and disorder → 0 (thermodynamic limit with weak disorder)
Short-range interactions dominate (screened propagator)
The HL model provides analytic benchmarks for EPM predictions.
Depinning Universality Class¶
The yielding transition in EPM belongs to the depinning universality class (interfaces driven through random media):
Below threshold: Pinned (solid-like)
At threshold: Critical dynamics (avalanches)
Above threshold: Steady flow (depinned)
Shared features:
Power-law avalanche distributions
Finite-size scaling: \(\xi \sim L\) at criticality
Hysteresis in rate-controlled protocols
This connection enables use of field-theoretic methods from depinning transitions to understand yielding rheology.
References: Nicolas et al. Rev. Mod. Phys. 2018 [2], Lemaitre & Caroli PRL 2009 [8]
Model Extensions¶
Several extensions to the basic EPM framework are commonly used:
1. Activated Yielding (Thermal/Athermal Noise)
Add thermal activation to the yield criterion:
\[r_i = r_0 \exp\left( -\frac{\Delta E(\sigma_i)}{k_B T} \right)\]where \(\Delta E(\sigma_i) = E_0 (1 - |\sigma_i|/\sigma_{y,i})^p\) (often \(p = 3/2\)).
This bridges EPM toward SGR-like dynamics and allows modeling of creep at sub-yield stresses.
2. Aging (Time-Dependent Yield Thresholds)
Allow \(\sigma_{y,i}\) to evolve:
\[\dot{\sigma}_{y,i} = \frac{\sigma_{y,\infty} - \sigma_{y,i}}{t_{\mathrm{age}}} - \text{(rejuvenation from yielding)}\]This captures physical aging in glassy materials.
3. Tensorial EPM for General Flow
Store the full deviatoric stress tensor \([\sigma_{xx}, \sigma_{yy}, \sigma_{xy}]\) at each site. Enables:
Normal stress predictions (\(N_1, N_2\))
Anisotropic yield criteria (Hill, von Mises)
More accurate flow instability predictions
See Tensorial Elasto-Plastic Model (EPM) for details.
4. Shear Banding / Nonlocal Models
Retain explicit gradient direction (y-dependence in planar Couette):
Track velocity field \(v_x(y, t)\)
Add stress diffusion \(D_\sigma \nabla^2 \sigma\) to regularize bands
Couple to fluidity field for nonlocal relaxation
Essential for predicting band width and transient banding dynamics.
Advanced Usage: Multi-Protocol Joint Fitting¶
For robust parameter estimation, fit EPM to multiple protocols simultaneously:
from rheojax.models import LatticeEPM
from rheojax.pipeline import Pipeline
import numpy as np
# Load multi-protocol data
flow_data = RheoData.from_csv("flow_curve.csv", test_mode='flow_curve')
startup_data = RheoData.from_csv("startup.csv", test_mode='startup')
creep_data = RheoData.from_csv("creep.csv", test_mode='creep')
# Create model with small lattice for fitting
model = LatticeEPM(L=12, dt=0.01)
# Joint fitting with protocol weights
model.fit_multi_protocol(
[flow_data, startup_data, creep_data],
weights=[1.0, 2.0, 1.0], # Emphasize startup
max_iter=500
)
# Bayesian with multi-protocol likelihood
result = model.fit_bayesian_multi_protocol(
[flow_data, startup_data, creep_data],
weights=[1.0, 2.0, 1.0],
num_warmup=1000,
num_samples=2000,
num_chains=4,
seed=42
)
# Validate on held-out protocol (LAOS)
laos_data = RheoData.from_csv("laos.csv", test_mode='oscillation')
laos_pred = model.predict(laos_data)
Parameter Sensitivity from Bayesian Posteriors¶
Use Bayesian posteriors to understand parameter identifiability and correlations:
import arviz as az
# After fit_bayesian()
idata = result.to_arviz()
# Pair plot reveals correlations
az.plot_pair(idata, var_names=["sigma_c_mean", "sigma_c_std", "tau_pl"])
# Sensitivity: which parameters are well-constrained?
summary = az.summary(idata, hdi_prob=0.95)
for param in summary.index:
cv = summary.loc[param, "sd"] / summary.loc[param, "mean"]
print(f"{param}: CV = {cv:.2f} ({'well-constrained' if cv < 0.3 else 'uncertain'})")
# Prior-posterior comparison (diagnostic for informativeness)
az.plot_dist_comparison(idata, var_names=["sigma_c_mean"])
Disorder Estimation from Stress Overshoot¶
The stress overshoot in startup shear contains information about disorder strength:
Physical basis:
Higher disorder → larger overshoot amplitude
Overshoot position (peak strain) → \(\tau_{\text{pl}}\) × \(\dot{\gamma}\)
Overshoot variability across runs → \(\sigma_{c,\text{std}}\)
def estimate_disorder_from_overshoot(gamma_dot_range, n_repeats=10):
"""Estimate disorder from overshoot variability.
Higher variability across runs indicates stronger disorder.
"""
model = LatticeEPM(L=16, dt=0.01)
overshoot_cv = [] # Coefficient of variation
for gamma_dot in gamma_dot_range:
peaks = []
for seed in range(n_repeats):
t = np.linspace(0, 50/gamma_dot, 500)
stress = model.predict(t, test_mode='startup',
gamma_dot=gamma_dot, seed=seed)
peaks.append(np.max(stress))
cv = np.std(peaks) / np.mean(peaks)
overshoot_cv.append(cv)
# High CV indicates strong disorder
return np.array(overshoot_cv)
Full BayesianPipeline Workflow¶
Complete pipeline from data loading to uncertainty quantification:
from rheojax.pipeline.bayesian import BayesianPipeline
from rheojax.models import LatticeEPM
# Initialize pipeline
pipeline = BayesianPipeline()
# Load and fit
(pipeline
.load("experimental_data.csv",
x_col="gamma_dot",
y_col="stress",
test_mode='flow_curve')
.model(LatticeEPM, L=12, dt=0.01) # Small lattice for fitting
.fit_nlsq(max_iter=500) # Fast point estimate
.fit_bayesian( # Full Bayesian
num_warmup=1000,
num_samples=2000,
num_chains=4,
seed=42
)
)
# Diagnostics (ArviZ integration)
(pipeline
.plot_trace() # MCMC convergence
.plot_pair(divergences=True) # Parameter correlations
.plot_forest(hdi_prob=0.95) # Credible intervals
.plot_energy() # HMC diagnostics
)
# Check convergence
diagnostics = pipeline.get_diagnostics()
assert max(diagnostics["r_hat"].values()) < 1.05, "R-hat too high"
assert min(diagnostics["ess"].values()) > 400, "ESS too low"
assert diagnostics["divergences"] < 0.01, "Too many divergences"
# Save results
(pipeline
.save_results("epm_fit.hdf5") # Full posteriors
.save_summary("epm_summary.csv") # Parameter estimates
)
# Production prediction at higher resolution
model_prod = LatticeEPM(L=64, dt=0.01)
model_prod.params = pipeline.model.params.copy()
gamma_dot_fine = np.logspace(-2, 1, 100)
stress_pred = model_prod.predict(gamma_dot_fine, test_mode='flow_curve')