Changelog#
This page lists user-visible changes for every tagged femorph-solver release. Entries follow the Keep a Changelog structure (Added / Changed / Deprecated / Removed / Fixed / Security) so the diff between any two releases reads consistently regardless of which contributor authored it.
Versions follow Semantic Versioning:
the public API is the surface enumerated by femorph_solver.__all__
and the public methods of the classes it re-exports. Pre-1.0 minor
bumps may break the public API; bumps after 1.0 will not.
Unreleased#
Tracking main. Compare against the most recent tag on
GitHub: v0.22.1…main.
v0.22.1 — 2026-05-08#
Docs deploy unblock. Compare against the prior tag: v0.22.0…v0.22.1.
Fixed#
Tag-triggered docs deploy no longer blocks on latent
unknown documentreferences in historical-tag snapshots.sphinx-multiversionre-checks out every released tag and rebuilds its docs through the current Sphinx environment; v0.20.0 tutorials reference doc tree paths that hadn’t been written yet (/interop/nastran,/interop/abaqus,/getting-started/known-limitations,/reference/theory/stress_recovery). Under the shared-W(warnings as errors) those latent refs become hard failures and the Cloudflare Pages deploy never runs. SplitSPHINXOPTS_MVso the multiversion build keeps--keep-goingwithout-W; single-version main / PR builds keep-W(#912).
v0.22.0 — 2026-05-08#
MAPDL parity push, native geometry creation, harness rebuild. Compare against the prior tag: v0.21.0…v0.22.0.
Added#
MAPDL parity playbook + scoreboard discipline.
tests/mapdl_reference/PLAYBOOK.mdis now the canonical handoff doc for the 100-VM parity push. Documents the four- layer strictness hierarchy (element K/M bit-level → assembled K/M → probe values → reference targets), the curatorial restraint rules for the deck-verb skip set, the multi-pass deck families (/CLEAR,NOSTART/ FINISH+``/PREP7`` /ETCHGelement-type swap), and a working-without-binary- solver-access section so the same discipline applies to Hexagon’s MSC.Nastran / Abaqus parity (#878, #886, #907). CompanionAGENTS.mdat the repo root spells out the rules for any AI / human contributor: element-first rule + solver-native kernel naming convention.Per-kernel parity tests against MAPDL ``.emat``. Element K / M now diff bit-level (~1e-12 relative) against MAPDL’s
file.ematfor every implemented kernel: COMBIN14 (#876), HEX8 (SOLID185), QUAD4_PLANE (PLANE182), TRUSS2 (LINK180), BEAM2 (BEAM188), MASS21, PLANE55 + LINK33 + LINK34 thermal, HEX20 (SOLID186). These tests are the gate every kernel must pass before any probe-level VM closure.Native geometry-creation pillar. New
femorph_solver.geometrymodule: Point / Line / Area / Volume primitives (frozen dataclasses), structured pure-NumPy meshers for rectangle (Q4) and box (Hex8) with bit-level patch-test verification, gmsh fallback for unstructured 2-D / 3-D, lazy pyvista tessellation. Mesher choice locked to gmsh-first (open-source robust) per RFC, native superior later. Runnable from-scratch demo atdocs/examples/geometry_from_scratch.pyexercises the full pipeline end-to-end (build geometry → mesh → solve → extract results in pure Python) and is gated in CI bytests/geometry/test_example_from_scratch.py(#890, #891, #892, #893, #901, #902).VM parity scoreboard. 16 VMs in the first 100 now pass end-to-end within the 5% relative-error gate (vm3, vm10, vm12, vm16, vm45, vm47, vm48, vm50, vm57, vm61, vm84, vm89, vm90, vm92, vm94, vm99). Closures this release: vm3 (CSYS,1 + thermal pre-strain in LS,1 stress recovery, #881), vm10 (BEAM2 T-section fiber-stress recovery, #900), vm12 (BEAM2 PLNSOL principal-stress recovery, #909), vm16 (PLNSOL,0,MAX evaluator + F-range form, #899), vm21 (RFORCE / VARI POST26 reaction-force evaluator, #898), vm50 (DK keypoint-displacement, #884).
Multi-pass deck routing.
/CLEAR,NOSTART-segmented decks (vm12 / vm33 / vm34) now route to the last solving pass for the build/solve pipeline, with last-write semantics on*VFILLso the comparison block at the deck tail resolves against the correct*GETbindings (#908).Harness probe-evaluator coverage. PLNSOL / PLESOL stress contours: principal stresses, intensity, von Mises, with beam-element fiber-stress augmentation so PLNSOL,S,1 aggregates over both solid principals and BEAM2 cardinal fibers (#903, #909). POST26
RFORCE/VARIreaction-time-history (#898).ETABLE/LSelement-table extraction expanded.Solver-native kernel naming. Element registry renamed away from MAPDL-vendor names (
Solid185,Plane182, …) to physics+topology names (Hex8,Quad4Plane,Bar2Conduction,LumpedSpringMass, …). The MAPDL catalogue dispatch lives at the interop boundary (_apdl_dialect._MAPDL_ALIASES); core registry and downstream code never see vendor names. Convention locked inAGENTS.md(#880).DAT loader: traceable skip table + unknown-verb tracking. Every verb the parser doesn’t fully implement is recorded on
model._deck_skipped(with a stated reason) ormodel._deck_unknownso the scoreboard surfaces the gap loudly rather than silently dropping commands (#885). Curated skip set covers post-only verbs (*VWRITE,*VFILL,ETABLE,PLNSOL,PRRSOL,OUTPR,OUTRES, POST26RFORCE/DERIV), default-toggle no-ops (HROPT,FULL,TRNOPT,FULL,CSYS), and deck- formatting artifacts (FORTRAN format continuations,LABEL(i,j) = '...'array assignments) without ever silently skipping a physics-relevant verb.DAT loader: more handlers —
RMORE(extend real constants beyond 6 slots, #897), stacked*IF / *DO / *DOWHILEblock-skipper (#896),*CREATE / *ENDmacro-body block-skip (#889),DSYMsymmetry-plane handler (#888),SFBEAMwith MAPDL→solver-native face remap (#883),DKkeypoint-displacement (#884),TREF / BFUNIF / BF / CP(#881).CHAN beam section for vm14 (channel-section beam properties derived from MAPDL
SECTYPE,..,BEAM,CHANSECDATA).Result-file magic marker + version stamp so disk-backed results identify the femorph-solver version that wrote them.
Changed#
Model.assignis a no-op on empty kernels; newModel.assign_allhelper attaches every registered kernel to its matching element block in one call.solvers.linear.list_available()runtime introspection reports which optional backends loaded (Cholmod / SuperLU / PARDISO).TTY-aware progress output: progress bars no longer overlap via
\rwhen redirected to a non-TTY pipe.
Fixed#
FV2/FV4 ARPACK degenerate-pair flake: deterministic
v0initialisation for the K-σM eigensolver path (#114, PRs #115, cyclic-modal companion fix).BEAM2 xfail closure: static condense MAPDL’s 24×24 cubic-shape function (BEAM188 KEYOPT(1)=3) down to the Hermite 12×12 we ship — element-K parity within ~1e-12 rel.
gmsh OSError on NixOS: harden the lazy-import path against both
ImportErrorandOSErrorso a broken gmsh wheel doesn’t break the geometry pillar (#893).
Deprecated#
MAPDL-vendor kernel names (
Solid185etc.) accepted at the interop boundary; downstream code that still references them via private imports should switch to the solver-native names (Hex8etc.). Vendor names will continue to translate through the alias table indefinitely; the deprecation is about internal uses only.
v0.21.0 — 2026-05-04#
API consistency cleanup + documentation overhaul + tag-triggered release infrastructure. Compare against the prior tag: v0.20.2…v0.21.0.
Added#
Documentation overhaul (`#583 <https://github.com/femorph/solver/issues/583>`_). Multi-week push to bring documentation up to commercial-solver quality ahead of the public release.
Verification corpus. MAPDL Verification Manual coverage driven by the #511 tracker — VM6 (pinched cylinder) and VM10 (T-section beam) added under the shared verification harness.
Interop coverage.
ETKEYOPT slot recognition for PLANE182 / BEAM188 (#607); CSYS,1 cylindrical coordinates with NSEL / DSYM / D,ALL / F,ALL (#588, #602).
Changed#
API consistency cleanup (`#750 <https://github.com/femorph/solver/issues/750>`_). Thirteen PRs that close the long tail of API / docs / module-naming gaps the v0.20 release surfaced. All renames ship a deprecation alias for one minor release; the next minor drops them.
Solve-method renames (#764). Every analysis driver now reads
solve_<analysis>:Model.solve(...) → Model.solve_static(...) Model.modal_solve(...) → Model.solve_modal(...) Model.transient_solve(...) → Model.solve_transient(...) Model.harmonic_solve(...) → Model.solve_harmonic(...) CyclicModel.modal_solve(...) → CyclicModel.solve_modal(...) solve_harmonic_modal(...) → solve_harmonic(...) solve_cyclic_modal(...) → solve_cyclic(...)
Kwarg consistency. Every
Model.*_solvenow accepts the same set of common kwargs (progress,thread_limit,release_inputs,mixed_precision,linear_solver).CyclicModel.solve_modalgainslumped(#762). The cyclic side’seigensolver=is renamed toeigen_solver=to match the rest of the modal-family API; defaults are aligned to"auto"everywhere (#754).Result types re-exported from the top level (#753):
from femorph_solver import ModalResult, ModalResultDisk, readis now the canonical import. Frozen Result dataclasses (#759).Module renames (drop false-private prefix on documented public types):
_cyclic_model.py→cyclic_model.py(#756),_labels.py→labels.py(#765).Factory parity:
Model.from_cdbmirrorsCyclicModel.from_cdb(#758).Doctest gating expanded from one module to thirteen so docstring
Examplesblocks acrossModel,CyclicModel, the result hierarchy, and the solver functions are now CI-tested (#763).
Pre-existing illustrative
>>>blocks infemorph_solver.Modeldocstrings (save,from_lines,apply_force) rewritten as runnable doctests using the bundledcyclic_bladed_rotor_sectorfixture.
Deprecated#
All pre-PR-K solve method + function names continue to work with a
DeprecationWarning; removed in the next minor release.
Fixed#
Three cyclic gallery examples and
tutorial_06_cdb_to_resultsno longer crash for users walking the docs verbatim (#752).T-sectionSECTYPEthickness convention bug (#576).PBAR / PBEAM
I1/I2swap on non-canonical NASTRAN decks (#573).Drilling-DOF false alarm on FV4 — turned out to be
n_modesconfiguration, not a kernel bug (#567).
v0.20.2 — 2026-04-25#
Documentation green-build patch. Compare against the prior tag: v0.20.1…v0.20.2.
Fixed#
Changed#
v0.20.1 — 2026-04-25#
CI / verification follow-up release. Compare against the prior tag: v0.20.0…v0.20.1.
Added#
Changed#
Fixed#
v0.20.0 — 2026-04-25#
First milestone tag of the public-release cadence. Compare against the project’s git history: everything before v0.20.0.
This tag captures the state of femorph-solver after the four-phase landing of the public-API + verification-corpus build-out:
Added#
Public
femorph_solver.ModelAPI with the full set of solve verbs (solve,modal_solve,harmonic_solve,transient_solve,cyclic_modal_solve). Note:Model.cyclic_modal_solvewas removed in v0.20.x; usesolve_modal()instead.Disk-backed result hierarchy (
StaticResult,ModalResult,TransientResult,HarmonicResultDisk,CyclicModalResult) with lazy.pvIO viapyvista-zstd. Note: the disk-backed classes were renamed in v0.20.x toStaticResultDisk/ModalResultDisk/TransientResultDisk/CyclicModalResultDiskto disambiguate from the in-memory dataclasses returned by the solve methods.Element kernels for HEX8, HEX20, TET10, WEDGE15, PYR13, BEAM2, TRUSS2, QUAD4 (plane + shell), POINT_MASS, SPRING — independently derived from public FEM textbooks; sourcing tracked under Provenance inventory.
Pluggable solver backends: Pardiso / CHOLMOD / MUMPS / UMFPACK / SuperLU (linear); ARPACK / LOBPCG / PRIMME / dense LAPACK (eigen). Auto-dispatch picks the fastest available SPD direct solver.
Foreign-deck import readers under
femorph_solver.interop: NASTRAN BDF, Abaqus INP, MAPDL CDB, OptiStruct FEM. Import-only — the resultingModelis identical to one built natively.Multi-version documentation site driven by
sphinx-multiversionwith a version switcher across everyv*tag (#392).User-guide tutorials covering cantilever combined loading, modal survey, pressure-vessel DBA, and cyclic-symmetry rotor design (#561–#569).
Cross-vendor terminology Rosetta and per-vendor migration deep-dives for MAPDL, NASTRAN, Abaqus, and LS-DYNA (#566–#574).
Changed#
mapdl_apire-homed underfemorph_solver.interop.mapdl. The legacy import path remains for one release with aDeprecationWarning.
Removed#
Pre-v0.20.0 history#
The project’s pre-tag history (the first eight months of
development) lived on main without formal releases — feature
branches landed via PR, with verification-coverage and CI-quality
gates as the de-facto release criteria. See the GitHub commit
history for the
detailed log.
How this page is maintained#
New entries go under Unreleased as work lands. When a tag is cut, the maintainer renames the
Unreleasedheading to the new version and date and starts a freshUnreleasedblock.PRs that warrant a changelog entry should propose one in their description; the merging maintainer copies it across. Pure test or CI churn (anything labelled
ci-failure-*or whose scope istest:/ci:) is excluded by default.The
release-readiness.ymlworkflow surfaces missing changelog entries on a PR’s checks page so the gap is visible before merge.