Writing a VUMAT
A VUMAT is not a UMAT with the tangent deleted. Four things change, and two of them are silent.
Porting a working UMAT to Explicit looks like a deletion job: drop the Jacobian, keep the stress update. Two of the four real differences produce no error message, and one of them is a transposition of two array slots.
The four differences
| UMAT (Standard) | VUMAT (Explicit) | |
|---|---|---|
| Called for | One integration point | A block of integration points |
| Material Jacobian | Required | Not used — there is no equilibrium iteration |
| 3-D component order | 11 22 33 12 13 23 | 11 22 33 12 23 31 |
| Stress in | STRESS, updated in place | STRESSOLD in, STRESSNEW out |
| State | STATEV, updated in place | STATEOLD in, STATENEW out |
| Strain | DSTRAN, engineering shear | STRAININC, tensor shear |
| Rotation | DROT applied by Abaqus | Quantities arrive in a co-rotational frame |
The component order, which is the one that bites
In three dimensions the first four components agree and the last two are transposed. 13 and 23 swap places. Copy a tangent or a flow direction between the two without reordering, and the code compiles and runs. It is wrong only when both of those shear components carry different values, which pure tension, pure shear and most simple test cases do not produce.
STRAININC carries tensor shear, DSTRAN carries engineering shear
This is the second silent one. A UMAT's DSTRAN(4) is 2*eps_12; a VUMAT's STRAININC(:,4) is eps_12. Move an expression across without adjusting and every shear response is out by a factor of two.
It is worth writing the factor explicitly rather than absorbing it into a constant. A line that says why it is halving something survives the next person; a 0.5 does not.
Block processing
A VUMAT is handed NBLOCK integration points at once and is expected to loop over them. Two consequences follow.
- Everything is a slice.
STRESSOLD(K,I)is componentIof pointK. A scalar that should be per-point and is written outside the loop silently shares one value across the block. - Vectorisation matters here in a way it does not in Standard. The block exists so the compiler can vectorise. A branch inside the loop that depends on the point — a yield test, for instance — is unavoidable, but everything that can be hoisted out of it should be.
No tangent, and what replaces the worry
Explicit does not iterate for equilibrium, so there is no Jacobian to supply and no convergence to lose. The thing that replaces it is stability.
The stable time increment is set by the wave speed, which depends on the material stiffness and density. A material that stiffens — through hardening, through a rate term, through a locking response — reduces the stable increment, and Abaqus reduces the step accordingly. A material whose stiffness spikes because of a bug will crash the increment size and the job will appear to hang rather than to fail.
If an Explicit job's increment size collapses after a certain point in the loading, look at what your material did at that point before looking at the mesh.
What to check
Everything on the UMAT page applies, minus the tangent and plus two:
- Compare against a Standard run of the same model. One element, same loading, small enough increments that the explicit dynamics are quasi-static. The stresses should agree closely. This single check catches both the ordering and the shear-convention differences.
- Watch the stable increment through the loading. A sudden drop is the material telling you something.
- Confirm the energy balance. Explicit gives you
ALLIE,ALLKEandALLWKfor free. A material that creates energy shows up here before it shows up anywhere else.
Common questions
Can I share code between my UMAT and my VUMAT?
Yes, and it is worth doing: put the constitutive algorithm in a subroutine that takes tensor-shear strain in a fixed component order, and let each interface do its own conversion.
The conversions are then two small routines you can test, rather than a convention spread through both implementations.
Do I need STATEV rotation in a VUMAT?
Abaqus/Explicit hands the subroutine quantities in a co-rotational frame, so tensor state variables generally do not need rotating by you.
Confirm this against the reference guide for the release you are running, because it is exactly the kind of detail that carries version caveats.
My VUMAT gives different results from my UMAT on the same problem.
Check the component order and the shear convention first — they account for most of these reports, and both are silent.
Then check that the explicit run is actually quasi-static. Kinetic energy above a small fraction of internal energy means you are comparing a dynamic result against a static one.