Repository navigation
Keep restrained DOFs fixed across solves; fix discretize() q-loads - #491
Open
mitchell-tesch wants to merge 2 commits into
Open
mitchell-tesch wants to merge 2 commits into
mitchell-tesch wants to merge 2 commits into
Conversation
process_conditions() treated every DOF whose entry in system_displacement_vector is exactly 0 as restrained. After a solve that vector holds the solution, so a free DOF that happened to be 0 (e.g. the transverse DOFs of a member under axial load only) became a support on the next solve. The restrained DOFs are now recorded once in process_supports(). discretize() re-applied a q-load with its components swapped and only to the first sub-element. It now splits the load of each element over all of its sub-elements, as insert_node() does. Together these made solve(geometrical_non_linear=True, discretize_kwargs=...) fail with a shape mismatch for horizontal members. The docs now state that discretize_kwargs only applies to the buckling factor, as the solve() docstring already does.
The docs recommended discretize_kwargs as if it refined the whole second order calculation. It only divides a copy of the model used for the buckling factor (as the solve() docstring says), so the second order moments within a member were silently first order. Recommend dividing the model itself, and describe discretize_kwargs as buckling factor only.
mitchell-tesch
marked this pull request as ready for review
November 3, 2026 05:29
This was referenced Nov 3, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
While testing the geometrical non-linear solver, I found that
solve(geometrical_non_linear=True, discretize_kwargs=dict(n=20)), as shown in the docs, fails for a horizontal member with:That came from two separate bugs.
1. Solving a model a second time can give wrong results. This affects plain linear analysis too:
process_conditions()treats any DOF that's exactly 0 insystem_displacement_vectoras a support. After a solve, that vectorholds the results, so any free DOF that happened to come out as 0 (here, every vertical displacement and rotation) is locked on the next solve. The non-linear solver always solves more than once, so it runs into this every time.
The fix records the restrained DOFs once in
process_supports(), andprocess_conditions()uses that record.2. discretize() loses distributed loads. It re-applies each q-load with its two components swapped, and only to the first sub-element. It now splits each element's load over all of its sub-elements, the same way
insert_node()already does.Docs (second commit). The docs recommend
discretize_kwargsas if it refines the whole second-order calculation. It only meshes a copy of the model that's used for the buckling factor (thesolve()docstring says this), so the moments within a single-element member stay first order. I caught myself out with this. The docs now suggestss.discretize(n)onthe model itself, and describe
discretize_kwargsas affecting the buckling factor only.Tests
tests/test_resolve_and_discretize.pychecks that a re-solved model matches a fresh one. It also checks that the reactions afterdiscretize()match the original model for uniform, varying and inclined loads. All four tests fail on master. black, mypy, pylint and pytest pass locally.This PR doesn't depend on #490, and they merge cleanly together. With both applied,
discretize_kwargsgives the Euler load for the column inexamples/ex_18_discretize.py(493.48 withn=15, against 600 without).A question
Would you like
discretize_kwargsto also apply to the second-order results, or to be deprecated in favour ofss.discretize()? I've left the behaviour as it is and only corrected the docs, but I'm happy tofollow up either way.