Repository navigation
Fix geometrically non-linear analysis - #490
Open
mitchell-tesch wants to merge 3 commits into
Open
mitchell-tesch wants to merge 3 commits into
mitchell-tesch wants to merge 3 commits into
Conversation
geometric_stiffness_matrix converted the reference (y-up) matrix to anastruct's y convention by flipping the y columns only. A change of DOF sign must be applied to rows and columns; flipping the columns alone negated the transverse terms, so in solve(geometrical_non_linear=True) axial compression stiffened elements and tension softened them. Also fixes row 4 (s1 * c2 -> s2 * c2), so node 2's forces are the negatives of node 1's.
det_linear_buckling replaced scipy.linalg.eigvals(k0, kg) with np.linalg.inv(kg) * k0. That is an element-wise product, and kg is singular for beam elements (no geometric stiffness on the axial DOFs), so every horizontal member raised LinAlgError: Singular matrix and other members returned wrong factors. Solve (k0 + lambda kg) x = 0 through the eigenvalues mu of inv(k0) kg, with lambda = -1/mu, and return the smallest positive lambda, or inf when nothing is in compression. Still numpy only.
Author
|
I also have a small follow-up that speeds up validate() and the buckling solve using symmetric eigen-solvers (~2× faster second-order solves on larger models). I'll open it once this is merged. |
det_linear_buckling assembled k0 + kg with a full solve(). Once the loads exceed the buckling load that matrix is no longer positive definite, so validate() rejected it with a StabilityError and no factor could be reported. Only the assembled matrix is needed, so build it with solve(naked=True). A member at 1.2 N_cr now reports a factor of 0.833.
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.
I was trying out
solve(geometrical_non_linear=True)on a simple beam and it raisedLinAlgError: Singular matrix:There turned out to be three bugs, one per commit.
1. The buckling eigen-solve. #138 replaced
scipy.linalg.eigvals(k0, kg)withnp.linalg.inv(kg) * k0.kgis always singular for beam elements (it has no axial terms), and*is an element-wise product rather than a matrix product. I've changed it to take the eigenvalues ofnp.linalg.solve(k0, kg)instead, which never invertskgand still only needs numpy. One small behaviour change: a structure with nothing in compression now gets a buckling factor ofinf. Before, theabs()gave it a finite number.2. The sign of the geometric stiffness matrix. Once the solve ran, compression was reducing the moments and tension was increasing them.
geometric_stiffness_matrixconverts the matrix from Gavin's notes (linked in the code, y up) to anaStruct's y direction by multiplying by[1, -1, 1, 1, -1, 1]. That only flips the columns; it needs to flip the rows as well, so it's now annp.outerof that vector with itself. I also fixed a typo in row 4 (s1 * c2should bes2 * c2).3. Buckling factors below 1.
det_linear_bucklingbuildsk0 + kgwith a secondsolve(). When the loads are already beyond the buckling load, that matrix is no longer positive definite, sovalidate()rejected it with aStabilityError("Check your support conditions") and no factor was returned. Only the assembled matrix is needed, so it's now built withsolve(naked=True). A member at 1.2 N_cr reports a factor of 0.833 (test_buckling_factor_below_one_is_reported, horizontal and vertical).Results
For the beam above (6 m, EI = 1810 kNm², 5 kN/m, 20 elements), compared with the closed-form beam-column solution:
On master all three raise. The existing buckling test for example 18 (a vertical column,
tests/test_e2e.py) still passes with a factor of 600.The new tests cover the matrix itself (
tests/test_geometric_stiffness.py) and the closed-form cases above for horizontal and vertical members (tests/test_geometrical_non_linear.py). black, mypy, pylint and pytest all pass locally.A member with no transverse load, or using
discretize_kwargs, still fails because of a separate bug, which I've fixed in #491. I also noticed #482 covers this as part of a much larger change. This is just the minimal fix, in case it's easier to review on its own.