Verification suite
Canonical benchmarks with known answers — textbook plate and beam solutions, the standard shell obstacle course, closed-form laminate results, conservation identities, and analytic derivatives. Each one runs a mesh refinement sweep and reports its value against a published or independently computed reference.
These are examples first and a regression gate second: every file is a readable, self-contained script that a user can run to see Hermit reproduce a result they already trust.
conda activate hermit
python examples/verification/ex_scordelis_lo.py # convergence sweep
python examples/verification/ex_scordelis_lo.py --quick # the single level CI runs
Writing a new one
Copy ex_scordelis_lo.py (curved geometry, distributed load)
or ex_pinched_cylinder.py (symmetry planes, point load).
The shape is always the same:
A module docstring whose first line is the title — the docs build turns it into a page and requires it. Follow it with the physical setup, the reference value, and what makes the case worth having.
A
solve_at(level) -> floatreturning the single scalar the reference is quoted for.A
CASE = Case(...)declaringreference,tolerance,citation,levelsandquick_level.if __name__ == "__main__": main(CASE).
Mesh builders live in _geometry.py — add one there rather than
inlining a mesh in an example. Meshes are built in memory: the env has no meshio,
and a benchmark’s mesh is a function of its refinement level anyway.
quick_level is the level CI runs, so it should be the cheapest one that is still
honest about the case. Prefer the coarsest level meeting tolerance; where no swept
level meets it, keep the most diagnostic affordable level rather than moving the
target (see ex_ss_plate_uniform). Keep a full sweep under ~30 s.
Reference-value integrity
The failure mode this suite must not have is a benchmark that passes while verifying nothing. Four rules, in priority order:
Compute the reference rather than quoting it, wherever the closed form allows. Sum the Navier series in NumPy; assemble the laminate
A/B/Dby hand from the ply definitions. A computed reference cannot be misremembered, and it documents itself. Quote a constant only when the reference genuinely is a published number from a converged numerical study (the obstacle-course cases).Every quoted constant carries a real citation — author, work, and the table or equation it came from — in the
Case.citationfield and inREFERENCES.md.The reference and the tolerance are fixed before the first run and are not adjustable to fit the result. If a case misses, report the convergence table and say so. A benchmark that misses its reference is a finding about Hermit — the API redesign turned up nine real defects this way, and several of them looked exactly like “this case is a bit off”. Loosening the gate throws that signal away.
Assert convergence, not just the endpoint. A wrong reference constant usually shows up as a sweep converging beautifully to a different number, which is diagnostic. The harness warns when the error is not monotone under refinement.
When a benchmark does not meet its reference
Set open_finding= on the Case with what is known and what is merely suspected.
The reference and tolerance stay at their correct values, the sweep still runs and
prints, and the test suite reports the case as an expected failure with that string as
the reason. Resolving one means fixing Hermit or correcting the reference — never
editing the field to be less honest.
This is not a formality. Of the five cases that first failed here, one was a wrong
analytic target, one a wrong load magnitude, one a measurement point at the wrong
place, one a genuine element defect (the warped-quadrilateral curvature, since fixed),
and one an optimiser failure (ex_optimal_thickness_taper, since resolved — it
passes). Four of the five would have been erased by a slightly wider tolerance.
ex_curved_beam is the only case still carrying an open_finding, and it is a
documented element limitation on a deliberately extreme 1-element-wide strip rather
than a defect — see its open_finding string for the measurements that establish
that.
Warped quadrilateral cells
ex_warped_quad_consistency.py records the resolved warped-cell defect and gates its
replacement. The former curvature gave a 40% wrong twisted-beam answer that worsened
under refinement. Hermit’s constant-normal, shallow-shell curvature now makes the
quadrilateral and triangular sequences converge together. Triangles are therefore no
longer required merely because a surface is doubly curved; see the formulation limits
in the user guide before applying this flat-facet theory to moderately thick,
strongly curved, membrane-loaded shells.
Layout
file |
what |
|---|---|
|
analytic in-memory mesh builders (plate, cylinder, sphere, disk, annulus, twisted strip, curved beam) |
|
|
|
one benchmark each |
|
every reference value with its source |