Skip to content

Fix COMPAS 1.x API calls that raise under COMPAS 2.x - #143

Open
mjqm1979 wants to merge 1 commit into
BlockResearchGroup:mainfrom
mjqm1979:fix/compas2-api
Open

Fix COMPAS 1.x API calls that raise under COMPAS 2.x#143
mjqm1979 wants to merge 1 commit into
BlockResearchGroup:mainfrom
mjqm1979:fix/compas2-api

Conversation

@mjqm1979

Copy link
Copy Markdown

Under COMPAS 2.x (tested with 2.15.1), the constraints / Newton / nullspace code paths in compas_ags.ags raise immediately, because a few call sites still use the pre-2.x API.

Reproduce

With COMPAS 2.15.1 and current main:

import compas_ags
from compas_ags.ags import ConstraintsCollection
from compas_ags.diagrams import FormDiagram, FormGraph

graph = FormGraph.from_obj(compas_ags.get("paper/gs_form_force.obj"))
form = FormDiagram.from_graph(graph)

C = ConstraintsCollection(form)
C.constraints_from_form()
# TypeError: edge_length() takes 2 positional arguments but 3 were given

form_compute_nullspace() and form_update_from_force_newton() fail the same way. scripts/example_nullspace.py and scripts/example_fix_x.py cannot run on main as a result.

Changes

ags/core.pyforce.key_index() and form.key_index() become vertex_index(). key_index() no longer exists in COMPAS 2.x, so compute_jacobian() and get_jacobian_and_residual() raise AttributeError.

ags/constraints.pyedge_length(*self.edge) and edge_coordinates(*self.edge) now pass the edge tuple as a single argument, which is the COMPAS 2.x signature. This is what breaks LengthFix, and therefore constraints_from_form().

ags/graphstatics.pyupdate_diagrams_from_constraints() takes a kmax parameter but did not forward it to its force_update_from_constraints() call, so that step always ran with the default of 100 parallelisation iterations no matter what the caller asked for. Measured with max_iter=20, kmax=20 on the paper diagrams:

diagram before after
gs_form_force (7v/7e) 125 ms 90 ms
exD_truss (17v/21e) 344 ms 261 ms
exE_truss_dense (32v/41e) 691 ms 520 ms

ags/__init__.py — export form_compute_nullspace and force_update_from_form_geometrical. Both are defined in graphstatics.py but were not re-exported; scripts/example_nullspace.py imports the former from compas_ags.ags and fails on import.

Test

tests/test_ags_compas2_api.py covers the three affected entry points. All three fail on main (TypeError/AttributeError) and pass with this change.

The fixtures use paper/gs_form_force.obj rather than paper/gs_arch.json, because the latter is a COMPAS 0.17.2-era serialization that FormGraph.from_json can no longer reconstruct under COMPAS 2.x. That looked like a separate issue, so I left it alone here.

key_index/index_vertex were renamed to vertex_index; edge_length and
edge_coordinates now take a single edge tuple instead of two positional
vertex keys. These broke the entire constraints/Newton/nullspace path
(ConstraintsCollection.constraints_from_form, form_compute_nullspace,
form_update_from_force_newton) under compas 2.15.1.

Also: force_update_from_constraints() inside update_diagrams_from_constraints
wasn't forwarding kmax, so it always solved with the default of 100
iterations regardless of the caller's setting. And export
form_compute_nullspace/force_update_from_form_geometrical from
compas_ags.ags, where they were missing.

Added tests/test_ags_compas2_api.py to guard the fixed code paths.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
mjqm1979 added a commit to mjqm1979/compas_ags that referenced this pull request Jul 30, 2026
Drops the graphstatics.py index_vertex() change: verified that the method
does exist on Diagram and works, so the replacement was equivalent code
resting on a wrong premise. Also removes a docstring reference to a file
in a separate private repo, and narrows the changelog entry to the calls
that actually raise.

No functional change; matches BlockResearchGroup#143.
@mjqm1979

Copy link
Copy Markdown
Author

A bit of context I should have put up front, plus the template checklist I skipped by creating this through the CLI.

Context. I'm an architect, not a structural engineer — I ran into these while building a Rhino plugin on top of compas_ags. The code was written with AI assistance (Claude Code). I mention both so you can weight the contribution accordingly, and because I'd rather you check the evidence than take my word for it: the three tests fail on main with TypeError/AttributeError and pass with this change.

The API fixes (key_indexvertex_index, and the edge_length/edge_coordinates signatures) are mechanical migrations where the tests speak for themselves.

The kmax change is the one worth scrutinising. I've asserted it's an oversight because the two sibling calls in the same loop — form_update_from_force and force_update_from_form_geometrical — already forward kmax, which makes the third one look inconsistent rather than deliberate. But if that step was in fact meant to always run at the default 100 regardless of what the caller asks for, then my change alters intended behaviour and should be dropped. I have no basis to judge whether the convergence of that particular parallelisation step matters more than the other two; you would.

Checklist

  • CHANGELOG.md entry under Unreleased
  • Tests run green — with the caveat that I ran tests/test_dummy.py and the new file directly, not via invoke test: pytest and invoke aren't installed in the Python environment I have compas_ags running in (Rhino 8's CPython 3.9 venv). CI here will be the real check.
  • Lint clean on this branch (ruff check src tests, black --check src tests)
  • New functions made available on a second-level import (form_compute_nullspace, force_update_from_form_geometrical on compas_ags.ags)
  • Tests added that prove the fix is effective
  • Documentation — none seemed needed; happy to add if you disagree

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant