Skip to content

materials: register plasticity, hardening, damage and state functions - #36

Open
petlenz wants to merge 3 commits into
feature/live-deck-constantsfrom
fix/register-materials
Open

materials: register plasticity, hardening, damage and state functions#36
petlenz wants to merge 3 commits into
feature/live-deck-constantsfrom
fix/register-materials

Conversation

@petlenz

@petlenz petlenz commented Aug 22, 2026

Copy link
Copy Markdown
Member

Closes #33.

Eight material classes were missing from register_default_materials(), so they could not be named in a JSON document. Two are small_strain_plasticity and linear_isotropic_hardeninga 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_function object parameter. It is not — all 8 declare only JSON-convertible types. The real reason is that 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 η, β and K_bulk and arrives as a C++ object through an undeclared yield_function parameter 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.

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 petlenz left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant