structsolve 0.8.0__tar.gz → 0.9.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {structsolve-0.8.0/structsolve.egg-info → structsolve-0.9.1}/PKG-INFO +15 -11
- {structsolve-0.8.0 → structsolve-0.9.1}/README.md +9 -4
- {structsolve-0.8.0 → structsolve-0.9.1}/pyproject.toml +8 -8
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve/analysis.py +145 -68
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve/arc_length.py +166 -38
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve/arc_length_crisfield.py +12 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve/arc_length_riks.py +11 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve/arpackutils.py +220 -38
- structsolve-0.9.1/structsolve/callbacks.py +278 -0
- structsolve-0.9.1/structsolve/convergence.py +345 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve/freq.py +151 -76
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve/linear_buckling.py +723 -133
- structsolve-0.9.1/structsolve/logger.py +87 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve/newton_raphson.py +254 -61
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve/sparseutils.py +61 -5
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve/static.py +31 -2
- {structsolve-0.8.0 → structsolve-0.9.1/structsolve.egg-info}/PKG-INFO +15 -11
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve.egg-info/SOURCES.txt +1 -0
- structsolve-0.9.1/tests/test_analysis.py +147 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/tests/test_arc_length.py +89 -2
- {structsolve-0.8.0 → structsolve-0.9.1}/tests/test_arpackutils.py +47 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/tests/test_follower_freq_static.py +8 -10
- structsolve-0.9.1/tests/test_freq.py +298 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/tests/test_linear_buckling.py +194 -1
- {structsolve-0.8.0 → structsolve-0.9.1}/tests/test_linear_buckling_unsymmetric.py +161 -10
- {structsolve-0.8.0 → structsolve-0.9.1}/tests/test_load_factor_dependent_load.py +8 -6
- {structsolve-0.8.0 → structsolve-0.9.1}/tests/test_newton_raphson.py +113 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/tests/test_sparseutils.py +41 -0
- structsolve-0.9.1/tests/test_static.py +129 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/tests/test_static_deflection.py +1 -4
- structsolve-0.8.0/structsolve/callbacks.py +0 -160
- structsolve-0.8.0/structsolve/logger.py +0 -72
- structsolve-0.8.0/tests/test_analysis.py +0 -73
- structsolve-0.8.0/tests/test_freq.py +0 -88
- structsolve-0.8.0/tests/test_static.py +0 -63
- {structsolve-0.8.0 → structsolve-0.9.1}/LICENSE +0 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/setup.cfg +0 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve/__init__.py +0 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve.egg-info/dependency_links.txt +0 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve.egg-info/requires.txt +0 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/structsolve.egg-info/top_level.txt +0 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/tests/test_follower_loads.py +0 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/tests/test_reuse.py +0 -0
- {structsolve-0.8.0 → structsolve-0.9.1}/tests/test_sparse_first.py +0 -0
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: structsolve
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.1
|
|
4
4
|
Summary: Structural analysis solvers
|
|
5
5
|
Author-email: "Saullo G. P. Castro" <castrosaullo@gmail.com>
|
|
6
|
-
License: BSD-
|
|
7
|
-
Project-URL: Homepage, https://github.com/
|
|
8
|
-
Project-URL:
|
|
6
|
+
License-Expression: BSD-3-Clause
|
|
7
|
+
Project-URL: Homepage, https://github.com/saullocastro/structsolve
|
|
8
|
+
Project-URL: Documentation, https://saullocastro.github.io/structsolve/
|
|
9
|
+
Project-URL: Repository, https://github.com/saullocastro/structsolve
|
|
9
10
|
Keywords: structural analysis,stress,vibration,linear buckling,newton raphson,arc length
|
|
10
11
|
Classifier: Development Status :: 4 - Beta
|
|
11
12
|
Classifier: Intended Audience :: Science/Research
|
|
12
13
|
Classifier: Intended Audience :: Developers
|
|
13
14
|
Classifier: Intended Audience :: Education
|
|
14
15
|
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
15
|
-
Classifier: License :: OSI Approved :: BSD License
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -22,7 +21,7 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
22
21
|
Classifier: Operating System :: Microsoft :: Windows
|
|
23
22
|
Classifier: Operating System :: Unix
|
|
24
23
|
Classifier: Environment :: WebAssembly :: Emscripten
|
|
25
|
-
Requires-Python: >=3.
|
|
24
|
+
Requires-Python: >=3.10
|
|
26
25
|
Description-Content-Type: text/markdown
|
|
27
26
|
License-File: LICENSE
|
|
28
27
|
Requires-Dist: numpy
|
|
@@ -57,15 +56,14 @@ Structural analysis solvers tailored for semi-analytical models
|
|
|
57
56
|
- Load vectors that depend on the load factor, e.g. prescribed displacements
|
|
58
57
|
imposed exactly as linear constraints
|
|
59
58
|
|
|
60
|
-
Currently these solvers are pretty much compatible with my other
|
|
61
|
-
[panels](https://github.com/saullocastro/panels)
|
|
62
|
-
[buckling](https://github.com/saullocastro/buckling).
|
|
59
|
+
Currently these solvers are pretty much compatible with my other repository
|
|
60
|
+
[panels](https://github.com/saullocastro/panels).
|
|
63
61
|
|
|
64
62
|
|
|
65
63
|
Citing this library
|
|
66
64
|
===================
|
|
67
65
|
|
|
68
|
-
Saullo G. P. Castro (2026). Structural analysis solvers tailored for semi-analytical models (Version 0.
|
|
66
|
+
Saullo G. P. Castro (2026). Structural analysis solvers tailored for semi-analytical models (Version 0.9.1). Zenodo. DOI: https://doi.org/10.5281/zenodo.2581212.
|
|
69
67
|
|
|
70
68
|
|
|
71
69
|
Documentation
|
|
@@ -80,6 +78,12 @@ History
|
|
|
80
78
|
|
|
81
79
|
See [CHANGELOG.md](CHANGELOG.md) for the details of each version.
|
|
82
80
|
|
|
81
|
+
* version 0.9.1 (2026-10-24)
|
|
82
|
+
- documentation published again: pandoc installed in the documentation workflow
|
|
83
|
+
* version 0.9.0 (2026-10-24)
|
|
84
|
+
- Crisfield's convergence criterion is the default of the non-linear analyses, `Analysis.convergence = 'crisfield'`, with `relTOL = 1e-9`: the residual and the reference forces are measured with the norm scaled by the diagonal of `calc_kC()` over the free degrees of freedom; the former check is kept with `convergence = 'relative'`
|
|
85
|
+
- `lb` returns the negative load multipliers closest to zero after the positive ones, and a tensile reference load no longer needs the dense fallback
|
|
86
|
+
- `freq(sort=True)` sorts and filters `lambda2` together with the eigenvectors, and rigid-body modes no longer fail the verification of the residuals
|
|
83
87
|
* version 0.8.0 (2026-10-14)
|
|
84
88
|
- Fewer evaluations and factorizations, same solutions: `dR/dlbd` is evaluated together with the tangent stiffness matrix only, Newton-Raphson reuses the factorization of the tangent while it is not updated, the follower linear static analysis factorizes `K0` once, and `lb` estimates its shift and the inertia of `K` once for all its attempts
|
|
85
89
|
* version 0.7.0 (2026-10-13)
|
|
@@ -21,15 +21,14 @@ Structural analysis solvers tailored for semi-analytical models
|
|
|
21
21
|
- Load vectors that depend on the load factor, e.g. prescribed displacements
|
|
22
22
|
imposed exactly as linear constraints
|
|
23
23
|
|
|
24
|
-
Currently these solvers are pretty much compatible with my other
|
|
25
|
-
[panels](https://github.com/saullocastro/panels)
|
|
26
|
-
[buckling](https://github.com/saullocastro/buckling).
|
|
24
|
+
Currently these solvers are pretty much compatible with my other repository
|
|
25
|
+
[panels](https://github.com/saullocastro/panels).
|
|
27
26
|
|
|
28
27
|
|
|
29
28
|
Citing this library
|
|
30
29
|
===================
|
|
31
30
|
|
|
32
|
-
Saullo G. P. Castro (2026). Structural analysis solvers tailored for semi-analytical models (Version 0.
|
|
31
|
+
Saullo G. P. Castro (2026). Structural analysis solvers tailored for semi-analytical models (Version 0.9.1). Zenodo. DOI: https://doi.org/10.5281/zenodo.2581212.
|
|
33
32
|
|
|
34
33
|
|
|
35
34
|
Documentation
|
|
@@ -44,6 +43,12 @@ History
|
|
|
44
43
|
|
|
45
44
|
See [CHANGELOG.md](CHANGELOG.md) for the details of each version.
|
|
46
45
|
|
|
46
|
+
* version 0.9.1 (2026-10-24)
|
|
47
|
+
- documentation published again: pandoc installed in the documentation workflow
|
|
48
|
+
* version 0.9.0 (2026-10-24)
|
|
49
|
+
- Crisfield's convergence criterion is the default of the non-linear analyses, `Analysis.convergence = 'crisfield'`, with `relTOL = 1e-9`: the residual and the reference forces are measured with the norm scaled by the diagonal of `calc_kC()` over the free degrees of freedom; the former check is kept with `convergence = 'relative'`
|
|
50
|
+
- `lb` returns the negative load multipliers closest to zero after the positive ones, and a tensile reference load no longer needs the dense fallback
|
|
51
|
+
- `freq(sort=True)` sorts and filters `lambda2` together with the eigenvectors, and rigid-body modes no longer fail the verification of the residuals
|
|
47
52
|
* version 0.8.0 (2026-10-14)
|
|
48
53
|
- Fewer evaluations and factorizations, same solutions: `dR/dlbd` is evaluated together with the tangent stiffness matrix only, Newton-Raphson reuses the factorization of the tangent while it is not updated, the follower linear static analysis factorizes `K0` once, and `lb` estimates its shift and the inertia of `K` once for all its attempts
|
|
49
54
|
* version 0.7.0 (2026-10-13)
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools>=
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "structsolve"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.9.1"
|
|
8
8
|
description = "Structural analysis solvers"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
license =
|
|
11
|
-
|
|
10
|
+
license = "BSD-3-Clause"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
requires-python = ">=3.10"
|
|
12
13
|
authors = [
|
|
13
14
|
{ name = "Saullo G. P. Castro", email = "castrosaullo@gmail.com" },
|
|
14
15
|
]
|
|
@@ -22,8 +23,6 @@ classifiers = [
|
|
|
22
23
|
"Intended Audience :: Developers",
|
|
23
24
|
"Intended Audience :: Education",
|
|
24
25
|
"Topic :: Scientific/Engineering :: Mathematics",
|
|
25
|
-
"License :: OSI Approved :: BSD License",
|
|
26
|
-
"Programming Language :: Python :: 3.9",
|
|
27
26
|
"Programming Language :: Python :: 3.10",
|
|
28
27
|
"Programming Language :: Python :: 3.11",
|
|
29
28
|
"Programming Language :: Python :: 3.12",
|
|
@@ -47,8 +46,9 @@ test = [
|
|
|
47
46
|
]
|
|
48
47
|
|
|
49
48
|
[project.urls]
|
|
50
|
-
Homepage = "https://github.com/
|
|
51
|
-
|
|
49
|
+
Homepage = "https://github.com/saullocastro/structsolve"
|
|
50
|
+
Documentation = "https://saullocastro.github.io/structsolve/"
|
|
51
|
+
Repository = "https://github.com/saullocastro/structsolve"
|
|
52
52
|
|
|
53
53
|
[tool.setuptools.packages.find]
|
|
54
54
|
include = ["structsolve*"]
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
"""Static analyses of a model given by callables (:class:`Analysis`)
|
|
2
|
+
|
|
3
|
+
The class :class:`Analysis` receives the callables that compute the force
|
|
4
|
+
vectors and the stiffness matrices of a model and runs a linear static
|
|
5
|
+
analysis, or a non-linear static analysis with the Newton-Raphson solver of
|
|
6
|
+
:mod:`.newton_raphson` or the arc-length solvers of :mod:`.arc_length`. The
|
|
7
|
+
optional keyword arguments of the callables are described in
|
|
8
|
+
:mod:`.callbacks`.
|
|
9
|
+
|
|
10
|
+
"""
|
|
1
11
|
from __future__ import absolute_import
|
|
2
12
|
|
|
3
13
|
import numpy as np
|
|
@@ -5,7 +15,7 @@ import numpy as np
|
|
|
5
15
|
from .static import solve, _factorize
|
|
6
16
|
from .logger import msg, warn
|
|
7
17
|
from . import callbacks
|
|
8
|
-
from .newton_raphson import _check_convergence
|
|
18
|
+
from .newton_raphson import _check_convergence, _weights
|
|
9
19
|
from .newton_raphson import _solver_NR
|
|
10
20
|
from .arc_length_riks import _solver_arc_length_riks
|
|
11
21
|
from .arc_length_crisfield import _solver_arc_length_crisfield
|
|
@@ -19,18 +29,11 @@ class Analysis(object):
|
|
|
19
29
|
static analysis, linear or non-linear, is run with :meth:`.static`, whose
|
|
20
30
|
solution is stored in the attributes ``increments`` and ``cs``.
|
|
21
31
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
vector scaled by the load factor
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
\{R\} = \lambda \{F_{ext}\} - \{F_{int}(c)\} = \{0\}
|
|
29
|
-
|
|
30
|
-
and the tangent stiffness matrix `[K_T] = [K_C] + [K_G]`, given by the
|
|
31
|
-
callables ``calc_kC`` and ``calc_kG``, should be the exact derivative of
|
|
32
|
-
`\{F_{int}\}` with respect to `\{c\}`, such that the Newton-Raphson
|
|
33
|
-
iterations converge quadratically.
|
|
32
|
+
The non-linear analyses find the solution vectors ``c`` for which the
|
|
33
|
+
internal force vector ``calc_fint(c)`` balances the external force
|
|
34
|
+
vector ``calc_fext(inc=1.)`` scaled by the load factor, using the
|
|
35
|
+
tangent stiffness matrix ``calc_kC(c, NLgeom=True) + calc_kG(c,
|
|
36
|
+
NLgeom=True)``.
|
|
34
37
|
|
|
35
38
|
The analysis parameters are attributes of this class, described in the
|
|
36
39
|
following tables together with their default values:
|
|
@@ -46,10 +49,9 @@ class Analysis(object):
|
|
|
46
49
|
methods, see
|
|
47
50
|
:func:`.arc_length._solver_arc_length`
|
|
48
51
|
``line_search`` ``bool``, activates a safeguarding line-search,
|
|
49
|
-
for the Newton-Raphson method only
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
residual norm. Default is ``False``
|
|
52
|
+
for the Newton-Raphson method only, see
|
|
53
|
+
:func:`.newton_raphson._NR_iterations`. Default
|
|
54
|
+
is ``False``
|
|
53
55
|
``max_iter_line_search`` ``int``, maximum number of iterations of the
|
|
54
56
|
line-search. Default is ``20``
|
|
55
57
|
``modified_NR`` ``bool``, activates the modified Newton-Raphson
|
|
@@ -84,22 +86,30 @@ class Analysis(object):
|
|
|
84
86
|
increment for the arc-length methods. Default is
|
|
85
87
|
``1.``
|
|
86
88
|
``maxArcLength`` maximum cumulative arc length covered by the
|
|
87
|
-
arc-length methods.
|
|
88
|
-
|
|
89
|
-
linear solution for a load factor of 1, such
|
|
90
|
-
that in the linear regime an arc length of
|
|
91
|
-
about ``sqrt(2)`` corresponds to a load factor
|
|
92
|
-
increment of 1. Default is ``18``
|
|
89
|
+
arc-length methods, dimensionless. Default is
|
|
90
|
+
``18``
|
|
93
91
|
================ =================================================
|
|
94
92
|
|
|
95
93
|
==================== ============================================
|
|
96
94
|
Convergence Criteria Description
|
|
97
95
|
==================== ============================================
|
|
98
|
-
``
|
|
99
|
-
the residual
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
96
|
+
``convergence`` ``str``, ``'crisfield'`` (default) for
|
|
97
|
+
Crisfield's criterion, the residual scaled
|
|
98
|
+
with the diagonal of the linear stiffness
|
|
99
|
+
matrix over the free degrees of freedom, or
|
|
100
|
+
``'relative'`` for the Euclidean norm of the
|
|
101
|
+
residual, see :mod:`.convergence`
|
|
102
|
+
``relTOL`` tolerance `\epsilon` of the relative force
|
|
103
|
+
imbalance: Crisfield's `\zeta \le` ``relTOL``,
|
|
104
|
+
or, with ``'relative'``, the norm of the
|
|
105
|
+
residual force vector smaller than ``relTOL``
|
|
106
|
+
times the largest norm between the external
|
|
107
|
+
and internal force vectors. Not used if
|
|
108
|
+
``None``. Default is ``1.e-9``, the tight
|
|
109
|
+
tolerance of Crisfield's criterion with a
|
|
110
|
+
consistent tangent; until version 0.8.0 the
|
|
111
|
+
relative criterion was the only one, with the
|
|
112
|
+
default ``1.e-6``
|
|
103
113
|
``absTOL`` the convergence is also achieved when the
|
|
104
114
|
maximum absolute residual force is smaller
|
|
105
115
|
than this value, which depends on the units of
|
|
@@ -121,24 +131,75 @@ class Analysis(object):
|
|
|
121
131
|
external force vector. Required for linear and non-linear static
|
|
122
132
|
analyses. The non-linear solvers call it with ``inc=1.`` and scale the
|
|
123
133
|
returned vector by the load factor. It may declare the optional
|
|
124
|
-
keyword arguments ``c
|
|
134
|
+
keyword arguments ``c``, the current configuration, and ``lbd``, the
|
|
135
|
+
current load factor, and must then return the load vector of that
|
|
136
|
+
configuration and load factor for a unit load factor, ``inc=1.``,
|
|
137
|
+
see :mod:`.callbacks`. The linear static analysis never passes
|
|
138
|
+
``lbd``.
|
|
125
139
|
calc_fint : callable, optional
|
|
126
140
|
``calc_fint(c, silent=False)``, must return a 1-D array with the
|
|
127
141
|
internal force vector for the solution vector ``c``. Required for
|
|
128
|
-
non-linear analyses.
|
|
142
|
+
non-linear analyses. It may declare the optional keyword argument
|
|
143
|
+
``inc``, which then receives the current load factor, see
|
|
144
|
+
:mod:`.callbacks`.
|
|
129
145
|
calc_kC : callable, optional
|
|
130
146
|
``calc_kC(c=None, NLgeom=False, silent=False)``, must return a sparse
|
|
131
147
|
matrix with the constitutive stiffness matrix. With ``c=None`` and
|
|
132
148
|
``NLgeom=False`` it must return the linear stiffness matrix, and with
|
|
133
149
|
``NLgeom=True`` the constitutive part of the tangent stiffness matrix
|
|
134
|
-
at ``c``. Required for linear and non-linear static analyses.
|
|
150
|
+
at ``c``. Required for linear and non-linear static analyses. It may
|
|
151
|
+
declare the optional keyword argument ``inc``, which then receives
|
|
152
|
+
the current load factor in the calls with ``NLgeom=True``, see
|
|
153
|
+
:mod:`.callbacks`.
|
|
135
154
|
calc_kG : callable, optional
|
|
136
155
|
``calc_kG(c=None, NLgeom=False, silent=False)``, must return a sparse
|
|
137
156
|
matrix with the geometric stiffness matrix at ``c``. It is called
|
|
138
|
-
with ``NLgeom=True``. Required for non-linear analyses.
|
|
157
|
+
with ``NLgeom=True``. Required for non-linear analyses. It may
|
|
158
|
+
declare the optional keyword argument ``inc``, which then receives
|
|
159
|
+
the current load factor, see :mod:`.callbacks`. The sum of
|
|
160
|
+
``calc_kC`` and ``calc_kG`` may be unsymmetric.
|
|
161
|
+
|
|
162
|
+
Attributes
|
|
163
|
+
----------
|
|
164
|
+
increments : list
|
|
165
|
+
Load factors of the converged increments, filled by :meth:`.static`.
|
|
166
|
+
cs : list
|
|
167
|
+
Solution vectors of the converged increments, filled by
|
|
168
|
+
:meth:`.static`.
|
|
169
|
+
last_analysis : str
|
|
170
|
+
Type of the last analysis run, ``'static'`` after :meth:`.static`.
|
|
139
171
|
|
|
140
172
|
Notes
|
|
141
173
|
-----
|
|
174
|
+
For non-linear analyses, the internal force vector
|
|
175
|
+
`\{F_{int}(c)\}` must be in equilibrium with the external force
|
|
176
|
+
vector scaled by the load factor `\lambda`:
|
|
177
|
+
|
|
178
|
+
.. math::
|
|
179
|
+
|
|
180
|
+
\{R\} = \lambda \{F_{ext}\} - \{F_{int}(c)\} = \{0\}
|
|
181
|
+
|
|
182
|
+
and the tangent stiffness matrix `[K_T] = [K_C] + [K_G]`, given by the
|
|
183
|
+
callables ``calc_kC`` and ``calc_kG``, should be the exact derivative of
|
|
184
|
+
`\{F_{int}\}` with respect to `\{c\}`, such that the Newton-Raphson
|
|
185
|
+
iterations converge quadratically. The convergence is checked by
|
|
186
|
+
default with Crisfield's criterion, the residual and the reference
|
|
187
|
+
force vectors scaled with the diagonal of the linear stiffness matrix
|
|
188
|
+
``calc_kC()`` over the free degrees of freedom, such that it does not
|
|
189
|
+
depend on the units of each degree of freedom, e.g. translations and
|
|
190
|
+
rotations, see :mod:`.convergence`; ``convergence = 'relative'`` keeps
|
|
191
|
+
the Euclidean norm of the versions up to 0.8.0.
|
|
192
|
+
|
|
193
|
+
The line-search tries the full step first and only reduces it when it
|
|
194
|
+
fails a sufficient-decrease test on the norm of the residual of the
|
|
195
|
+
convergence criterion, see
|
|
196
|
+
:func:`.newton_raphson._NR_iterations`.
|
|
197
|
+
|
|
198
|
+
The arc length is dimensionless, with displacements scaled by the
|
|
199
|
+
linear solution for a load factor of 1, such that in the linear regime
|
|
200
|
+
an arc length of about ``sqrt(2)`` corresponds to a load factor
|
|
201
|
+
increment of 1, see :func:`.arc_length._solver_arc_length`.
|
|
202
|
+
|
|
142
203
|
Configuration-dependent loads, e.g. follower pressures, are supported
|
|
143
204
|
through optional keyword arguments, passed only to the callables that
|
|
144
205
|
declare them explicitly, see :mod:`.callbacks`:
|
|
@@ -158,28 +219,19 @@ class Analysis(object):
|
|
|
158
219
|
reference vector ``calc_fext(inc=1.)`` may be null. The solvers then
|
|
159
220
|
use `\partial R/\partial \lambda` for the displacement scale of the
|
|
160
221
|
arc-length methods, for the predictor of the first Newton-Raphson
|
|
161
|
-
increment and as a reference of the
|
|
162
|
-
|
|
222
|
+
increment and as a reference of the convergence criterion, see
|
|
223
|
+
:mod:`.callbacks`. The linear static analysis never passes
|
|
163
224
|
``lbd``.
|
|
164
225
|
|
|
165
226
|
The tangent stiffness matrix may then be unsymmetric, which the solvers
|
|
166
227
|
support, since they use LU factorizations.
|
|
167
228
|
|
|
168
|
-
Attributes
|
|
169
|
-
----------
|
|
170
|
-
increments : list
|
|
171
|
-
Load factors of the converged increments, filled by :meth:`.static`.
|
|
172
|
-
cs : list
|
|
173
|
-
Solution vectors of the converged increments, filled by
|
|
174
|
-
:meth:`.static`.
|
|
175
|
-
last_analysis : str
|
|
176
|
-
Type of the last analysis run, ``'static'`` after :meth:`.static`.
|
|
177
|
-
|
|
178
229
|
"""
|
|
179
230
|
__slots__ = ['NL_method', 'line_search', 'max_iter_line_search',
|
|
180
231
|
'modified_NR', 'compute_every_n',
|
|
181
232
|
'kT_initial_state', 'initialInc', 'minInc', 'maxInc',
|
|
182
|
-
'maxArcLength', '
|
|
233
|
+
'maxArcLength', 'convergence', 'absTOL', 'relTOL', 'maxNumIter',
|
|
234
|
+
'too_slow_TOL',
|
|
183
235
|
'increments', 'cs', 'last_analysis', 'calc_fext', 'calc_kC',
|
|
184
236
|
'calc_fint', 'calc_kG']
|
|
185
237
|
|
|
@@ -199,8 +251,9 @@ class Analysis(object):
|
|
|
199
251
|
self.maxInc = 1.
|
|
200
252
|
self.maxArcLength = 18
|
|
201
253
|
# convergence criteria
|
|
254
|
+
self.convergence = 'crisfield'
|
|
202
255
|
self.absTOL = None
|
|
203
|
-
self.relTOL = 1.e-
|
|
256
|
+
self.relTOL = 1.e-9
|
|
204
257
|
self.maxNumIter = 30
|
|
205
258
|
self.too_slow_TOL = 0.005
|
|
206
259
|
|
|
@@ -221,28 +274,17 @@ class Analysis(object):
|
|
|
221
274
|
def static(self, NLgeom=False, silent=False):
|
|
222
275
|
r"""General solver for static analyses
|
|
223
276
|
|
|
224
|
-
The linear analysis solves
|
|
277
|
+
The linear analysis solves the system of the linear stiffness matrix
|
|
278
|
+
``calc_kC()`` and the external force vector ``calc_fext()`` using
|
|
225
279
|
:func:`.solve`. When the load depends on the configuration, i.e.
|
|
226
280
|
``calc_fext`` declares the keyword argument ``c``, see
|
|
227
|
-
:mod:`.callbacks`, the
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
\{c_{k+1}\} = \{c_k\} + [K_C]^{-1}(\{F_{ext}(c_k)\}
|
|
235
|
-
- [K_C]\{c_k\})
|
|
236
|
-
|
|
237
|
-
starting from the solution of the reference load, until the relative
|
|
238
|
-
criterion ``relTOL`` is satisfied, see
|
|
239
|
-
:func:`.newton_raphson._check_convergence`, or ``maxNumIter``
|
|
240
|
-
iterations are done. For a follower load whose force vector is
|
|
241
|
-
affine in `c`, `\{F(c)\} = \{F_0\} - [K_f]\{c\}`, this is the
|
|
242
|
-
solution of `([K_C] + [K_f])\{c\} = \{F_0\}`, with the
|
|
243
|
-
convergence rate of the spectral radius of `[K_C]^{-1}[K_f]`, i.e.
|
|
244
|
-
of the ratio of the load to the lowest critical load of the
|
|
245
|
-
linearized problem; beyond it the iterations diverge. The non-linear
|
|
281
|
+
:mod:`.callbacks`, the load is evaluated in the current configuration
|
|
282
|
+
and corrected by iterations that reuse one factorization of the
|
|
283
|
+
linear stiffness matrix, starting from the solution of the reference
|
|
284
|
+
load, until the convergence criteria ``relTOL`` and ``absTOL`` are
|
|
285
|
+
satisfied, see :func:`.newton_raphson._check_convergence`, or
|
|
286
|
+
``maxNumIter`` iterations are done; a warning is printed when they do
|
|
287
|
+
not converge and the last iterate is returned. The non-linear
|
|
246
288
|
analysis uses the solver selected by the ``NL_method`` attribute.
|
|
247
289
|
|
|
248
290
|
Parameters
|
|
@@ -263,6 +305,39 @@ class Analysis(object):
|
|
|
263
305
|
cs : list
|
|
264
306
|
Solution vectors of the converged increments.
|
|
265
307
|
|
|
308
|
+
Raises
|
|
309
|
+
------
|
|
310
|
+
ValueError
|
|
311
|
+
When ``NLgeom=True`` and the ``NL_method`` attribute is not
|
|
312
|
+
``'NR'``, ``'arc_length_riks'`` or ``'arc_length_crisfield'``.
|
|
313
|
+
|
|
314
|
+
Notes
|
|
315
|
+
-----
|
|
316
|
+
The linear analysis solves `[K_C]\{c\} = \{F_{ext}\}`. When the load
|
|
317
|
+
depends on the configuration, the structure is still geometrically
|
|
318
|
+
linear but the load is evaluated in the current configuration,
|
|
319
|
+
`[K_C]\{c\} = \{F_{ext}(c)\}`, which is solved by the load
|
|
320
|
+
correction iterations
|
|
321
|
+
|
|
322
|
+
.. math::
|
|
323
|
+
|
|
324
|
+
\{c_{k+1}\} = \{c_k\} + [K_C]^{-1}(\{F_{ext}(c_k)\}
|
|
325
|
+
- [K_C]\{c_k\})
|
|
326
|
+
|
|
327
|
+
starting from `\{c_0\} = [K_C]^{-1}\{F_{ext}\}`, the solution of the
|
|
328
|
+
reference load ``calc_fext()``, with `\{F_{ext}(c_k)\}` given by
|
|
329
|
+
``calc_fext(inc=1., c=c_k)``. This is a fixed-point iteration
|
|
330
|
+
without the load stiffness in the iteration matrix. For a follower
|
|
331
|
+
load whose force vector is affine in `c`, `\{F(c)\} = \{F_0\} -
|
|
332
|
+
[K_f]\{c\}`, this is the solution of `([K_C] + [K_f])\{c\} =
|
|
333
|
+
\{F_0\}`, with the convergence rate of the spectral radius of
|
|
334
|
+
`[K_C]^{-1}[K_f]`, i.e. of the ratio of the load to the lowest
|
|
335
|
+
critical load of the linearized problem; beyond it the iterations
|
|
336
|
+
diverge. The error is multiplied by `-[K_C]^{-1}[K_f]` at each
|
|
337
|
+
iteration, whose spectral radius is `1/\min|\lambda|` over the load
|
|
338
|
+
multipliers `\lambda` of `([K_C] + \lambda [K_f])\{u\} = \{0\}`,
|
|
339
|
+
including the negative and complex ones.
|
|
340
|
+
|
|
266
341
|
"""
|
|
267
342
|
self.increments = []
|
|
268
343
|
self.cs = []
|
|
@@ -302,14 +377,16 @@ class Analysis(object):
|
|
|
302
377
|
configuration-dependent load, see :meth:`.static`"""
|
|
303
378
|
msg('Configuration-dependent load: load correction iterations',
|
|
304
379
|
level=2, silent=silent)
|
|
380
|
+
w = _weights(self, k0)
|
|
305
381
|
# k0 is factorized once for all the corrections
|
|
306
382
|
solve_k0 = None
|
|
307
383
|
for iteration in range(1, self.maxNumIter + 1):
|
|
308
384
|
fext = self.calc_fext(inc=1., c=c, silent=True)
|
|
309
385
|
fint = k0 @ c
|
|
310
386
|
R = fext - fint
|
|
311
|
-
conv, Rnorm, Rrel = _check_convergence(self, R, fint, fext)
|
|
312
|
-
msg('Iteration: %d,
|
|
387
|
+
conv, Rnorm, Rrel = _check_convergence(self, R, fint, fext, w=w)
|
|
388
|
+
msg('Iteration: %d, %s = %1.3e' % (iteration, 'zeta' if
|
|
389
|
+
self.convergence == 'crisfield' else 'relative ||R||', Rrel),
|
|
313
390
|
level=3, silent=silent)
|
|
314
391
|
if conv:
|
|
315
392
|
return c
|