TNT Tanaka-Edwards (Basic Transient Network) — Handbook¶
Quick Reference¶
- Use when:
Simple associating polymers with reversible physical crosslinks
Telechelic networks (e.g., PEG-PEO telechelics)
Dilute wormlike micelles (initial approximation)
Initial model for any transient network system
Maxwell-like behavior expected (single relaxation time)
- Parameters:
3 parameters: \(G\) (network modulus, Pa), \(\tau_b\) (bond lifetime, s), \(\eta_s\) (solvent viscosity, Pa·s)
- Key equation:
- \[\frac{d\mathbf{S}}{dt} = \boldsymbol{\kappa} \cdot \mathbf{S} + \mathbf{S} \cdot \boldsymbol{\kappa}^T - \frac{\mathbf{S} - \mathbf{I}}{\tau_b}\]
- Test modes:
All 6 protocols (FLOW_CURVE, OSCILLATION, RELAXATION, STARTUP, CREEP, LAOS)
- Material examples:
Hydrophobically modified ethoxylated urethane (HEUR) solutions
PVA-borax gels
Telechelic PEG-PEO associative polymers
Reversible gelatin networks
Casein micelle dispersions (dilute)
- Key characteristics:
Newtonian steady-state flow (no shear thinning without variants)
Quadratic normal stress difference: \(N_1 \propto \dot{\gamma}^2\)
Single exponential stress relaxation
Stress overshoot in startup flow
Maxwell-type SAOS response
Notation Guide¶
Symbol |
Units |
Description |
|---|---|---|
\(\mathbf{S}\) |
dimensionless |
Conformation tensor (3×3 symmetric, normalized second moment of end-to-end vector) |
\(G\) |
Pa |
Network elastic modulus (related to chain density via \(G \approx n_{chains} k_B T\)) |
\(\tau_b\) |
s |
Bond lifetime — mean time between bond breaking and reformation events |
\(\eta_s\) |
Pa·s |
Solvent viscosity (non-network contribution to total viscosity) |
\(\eta_0\) |
Pa·s |
Zero-shear viscosity: \(\eta_0 = G \tau_b + \eta_s\) |
\(\boldsymbol{\kappa}\) |
1/s |
Velocity gradient tensor: \(\kappa_{ij} = \partial v_i / \partial x_j\) |
\(\mathbf{D}\) |
1/s |
Rate of deformation tensor: \(\mathbf{D} = (\boldsymbol{\kappa} + \boldsymbol{\kappa}^T)/2\) |
\(\dot{\gamma}\) |
1/s |
Shear rate (scalar, for simple shear flow) |
\(Wi\) |
dimensionless |
Weissenberg number: \(Wi = \tau_b \dot{\gamma}\) (ratio of relaxation to flow timescales) |
\(\mathbf{I}\) |
dimensionless |
Identity tensor (equilibrium conformation) |
\(\mathbf{R}\) |
m |
End-to-end vector of network chain between crosslinks |
\(R_0\) |
m |
Equilibrium root-mean-square end-to-end distance |
\(N_1\) |
Pa |
First normal stress difference: \(N_1 = \sigma_{xx} - \sigma_{yy}\) |
\(N_2\) |
Pa |
Second normal stress difference: \(N_2 = \sigma_{yy} - \sigma_{zz}\) |
Overview¶
The Tanaka-Edwards model is the foundational transient network theory for viscoelastic materials where polymer chains are connected by reversible physical crosslinks. Originally proposed by Green and Tobolsky (1946) in their seminal work on elastomers with interchanging bonds, and later formalized by Tanaka and Edwards (1992) using a conformation tensor approach, this model describes materials where bonds break and reform with a constant rate \(1/\tau_b\), independent of chain stretch or applied force.
At equilibrium, bonds break and reform at equal rates, maintaining a constant network structure. Under deformation, chains between crosslinks stretch and orient, generating stress proportional to the deviation of the conformation tensor \(\mathbf{S}\) from its equilibrium value (the identity tensor \(\mathbf{I}\)). When a bond breaks, the chain relaxes instantly to its equilibrium conformation; when a new bond forms, the chain joins the network with the current equilibrium state. This kinetic balance gives rise to a single relaxation mode with Maxwell-like linear viscoelastic behavior.
The model predicts:
Linear viscoelasticity: Single-mode Maxwell response in SAOS with \(G' \sim \omega^2\) and \(G'' \sim \omega\) at low frequencies
Steady-state flow: Newtonian behavior (constant viscosity \(\eta_0\))
Normal stresses: Quadratic in shear rate (\(N_1 = 2G(\tau_b \dot{\gamma})^2\))
Transient response: Stress overshoot in startup flow, single exponential relaxation
LAOS: Nonlinear harmonics from conformation tensor evolution
Despite its simplicity (only 3 parameters), the Tanaka-Edwards model provides the molecular foundation for understanding more complex transient network materials and serves as a starting point for extensions incorporating force-dependent breakage, finite extensibility, and multiple relaxation modes.
Historical Context¶
The development of transient network theory spans several decades:
Green & Tobolsky (1946): First transient network model for rubber-like materials with reversible crosslinks. They introduced the concept of a network with bonds that can break and reform, leading to stress relaxation without permanent deformation.
Yamamoto (1956): Provided a more rigorous kinetic theory based on statistical mechanics, deriving the evolution equations for network structure under deformation.
Lodge (1956): Developed the network model framework emphasizing the role of entanglements and temporary junctions in polymer melts and concentrated solutions.
Tanaka & Edwards (1992): Formulated the conformation tensor approach used in modern TNT models, providing a unified framework for transient networks with various kinetic mechanisms. Their work established the connection between molecular-scale bond dynamics and macroscopic rheological response.
Modern developments: The TNT framework has been extended to incorporate force-dependent breakage (Bell model), finite chain extensibility (FENE-P), multiple species, and Rouse dynamics for chain relaxation.
The Tanaka-Edwards model is mathematically equivalent to the upper-convected Maxwell (UCM) model, but derives from molecular network kinetics rather than continuum mechanical arguments. This molecular foundation provides physical interpretation of the parameters and enables systematic extensions to more complex network behaviors.
Physical Foundations¶
Mechanical Analogue¶
The Tanaka-Edwards model can be represented as a simple mechanical analogue:
┌─────────┐
│ Spring │──── Network contribution (modulus G)
│ (G) │
└────┬────┘
│
┌────┴────┐
│ Dashpot │──── Network relaxation (viscosity η_p = G·τ_b)
│ (η_p) │
└─────────┘
║
║ (parallel)
║
┌─────────┐
│ Dashpot │──── Solvent contribution (viscosity η_s)
│ (η_s) │
└─────────┘
This is equivalent to the Jeffreys model or Oldroyd-B model (when solvent viscosity is included). The spring represents the elastic response of stretched network chains. The series dashpot represents stress relaxation due to bond breaking (at rate \(1/\tau_b\)). The parallel dashpot represents the contribution of the solvent and any free (non-network) chains.
Physical interpretation:
Spring (G): When chains are stretched, they store elastic energy. The modulus \(G \approx n_{chains} k_B T\) where \(n_{chains}\) is the number density of elastically active chains.
Series dashpot (η_p = G·τ_b): Bonds break randomly at rate \(1/\tau_b\), releasing stored elastic energy and allowing chains to relax. The longer the bond lifetime, the higher the viscosity contribution from the network.
Parallel dashpot (η_s): Solvent and free chains provide immediate viscous resistance to flow, independent of network dynamics.
Network Kinetics¶
The transient network is characterized by the following kinetic processes:
Bond breakage and reformation:
Breakage rate: \(1/\tau_b\) (constant, independent of chain conformation)
Reformation rate: \(1/\tau_b\) (maintains equilibrium at zero stress)
Active chain fraction: \(\phi = 1\) (all chains are connected, constant)
Kinetic balance at equilibrium:
At equilibrium (zero applied stress), bonds break and reform at equal rates:
This maintains a constant network structure with isotropic conformation \(\mathbf{S} = \mathbf{I}\).
Under deformation:
When the material is deformed, the conformation tensor \(\mathbf{S}\) deviates from \(\mathbf{I}\). Chains become stretched and oriented:
Bond breaks: The chain instantly relaxes to equilibrium conformation \(\mathbf{S} = \mathbf{I}\) and contributes \(-(\mathbf{S} - \mathbf{I})/\tau_b\) to the rate of change of the average conformation.
Bond forms: The chain joins the network with the current equilibrium conformation \(\mathbf{I}\) and contributes \(+(\mathbf{S} - \mathbf{I})/\tau_b\) to restore equilibrium.
Deformation: The velocity gradient \(\boldsymbol{\kappa}\) continuously stretches and rotates the conformation tensor, contributing \(\boldsymbol{\kappa} \cdot \mathbf{S} + \mathbf{S} \cdot \boldsymbol{\kappa}^T\).
The competition between deformation (which stretches chains) and bond breaking (which relaxes chains) determines the steady-state network structure and stress.
Constant breakage assumption:
The key simplification of the Tanaka-Edwards model is that the breakage rate \(1/\tau_b\) is independent of chain stretch. This is appropriate when:
Bonds are weak enough that thermal fluctuations dominate over mechanical stress
The activation energy for bond breaking is independent of chain conformation
The applied stress is much smaller than the bond dissociation energy
For materials where stress significantly affects bond lifetime (e.g., strong shear thinning), force-dependent breakage models (Bell, catch-slip) are required.
Conformation Tensor¶
The conformation tensor \(\mathbf{S}\) is the normalized second moment of the end-to-end vector \(\mathbf{R}\) of network chains:
where \(R_0 = \sqrt{\langle R^2 \rangle_0}\) is the equilibrium root-mean-square end-to-end distance (related to the number of Kuhn segments per chain).
Physical meaning:
\(\mathbf{S} = \mathbf{I}\): Chains are unstretched and isotropically oriented (equilibrium state)
\(S_{ii} > 1\): Chains are stretched along direction \(i\)
\(S_{ii} < 1\): Chains are compressed along direction \(i\)
\(S_{ij} \neq 0\) (off-diagonal): Chains are oriented at an angle to the principal axes
In simple shear flow:
For shear in the \(xy\)-plane with velocity \(v_x = \dot{\gamma} y\):
\(S_{xx}\): Chain extension in flow direction (increases with \(Wi = \tau_b \dot{\gamma}\))
\(S_{yy}\): Chain extension in gradient direction (decreases slightly)
\(S_{zz}\): Chain extension in vorticity direction (unchanged for 2D flow, \(S_{zz} = 1\))
\(S_{xy}\): Chain orientation (proportional to shear stress)
Stress-conformation relation:
The stress tensor is proportional to the deviation of \(\mathbf{S}\) from equilibrium:
This is the Giesekus-type constitutive relation, derived from entropic elasticity of network chains. The total stress includes the solvent contribution:
where \(\mathbf{D} = (\boldsymbol{\kappa} + \boldsymbol{\kappa}^T)/2\) is the rate of deformation tensor.
Governing Equations¶
Constitutive Equation¶
The evolution of the conformation tensor is governed by the upper-convected derivative:
where:
\(\frac{d\mathbf{S}}{dt}\) is the material derivative (rate of change following the flow)
\(\boldsymbol{\kappa} \cdot \mathbf{S} + \mathbf{S} \cdot \boldsymbol{\kappa}^T\) is the upper-convected term (describes affine deformation and rotation of the conformation tensor with the flow)
\(-(\mathbf{S} - \mathbf{I})/\tau_b\) is the relaxation term (bond breaking returns chains to equilibrium at rate \(1/\tau_b\))
Affine deformation assumption:
The upper-convected derivative assumes that network chains deform affinely with the bulk flow, i.e., the end-to-end vector \(\mathbf{R}\) transforms as a material line element. This is valid when:
Chains are much smaller than any length scale of flow variation
Chains are well-connected to the surrounding network
Chain relaxation is much slower than local flow rearrangements
2D simple shear flow:
For simple shear with \(\boldsymbol{\kappa} = \dot{\gamma} \mathbf{e}_x \otimes \mathbf{e}_y\), the conformation tensor evolution reduces to:
Total stress:
The total shear stress and normal stress differences are:
For the Tanaka-Edwards model with constant breakage, \(N_2 = 0\) in simple shear (since \(S_{yy} = S_{zz}\)).
Steady-State Solutions¶
At steady state, \(d\mathbf{S}/dt = \mathbf{0}\). Solving the ODEs for simple shear:
Conformation tensor components:
Shear stress (flow curve):
where \(\eta_0 = G \tau_b + \eta_s\) is the zero-shear viscosity. The flow curve is Newtonian (constant viscosity).
First normal stress difference:
This is quadratic in shear rate, consistent with Maxwell-type viscoelasticity. The normal stress coefficient \(\Psi_1 = N_1 / \dot{\gamma}^2 = 2 G \tau_b^2\) is constant.
Second normal stress difference:
The Tanaka-Edwards model predicts zero second normal stress difference in simple shear.
Physical Insight: \(N_2 = 0\)¶
The prediction \(N_2 = 0\) in simple shear is a direct consequence of the upper-convected derivative (affine kinematics). The gradient direction (\(y\)) and vorticity direction (\(z\)) are equivalent because the affine deformation acts only through \(\boldsymbol{\kappa}\), which has no \(yy\) or \(zz\) components in simple shear. Therefore \(S_{yy}(t) = S_{zz}(t)\) for all \(t\), giving \(N_2 = G(S_{yy} - S_{zz}) = 0\).
Experimental observation of \(N_2 \neq 0\) is a clear indicator that non-affine deformation is present. See TNT Non-Affine (Gordon-Schowalter) — Handbook for the Gordon-Schowalter extension that breaks this symmetry.
Stress Relaxation Non-Exponentiality¶
For the base Tanaka-Edwards model, stress relaxation is a perfect single exponential \(G(t) = G e^{-t/\tau_b}\). However, even within the TNT framework, non-exponential relaxation arises naturally from several extensions:
Bell breakage: Initially stretched chains have shorter \(\tau_b^{\text{eff}}\), producing fast initial decay that slows as chains relax toward equilibrium. This mimics a broad spectrum without requiring multiple modes.
Multi-mode (StickyRouse, MultiSpecies): Explicit multi-exponential decay from discrete \(\{G_k, \tau_k\}\) spectrum.
Cates model: \(G(t) \sim \exp(-\sqrt{2t/\tau_b})\) in the fast-breaking regime — a stretched exponential from scission/recombination dynamics.
Weissenberg number dependence:
The dimensionless Weissenberg number \(Wi = \tau_b \dot{\gamma}\) controls the relative magnitude of elastic and viscous stresses:
\(Wi \ll 1\): Viscous-dominated, \(\sigma \approx \eta_0 \dot{\gamma}\)
\(Wi \sim 1\): Comparable elastic and viscous contributions
\(Wi \gg 1\): Elastic-dominated, \(N_1 \gg \sigma_{xy}\)
SAOS Response¶
For small-amplitude oscillatory shear (SAOS), the conformation tensor is linearized around equilibrium \(\mathbf{S} = \mathbf{I}\):
Substituting into the evolution equation and solving for the complex modulus:
where the storage and loss moduli are:
Low-frequency behavior (\(\omega \tau_b \ll 1\)):
This is characteristic of Maxwell-type viscoelasticity with a single relaxation mode.
High-frequency behavior (\(\omega \tau_b \gg 1\)):
The storage modulus approaches the network modulus \(G\), representing the elastic response of the network before bonds have time to break.
Crossover frequency:
The loss tangent \(\tan \delta = G'' / G'\) equals 1 at the crossover frequency:
This provides a direct experimental measure of the bond lifetime.
Complex viscosity:
where:
At low frequencies, \(\eta'(\omega \to 0) = \eta_0\).
Relaxation¶
For stress relaxation after a step shear strain \(\gamma_0\) applied at \(t = 0\):
Initial condition:
so \(S_{xy}(0) = \gamma_0\) and all other components are at equilibrium.
Evolution:
For \(t > 0\), with \(\boldsymbol{\kappa} = \mathbf{0}\) (no further deformation):
Solution:
Stress relaxation:
This is a single exponential decay with relaxation time \(\tau_b\). The relaxation modulus is:
Characteristic times:
Time to relax to \(1/e\) of initial stress: \(t = \tau_b\)
Time to relax to 5% of initial stress: \(t \approx 3 \tau_b\)
Time to relax to 1% of initial stress: \(t \approx 4.6 \tau_b\)
Startup Flow¶
For startup of steady shear at constant \(\dot{\gamma}\) starting from equilibrium at \(t = 0\):
Initial condition:
Evolution:
The conformation tensor evolves according to the ODEs derived above. For shear stress, the analytical solution is:
This can be rewritten as:
Limiting behavior:
Initial slope (\(t \to 0\)): \(\frac{d\sigma}{dt}\bigg|_{t=0} = G \dot{\gamma}\) (elastic response)
Steady state (\(t \to \infty\)): \(\sigma_{ss} = \eta_0 \dot{\gamma}\) (Newtonian flow)
Time to steady state: \(t \approx 5 \tau_b\) (>99% of steady state)
Stress overshoot:
For the Tanaka-Edwards model with constant breakage, there is no stress overshoot in startup shear. The stress increases monotonically from zero to the steady-state value. Stress overshoot requires either:
Force-dependent breakage (shear thinning → overshoot)
Finite extensibility (strain hardening → overshoot)
Nonlinear damping (Giesekus-type nonlinearity)
Startup Phase Decomposition¶
The startup transient can be understood in three phases:
Phase 1 — Elastic loading (\(t \ll \tau_b\)): Chains stretch affinely with the flow. \(S_{xy} \approx \dot{\gamma} t\) grows linearly. Stress rises as \(\sigma \approx G \dot{\gamma} t\) (purely elastic). No bonds have yet broken.
Phase 2 — Bond turnover onset (\(t \sim \tau_b\)): Bonds begin breaking at rate \(1/\tau_b\). For force-dependent variants (Bell), \(\text{tr}(\mathbf{S})\) rises and \(\tau_b^{\text{eff}}\) decreases, accelerating destruction beyond creation. This produces a stress overshoot in Bell/FENE variants (but not in the base Tanaka-Edwards model with constant breakage).
Phase 3 — Steady state (\(t \gg \tau_b\)): Formation-destruction balance is reached. The conformation tensor settles to its steady-state value. For the base model, this is \(S_{xy} = \tau_b \dot{\gamma}\).
Note
The base Tanaka-Edwards model reaches steady state monotonically (no overshoot). A stress overshoot requires force-dependent breakage (TNT Bell (Force-Dependent Breakage) — Handbook), finite extensibility (TNT FENE-P (Finite Extensibility) — Handbook), or non-affine slip (TNT Non-Affine (Gordon-Schowalter) — Handbook).
First normal stress difference in startup:
The analytical solution for \(N_1(t)\) involves both \(S_{xx}\) and \(S_{yy}\):
The normal stress exhibits a transient overshoot before approaching the steady-state value \(N_1^{ss} = 2 G (\tau_b \dot{\gamma})^2\). The overshoot occurs at \(t_{max} \approx 2 \tau_b\).
Creep¶
For creep under constant applied stress \(\sigma_0\), the shear rate \(\dot{\gamma}(t)\) and strain \(\gamma(t)\) must be solved from the coupled ODEs:
Governing equations:
Shear rate from stress balance:
Strain:
Analytical solution:
The creep compliance \(J(t) = \gamma(t) / \sigma_0\) is:
This consists of:
Elastic contribution: \(J_e = 1/G\) (instantaneous elastic deformation, approached at \(t \approx 5\tau_b\))
Viscous contribution: \(J_v(t) = t/\eta_0\) (linear in time, steady-state flow)
Limiting behavior:
Short time (\(t \ll \tau_b\)): \(J(t) \approx t/G \tau_b = t/\eta_p\) (network relaxation)
Long time (\(t \gg \tau_b\)): \(J(t) \approx 1/G + t/\eta_0\) (steady flow with elastic offset)
Creep recovery:
If stress is removed at \(t = t_1\), the recoverable strain is:
The non-recoverable (viscous) strain is:
Creep Rupture (Force-Dependent Extension)¶
While the base Tanaka-Edwards model with constant breakage always reaches a finite steady-state creep rate \(\dot{\gamma}_{ss} = \sigma_0/\eta_0\), the introduction of force-dependent breakage (Bell variant) creates the possibility of creep rupture:
Applied stress \(\sigma_0\) stretches chains → \(\text{tr}(\mathbf{S})\) increases
Stretch increases \(k_{\text{off}}\) (Bell) → effective \(\tau_b\) decreases
Reduced \(\tau_b\) means lower effective viscosity → \(\dot{\gamma}\) increases
Higher \(\dot{\gamma}\) stretches chains further → positive feedback loop
Above a critical stress \(\sigma_c\), the system undergoes delayed yielding (creep rate accelerates without bound)
This viscosity bifurcation is analogous to the yielding transition in thixotropic fluids. See TNT Bell (Force-Dependent Breakage) — Handbook for the full treatment.
LAOS¶
For large-amplitude oscillatory shear (LAOS) with strain \(\gamma(t) = \gamma_0 \sin(\omega t)\):
Strain rate:
Governing ODEs:
The conformation tensor components evolve according to:
Stress response:
Fourier decomposition:
The stress can be decomposed into odd harmonics:
where \(G'_1\) and \(G''_1\) are the linear viscoelastic moduli (at small \(\gamma_0\)), and higher harmonics \(G'_3, G''_3, G'_5, \ldots\) characterize nonlinearity.
Lissajous curves:
Plots of \(\sigma\) vs. \(\gamma\) (elastic Lissajous) and \(\sigma\) vs. \(\dot{\gamma}\) (viscous Lissajous) reveal:
Linear regime (\(\gamma_0 \ll 1\)): Elliptical curves
Nonlinear regime (\(\gamma_0 \sim 1\)): Distorted ellipses with higher harmonics
Numerical solution:
LAOS requires numerical integration of the ODEs over multiple cycles until a periodic steady state is reached. The RheoJAX implementation uses Diffrax with adaptive time stepping.
LAOS: Linear Stress Response at All Amplitudes¶
A remarkable property of the base Tanaka-Edwards model (constant breakage, Hookean chains) is that the stress response in LAOS is perfectly sinusoidal regardless of strain amplitude \(\gamma_0\). This means:
\(I_3/I_1 = 0\) (no third harmonic) at all \(\gamma_0\)
The elastic Lissajous curve is always a perfect ellipse
The Fourier spectrum contains only the fundamental frequency
This occurs because the constitutive equation is linear in \(\mathbf{S}\) (the upper-convected Maxwell model). The time-varying shear rate \(\dot{\gamma}(t) = \gamma_0 \omega \cos(\omega t)\) enters linearly through the velocity gradient \(\boldsymbol{\kappa}\), and the relaxation term is also linear.
Consequence for model identification: If LAOS data show any higher harmonics (\(I_3/I_1 > 0\)), the base Tanaka-Edwards model is immediately ruled out. One must invoke nonlinear extensions:
Bell breakage → odd harmonics from \(\exp[\nu(\text{tr}\mathbf{S} - 3)]\)
FENE stress → harmonics from \(L^2/(L^2 - \text{tr}\mathbf{S})\) nonlinearity
Non-affine slip → harmonics from Gordon-Schowalter coupling
Parameters¶
Parameter |
Symbol |
Default |
Bounds |
Units |
Description |
|---|---|---|---|---|---|
G |
\(G\) |
1000 |
(1, 108) |
Pa |
Network elastic modulus (related to chain density via \(G \approx n_{chains} k_B T\)) |
tau_b |
\(\tau_b\) |
1.0 |
(10-6, 104) |
s |
Mean bond lifetime (characteristic relaxation time of the network) |
\(\eta_s\) |
\(\eta_s\) |
0.0 |
(0, 104) |
Pa·s |
Solvent viscosity (non-network contribution, can be zero for entangled systems) |
Parameter Interpretation¶
Network modulus (G):
The network modulus is related to the number density of elastically active chains:
where:
\(n_{chains}\) is the number of chains per unit volume (m-3)
\(k_B = 1.38 \times 10^{-23}\) J/K is Boltzmann’s constant
\(T\) is absolute temperature (K)
For a polymer solution with concentration \(c\) (g/mL) and molecular weight \(M_w\) (g/mol):
where \(N_A = 6.02 \times 10^{23}\) mol-1 is Avogadro’s number.
Typical values:
Dilute polymer solutions: \(G \sim 1-100\) Pa
Semi-dilute solutions: \(G \sim 100-10^4\) Pa
Entangled melts and gels: \(G \sim 10^4-10^6\) Pa
Bond lifetime (τ_b):
The bond lifetime \(\tau_b\) is the mean time between bond breaking and reformation events. It is related to the activation energy \(E_a\) for bond dissociation via Arrhenius kinetics:
where \(\tau_0\) is a pre-exponential attempt time (typically 10-9 to 10-12 s).
Experimental determination:
SAOS: Crossover frequency \(\omega_c = 1/\tau_b\)
Stress relaxation: Time to decay to \(1/e\) of initial stress
DLS: Characteristic time for structural relaxation
Fluorescence recovery: Bond exchange timescale
Typical values:
Weak physical gels: \(\tau_b \sim 10^{-3}-1\) s
Associating polymers: \(\tau_b \sim 0.1-100\) s
Strong supramolecular networks: \(\tau_b \sim 10-10^4\) s
Solvent viscosity (η_s):
The solvent viscosity \(\eta_s\) accounts for viscous dissipation not associated with network relaxation. It includes:
Viscosity of the solvent (e.g., water ~ 0.001 Pa·s at 20°C)
Contribution from free (non-network) chains
Hydrodynamic interactions
For entangled polymer melts without added solvent, \(\eta_s \approx 0\) is a reasonable approximation.
Zero-shear viscosity:
The zero-shear viscosity is the sum of network and solvent contributions:
This can be measured directly from steady-state flow curves (Newtonian plateau at low \(\dot{\gamma}\)).
Parameter correlations:
\(G\) and \(\tau_b\) are strongly correlated when fitting SAOS or relaxation data (both affect the magnitude and timescale of the response)
\(\eta_s\) is most easily determined from high-frequency (or high shear rate) behavior where network relaxation is fast
Bayesian priors:
For Bayesian inference, recommended priors are:
These can be refined based on prior knowledge of the material system.
Validity and Assumptions¶
The Tanaka-Edwards model is valid under the following assumptions:
1. Constant breakage rate:
Bond lifetime \(\tau_b\) is independent of chain stretch or applied force
Appropriate when thermal fluctuations dominate over mechanical stress
Fails for materials with strong force-dependent bond kinetics (use Bell or catch-slip variants instead)
2. Affine deformation:
Network chains deform affinely with the bulk flow (no slip)
Valid when chains are well-connected and much smaller than flow length scales
Fails for poorly connected networks or spatially heterogeneous deformation
3. Instant reformation at equilibrium:
When a bond breaks, the chain instantly relaxes to \(\mathbf{S} = \mathbf{I}\)
When a bond forms, the chain joins with equilibrium conformation
Neglects finite Rouse relaxation time (use TNTStickyRouse for chain dynamics)
4. Linear springs (Hookean elasticity):
No finite extensibility limit for network chains
Stress is proportional to \(\mathbf{S} - \mathbf{I}\) at all strain levels
Fails at high strains where chains approach full extension (use FENE-P variant)
5. Monodisperse network:
Single bond lifetime \(\tau_b\) (single relaxation mode)
All chains have the same \(G\) and \(R_0\)
For polydisperse systems with multiple relaxation times, use TNTMultiSpecies or sum of Maxwell modes
6. No entanglements beyond crosslinks:
Chain relaxation occurs only via bond breaking, not reptation or constraint release
Appropriate for dilute to semi-dilute solutions
For entangled melts, additional relaxation mechanisms may be important
7. Homogeneous deformation:
Assumes no shear banding or spatial gradients in structure
Fails when flow induces heterogeneous microstructure (use 1D nonlocal model if needed)
8. Incompressibility:
Volume is conserved (\(\text{tr}(\boldsymbol{\kappa}) = 0\))
Appropriate for polymer solutions and melts
May fail for compressible systems (e.g., foams)
Regimes and Behavior¶
The Tanaka-Edwards model exhibits distinct rheological regimes depending on the dimensionless Weissenberg number \(Wi = \tau_b \dot{\gamma}\) (for flow) or dimensionless frequency \(\omega \tau_b\) (for oscillatory shear).
Linear viscoelastic regime (\(Wi \ll 1\) or \(\omega \tau_b \ll 1\)):
SAOS: \(G' \sim \omega^2\), \(G'' \sim \omega\) (terminal regime)
Flow: Newtonian behavior, \(\sigma = \eta_0 \dot{\gamma}\)
Normal stress: Negligible, \(N_1 \ll \sigma\)
Physical picture: Bonds break and reform faster than chains can be significantly stretched
Crossover regime (\(Wi \sim 1\) or \(\omega \tau_b \sim 1\)):
SAOS: \(G' \approx G'' \approx G/2\), \(\tan \delta = 1\)
Flow: Comparable elastic and viscous stresses
Normal stress: \(N_1 \sim \sigma^2 / G\)
Physical picture: Deformation and relaxation timescales are matched
Elastic-dominated regime (\(Wi \gg 1\) or \(\omega \tau_b \gg 1\)):
SAOS: \(G' \to G\) (rubber-like plateau), \(G'' \ll G'\)
Flow: Normal stress dominates, \(N_1 \gg \sigma\)
Physical picture: Chains are highly stretched before bonds break, elastic energy storage dominates
Key behavioral features:
Newtonian flow curve: The Tanaka-Edwards model always predicts constant viscosity \(\eta_0\) at steady state. This is a key limitation for materials that exhibit shear thinning. For shear-thinning behavior, use force-dependent breakage variants (Bell, catch-slip).
Quadratic normal stress: \(N_1 \propto \dot{\gamma}^2\) is a universal prediction of single-mode Maxwell models. Experimental data showing different scaling (e.g., \(N_1 \propto \dot{\gamma}^{1.5}\) for some wormlike micelles) indicates more complex network dynamics.
Single relaxation time: All transient responses (relaxation, startup, creep) are characterized by the single timescale \(\tau_b\). Materials with multiple relaxation times require multi-mode extensions.
No stress overshoot in startup shear: Unlike shear-thinning models, the Tanaka-Edwards model predicts monotonic stress increase. Experimental overshoot indicates force-dependent kinetics or finite extensibility effects.
Zero second normal stress difference: \(N_2 = 0\) in simple shear. Experimental observation of \(N_2 < 0\) indicates non-affine deformation or additional microstructural effects.
What You Can Learn¶
Fitting the Tanaka-Edwards model to experimental data provides the following physical insights:
From SAOS (:math:`G’`, :math:`G’’` vs. ω):
Network modulus (G): High-frequency plateau of \(G'\) gives \(G\) directly. This is related to chain density via \(G \approx n_{chains} k_B T\), allowing estimation of the number of elastically active chains per unit volume.
Bond lifetime (τ_b): Crossover frequency \(\omega_c\) where \(G' = G''\) gives \(\tau_b = 1/\omega_c\). This is the characteristic timescale for bond breaking and network relaxation.
Zero-shear viscosity (η_0): Low-frequency limit \(\eta_0 = G'' / \omega\) as \(\omega \to 0\) gives \(\eta_0 = G \tau_b + \eta_s\).
Solvent viscosity (η_s): High-frequency viscous contribution \(\eta_s \omega\) determines the non-network viscosity.
From stress relaxation (σ vs. t):
Bond lifetime (τ_b): Time to decay to \(1/e\) of initial stress is \(\tau_b\). This is the most direct measure of bond dynamics.
Network modulus (G): Initial stress \(\sigma(0) = G \gamma_0\) after step strain \(\gamma_0\).
From steady-state flow (σ vs. γ̇):
Zero-shear viscosity (η_0): Slope of the Newtonian flow curve.
Model validity check: If the flow curve shows shear thinning (decreasing viscosity with \(\dot{\gamma}\)), the Tanaka-Edwards model is not appropriate. Switch to force-dependent breakage models (Bell, catch-slip).
From normal stress (N₁ vs. γ̇):
Bond lifetime (τ_b): From \(N_1 = 2 G (\tau_b \dot{\gamma})^2\), the ratio \(N_1 / \sigma^2 = 2 \tau_b / \eta_0\) gives a second estimate of \(\tau_b\) that is independent of SAOS.
Consistency check: If \(N_1 / \dot{\gamma}^2\) is not constant, the model assumptions are violated (force-dependent kinetics or finite extensibility).
From creep (γ vs. t):
Compliance (J): Long-time slope \(1/\eta_0\) and elastic offset \(1/G\).
Recoverable strain: Fraction of strain that recovers after stress removal is \(\gamma_{rec} / \gamma_{total} = (1 - e^{-t_1/\tau_b}) / [1 + G t_1 / (\eta_0 \tau_b)]\).
From LAOS (harmonics vs. γ_0):
Onset of nonlinearity: Strain amplitude \(\gamma_0\) at which higher harmonics become significant. For the Tanaka-Edwards model, nonlinearity appears at \(\gamma_0 \sim 1\) (order-unity strain).
Nonlinear parameter space: Odd harmonics \(G'_3, G''_3, \ldots\) characterize the shape of the stress-strain response.
Temperature dependence:
If data are available at multiple temperatures, Arrhenius analysis of \(\tau_b(T)\) gives the activation energy \(E_a\) for bond dissociation:
This provides insight into the molecular mechanism of bond breaking (hydrogen bonding, hydrophobic interactions, electrostatic interactions, etc.).
Experimental Design¶
Recommended protocols for parameter extraction:
SAOS (essential):
Frequency range: At least 2 decades around \(\omega_c = 1/\tau_b\)
Recommended: \(10^{-2}\) to \(10^2\) rad/s for typical \(\tau_b \sim 1\) s
Strain amplitude: \(\gamma_0 < 0.1\) (linear regime)
Output: \(G\), \(\tau_b\), \(\eta_s\)
Stress relaxation (highly informative):
Step strain: \(\gamma_0 \sim 0.1-0.5\) (linear regime)
Time range: At least \(5 \tau_b\) to reach baseline
Output: \(\tau_b\) (most direct), \(G\)
Steady-state flow (model validation):
Shear rate range: \(10^{-3}\) to \(10^2\) s-1 (to cover \(Wi < 1\) and \(Wi > 1\))
Check: Flow curve should be Newtonian (constant \(\eta_0\))
If shear thinning is observed: model is inappropriate, use Bell variant
Normal stress (optional, for consistency check):
Same shear rate range as flow curve
Check: \(N_1 / \dot{\gamma}^2 = 2 G \tau_b^2\) should be constant
Provides independent estimate of \(\tau_b\)
Startup flow (optional):
Useful for validating transient behavior
Apply constant \(\dot{\gamma}\) from equilibrium
For Tanaka-Edwards: no stress overshoot expected (monotonic rise)
Creep (alternative to relaxation):
Apply constant \(\sigma_0 < G\) (linear regime)
Time range: At least \(5 \tau_b\) to observe steady flow
Output: \(G\), \(\eta_0\), \(\tau_b\)
LAOS (for advanced characterization):
Strain amplitude sweep: \(\gamma_0 = 0.01\) to \(10\)
Fixed frequency: \(\omega \sim 1/\tau_b\) (crossover)
Output: Nonlinear parameters, Lissajous curves
Experimental considerations:
Sample equilibration: Allow sufficient rest time (\(\sim 10 \tau_b\)) between measurements to restore equilibrium structure
Temperature control: Maintain constant temperature (±0.1°C) as \(\tau_b\) is strongly temperature-dependent
Wall slip: Check for slip (especially at low \(\dot{\gamma}\)) using parallel plate gap variation or roughened surfaces
Edge fracture: At high \(Wi\), normal stresses can cause edge instabilities in parallel plate geometry
Instrument compliance: Subtract instrument inertia and compliance (especially important for low-modulus materials \(G < 100\) Pa)
Minimal experimental set for fitting:
For quick parameter estimation with limited instrument time:
SAOS frequency sweep (\(\gamma_0 = 0.05\), \(10^{-2}\) to \(10^2\) rad/s)
Stress relaxation (step \(\gamma_0 = 0.2\), measure for \(5\tau_b\))
These two experiments are sufficient to extract all three parameters and validate the model assumptions.
Computational Implementation¶
RheoJAX TNTSingleMode implementation:
The Tanaka-Edwards model is implemented as TNTSingleMode with breakage="constant":
from rheojax.models import TNTSingleMode
# Create model with constant breakage (Tanaka-Edwards)
model = TNTSingleMode(breakage="constant")
# Default parameters: G=1000 Pa, tau_b=1.0 s, eta_s=0.0 Pa·s
# Bounds: G in [1, 1e8], tau_b in [1e-6, 1e4], eta_s in [0, 1e4]
Test modes and predictions:
OSCILLATION: Analytical solution for \(G'(\omega)\) and \(G''(\omega)\)
RELAXATION: Analytical solution \(\sigma(t) = G \gamma_0 e^{-t/\tau_b}\)
STARTUP: Analytical solution \(\sigma(t) = \eta_0 \dot{\gamma} [1 - (G \tau_b / \eta_0) e^{-t/\tau_b}]\)
FLOW_CURVE: Analytical solution \(\sigma = \eta_0 \dot{\gamma}\)
CREEP: ODE integration for \(\gamma(t)\)
LAOS: ODE integration for \(\mathbf{S}(t)\) over multiple cycles
ODE solver details:
For protocols requiring numerical integration (CREEP, LAOS):
Solver: Diffrax
Tsit5(adaptive 5th-order Runge-Kutta)Tolerances:
rtol=1e-6,atol=1e-8(configurable)Time stepping: Adaptive with safety factor 0.9
JIT compilation: All functions are JIT-compiled for GPU acceleration
Conformation tensor representation:
The 3×3 symmetric conformation tensor \(\mathbf{S}\) is stored as a 6-component
vector: [S_xx, S_yy, S_zz, S_xy, S_xz, S_yz]. For 2D simple shear, only the first
4 components are active.
Numerical stability:
At very high \(Wi\) (\(> 10^3\)), the conformation tensor can become stiff. The adaptive solver automatically reduces time step size to maintain accuracy.
For LAOS at high \(\gamma_0\) (\(> 10\)), the model may predict unphysically large chain extension (since there is no finite extensibility limit). Use the FENE-P variant if strain stiffening is observed experimentally.
Performance:
SAOS, RELAXATION, STARTUP, FLOW_CURVE: Analytical solutions, no ODE integration required. Prediction time: ~0.1-1 ms for 100 points (GPU).
CREEP, LAOS: ODE integration required. Prediction time: ~10-100 ms for 1000 time points (GPU, depends on stiffness and number of cycles).
Fitting workflow:
The recommended workflow uses NLSQ for fast point estimation followed by Bayesian inference for uncertainty quantification:
# Step 1: NLSQ fit (fast, deterministic)
model.fit(omega, G_star, test_mode='oscillation')
print(f"NLSQ: G={model.G}, tau_b={model.tau_b}, eta_s={model.eta_s}")
# Step 2: Bayesian fit with NLSQ warm-start
result = model.fit_bayesian(omega, G_star, test_mode='oscillation',
num_warmup=1000, num_samples=2000, num_chains=4)
# Step 3: Extract credible intervals
intervals = model.get_credible_intervals(result.posterior_samples, credibility=0.95)
print(f"95% CI for G: {intervals['G']}")
Custom parameter bounds:
For materials with known parameter ranges, custom bounds improve fitting:
from rheojax.core import Parameter
model = TNTSingleMode(breakage="constant")
model.parameters['G'].bounds = (100, 10000) # Pa, for dilute solutions
model.parameters['tau_b'].bounds = (0.01, 100) # s, for fast networks
model.fit(omega, G_star, test_mode='oscillation')
Fitting Guidance¶
SAOS fitting:
For small-amplitude oscillatory shear data:
import numpy as np
from rheojax.models import TNTSingleMode
# Prepare data: frequency, complex modulus
omega = np.logspace(-2, 2, 50) # 50 points, 10^-2 to 10^2 rad/s
G_star = G_prime + 1j * G_double_prime # Complex modulus
# Option 1: Fit to complex modulus (recommended)
model = TNTSingleMode(breakage="constant")
model.fit(omega, G_star, test_mode='oscillation')
# Option 2: Fit to G' and G'' separately (if complex data not available)
# Stack G' and G'' as [G'_1, ..., G'_N, G''_1, ..., G''_N]
y_data = np.concatenate([G_prime, G_double_prime])
model.fit(omega, y_data, test_mode='oscillation')
Tips for SAOS fitting:
Ensure frequency range covers at least 1 decade below and above \(\omega_c = 1/\tau_b\)
If \(\tau_b\) is unknown, use \(\omega = 10^{-3}\) to \(10^3\) rad/s
Weight low-frequency points more heavily if zero-shear viscosity is important
Check for instrument compliance (spurious upturn in \(G''\) at high \(\omega\))
Stress relaxation fitting:
For step strain relaxation:
# Prepare data: time, shear stress
t = np.linspace(0, 10, 200) # 10 s, 200 points
sigma = ... # Measured stress after step strain gamma_0
# Fit (note: gamma_0 must be provided as a keyword argument)
model = TNTSingleMode(breakage="constant")
model.fit(t, sigma, test_mode='relaxation', gamma_0=0.2)
# Extract parameters
print(f"tau_b = {model.tau_b:.3f} s")
print(f"G = {model.G:.0f} Pa")
Tips for relaxation fitting:
Measure for at least \(5\tau_b\) to reach baseline (stress decays to <1% of initial)
If \(\tau_b\) is unknown, measure for at least 100 s
Subtract residual stress (instrument drift, sample thixotropy) if non-zero at long times
The fit is relatively insensitive to \(\eta_s\) (relaxation is dominated by network)
Flow curve fitting:
For steady-state shear stress vs. shear rate:
# Prepare data: shear rate, shear stress
gamma_dot = np.logspace(-3, 2, 50) # 10^-3 to 10^2 s^-1
sigma = ... # Measured steady-state stress
# Fit
model = TNTSingleMode(breakage="constant")
model.fit(gamma_dot, sigma, test_mode='flow_curve')
# Expected: constant viscosity (Newtonian)
eta_0 = model.G * model.tau_b + model.eta_s
print(f"Zero-shear viscosity: {eta_0:.2f} Pa·s")
Important: If the flow curve shows shear thinning (decreasing \(\sigma / \dot{\gamma}\) with increasing \(\dot{\gamma}\)), the Tanaka-Edwards model is not appropriate. Switch to force-dependent breakage:
# For shear-thinning materials
model = TNTSingleMode(breakage="bell") # Bell force-dependent breakage
model.fit(gamma_dot, sigma, test_mode='flow_curve')
Startup flow fitting:
For transient shear stress during startup:
# Prepare data: time, shear stress during startup at constant gamma_dot
t = np.linspace(0, 10, 200)
sigma = ... # Measured stress during startup
# Fit (gamma_dot must be provided)
model = TNTSingleMode(breakage="constant")
model.fit(t, sigma, test_mode='startup', gamma_dot=1.0)
Creep fitting:
For strain vs. time under constant stress:
# Prepare data: time, shear strain
t = np.linspace(0, 100, 500)
gamma = ... # Measured strain under constant sigma_0
# Fit (sigma_applied must be provided)
model = TNTSingleMode(breakage="constant")
model.fit(t, gamma, test_mode='creep', sigma_applied=100.0)
LAOS fitting:
For large-amplitude oscillatory shear:
# Prepare data: time, shear stress (multiple cycles)
t = np.linspace(0, 10*T, 1000) # 10 cycles, T = 2*pi/omega
sigma = ... # Measured stress
# Fit (gamma_0 and omega must be provided)
model = TNTSingleMode(breakage="constant")
model.fit(t, sigma, test_mode='laos', gamma_0=0.5, omega=1.0)
Bayesian inference with NLSQ warm-start:
For parameter uncertainty quantification:
# Step 1: NLSQ for initial guess
model = TNTSingleMode(breakage="constant")
model.fit(omega, G_star, test_mode='oscillation')
# Step 2: Bayesian with warm-start (4 chains for robust diagnostics)
result = model.fit_bayesian(omega, G_star, test_mode='oscillation',
num_warmup=1000, # Burn-in
num_samples=2000, # Samples per chain
num_chains=4, # Parallel chains (default)
seed=42) # Reproducibility
# Step 3: Check diagnostics
print(f"R-hat: {result.diagnostics['r_hat']}") # Should be < 1.01
print(f"ESS: {result.diagnostics['ess']}") # Should be > 400
# Step 4: Extract credible intervals
intervals = model.get_credible_intervals(result.posterior_samples, credibility=0.95)
print(f"G: {intervals['G'][0]:.0f} - {intervals['G'][1]:.0f} Pa (95% CI)")
print(f"tau_b: {intervals['tau_b'][0]:.3f} - {intervals['tau_b'][1]:.3f} s (95% CI)")
Parameter initialization:
For models that are difficult to fit (e.g., multiple relaxation modes, high noise), smart initialization improves convergence:
from rheojax.utils.initialization import initialize_from_saos
# Extract initial guess from SAOS data
initial_params = initialize_from_saos(omega, G_star, model_type='maxwell')
# Set initial values
model = TNTSingleMode(breakage="constant")
model.G = initial_params['G']
model.tau_b = initial_params['tau_b']
# Fit with improved initial guess
model.fit(omega, G_star, test_mode='oscillation')
Common fitting issues:
Poor fit quality (low R²):
Check data quality (noise, instrument artifacts)
Verify model assumptions (Newtonian flow curve, single relaxation time)
Try multi-mode model if data show multiple relaxation times
Parameter bounds hit:
If \(G\) hits upper bound (10⁸ Pa): check for instrument compliance or dimensionless data
If \(\tau_b\) hits lower bound (10⁻⁶ s): relaxation is too fast for instrument or model is inappropriate
If \(\eta_s\) hits upper bound: network relaxation may be too slow, or solvent dominates
Bayesian convergence issues (R-hat > 1.1, low ESS):
Increase
num_warmup(try 2000-5000 for difficult posteriors)Check for multimodal posteriors (plot pair plots)
Tighten parameter bounds if physically justified
Ensure NLSQ warm-start is used (critical for convergence)
Numerical instability in ODE integration (CREEP, LAOS):
Reduce
rtolandatol(try 1e-8 and 1e-10)Check for unphysical parameter values (negative \(\eta_s\), too large \(Wi\))
Use implicit solver for stiff systems (not yet implemented in RheoJAX)
Usage¶
Basic SAOS prediction and fitting:
from rheojax.models import TNTSingleMode
import numpy as np
import matplotlib.pyplot as plt
# Create model with default parameters
model = TNTSingleMode(breakage="constant")
print(f"Default: G={model.G} Pa, tau_b={model.tau_b} s, eta_s={model.eta_s} Pa·s")
# Generate SAOS prediction
omega = np.logspace(-2, 2, 100) # 0.01 to 100 rad/s
G_star = model.predict(omega, test_mode='oscillation')
# Extract G' and G''
G_prime = G_star.real
G_double_prime = G_star.imag
# Plot
plt.figure(figsize=(8, 6))
plt.loglog(omega, G_prime, 'o-', label="G' (storage)")
plt.loglog(omega, G_double_prime, 's-', label="G'' (loss)")
plt.xlabel('Angular frequency (rad/s)')
plt.ylabel('Modulus (Pa)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.title('Tanaka-Edwards SAOS Response')
plt.show()
# Fit to synthetic data (with noise)
np.random.seed(42)
noise = 1 + 0.05 * np.random.randn(len(omega)) # 5% noise
G_star_data = G_star * noise
model_fit = TNTSingleMode(breakage="constant")
model_fit.fit(omega, G_star_data, test_mode='oscillation')
print(f"Fitted: G={model_fit.G:.0f} Pa, tau_b={model_fit.tau_b:.3f} s, eta_s={model_fit.eta_s:.3f} Pa·s")
Stress relaxation:
# Predict stress relaxation after step strain
t = np.linspace(0, 10, 200) # 0 to 10 s
gamma_0 = 0.2 # Step strain (20%)
sigma = model.predict(t, test_mode='relaxation', gamma_0=gamma_0)
# Plot
plt.figure(figsize=(8, 6))
plt.semilogy(t, sigma, 'o-')
plt.axhline(sigma[0] / np.e, color='red', linestyle='--',
label=f'τ_b = {model.tau_b:.2f} s')
plt.xlabel('Time (s)')
plt.ylabel('Stress (Pa)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.title('Stress Relaxation (Tanaka-Edwards)')
plt.show()
Startup flow:
# Predict stress during startup at constant shear rate
t = np.linspace(0, 5, 200) # 0 to 5 s
gamma_dot = 1.0 # 1 s^-1
sigma = model.predict(t, test_mode='startup', gamma_dot=gamma_dot)
# Analytical steady-state
eta_0 = model.G * model.tau_b + model.eta_s
sigma_ss = eta_0 * gamma_dot
# Plot
plt.figure(figsize=(8, 6))
plt.plot(t, sigma, 'o-', label='Transient')
plt.axhline(sigma_ss, color='red', linestyle='--', label=f'Steady state ({sigma_ss:.1f} Pa)')
plt.xlabel('Time (s)')
plt.ylabel('Stress (Pa)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.title(f'Startup Flow (γ̇ = {gamma_dot} s⁻¹)')
plt.show()
Flow curve:
# Predict steady-state flow curve
gamma_dot = np.logspace(-3, 2, 50) # 0.001 to 100 s^-1
sigma = model.predict(gamma_dot, test_mode='flow_curve')
# Calculate viscosity
eta = sigma / gamma_dot
# Plot
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
ax1.loglog(gamma_dot, sigma, 'o-')
ax1.set_xlabel('Shear rate (s⁻¹)')
ax1.set_ylabel('Shear stress (Pa)')
ax1.grid(True, alpha=0.3)
ax1.set_title('Flow Curve (Tanaka-Edwards)')
ax2.semilogx(gamma_dot, eta, 'o-')
ax2.axhline(eta_0, color='red', linestyle='--', label=f'η₀ = {eta_0:.1f} Pa·s')
ax2.set_xlabel('Shear rate (s⁻¹)')
ax2.set_ylabel('Viscosity (Pa·s)')
ax2.legend()
ax2.grid(True, alpha=0.3)
ax2.set_title('Viscosity (Newtonian)')
plt.tight_layout()
plt.show()
Normal stress difference:
# Predict first normal stress difference (requires custom calculation)
# For Tanaka-Edwards: N_1 = 2 * G * (tau_b * gamma_dot)^2
gamma_dot = np.logspace(-2, 2, 50)
N_1 = 2 * model.G * (model.tau_b * gamma_dot)**2
# Normal stress coefficient
Psi_1 = N_1 / gamma_dot**2
# Plot
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
ax1.loglog(gamma_dot, N_1, 'o-')
ax1.set_xlabel('Shear rate (s⁻¹)')
ax1.set_ylabel('N₁ (Pa)')
ax1.grid(True, alpha=0.3)
ax1.set_title('First Normal Stress Difference')
ax2.semilogx(gamma_dot, Psi_1, 'o-')
ax2.set_xlabel('Shear rate (s⁻¹)')
ax2.set_ylabel('Ψ₁ (Pa·s²)')
ax2.grid(True, alpha=0.3)
ax2.set_title('Normal Stress Coefficient (Constant)')
plt.tight_layout()
plt.show()
Creep simulation:
# Predict creep under constant stress
t = np.linspace(0, 50, 500) # 0 to 50 s
sigma_0 = 100.0 # Applied stress (Pa)
gamma = model.predict(t, test_mode='creep', sigma_applied=sigma_0)
# Analytical creep compliance
J_t = (1/model.G) * (1 - np.exp(-t/model.tau_b)) + t / eta_0
gamma_analytical = sigma_0 * J_t
# Plot
plt.figure(figsize=(8, 6))
plt.plot(t, gamma, 'o-', label='Numerical', markersize=3)
plt.plot(t, gamma_analytical, 'r--', label='Analytical')
plt.xlabel('Time (s)')
plt.ylabel('Strain')
plt.legend()
plt.grid(True, alpha=0.3)
plt.title(f'Creep (σ₀ = {sigma_0} Pa)')
plt.show()
LAOS simulation:
# Predict LAOS response
omega = 1.0 # rad/s
gamma_0 = 0.5 # Strain amplitude
n_cycles = 10
T = 2 * np.pi / omega
t = np.linspace(0, n_cycles * T, 1000)
# Note: For LAOS, predict() returns stress vs. time
# Strain must be computed separately
gamma_t = gamma_0 * np.sin(omega * t)
sigma = model.predict(t, test_mode='laos', gamma_0=gamma_0, omega=omega)
# Plot last 2 cycles (steady periodic state)
t_plot = t[t > (n_cycles - 2) * T]
gamma_plot = gamma_t[t > (n_cycles - 2) * T]
sigma_plot = sigma[t > (n_cycles - 2) * T]
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
# Time series
ax1.plot(t_plot, sigma_plot, 'o-', markersize=3, label='Stress')
ax1.set_xlabel('Time (s)')
ax1.set_ylabel('Stress (Pa)')
ax1.legend()
ax1.grid(True, alpha=0.3)
ax1.set_title('LAOS Time Series')
# Lissajous (elastic)
ax2.plot(gamma_plot, sigma_plot, 'o-', markersize=3)
ax2.set_xlabel('Strain')
ax2.set_ylabel('Stress (Pa)')
ax2.grid(True, alpha=0.3)
ax2.set_title('Elastic Lissajous Curve')
plt.tight_layout()
plt.show()
Bayesian inference workflow:
from rheojax.pipeline.bayesian import BayesianPipeline
# Create synthetic SAOS data
omega_true = np.logspace(-2, 2, 30)
G_true, tau_b_true, eta_s_true = 1000, 1.0, 0.1
model_true = TNTSingleMode(breakage="constant")
model_true.G = G_true
model_true.tau_b = tau_b_true
model_true.eta_s = eta_s_true
G_star_true = model_true.predict(omega_true, test_mode='oscillation')
# Add noise
np.random.seed(42)
noise_factor = 1 + 0.1 * np.random.randn(len(omega_true))
G_star_data = G_star_true * noise_factor
# Step 1: NLSQ fit for initial guess
model_nlsq = TNTSingleMode(breakage="constant")
model_nlsq.fit(omega_true, G_star_data, test_mode='oscillation')
print(f"NLSQ: G={model_nlsq.G:.0f}, tau_b={model_nlsq.tau_b:.3f}, eta_s={model_nlsq.eta_s:.3f}")
# Step 2: Bayesian inference with NLSQ warm-start
result = model_nlsq.fit_bayesian(omega_true, G_star_data, test_mode='oscillation',
num_warmup=1000, num_samples=2000, num_chains=4, seed=42)
# Step 3: Check diagnostics
print(f"R-hat (G): {result.diagnostics['r_hat']['G']:.4f}") # Should be < 1.01
print(f"ESS (G): {result.diagnostics['ess']['G']:.0f}") # Should be > 400
# Step 4: Credible intervals
intervals = model_nlsq.get_credible_intervals(result.posterior_samples, credibility=0.95)
print(f"G: [{intervals['G'][0]:.0f}, {intervals['G'][1]:.0f}] Pa (true: {G_true})")
print(f"tau_b: [{intervals['tau_b'][0]:.3f}, {intervals['tau_b'][1]:.3f}] s (true: {tau_b_true})")
print(f"eta_s: [{intervals['eta_s'][0]:.3f}, {intervals['eta_s'][1]:.3f}] Pa·s (true: {eta_s_true})")
# Step 5: Posterior predictive check
# (Sample from posterior and compare predictions to data)
posterior_samples = result.posterior_samples
n_samples = min(100, len(posterior_samples['G']))
plt.figure(figsize=(10, 6))
for i in range(n_samples):
model_sample = TNTSingleMode(breakage="constant")
model_sample.G = posterior_samples['G'][i]
model_sample.tau_b = posterior_samples['tau_b'][i]
model_sample.eta_s = posterior_samples['eta_s'][i]
G_star_sample = model_sample.predict(omega_true, test_mode='oscillation')
plt.loglog(omega_true, np.abs(G_star_sample), 'gray', alpha=0.1)
plt.loglog(omega_true, np.abs(G_star_data), 'ro', label='Data')
plt.loglog(omega_true, np.abs(G_star_true), 'b-', linewidth=2, label='True')
plt.xlabel('Angular frequency (rad/s)')
plt.ylabel('|G*| (Pa)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.title('Posterior Predictive Check (100 samples)')
plt.show()
Using BayesianPipeline for streamlined workflow:
from rheojax.pipeline.bayesian import BayesianPipeline
# Streamlined workflow with diagnostics and plotting
pipeline = BayesianPipeline()
(pipeline.load_data(omega_true, G_star_data, test_mode='oscillation')
.fit_nlsq('tnt_tanaka_edwards') # Automatic model selection
.fit_bayesian(num_warmup=1000, num_samples=2000, num_chains=4)
.plot_trace() # MCMC trace plots
.plot_pair() # Parameter correlations
.plot_forest() # Credible intervals
.save('tanaka_edwards_results.hdf5'))
See Also¶
Related TNT model variants:
TNT Protocol Equations — Shared Reference — Full protocol equations, cohort formulation, and numerical methods
TNT Knowledge Extraction Guide — Model identification and fitting guidance
TNT Bell (Force-Dependent Breakage) — Handbook — Force-dependent breakage (Bell model) for shear-thinning networks
TNT FENE-P (Finite Extensibility) — Handbook — Finite extensibility (FENE-P) for strain stiffening
TNT Non-Affine (Gordon-Schowalter) — Handbook — Gordon-Schowalter non-affine motion
TNT Sticky Rouse (Multi-Mode Sticker Dynamics) — Handbook — Chain Rouse dynamics between crosslinks
TNT Multi-Species (Multiple Bond Types) — Handbook — Multiple chain types with different bond lifetimes
Alternative constitutive models:
Giesekus Nonlinear Viscoelastic Models — Giesekus model family (nonlinear damping)
/models/ptt/index — Phan-Thien-Tanner model (shear thinning via trace of stress)
/models/rolie_poly/index — Rolie-Poly model (entangled polymer melts)
Theoretical background:
TNT Protocol Equations — Shared Reference — Detailed protocol equations for all test modes
TNT Knowledge Extraction Guide — Knowledge extraction guide for TNT models
API Reference¶
- class rheojax.models.TNTSingleMode(breakage='constant', stress_type='linear', xi=0.0)[source]¶
Single-mode Transient Network Theory model.
Implements the Green-Tobolsky / Tanaka-Edwards transient network model with composable physics variants. The conformation tensor S tracks the average chain configuration between reversible crosslinks.
The constitutive equation is:
dS/dt = L·S + S·L^T + g₀·I - β(S)·S
Stress is computed from S via σ = G·f(S)·(S - I) + η_s·γ̇.
- Parameters:
breakage (
Literal['constant','bell','power_law','stretch_creation']) – Breakage rate function: - “constant”: β = 1/τ_b (Tanaka-Edwards, UCM-like) - “bell”: β = (1/τ_b)·exp(ν·(stretch-1)) (force-dependent) - “power_law”: β = (1/τ_b)·stretch^m - “stretch_creation”: β = (1/τ_b), g₀ = (1+κ·stretch)/τ_bstress_type (
Literal['linear','fene']) – Stress formula: - “linear”: σ = G·(S - I) (Gaussian chains) - “fene”: σ = G·f(tr(S))·(S - I) (finitely extensible)xi (
float) – Gordon-Schowalter slip parameter (0=upper-convected, 1=corotational)
- parameters¶
Model parameters
- Type:
ParameterSet
Examples
Basic Tanaka-Edwards model:
>>> model = TNTSingleMode() >>> gamma_dot = np.logspace(-2, 2, 50) >>> sigma = model.predict(gamma_dot, test_mode='flow_curve')
Bell force-dependent breakage:
>>> model = TNTSingleMode(breakage="bell") >>> # Now has additional parameter 'nu' (force sensitivity)
See also
TNTLoopBridgeTwo-species loop-bridge kinetics
TNTCatesLiving polymer (wormlike micelle) model
- __init__(breakage='constant', stress_type='linear', xi=0.0)[source]¶
Initialize single-mode TNT model.
- model_function(X, params, test_mode=None, **kwargs)[source]¶
NumPyro/BayesianMixin model function.
Routes to appropriate prediction based on test_mode. This is the stateless function used for both NLSQ optimization and Bayesian inference.
- Parameters:
X (array-like) – Independent variable
params (array-like) – Parameter values in ParameterSet order: [G, tau_b, eta_s, …]
test_mode (str, optional) – Override stored test mode
**kwargs – Protocol-specific parameters: gamma_dot, sigma_applied, gamma_0, omega
- Returns:
Predicted response
- Return type:
jnp.ndarray
- predict_flow_curve(gamma_dot, return_components=False)[source]¶
Predict steady shear stress and viscosity.
For constant breakage: analytical (UCM-like, no shear thinning). For non-constant breakage: ODE-to-steady-state (shear thinning).
- predict_saos(omega, return_components=True)[source]¶
Predict SAOS storage and loss moduli.
In the linear regime, TNT reduces to single-mode Maxwell: G’(ω) = G·(ωτ_b)²/(1+(ωτ_b)²) G’’(ω) = G·(ωτ_b)/(1+(ωτ_b)²) + η_s·ω
- predict_normal_stresses(gamma_dot)[source]¶
Predict first and second normal stress differences.
Basic TNT (constant/linear/UC): N₁ = 2G·(τ_b·γ̇)², N₂ = 0. Gordon-Schowalter (ξ > 0): N₂ ≠ 0. FENE-P: N₁ enhanced by Peterlin factor f(trS).
- simulate_startup(t, gamma_dot, return_full=False)[source]¶
Simulate startup flow at constant shear rate.
- simulate_relaxation(t, gamma_dot_preshear, return_full=False)[source]¶
Simulate stress relaxation after cessation of steady shear.
For constant breakage + linear stress, relaxation is analytical: σ(t) = G·S_xy(0)·exp(-t/τ_b). For non-constant breakage or FENE stress, ODE integration is used.
- Parameters:
- Returns:
Relaxing stress σ(t), or (S_xx, S_yy, S_xy, S_zz) if return_full
- Return type:
- simulate_creep(t, sigma_applied, return_rate=False)[source]¶
Simulate creep deformation under constant stress.
- simulate_laos(t, gamma_0, omega, n_cycles=None)[source]¶
Simulate Large-Amplitude Oscillatory Shear (LAOS).
- Parameters:
- Returns:
Dictionary with keys: ‘t’, ‘strain’, ‘stress’, ‘strain_rate’
- Return type:
- get_overshoot_ratio(gamma_dot, t_max=None)[source]¶
Compute stress overshoot ratio in startup flow.
For constant breakage, there is no overshoot (UCM behavior). Overshoot requires Bell or stretch-dependent breakage.
- get_relaxation_spectrum(t=None, n_points=100)[source]¶
Get relaxation modulus G(t).
For single-mode TNT: G(t) = G·exp(-t/τ_b)
- extract_laos_harmonics(laos_result, n_harmonics=5)[source]¶
Extract Fourier harmonics from LAOS stress response.
- static compute_stretch(S_xx, S_yy, S_zz)¶
Compute stretch ratio from conformation tensor.
stretch = sqrt(tr(S)/3)
At equilibrium (S=I): stretch = 1. stretch > 1 indicates chains are extended beyond equilibrium.
- deborah_number(omega)¶
Compute Deborah number De = τ_b·ω.
- fit(X, y, method='nlsq', check_compatibility=False, use_log_residuals=None, use_multi_start=None, n_starts=5, perturb_factor=0.3, deformation_mode=None, poisson_ratio=0.5, auto_init=False, return_result=False, check_physics=False, uncertainty=None, **kwargs)¶
Fit the model to data using NLSQ optimization.
This method uses NLSQ (GPU-accelerated nonlinear least squares) by default for fast point estimation. The optimization result is stored for potential warm-starting of Bayesian inference.
For very wide frequency ranges (>10 decades), multi-start optimization is automatically enabled to escape local minima.
- Parameters:
X (numpy.typing.ArrayLike) – Input features
y (numpy.typing.ArrayLike) – Target values
method (
str) – Optimization method (‘nlsq’ by default for compatibility)check_compatibility (
bool) – Whether to check model-data compatibility before fitting. If True, warns when model may not be appropriate for data. Default is False for backward compatibility.use_log_residuals (
bool|None) – Whether to use log-space residuals for fitting. Recommended for wide frequency ranges (>8 decades) to prevent optimizer bias. If None (default), automatically detected based on data range. Explicit True/False overrides auto-detection.use_multi_start (
bool|None) – Whether to use multi-start optimization to escape local minima. Recommended for very wide ranges (>10 decades). If None (default), automatically enabled for >10 decades.n_starts (
int) – Number of random starts for multi-start optimization (default: 5)perturb_factor (
float) – Perturbation magnitude for multi-start random starts (default: 0.3). Parameters are perturbed by ± perturb_factor * (value or range). Larger values (0.7-0.9) explore wider parameter space.auto_init (
bool) – If True, callsauto_p0()to estimate initial parameters from data before running the optimizer (default: False).return_result (
bool) – If True, returns aFitResultinstead ofself. This intentionally breaks method chaining for workflows that need structured result objects (default: False).check_physics (
bool) – If True, runs post-fit physics validation and emitsRheoJaxPhysicsWarningfor any violations (default: False).uncertainty (
str|None) – Post-fit uncertainty method."hessian"for fast Cramér-Rao bounds,"bootstrap"for residual bootstrap CIs, orNoneto skip (default: None).**kwargs – Additional fitting options passed to _fit()
- Return type:
BaseModel|Any- Returns:
selffor method chaining (default), orFitResultifreturn_result=True.
Example
>>> model = Maxwell() >>> model.fit(t, G_data) # Uses NLSQ by default >>> model.fit(t, G_data, method='nlsq', max_iter=1000) >>> model.fit(t, G_data, check_compatibility=True) # Check compatibility >>> model.fit(omega, G_star, use_log_residuals=True) # Force log-residuals >>> model.fit(mastercurve, None, use_multi_start=True, n_starts=10) # Multi-start >>> result = model.fit(t, G_data, return_result=True) # Structured result >>> result = model.fit(t, G_data, auto_init=True, check_physics=True, ... return_result=True) # Full pipeline
- fit_bayesian(X, y=None, num_warmup=1000, num_samples=2000, num_chains=4, initial_values=None, test_mode=None, seed=None, deformation_mode=None, poisson_ratio=0.5, **nuts_kwargs)¶
Perform Bayesian inference using NumPyro NUTS sampler.
This method delegates to BayesianMixin.fit_bayesian() to run NUTS sampling for Bayesian parameter estimation. If initial_values is not provided and the model has been previously fitted with fit(), the NLSQ point estimates are automatically used for warm-starting.
Multi-chain sampling is enabled by default (num_chains=4) to provide reliable convergence diagnostics (R-hat, ESS) and parallel execution on multi-GPU systems.
- Parameters:
X (numpy.typing.ArrayLike) – Independent variable data (input features) or RheoData object
y (
Optional[numpy.typing.ArrayLike]) – Dependent variable data (observations to fit). If X is RheoData, y is ignored and extracted from X.num_warmup (
int) – Number of warmup/burn-in iterations (default: 1000)num_samples (
int) – Number of posterior samples per chain (default: 2000)num_chains (
int) – Number of MCMC chains (default: 4). Multiple chains enable proper R-hat computation and parallel execution. Chain method is auto-selected: ‘parallel’ on multi-GPU, ‘vectorized’ on single GPU/CPU.initial_values (
dict[str,float] |None) – Optional dict of initial parameter values for warm-start. If None and model is fitted, uses NLSQ estimates.test_mode (
str|None) – Explicit test mode (e.g., ‘relaxation’, ‘creep’, ‘oscillation’). If None, inferred from RheoData.metadata[‘test_mode’] or defaults to ‘relaxation’. Overrides RheoData metadata if provided.seed (
int|None) – Random seed for reproducibility. If None, uses seed=0 for deterministic results. Set to different values for independent runs.**nuts_kwargs – Additional arguments passed to NUTS sampler (e.g., target_accept_prob, chain_method)
- Return type:
BayesianResult- Returns:
BayesianResult containing posterior samples, summary statistics, and convergence diagnostics (R-hat, ESS, divergences)
Example
>>> model = Maxwell() >>> # Warm-start from NLSQ with explicit mode >>> model.fit(t, G_data, test_mode='relaxation') # NLSQ optimization >>> result = model.fit_bayesian(t, G_data, test_mode='relaxation') >>> >>> # RheoData with embedded mode (recommended) >>> rheo_data = RheoData(x=omega, y=G_star, metadata={'test_mode': 'oscillation'}) >>> result = model.fit_bayesian(rheo_data) >>> >>> # Or provide explicit initial values >>> result = model.fit_bayesian( ... t, G_data, ... initial_values={'G0': 1e5, 'eta': 1e3}, ... test_mode='creep' ... )
- fit_predict(X, y, **kwargs)¶
Fit model and return predictions.
- Parameters:
X (numpy.typing.ArrayLike) – Input features
y (numpy.typing.ArrayLike) – Target values
**kwargs – Additional fitting options
- Return type:
numpy.typing.ArrayLike
- Returns:
Model predictions on training data
- classmethod from_dict(data)¶
Create model from dictionary.
- get_bayesian_result()¶
Get stored Bayesian inference result.
- Return type:
BayesianResult|None- Returns:
BayesianResult from fit_bayesian(), or None if not run
Example
>>> model.fit_bayesian(t, G_data) >>> result = model.get_bayesian_result() >>> print(result.diagnostics['r_hat'])
- get_credible_intervals(posterior_samples, credibility=0.95)¶
Compute highest density intervals (HDI) for posterior samples.
Computes the highest posterior density interval for each parameter, which is the shortest interval containing the specified probability mass. This is preferred over equal-tailed intervals for skewed distributions.
- Parameters:
- Return type:
- Returns:
Dictionary mapping parameter names to (lower, upper) credible interval tuples. All values are float64.
Example
>>> result = model.fit_bayesian(X, y) >>> intervals_95 = model.get_credible_intervals( ... result.posterior_samples, credibility=0.95 ... ) >>> print(f"95% CI for a: {intervals_95['a']}")
- static get_equilibrium_conformation()¶
Return equilibrium conformation tensor S_eq = I.
In the absence of flow, chains adopt their equilibrium configuration: S = I (isotropic, unstretched).
- Returns:
Equilibrium state [S_xx, S_yy, S_zz, S_xy] = [1, 1, 1, 0]
- Return type:
- get_nlsq_result()¶
Get stored NLSQ optimization result.
- Returns:
OptimizationResult from NLSQ fit, or None if not fitted
Example
>>> model.fit(t, G_data) >>> result = model.get_nlsq_result() >>> if result: ... print(f"Converged: {result.success}")
- get_parameter_dict()¶
Get all parameters as a dictionary.
- get_parameter_uncertainties()¶
Get standard errors for fitted parameters from NLSQ covariance.
- Returns:
std_error}, or None if covariance unavailable
- Return type:
dict of {param_name
- get_params(deep=True)¶
Get model parameters.
- initialize_from_flow_curve(gamma_dot, sigma)¶
Initialize parameters from flow curve data.
- initialize_from_saos(omega, G_prime, G_double_prime)¶
Initialize parameters from SAOS data.
Uses the crossover frequency and modulus to estimate τ_b and G. In the linear regime, TNT reduces to Maxwell: crossover at ω_c·τ_b = 1.
- property pcov_¶
Parameter covariance matrix from NLSQ fit.
- Returns:
ndarray of shape (n_params, n_params), or None if not fitted
- property popt_¶
Optimal parameter values from NLSQ fit.
- Returns:
ndarray of shape (n_params,), or None if not fitted
- precompile(test_mode='relaxation', X=None, y=None)¶
Precompile NLSQ residual functions to eliminate JIT cold-start.
Triggers JIT compilation by running a minimal fit (
max_iter=1) with dummy data. The model parameters are reset afterwards so the model is left in its original state.This is useful for interactive sessions or benchmarks where the ~870ms first-fit JIT overhead should be excluded.
- Parameters:
- Return type:
- Returns:
Compilation time in seconds.
Example
>>> model = Maxwell() >>> t = model.precompile(test_mode='relaxation') >>> print(f"Compiled in {t:.2f}s") >>> model.fit(X, y) # No JIT overhead
- precompile_bayesian(X=None, y=None, test_mode=None, num_chains=4)¶
Precompile NUTS kernel to eliminate JIT overhead in subsequent calls.
Triggers JIT compilation of the NumPyro model by running a minimal sampling (1 warmup, 1 sample). This caches the compiled kernel so that subsequent fit_bayesian() calls are 2-5x faster.
- Parameters:
X (
ndarray|RheoData|None) – Sample input data for determining array shapes. If None, uses a default 10-point linspace [0.01, 100].y (
ndarray|None) – Sample output data. If None, generates dummy data.test_mode (
str|TestModeEnum|None) – Test mode to precompile for. If None, defaults to ‘relaxation’.
- Returns:
Compilation time in seconds.
- Return type:
Example
>>> model = Maxwell() >>> compile_time = model.precompile_bayesian(test_mode='relaxation') >>> print(f"Compiled in {compile_time:.1f}s") >>> # Now fit_bayesian() will be faster >>> result = model.fit_bayesian(X, y) # No compilation overhead
- predict(X, test_mode=None, deformation_mode=None, poisson_ratio=None, **kwargs)¶
Make predictions.
- Parameters:
X (numpy.typing.ArrayLike) – Input features
test_mode (
str|None) – Optional test mode (‘oscillation’, ‘relaxation’, ‘creep’, ‘flow’). If provided, sets model’s test_mode before prediction. Useful for data generation without fitting.deformation_mode (
str|DeformationMode|None) – Optional deformation mode for output conversion. If None, uses the mode stored from fit(). If tensile, converts G* predictions to E* space.poisson_ratio (
float|None) – Poisson’s ratio for conversion. If None, uses value stored from fit() (default 0.5).**kwargs – Additional arguments passed to the internal _predict method.
- Return type:
numpy.typing.ArrayLike
- Returns:
Model predictions (in E* space if deformation_mode is tensile)
- sample_prior(num_samples=1000, seed=None)¶
Sample from prior distributions over parameter bounds.
Samples from uniform prior distributions defined by parameter bounds. This is useful for prior predictive checks and understanding the prior’s influence on the posterior.
- Parameters:
- Return type:
- Returns:
Dictionary mapping parameter names to arrays of prior samples. Each array has shape (num_samples,) and dtype float64.
- Raises:
AttributeError – If class doesn’t have parameters attribute
ValueError – If any parameter lacks bounds
Example
>>> model = MyModel() >>> prior_samples = model.sample_prior(num_samples=500, seed=42) >>> print(prior_samples["a"].shape) # (500,)
- score(X, y)¶
Compute model score (R² by default).
- Parameters:
X (numpy.typing.ArrayLike) – Input features
y (numpy.typing.ArrayLike) – True target values
- Return type:
- Returns:
Model score (R² coefficient)
- set_parameter_dict(params)¶
Set parameters from a dictionary.
- set_params(**params)¶
Set model parameters.
- Parameters:
**params – Parameter names and values
- Return type:
BaseModel- Returns:
self for method chaining
- to_dict()¶
Serialize model to dictionary.
Key methods:
fit(x, y, test_mode, **kwargs): NLSQ fit to datapredict(x, test_mode, **kwargs): Model predictionfit_bayesian(x, y, test_mode, **kwargs): Bayesian inference with NUTSget_credible_intervals(samples, credibility): Extract credible intervals from posterior
Parameters (attributes):
G: Network elastic modulus (Pa), default 1000, bounds (1, 1e8)tau_b: Bond lifetime (s), default 1.0, bounds (1e-6, 1e4)eta_s: Solvent viscosity (Pa·s), default 0.0, bounds (0, 1e4)
Test modes:
'oscillation': Small-amplitude oscillatory shear (SAOS)'relaxation': Stress relaxation after step strain'startup': Startup of steady shear'flow_curve': Steady-state flow curve'creep': Creep under constant stress'laos': Large-amplitude oscillatory shear