Skip to content

Generic material test structure: registry conformance, property contract, tangent conformance #35

Description

@petlenz

Every material is currently tested — when it is tested — by a bespoke file. That scales badly and leaves systematic gaps: #33 (8 materials unreachable from JSON) and #34 (6 materials with no test) are both things a generic layer would have caught the day they appeared, rather than by someone auditing.

Three tiers, in descending order of how generic they can actually be. The honesty of this proposal is in the third column.

tier what it asserts how generic
1. Registry conformance every material_base subclass is registered or explicitly opted out; every schema declares name; a missing required parameter throws; an unknown JSON key is reported fully generic — a directory scan plus the factory's own type list. No wiring, no fixtures
2. Property contract the documented outputs exist after finalize(); nothing publishes a history property unintentionally needs a minimal fixture per material
3. Tangent conformance for anything publishing stress and tangent, the tangent matches numerical_diff_checker over a table of load paths needs a fixture and a driver

Tier 1 is worth doing on its own

It needs no per-material work and it closes #33 permanently. The check is roughly:

// every class deriving material_base in materials/ is registered,
// unless it is on an explicit, commented opt-out list
for (const auto& cls : material_classes())
  EXPECT_TRUE(factory.contains(cls) || deliberately_unregistered.contains(cls))
      << cls << " cannot be named in a JSON document";

The opt-out list is the point: it forces "this material is not for JSON" to be a decision someone wrote down, instead of the current situation where it is indistinguishable from an oversight.

Tier 3 is what would have caught the Drucker-Prager apex

The apex return had zero test coverage until last week — instrumenting needs_apex_return() gave APEX_HITS=0 across every test binary. The reason is structural, not carelessness: every existing path was uniaxial, and the apex sits on the hydrostatic axis, so it was unreachable by construction.

A tangent-conformance test parameterized over load paths — uniaxial, hydrostatic, shear, and a non-proportional path — reaches branches that a single path cannot. numerical_diff_checker already exists and only three materials use it.

The cost, stated plainly

Tiers 2 and 3 need a type -> minimal JSON snippet table, roughly one entry per material, because materials need their sources wired before they can be built. That is real work and it will not write itself.

The upside is that the table becomes the definition of "done" for a new material: supply a snippet, and the generic tests cover you. That is a better contract than "remember to write a test file, and remember to add a line to default_materials.h", which is the contract that produced #33 and #34.

Suggested order

  1. Tier 1 — self-contained, closes 8 materials are not registered in the factory, so a JSON model cannot express plasticity #33's recurrence
  2. The fixture table — unblocks 2 and 3
  3. Tier 3 with a load-path table — highest defect-finding value per line
  4. Tier 2 — cheapest once the table exists

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions