Fixtures and decks ================== Rules for vendor-format fixture files (BDF / INP / DAT / CDB) under ``tests/interop//fixtures/``. Companion to :doc:`verification_manual_spec` (which describes how a fixture is *used* by a registry row); this page covers how the fixture itself is sourced, named, edited, and retired. .. contents:: Page contents :local: :depth: 2 The immutable-deck rule ----------------------- **Fixtures are immutable in the test repo.** Once authored, a fixture file is not edited to make a test pass. If a deck doesn't round-trip through the reader, the fix is on: #. The **reader** — open a ``[interop]`` child issue, fix the parser, re-run the test. #. The **kernel** — open a ``[kernel]`` child issue, land the kernel feature, re-run the test. #. The **registry tolerance** — only as a one-line tighten/widen with a written rationale; never to mask an actual divergence. There are exactly **two** legitimate reasons to edit an existing fixture: * The fixture was authored as a workaround for a reader bug, the reader bug is being fixed, and the deck must canonicalise as part of the same coordinated PR. ``vm_pinched_ring`` and ``vm_msc_vg_2_5_cantilever_statics`` are the prior reference cases (issue #509, PR #573). * The published problem statement we re-authored from contained a deck-level error that we caught after-the-fact. Document the catch in the PR; never silently "fix and move on". Editing a fixture for any other reason is a regression: it hides a real bug behind a tampered test input. This rule is enforced — ``doc/source/verification/vendor_matrix.rst`` carries an ``.. important::`` block to the same effect. Where decks come from --------------------- Vendor decks fall into two categories. The provenance handling differs. Re-author from problem statement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The default for every BDF and most INP fixtures. Hexagon (MSC), Dassault (Abaqus), and NAFEMS publish their verification corpora as PDFs whose **problem statements** are exhaustive enough to recreate the deck — geometry, materials, BCs, loading, mesh density. The deck text itself is sometimes also published, sometimes only inside the PDF, sometimes behind a vendor login. We **do not lift deck text**, regardless. Re-authored decks follow these conventions: * Header lines (``$``-comments in BDF, ``**``-comments in INP) cite the source: vendor manual section, PDF page, the canonical reference (Roark, Timoshenko, NAFEMS R0015 / R0016, MacNeal-Harder 1985). * The closed-form value the test asserts against is reproduced inline as a derived quantity — both so a future reader can audit the derivation, and so the deck and the registry row stay in sync. * Mesh density mirrors what the published problem uses (or finer); if we use a coarser mesh, the header notes the discretisation choice explicitly. * Units are consistent (one of: SI, in-lb-sec, mm-N-tonne); units are noted in the header. Vendor-shipped (provenance preserved) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Some vendors publish their verification decks as part of their documentation and place them in the public domain or under explicit redistributable licences. Ansys publishes every ``vm{N}.dat`` openly on the help portal; older Abaqus releases' benchmarks are mirrored across engineering-school courseware under fair use. When we use a vendor-shipped deck: * The original ``/COM`` / ``** ANSYS MEDIA REL.`` / equivalent provenance line is preserved verbatim. Don't strip it. * Don't edit the deck content. If a card we don't yet support surfaces, that's a reader gap — open a child issue, leave the fixture as-is, mark the registry row ``xfail`` until the reader lands. If a vendor deck is available from a primary source, prefer the vendor-shipped path: it lets the reader exercise the deck text the real-world user will hand it. Otherwise re-author. Sourcing exclusions ~~~~~~~~~~~~~~~~~~~ We do **not** vendor: * MSC VG copy-restricted notes / commentary; * SIMULIA licensed example files; * Any vendor's *consolidated PDF* checked into git (the raw PDFs in the local ``pdfs/`` directory are user-owned working copies, not part of the source release). The umbrella sourcing policy lives in ``SOURCES.md`` at the repo root. When in doubt, the answer is "re-author". Naming conventions ------------------ Fixtures are named for the registry stem they serve. Conventions by source (mirrors the spec; reproduced here for reference): * ``vm_msc_vg_
_.bdf`` / ``.inp`` — MSC Nastran VG. * ``vm[_].dat`` — Ansys MAPDL VM (vendor's official numbering). * ``vm_nafems_.bdf`` / ``.inp`` — NAFEMS standalone benchmark. * ``vm_.bdf`` / ``.inp`` — internal canonical problems with a clear closed form. Pairing ------- When a stem has both BDF and INP fixtures, the two decks must encode the **same physical problem**: same geometry, same material, same BCs, same loading. The harness's BDF↔INP agreement test runs on every paired stem and trips loud on any divergence: * Different node count or coordinates → 100 % divergence. * Different load magnitude or direction → divergence proportional to the swap. * Different element formulation (HEX8 vs C3D8I) → systematic off-by-the-formulation-difference; document explicitly via ``xfail_agreement`` on the registry row. Multi-format pairing (``("bdf", "inp", "dat")``) extends the same contract: every pair (BDF↔INP, BDF↔DAT, INP↔DAT) must agree. Adding a new fixture -------------------- #. **Decide source.** Re-author or vendor-shipped (above). #. **Pick the stem.** Mirror the convention; cross-check the stem isn't already in use under another vendor. #. **Author the file.** Include header citation, derived closed-form value, units, mesh density rationale. #. **Add the registry row.** See :doc:`verification_manual_spec` for the spec types and selectors. #. **Run the harness.** Confirm the row passes; the BDF↔INP agreement is automatic. #. **PR.** Body must include the published reference (chapter, page, DOI), the closed-form derivation, and the empirically-measured FE error. Retiring a fixture ------------------ Three reasons a fixture might leave the repo: * The registry row that uses it was deleted (no other rows refer to the fixture). The fixture is then orphan and can be removed in the same PR. * The fixture was authored against a misunderstood problem statement and a corrected fixture has landed under a new stem. The misnamed fixture is removed; the stem name is freed for re-use. * The vendor revised the published problem in a later release and the fixture is no longer the canonical version. Document the revision in the PR and replace. Don't retire a fixture just because the registry row is currently ``xfail``-blocked on a kernel gap. The fixture stays so the row stays trackable and lights up the moment the kernel lands. Common pitfalls --------------- * **Lifting deck text from a vendor PDF.** Always re-author from the problem statement. If the deck is openly published, treat it as vendor-shipped (preserve ``/COM`` provenance) — never edit-and-claim-it-as-yours. * **Running BDF/INP through different-formulation kernels.** If ``from_bdf`` routes the deck to HEX8 and ``from_inp`` routes the same deck to C3D8I (EAS), the agreement test will diverge. Either change one of the decks (see the immutable-deck rule — authored-from-statement decks are still immutable!), or set ``xfail_agreement`` with a written rationale. * **Incomplete unit consistency.** A deck with mixed psi / Pa silently scales by 6894.76 in the result. Header-line audit every deck for unit consistency before authoring the registry row. * **Using ``RBE2`` / ``RBE3`` / multi-point constraints we don't yet support.** The card may parse but produce a wrong result. Open the interop gap as a child issue and ``xfail`` the row with a link. * **Hard-coded paths in the registry row's ``notes``.** Notes are free text but should not encode paths that drift; refer to source files by their canonical name. Where things live ----------------- .. list-table:: :header-rows: 1 :widths: 32 68 * - Artifact - Path * - BDF / INP / DAT / CDB fixtures - ``tests/interop//fixtures/`` * - Registry rows - ``tests/cross_solver/_verification_registry.py`` * - Harness - ``tests/cross_solver/test_verification_round_trip.py`` * - Reader-pending build factories - ``tests/validation/_vm/test_.py`` (see :ref:`vm-spec-reader-pending`) * - Vendor-source PDFs (working copies, not vendored) - ``pdfs/`` (repo root; user-owned) * - Sourcing policy - ``SOURCES.md`` (repo root)