Changelog#

The changes of each version, from the file CHANGELOG.md of the repository:

# Changelog

The dates of the released versions are those of their tagged commits.

## 0.7.1 (2026-11-03)

### Tutorials

- New tutorial `doc/source/tutorials/simo1990_cylinder_postbuckling.ipynb`,
  with its module `simo1990_cylinder.py`: the post-buckling of the axially
  compressed cylinder of Simo, Fox and Rifai (1990), Section 6.3.4 and Fig.
  6.3.4, traced with the Riks method of structsolve to an axial deflection of
  0.04. The `L/10 x 15 deg` section of the paper is meshed with the
  Donnell-type element, with symmetry conditions on the degrees of freedom of
  the interior edges and a simple support on the loaded one; its lowest
  buckling load converges to 1.0043 times the classical one (1.0049 with
  8 x 8 elements).
- An initial geometric imperfection is added exactly for the Donnell-type
  kinematics, from the vector `u0` of its degrees of freedom:
  `F_int(u + u0) - F_int(u0) - K_G(N0) u` and `K_T(u + u0) - K_G(N0)`, with
  `K_G(N0)` the geometric stiffness matrix of the membrane resultants of the
  linear and non-linear strains of `u0`. `update_KG` builds it from the
  resultants of the linear strains only, and the part of the non-linear
  strains is added by `SectionModel.calc_kG_N`. Verified against the
  gradient of a strain energy computed independently of the kernels
  (relative difference 4e-8 with central differences of step 1e-5, against
  1e-4 with the matrix of `update_KG` alone).
- Results of the 12 x 12 mesh: limit loads 0.727 at a maximum deflection of
  0.0163 (10 % imperfection) and 0.390 at 0.0107 (50 %), against 0.715 at
  0.0168 and 0.411 at 0.0108 read from Fig. 6.3.4(a) (to +-0.01 and
  +-0.0003); the perfect cylinder, 8 x 8 elements, with `inertia` and
  `branch_switching`, bifurcates at 0.824 at 0.0181 (0.833 at 0.0183 in
  Fig. 6.3.4(d)) and reaches a deflection of 0.04 on the bifurcated branch.

- New tutorial `doc/source/tutorials/schweizerhof1984_cylinder_follower.ipynb`,
  with its module `schweizerhof1984_cylinder.py`: the cantilever cylinders
  of Schweizerhof and Ramm (1984), Section 6.4, under a dead and a follower
  external pressure, upper edge free, lower edge hinged (B1) or with the
  axial displacement restrained at one point (B2), with the sectors of
  `180 deg/n` of the paper meshed with the Sanders-type element and the
  full unsymmetric load stiffness matrix of `update_KCfollower`. With
  64 x 8 elements the linear buckling factors of the three shells of Table 4
  are reproduced within 0.3 % (shell 1, B1: `k_c = 10.90`, `k_f = 9.70`,
  against 10.88 and 9.70); the symmetrizations of eqs. (63) to (65) of the
  paper change `k_f` by +-0.2 %. The Donnell-type kinematics are 2 % to
  3.4 % low for B1 with `n = 3` and 4 waves.
- Riks analysis of shell 1 with an imperfection of 1 % of `t`, with
  `inertia` and `inertia_num_eigvals` (unsymmetric tangent stiffness
  matrix): with B1 a flat limit point at `k = 9.669`, 0.4 % below `k_f`, at
  `w/t = 4.0`, where the count of negative eigenvalues goes from 0 to 1 with
  the sign of the determinant; with B2 a path that still rises at `w/t =
  8`, without negative eigenvalue. Fig. 13 of the paper, labelled B1 in its
  text, matches the path of B2 (plateau 8.0 against 8.09 at `w/t = 3`,
  perfect-shell line 8.06 against `k_f = 8.11`, and the current stiffness
  parameter), not that of B1 (plateau 9.67).
- The imperfection is added exactly as in the Simo, Fox and Rifai case,
  which holds for the Sanders-type kinematics with the rows `Sw_y - Sv/R` of
  the rotations; the follower force vector is that of `u + u0`, and
  `calc_fext` declares the configuration `c` and returns the load vector of
  the current configuration, which keeps the Riks iterations quadratic.
  `CantileverModel.calc_KT` assembles `KC0 + KCNL + KG` vectorized with
  NumPy, equal to the kernels to the round-off and about 7 times faster
  than `update_KCNL` of the Sanders-type element.

### Tests

- New `tests/test_schweizerhof1984_cylinder.py`, about 20 s: the identities
  of the imperfect shell under the follower pressure for both kinematics,
  `k_c` and `k_f` of shell 1, B1, within 0.5 % of Table 4 with `n = 3`, and
  the Riks method through the limit point of B1 with the count of negative
  eigenvalues and the sign of the determinant.
- New `tests/test_simo1990_cylinder.py`, about 7 s: the identities of the
  imperfect shell, and the Riks method past the limit point of the cylinder
  with an imperfection of 10 % of the thickness, at the limit load of Fig.
  6.3.4(a) within 0.025.
- `structsolve>=0.10.0` in `requirements.txt` (was 0.9.3), and in the
  installation page.

### Documentation

- The documentation is deployed to the `gh-pages` branch from the release
  tags only, as in panels: the manual run of `auto_doc.yml`, which deployed
  from any branch, is removed. Pull requests still build it.

## 0.7.0 (2026-10-26)

### Python versions

- Python 3.9 is no longer supported, it reached its end of life in October 2025: Python 3.10 or newer is required, and the tests and wheels cover Python 3.10 to 3.14.

### Packaging

- Packaging: the metadata, with the version, in `pyproject.toml` (PEP 621), built with `setuptools>=77` and Cython; `setup.py` keeps only the Cython extensions with the compiler flags and writes `bfsccylinder/version.py` from `pyproject.toml`. NumPy and wheel are no longer build requirements, and README.md and LICENSE are no longer installed in the root of the Python environment (`data_files`); the license is in the wheel metadata.

### New: follower pressure

- `update_fext_follower` and `update_KCfollower`, for both kinematics, with
  the module constants `KCfollower_SPARSE_SIZE = 1312` (Donnell-type) and
  `1456` (Sanders-type) and the element attribute `init_k_KCfollower`: the
  force vector and the unsymmetric load stiffness matrix of a pressure
  normal to the deformed mid-surface, with the area vector truncated to
  first order (`quadratic=0`) or complete (`quadratic=1`), and the dead
  part optional (`reference`). The kernels are written by
  `deriving_equations/*/derive_bfsccylinder_follower.py` and kept in sync
  by `regenerate.py`. New `tests/test_follower_pressure.py` and
  `tests/test_follower_pressure_validation.py`, with rings and finite
  cylinders against closed forms.
- The Notes of `bfsccylinder.bfsccylinder` state the conditions under which
  the load stiffness matrix of the first-order area vector is symmetric,
  for the element matrix and for the assembled matrix.

### Bug fixes

- `update_M` of the Sanders-type element uses the rotation `-w,y + v/R` of
  the Sanders-type kinematics in the rotary inertia, instead of the
  Donnell-type rotation `-w,y`. The mass matrix now reads `R` and couples
  `v` and `w`: `M_SPARSE_SIZE` of the Sanders-type module grows from 544 to
  920. The Donnell-type element is unchanged. New test of the mass matrix
  against an independent quadrature of the kinetic energy.
- The constructors of `BFSCCylinder` and `BFSCCylinderSanders` set
  `init_k_KCNL`, which a second call of a constructor left at its previous
  value. New test that the constructors set every `init_k_*` to zero.
- The natural frequency tests are deterministic and verified: the standard
  problem of `([K] + [M])^-1 [M]` is solved from a fixed starting vector,
  with the residual of each eigenpair checked and, by Sylvester's law of
  inertia, no lower eigenvalue missing, see
  `tests/natural_frequency_solver.py`. Before, `eigsh` in shift-invert mode
  started ARPACK from a random vector and failed in about 40 % of the runs.
  The reference values are unchanged.

### Documentation

- The documentation is built by the workflow `auto_doc.yml` for every pull request and deployed to the
  `gh-pages` branch for every tag (or a manual run), with the packages of `requirements_doc.txt`.
- D1: functional docstrings of the modules, of `BFSCCylinder` and
  `BFSCCylinderSanders` and of every public function.
- D2: Notes and References of the theory: Hermite interpolation of the
  single-curvature BFSC element, the Donnell-type and Sanders-type
  kinematics, the element matrices, the internal forces and the
  quadrature.
- D3: Sphinx documentation in `doc/`, with a user guide (the element, the
  kinematics, assembling a model, the analyses, the follower pressure) and
  usage examples `ex_*.rst` with the code of the tests.
- Solving with structsolve: the callables of `structsolve.Analysis` for an
  element loop, the boundary conditions, the follower pressure and the
  convergence criterion, in `analyses.rst` and
  `ex_structsolve_nonlinear.rst`.
- Tutorials, Jupyter notebooks in `doc/source/tutorials/` stored with their
  outputs: natural frequencies (Sewall and Naumann, NASA TN D-4705, 1968)
  and axial buckling (Card and Jones, NASA TN D-3639, 1966) of
  stringer-stiffened cylinders, with the skin of `BFSCCylinderSanders`
  elements and blade stringers of the BFSC plate element of `bfscplate2d`,
  compared with the published tests and theories. The tutorial module
  `stiffened_cylinder.py` uses `update_Sv_x`, `update_Sv_y`, `Sv_x` and
  `Sv_y` of `BFSCPlate2D`, and requires bfscplate2d 0.5.0 or newer, in which
  its shape functions are renamed from `N` to `S`.
- The shape functions are written `\boldsymbol{S}^u`, `\boldsymbol{S}^v`,
  `\boldsymbol{S}^w` and their derivatives, e.g. `\boldsymbol{S}^w_{,x}`,
  as in pyfe3d, instead of `[S_u]`, `[S_{w,x}]`, ...; the names of the code
  are unchanged.
- Notation of the book in the math of the docstrings, the user guide, the
  test docstrings, the tutorial module and the markdown of the tutorials:
  vectors bold lower case without braces, e.g. `\boldsymbol{u}_e`,
  `\boldsymbol{\varepsilon}_L`, `\boldsymbol{a}` (were `\{u_e\}`,
  `\{\varepsilon_L\}`, `\{a\}`), the force vectors and the residual upper
  case, `\boldsymbol{F}_{int}`, `\boldsymbol{F}_{ext}`, `\boldsymbol{F}_p`,
  `\boldsymbol{F}_k`, `\boldsymbol{R}` (were `\{f_{int}\}`, `\{f\}`,
  `\{F_p\}`, `\{f_k\}`); matrices bold upper case without brackets, e.g.
  `\boldsymbol{B}_m`, `\boldsymbol{K}_{C0}`, `\boldsymbol{K}_{CNL} +
  \boldsymbol{K}_{GNL}`, `\boldsymbol{K}_G` (were `[B_m]`, `[K_{C0}]`,
  `[K_{CNL}]`, `[K_G]`), the matrix KCNL of `update_KCNL` being the book's
  nonlinear constitutive stiffness matrix `\boldsymbol{K}_{CNL}`, of the
  terms of `\boldsymbol{B}_{NL}`, plus the geometric term
  `\boldsymbol{K}_{GNL}`; the constraint basis of the tutorial,
  `\boldsymbol{u} = \boldsymbol{Z} \boldsymbol{u}_r` (was `[T]`, and
  `StiffenedCylinder.T` is `StiffenedCylinder.Z` in the tutorial module and
  notebooks); the prescribed displacements `\bar{\boldsymbol{u}}_k` (were
  `\{u_k\}`); the operator of the nonlinear strains
  `\boldsymbol{B}_{NL}` (was `[B_{mL}]`, `BmL` in the code); the load
  stiffness matrix `\boldsymbol{K}_F` (was `[K_{Cfollower}]`), and
  `\boldsymbol{K}_{F_{ref}}` for the reference pressure `p_0` of a linear
  buckling analysis; the position `\boldsymbol{X}` and the basis vectors
  `\boldsymbol{e}_x`, ... in bold; the transpose `^\top` (was `^T`). The
  residual is `\boldsymbol{R} = \boldsymbol{F}_{int} - \boldsymbol{F}_{ext}`
  throughout, and the examples with structsolve require structsolve 0.9.3
  or newer, which has this residual and the Newton-Raphson corrections
  `\boldsymbol{K}_T \Delta \boldsymbol{c} = -\boldsymbol{R}`. Seven docstrings that now contain a backslash, or already did
  (`update_KG_constant_stress` of `bfsccylinder_sanders`), are raw strings.
  The code identifiers of the package, plain-text comments and README.md
  are unchanged.

### Derivations

- The shape functions of the scripts of `deriving_equations/donnell/` and
  of `deriving_equations/sanders/derive_bfsccylinder_M_sparse.py` renamed
  from `N` to `S`, as in the other scripts; `regenerate.py` no longer looks
  for operators named `Nu`, `Nv` and `Nw`.

### Tests

- `structsolve>=0.9.3`, with its module `structsolve.convergence`, is a
  requirement of the tests, listed in
  `requirements.txt` and not in `install_requires`.
- `tests/test_nonlinear_axial_compression.py` solves the non-linear static
  analysis with `structsolve.Analysis` instead of hand-written
  Newton-Raphson iterations.
- New `tests/test_follower_pressure_structsolve.py`: the follower pressure
  on a cylinder with a free end with `structsolve.Analysis`, for both
  kinematics.
- An underscore introduces a partial derivative in the names of the tests
  and of the tutorial module: the keys `u_x`, ..., `w_xx`, `w_yy`, `w_xy`
  of the fields of `test_follower_pressure_validation.py` (were `ux`, ...,
  `wxy`) and the rows `Sv_x`, `Sv_y` of `stiffened_cylinder.py` (were
  `Gvx`, `Gvy`).
- The disabled plotting blocks of the `Z22` and `Z33` buckling tests use
  `update_Su`, `Su`, `Su_x`, ..., the names of the shape functions since
  0.5.0, and `u_x` (was `displux`).

## 0.6.1 (2026-09-25)

- Cython compiler flags.

## 0.6.0 (2026-09-11)

- Fixed the tangent stiffness matrix, now the derivative of the internal
  force vector, for both kinematics: `fint` counted the quadratic membrane
  strain twice, and the geometric term of the stress of the quadratic
  membrane strain is added to `update_KCNL`, such that `update_KG` remains
  homogeneous of degree one in the displacements. `update_KC0` of the
  Sanders-type element had been missing the `-Su_y/(2R)` part of the
  twisting curvature.
- `regenerate.py` fails instead of skipping a missing derivation script,
  target function or block.
- README: the kinematics description includes the Sanders-Koiter type.

## 0.5.1 (2026-08-27)

- Continuous integration with Python 3.14.

## 0.5.0 (2026-08-27)

- Fixed the derivation and the implementation of the bending part of the
  Sanders-type equations.
- The shape functions renamed from `N` to `S`.
- Derivation results added; improved `eigsh` setup of the tests; updated
  actions and support of Python 3.14.

## 0.4.8 (2025-11-25)

- Updated Python version and improved deployment.

## 0.4.7 (2024-09-25)

- Fixed tolerances in the test results.

## 0.4.6 (2024-09-25)

- Updated parameters of the tests.

## 0.4.5 (2024-09-25)

- Fixed the compatibility with integer numbers.

## 0.4.3 (2024-09-25)

- Fixed `atol` of the tests.

## 0.4.2 (2024-09-25)

- Fixed the compatibility with integer numbers.

## 0.4.1 (2024-09-25)

- Updates of the continuous integration and of the deployment workflow.

## 0.4.0 (2023-04-12)

- Removed the dependency on the NumPy C API, improving the compatibility.
- Fixed an issue with the integer types `long` and `long long`, and an
  import error.
- Updated workflows; the tests use `INT`, `DOUBLE` and `DOF`.

## 0.3.12 (2021-12-04)

- Readable definition of `fint`, without change in the results.

## 0.3.11 (2021-12-04)

- Fixed the non-linear terms, where `v` was missing, and `fint`, which
  included terms of `KG`.

## 0.3.0 (2021-11-03)

- Sanders-type kinematics: the module `bfsccylinder.bfsccylinder_sanders`
  with the element `BFSCCylinderSanders`, accessed through
  `bfsccylinder.sanders`, with tests.
- Reorganized folders.

## 0.2.3 (2021-10-04)

- Release of 0.2.2.

## 0.2.2 (2021-10-04)

- License from the 2-clause BSD license to the 3-clause BSD license.
- Fixed the load of the non-linear test; faster coverage compilation;
  README integrated with PyPI.

## 0.2.0 (2021-05-26)

- Geometrically non-linear analyses: `update_KCNL` and `update_fint`.
- Improved call of `assign_constant_ABD`.

## 0.1.5 (2021-03-18)

- Faster test and coverage.

## 0.1.4 (2021-03-18)

- Updated badges.

## 0.1.3 (2021-03-18)

- New version of composites; better automated deployment.

## 0.1.1 (2020-08-22)

- First tagged version, after the commit `REL: Version 0.1.0` of
  2020-08-21: the BFSC cylinder element `BFSCCylinder`, with `update_KC0`,
  `update_KG`, with a fix of its calculation, `update_KG_constant_stress`,
  new after 0.1.0, and `update_M`, the Gauss-Legendre points and weights of
  `bfsccylinder.quadrature` and `assign_constant_ABD` of
  `bfsccylinder.utils`.