All notable changes to ospgrillage are documented here. The format follows Keep a Changelog and the project adheres to Semantic Versioning.
- Interactive Plotly backend for
plot_bmd(),plot_sfd(), andplot_def(): passbackend="plotly"for 3D rotation, zoom, and hover in Jupyter notebooks and browser windows. Plotly is bundled in theguiextra (pip install ospgrillage[gui]). LoadVertexnamedtuple — the preferred name for the coordinate+magnitude tuple that defines where a load acts and how much.LoadPointis retained as a backwards-compatible alias.GrillageMember.sectionand.materialread-only properties.Mesh.orthogonalattribute (was missing; code paths that checked it would raiseAttributeErroron oblique meshes).beam_z_spacing→beam_widthdeprecation shim increate_grillage(): the old name now emitsDeprecationWarningand maps correctly instead of being silently ignored.Section(E=…)/Section(G=…)now raiseValueErrorwith a clear message (elastic moduli belong onMaterial, notSection).- Plotting keyword arguments for all plotting functions (
plot_force,plot_defo,plot_bmd,plot_sfd,plot_def):figsize,ax(existing matplotlib Axes),scale,title,color,fill,alpha, andshow. Plotly equivalents (fig,figsize,scale,title,alpha) are forwarded through convenience wrappers. plot_model()function for visualising grillage mesh geometry withbackend="matplotlib"(2-D plan view) andbackend="plotly"(interactive 3-D). Replacesog.opsv.plot_model()andog.opsplt.plot_model().- 5 new Plotly tests, 8 new plotting-kwargs tests, 5 new plot_model tests, plus
tests for
beam_z_spacing,Section(E=),GrillageMemberproperties, andMesh.orthogonal.
vfois no longer a required dependency. It is still accessible viaog.opsplt(with a deprecation warning) if installed, butpip install ospgrillageno longer pulls it in. Useog.plot_model()instead.og.opsvandog.opspltre-exports now emitDeprecationWarning. Useog.plot_model()for mesh visualisation.plot_deflectionrenamed toplot_def(consistent withplot_bmd/plot_sfd).- Documentation restructured:
performing_analysis.mdsplit intodefining_loads.md(load types, compound loads, load cases, moving loads) and the "Running analysis" section merged intogetting_results.md(now titled "Analysis and results"). - All docs code examples updated to use
LoadVertexinstead ofLoadPoint. - 15+ documentation content fixes: removed non-existent
set_material()reference, correctedlink_nodes_width→beam_width,NodalForce→NodeForces,type=→loadtype=, duplicate member assignments, missing Sphinx cross-references, and sparse pages. - Added missing methods to API reference:
set_spring_support,set_previous_state,store_state,parse_moving_load_cases.
- GUI code generation:
set_member()calls wrotemember=interior_main_beam(unquoted) instead ofmember="interior_main_beam". - Removed stale
html_static_pathandhtml_theme_pathfrom Sphinxconf.py(referenced non-existent_static/and_themes/directories, causing build warnings).
LoadPoint— useLoadVertexinstead.LoadPointremains as an alias and existing code is unaffected.
- 30 new tests across
test_load.py,test_material.py,test_member.py, and the newtest_ospgui.py; overall coverage rises from 71 % to 75 %. test_ospgui.py: new test module verifying the PyQt5-absent import guard and gracefulmain()exit.
- Minimum supported Python version raised from 3.9 to 3.10, allowing use of
PEP 604
X | Yunion-type syntax throughout the codebase. Note: Python 3.9 reached end-of-life in October 2025. - Sphinx documentation source converted from reStructuredText to Markdown using
MyST-Parser;
myst-parseradded to the docs-build dependency list. _OpsProxydual-mode dispatch pattern: a thin proxy around OpenSeesPy that either executes commands live or serialises them to a.tcl/.pyscript file, controlled by a singlepy_fileflag oncreate_grillage._OpsProxy._dispatch(call)helper that routes pre-built(name, args, kwargs)tuples through the proxy, eliminating alleval()in the analysis path.- Load assignment pipeline refactored from format-string building to
(func_name, args, kwargs)tuples throughout_assign_load_to_four_node(),_distribute_load_types_to_model(),Analysis._time_series_command(), andAnalysis._pattern_command();evaluate_analysis()dispatches via_dispatch(). Envelope.get()now usesgetattr(da, self.selected_xarray_command)(dim="Loadcase")instead ofeval(); the dead format-string infrastructure inEnvelope.__init__has been removed.ospgui.pylog output converted fromprint()tologging.getLogger(__name__).- NumPy-style docstrings added to all public functions and classes across every
source module (
osp_grillage.py,load.py,mesh.py,members.py,utils.py,postprocessing.py). sphinx_autodoc_typehintsadded to Sphinx extension list so type annotations are rendered automatically in the HTML docs.
- Nine dead command-string attributes from
Analysis.__init__that became obsolete after the proxy refactor (wipe_command,numberer_command,system_command,constraint_command,algorithm_command,analyze_command,analysis_command,intergrator_command,sensitivity_integrator_command,remove_pattern_command). - Dead
analysis_argumentsdict fromAnalysis.__init__. - Unused
scipy.interpolateimports frompostprocessing.py. - Five orphaned RST stub pages that referenced non-existent autodoc targets
(
Analysis.rst,Material.rst,Loads.rst,GrillageMember.rst,OpsGrillage.rst).
Loads.get_magnitude()crashed withAttributeErroronNoneitems inpoint_list; now skips undefined load points.ospguicrashed on import withModuleNotFoundError: No module named 'PyQt5'in environments without the optional GUI dependency; now exits gracefully with an actionable error message._OpsProxystr | Noneannotation causedTypeErroron Python ≤ 3.9 at import time (resolved by the Python 3.10 minimum bump).- Compound
NodalLoadbug in_distribute_load_types_to_model()whereload_str += stringwas spreading individual characters into the list; now correctly appends a single tuple. PatchLoadingcyclic-rotation-aware vertex validation via_is_cyclic_rotation()helper: any valid starting point of the CCW polygon is now accepted.NodalLoad.get_nodal_load_call()returning a structured tuple instead of a raw command string.stitch_slab_x_spacingtypo corrected throughoutospgui.py(wasstich).- Docs build workflow now installs
myst-parser;sphinx_docs_to_gh_pages.ymlmodernised to usepeaceiris/actions-gh-pages@v4.
- Documentation navigation restructured into four top-level sections: Getting Started, User Guide, API Reference, and Additional Resources.
- API reference split into per-module pages (Grillage, Material, Members, Load, Mesh, PostProcessing); Load module further subdivided into load types, load cases, and moving loads.
- All documentation source files renamed to match their page titles
(e.g.
Module_description.md→creating_grillage_models.md); source folder renamedrst/→pages/. - Pandoc conversion artefacts removed throughout: escaped characters in prose
(
\',\",\_), malformed MyST/RST directives, broken internal anchors, and Pandoc grid tables converted to GFM pipe tables. - Docstrings improved for
PatchLoading,LoadCase,CompoundLoad, andOspGrillage(full:param:/:raises:fields; NumPyAttributessection rewritten as plain prose to avoid raw-text rendering without Napoleon). - Getting Results page rewritten with an xarray concept overview, a summary
table of data variables, and annotated
.sel()/.isel()examples. - Contributing guidelines page added via MyST
{include}of rootCONTRIBUTING.md(single source of truth). - JOSS citation added to the front page and Additional Resources.
- Jupyter example notebooks cleaned up: version-output cells and trailing empty cells removed from all four notebooks.
- GUI-based geometry generator (
ospgui) for interactive model creation without writing Python code (#128).
- NumPy 2 and upstream dependency compatibility issues (#126).
- GitHub Pages deployment workflow (#109).
- Replaced deprecated
openseespyvisvisualisation back-end withvfo(#74). - Mass and displacement interpolator updated (#72).
- Code reformatted with
black(#73).
- Plot module errors following the
vfomigration (#107).
- Package metadata migrated from
setup.cfgto PEP 621pyproject.toml. - Documentation build fixed for
src-layout packages.
- Multi-span orthogonal meshing feature.
- Refined member assignment:
set_member()now supports per-group overrides for common grillage elements with multiple groups. - Rotational spring support via a dedicated
Materialtype backed by OpenSeesPy'szeroLengthelement.
- Minor paper / citation tweaks; dependency version pins.
- Multi-span meshing: intermediate edge construction lines and stitch elements between spans.
- Curve-mesh support: sweep path can now follow a curved line.
- Custom transverse member spacings for oblique meshes.
- Example Jupyter notebooks restructured under
docs/source/notebooks/.
- Miscellaneous bug fixes and documentation corrections following initial release.
- Initial public release.
- Beam-only, beam-with-rigid-links, and shell-beam hybrid model types.
- Orthogonal and oblique meshing algorithms.
- Full load suite:
PointLoad,LineLoading,PatchLoading,NodalLoad,CompoundLoad,MovingLoad. LoadCase,LoadModel, andPathhelpers.EnvelopeandPostProcessorpost-processing utilities.- Sphinx documentation published to GitHub Pages.