materials: register plasticity, hardening, damage and state functions - #36
materials: register plasticity, hardening, damage and state functions#36petlenz wants to merge 3 commits into
Conversation
Eight material classes were missing from register_default_materials(), so they could not be named in a JSON document at all. Two of them are small_strain_plasticity and linear_isotropic_hardening, which means a document could build elasticity and damage and NOT J2 plasticity -- the library's flagship model -- against a stated goal of being config driven. Registration is a hand-maintained list, and every test that uses these materials constructs them in C++ through ctx.create<T>(), never through the factory. So the tests passed, the materials worked, and the only broken thing was the path the document layer depends on. small_strain_plasticity and rk_plasticity are templates over the yield-function TYPE, so the registrable names are the concrete aliases: j2_plasticity, drucker_prager_plasticity, j2_rk_plasticity. drucker_prager_plasticity is registered but NOT yet fully configurable from a document. Its yield function carries eta, beta and K_bulk and arrives as a C++ object through an undeclared "yield_function" parameter, which the JSON reader cannot convert. A document can name it; it cannot set those three. That is recorded in a test rather than left to be discovered. Three tests: the names resolve; a J2 model built entirely from a document yields (registration alone would pass the name check while still failing here if a parameter were not convertible); and Drucker-Prager's limitation is pinned, so the test fails if yield_function ever becomes expressible and the note goes stale. Closes #33.
…be configured Registering it made a document able to NAME it, and the yield function -- which carries eta, beta and K_bulk -- cannot be expressed in JSON. A document naming it therefore got a DEFAULT-constructed one: eta = beta = k = 0. Probed: it builds without error, runs 20 steps, never yields, and is indistinguishable from elasticity. That is worse than not registering it. Unregistered, a document naming it fails with an unknown material type, which says exactly what is wrong. Registered, it silently returns elastic results from a model the user believes is Drucker-Prager. The test now pins the absence and its reason, so registering it again without making yield_function expressible fails.
petlenz
left a comment
There was a problem hiding this comment.
Critical review of my own PR — probed, not read. One finding, and it made this PR a net negative until fixed. Fixed in the branch; recording it because the failure mode is the one this stack keeps producing.
Registering drucker_prager_plasticity was worse than leaving it out
Its yield function carries eta, beta and K_bulk and arrives as a C++ object the JSON reader cannot convert. Registered, a document could NAME it — and silently got a default-constructed yield function, eta = beta = k = 0. Probed:
built from JSON without error
ran 20 steps: alpha=0.000000
-> a document can build a DP material with eta=beta=k=0 and it runs silently
It builds, runs, never yields, and is indistinguishable from elasticity. A user writing a Drucker-Prager model in JSON gets elastic results and no error anywhere.
Unregistered, the same document fails immediately:
rejected: object_registry::entry(): unknown type 'drucker_prager_plasticity'
That names exactly what is wrong. So it is now deliberately NOT registered, with the reason in the code and a test pinning the absence — registering it again without making yield_function expressible fails the test.
I had originally written a test asserting yield_function was absent from the schema, which recorded the limitation without noticing that the limitation made the registration harmful. Documenting a hazard is not the same as removing it.
What I checked and could not break
- The other eight registrations are reachable and configurable; a J2 model built entirely from a document is driven to yield, which registration alone would not prove.
- No name collisions: 27 registered types, all distinct.
- CI green.
Follow-up worth its own issue: making yield functions expressible in JSON is what unblocks Drucker-Prager, and it is the same shape as zero_blocks on #17 — a typed C++ object reaching a material through an undeclared parameter.
Closes #33.
Eight material classes were missing from
register_default_materials(), so they could not be named in a JSON document. Two aresmall_strain_plasticityandlinear_isotropic_hardening— a document could build elasticity and damage but not J2 plasticity, against a stated goal of being config driven.Nothing detected it: registration is a hand-maintained list, and every test that uses these materials constructs them in C++ via
ctx.create<T>(), never through the factory. The tests passed, the materials worked, and only the document layer was broken.Correcting the issue's guess
#33 speculated the obstacle was a
yield_functionobject parameter. It is not — all 8 declare only JSON-convertible types. The real reason is thatsmall_strain_plasticityandrk_plasticityare templates over the yield-function type, so the registrable names are the concrete aliases:j2_plasticity,drucker_prager_plasticity,j2_rk_plasticity.drucker_prager_plasticityis registered but not yet fully configurable from a document: its yield function carries η, β and K_bulk and arrives as a C++ object through an undeclaredyield_functionparameter the JSON reader cannot convert. A document can name it; it cannot set those three. That is pinned by a test rather than left in a comment, so the test fails if it ever becomes expressible.Tests
Three. The names resolve; a J2 model built entirely from a document is driven to yield (registration alone would pass a name check while still failing if a parameter were unconvertible); and Drucker-Prager's limitation is recorded.