On the confined cylinder (Oldroyd-B, beta 0.59) every stress history loses positive-definiteness of the conformation c = tau*/G + I in the first step at dt 0.4 (Courant 1 on the far-field mesh): the wall strain rate is about 7, so the local lambda|D| is about 3 and the explicit stretching term over one step is far outside its range. The nodal history then runs away and hangs (with or without DEVSS); the IP history holds the defect bounded and gives out at Wi 0.6. At dt 0.04 the IP history is admissible everywhere to Wi 0.6 and the drag lands at 119.3 / 114.4 (references 120.6 / 117.8) on the coarse mesh.
Two things the model should provide:
max_elastic_timestep(safety=0.3): safety / max over the domain of the strain-rate magnitude, so a run can take dt = min(courant_dt, model.max_elastic_timestep()). The Courant number on the far-field mesh is the wrong criterion for the stretching term.
conformation_min_eigenvalue(): the smallest eigenvalue of tau*/G + I on the carried polymer stress (nodal or integration-point storage), with its location and the fraction of points below zero. This is the health line that separates a preconditioner failure from a lost conformation; the per-step check that found the problem lives only in a run script so far (~/+Simulations/stress_transport/cylinder_ob/ob_cylinder.py, CONF lines).
Both with hard-baseline tests on a simple shear box (one BDF-1 step from rest at dt = lambda gives min eigenvalue 1 - lambda/2 exactly).
Underworld development team with AI support from Claude Code
On the confined cylinder (Oldroyd-B, beta 0.59) every stress history loses positive-definiteness of the conformation c = tau*/G + I in the first step at dt 0.4 (Courant 1 on the far-field mesh): the wall strain rate is about 7, so the local lambda|D| is about 3 and the explicit stretching term over one step is far outside its range. The nodal history then runs away and hangs (with or without DEVSS); the IP history holds the defect bounded and gives out at Wi 0.6. At dt 0.04 the IP history is admissible everywhere to Wi 0.6 and the drag lands at 119.3 / 114.4 (references 120.6 / 117.8) on the coarse mesh.
Two things the model should provide:
max_elastic_timestep(safety=0.3): safety / max over the domain of the strain-rate magnitude, so a run can takedt = min(courant_dt, model.max_elastic_timestep()). The Courant number on the far-field mesh is the wrong criterion for the stretching term.conformation_min_eigenvalue(): the smallest eigenvalue of tau*/G + I on the carried polymer stress (nodal or integration-point storage), with its location and the fraction of points below zero. This is the health line that separates a preconditioner failure from a lost conformation; the per-step check that found the problem lives only in a run script so far (~/+Simulations/stress_transport/cylinder_ob/ob_cylinder.py, CONF lines).Both with hard-baseline tests on a simple shear box (one BDF-1 step from rest at dt = lambda gives min eigenvalue 1 - lambda/2 exactly).
Underworld development team with AI support from Claude Code