Large rigid rotation is separated from a small-local-strain additive J2 law; this is not multiplicative finite-strain plasticity.
01 Model and scope
At each integration point, the deformation gradient is split into a proper rotation R and a right stretch U. The rotation is removed before a small-strain J2 update on U−I; tensor history is transported into the new corotated frame. This supports large rigid rotation with bounded local strain, not arbitrary finite-strain plasticity.
Read the kinematics, constitutive law and solution lifecycle together. A component's evidence does not qualify their combination.
Route assumptions and calculation checks
- Polar decomposition removes rigid rotation before evaluating the bounded Biot-like local strain U−I; tensor history is transported between frames.
- The element tangent is a symmetrized central difference at a fixed committed state, not an exact analytical consistent tangent.
- Formal acceptance is owner-accepted bounded HEX8 only. TET10/HEX20 extensions have limited evidence; no multiplicative finite-strain plasticity is implemented.
Useful foundations and prerequisites
02 Essential equations and symbols
Definitions and conventions
- Right polar decomposition; R is proper rotation and U is symmetric positive stretch.
- Biot-like corotated strain used by this implementation; limited by a configured norm bound.
- Sₙ, Rₙ
- Accepted constitutive history and corotation frame at the prior increment.
- First Piola stress used to assemble internal force in the reference configuration.
- KFD
- Central-difference force tangent evaluated from the same committed material state.
03 Step by step derivation
Follow the assumptions, equations and discrete operations in order. The full explanation stays visible.
The current implementation forms internal force from P=Rσlocal and reference shape gradients. It computes a central-difference tangent at a fixed committed state, then symmetrizes that numerical matrix. Formal acceptance is bounded to HEX8; TET10 and HEX20 extension evidence does not inherit that maturity.
1 · Start from the reference-to-current deformation gradient
With reference coordinates X and displacement u, F maps infinitesimal reference line elements to current line elements. A pure rigid motion may make F far from I even when the material is not strained; using the small-strain tensor sym(∇u) directly would mistake that rotation for deformation.
A non-positive determinant is rejected. The implementation also rejects determinants at or below its numerical threshold 10⁻¹⁰.
2 · Factor rigid rotation from material stretch
The right polar decomposition F=RU separates a proper rotation R from the symmetric positive-definite right stretch U. The implementation obtains this factorization with an SVD and verifies that R is finite and orientation-preserving. For a pure rotation, U=I.
This decomposition is kinematic. It does not introduce the multiplicative plastic split F=FeFp or a finite-strain yield law.
3 · Apply the small-strain constitutive update in the rotating frame
The local measure is εcorot=U−I, a Biot-like stretch strain. It is symmetrized and converted to engineering Voigt form before calling the material model. The configured default maximum Frobenius norm is 0.05; exceeding it raises an error instead of silently extending the model.
A constitutive call returns a trial state S*. The global nonlinear lifecycle decides whether it is committed after equilibrium convergence or discarded after rejection.
4 · Transport history between successive corotated frames
Plastic strain, stress, and stored strain are tensors expressed in the last local frame. When R changes, the code rotates these second-order tensors through the relative frame rotation before the next J2 update. Equivalent plastic strain and scalar history remain unchanged by this coordinate change.
A non-zero restart state without its committed corotation metadata is rejected because its tensor components cannot be interpreted safely in a new frame.
5 · Rotate stress back and assemble internal force
The local stress is rotated into a first Piola stress, then multiplied by reference gradients and integrated over the reference element. This is the virtual-work path used by the current kernel. It is not the same operation as simply rotating a final plotted stress field.
Post-processing reports several stress measures. Compare only matching measures and configurations when correlating results.
6 · Understand the numerical tangent and accepted scope
For each element displacement component, the code perturbs the displacement by ±h, reevaluates force from the same committed state, and forms a central difference. It symmetrizes the result. This exposes frame and geometric effects to Newton but costs two force evaluations per DOF and can depend on the perturbation scale.
The v0.2.10 V&V summary records owner-accepted bounded HEX8 scope, with large rotations and small local strain. TET10/HEX20 extensions are accepted with limitations, not formally promoted. This is not general finite-strain plasticity, arbitrary local strain, contact, or dynamic qualification.
04 Algorithm and implementation
Source excerpt · v0.2.11
The kernel extracts rotation and stretch at each integration point, bounds U−I, transports the accepted state, evaluates J2, and forms P=Rσlocal. Its tangent is computed separately by central differences.
rotation, stretch, determinant = _polar_decomposition(deformation)
corotated_strain = symmetrize(stretch - identity)
local_strain_norm = float(np.linalg.norm(corotated_strain))
if local_strain_norm > self.max_corotational_strain:
raise ValueError('Corotational small-strain bound exceeded.')
transported = _transport_state(committed, rotation)
response = evaluate_constitutive(self.material, strain_voigt(corotated_strain), transported)
first_piola = rotation @ stress_tensor(response.stress)
internal += measure * np.einsum('iJ,aJ->ai', first_piola, gradients).reshape(-1)
force_plus, _, _ = self._force_and_states(coords, plus, states)
force_minus, _, _ = self._force_and_states(coords, minus, states)
tangent[:, column] = (force_plus - force_minus) / (2.0 * scale)05 Verification and limitations
QUALIFIED_BOUNDED · formal acceptance is HEX8-only
Each reference supports its own model, observable and analysis route. Read the original contract and limitations before transferring a conclusion.