Skip to content

Commit b5c5bde

Browse files
Merge pull request #342 from robbievanleeuwen/joss
JOSS Paper
2 parents 80f0b8b + 98667dd commit b5c5bde

File tree

8 files changed

+351
-4
lines changed

8 files changed

+351
-4
lines changed

.github/workflows/draft-pdf.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Draft JOSS paper
2+
3+
on: [push]
4+
5+
jobs:
6+
paper:
7+
runs-on: ubuntu-latest
8+
name: Paper Draft
9+
steps:
10+
- name: Checkout
11+
uses: actions/checkout@v3
12+
- name: Build draft PDF
13+
uses: openjournals/openjournals-draft-action@master
14+
with:
15+
journal: joss
16+
# This should be the path to the paper within your repo.
17+
paper-path: paper/paper.md
18+
- name: Upload
19+
uses: actions/upload-artifact@v1
20+
with:
21+
name: paper
22+
# This is the output path where Pandoc will write the compiled
23+
# PDF. Note, this should be the same directory as the input
24+
# paper.md
25+
path: paper/paper.pdf

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ repos:
1111
name: Check for added large files
1212
entry: check-added-large-files
1313
language: system
14+
args: ["--maxkb=750"]
1415
- id: check-toml
1516
name: Check Toml
1617
entry: check-toml

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
[![Codecov](https://codecov.io/gh/robbievanleeuwen/section-properties/branch/master/graph/badge.svg)][codecov]
1414
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)][pre-commit]
1515
[![Black](https://img.shields.io/badge/code%20style-black-000000.svg)][black]
16+
[![DOI](https://zenodo.org/badge/104638241.svg)][zenodo]
1617

1718
[pypi_]: https://pypi.org/project/sectionproperties/
1819
[status]: https://pypi.org/project/sectionproperties/
@@ -22,6 +23,7 @@
2223
[codecov]: https://app.codecov.io/gh/robbievanleeuwen/section-properties
2324
[pre-commit]: https://github.com/pre-commit/pre-commit
2425
[black]: https://github.com/psf/black
26+
[zenodo]: https://zenodo.org/badge/latestdoi/104638241
2527

2628
`sectionproperties` is a python package for the analysis of arbitrary cross-sections
2729
using the finite element method. `sectionproperties` can be used to determine

docs/user_guide/theory.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,9 +320,10 @@ describe the resulting modified stiffness matrix, and solution and load vector:
320320
0 \\
321321
\end{bmatrix}
322322
323-
where :math:`\textbf{C}` is a row vector of ones and :math:`\lambda` may be though of as
324-
a force acting to enforce the constraints, which should be relatively small when
325-
compared to the values in the force vector and can be omitted from the solution vector.
323+
where :math:`\textbf{C}` is the assembly of :math:`\int_{\Omega} \textbf{N} \, d \Omega`
324+
and :math:`\lambda` may be thought of as a force acting to enforce the constraints, which
325+
should be relatively small when compared to the values in the force vector and can be
326+
omitted from the solution vector.
326327

327328
Calculation of Cross-Section Properties
328329
---------------------------------------
@@ -531,7 +532,7 @@ Applying numerical integration to the stiffness matrix and load vector results i
531532
following expressions:
532533

533534
.. math::
534-
\textbf{k}^e &= \sum_{i=1}^3 w_i \textbf{B}_i^{\rm T} \textbf{B}_i J_e \\
535+
\textbf{k}^e &= \sum_{i=1}^6 w_i \textbf{B}_i^{\rm T} \textbf{B}_i J_e \\
535536
\textbf{f}^e &= \sum_{i=1}^6 w_i \textbf{B}_i^{\rm T}
536537
\begin{bmatrix}
537538
\textbf{N}_i \textbf{y}_e \\

paper/example/paper_example.ipynb

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"id": "219c61c6-eef9-43bf-bcb9-49d2de2dd879",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"from sectionproperties.analysis import Section\n",
11+
"from sectionproperties.pre.library import bulb_section"
12+
]
13+
},
14+
{
15+
"cell_type": "code",
16+
"execution_count": null,
17+
"id": "a1f98f26-78d8-4861-b0ba-66096e32e5cd",
18+
"metadata": {},
19+
"outputs": [],
20+
"source": [
21+
"geom = bulb_section(d=200, b=50, t=12, r=10, n_r=8)\n",
22+
"geom.create_mesh(mesh_sizes=5)\n",
23+
"sec = Section(geometry=geom)\n",
24+
"sec.plot_mesh(materials=False)"
25+
]
26+
},
27+
{
28+
"cell_type": "code",
29+
"execution_count": null,
30+
"id": "2bad83b0-d055-4fef-9b32-70dc8308e48c",
31+
"metadata": {},
32+
"outputs": [],
33+
"source": [
34+
"sec.calculate_geometric_properties()\n",
35+
"sec.calculate_warping_properties()\n",
36+
"post = sec.calculate_stress(mzz=1e6)"
37+
]
38+
},
39+
{
40+
"cell_type": "code",
41+
"execution_count": null,
42+
"id": "0b62f94f-1fa9-4659-a354-a6281628f973",
43+
"metadata": {},
44+
"outputs": [],
45+
"source": [
46+
"import matplotlib.pyplot as plt\n",
47+
"\n",
48+
"\n",
49+
"sec.plot_centroids(alpha=0.2)\n",
50+
"ax = sec.plot_centroids(alpha=0.2, nrows=1, ncols=2, render=False)\n",
51+
"fig = ax.get_figure()\n",
52+
"post.plot_stress(\n",
53+
" stress=\"mzz_zxy\",\n",
54+
" cmap=\"viridis\",\n",
55+
" normalize=False,\n",
56+
" alpha=0.2,\n",
57+
" title=\"Torsion Stress\",\n",
58+
" ax=fig.axes[1],\n",
59+
" fmt=\"{x:.3f}\",\n",
60+
")\n",
61+
"fig.savefig(\"../figures/example.png\", dpi=300)"
62+
]
63+
}
64+
],
65+
"metadata": {
66+
"kernelspec": {
67+
"display_name": "Python 3 (ipykernel)",
68+
"language": "python",
69+
"name": "python3"
70+
},
71+
"language_info": {
72+
"codemirror_mode": {
73+
"name": "ipython",
74+
"version": 3
75+
},
76+
"file_extension": ".py",
77+
"mimetype": "text/x-python",
78+
"name": "python",
79+
"nbconvert_exporter": "python",
80+
"pygments_lexer": "ipython3",
81+
"version": "3.9.17"
82+
}
83+
},
84+
"nbformat": 4,
85+
"nbformat_minor": 5
86+
}

paper/figures/example.png

535 KB
Loading

paper/paper.bib

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
@book{pilkey,
2+
author = {Pilkey, W. D.},
3+
address = {New York},
4+
booktitle = {Analysis and Design of Elastic Beams: Computational Methods},
5+
doi = {10.1002/9780470172667},
6+
isbn = {9780471381525},
7+
language = {eng},
8+
publisher = {Wiley},
9+
title = {Analysis and Design of Elastic Beams: Computational Methods},
10+
year = {2002},
11+
}
12+
13+
@book{larson,
14+
author = {Larson, M. G. and Bengzon, F.},
15+
address = {Netherlands},
16+
booktitle = {The Finite Element Method},
17+
doi = {10.1007/978-3-642-33287-6},
18+
edition = {1},
19+
isbn = {9783642332869},
20+
language = {eng},
21+
publisher = {Springer Berlin, Heidelberg},
22+
series = {Texts in Computational Science and Engineering},
23+
title = {The Finite Element Method: Theory, Implementation, and Applications},
24+
volume = {10},
25+
year = {2013},
26+
}
27+
28+
@software{shapely,
29+
author = {Gillies, Sean and van der Wel, Casper and Van den Bossche, Joris and Taves, Mike W. and Arnott, Joshua and Ward, Brendan C. and {others}},
30+
doi = {10.5281/zenodo.5597138},
31+
license = {BSD-3-Clause},
32+
month = oct,
33+
title = {Shapely},
34+
url = {https://github.com/shapely/shapely},
35+
version = {2.0.2},
36+
year = {2023}
37+
}
38+
39+
@misc{triangle,
40+
author = {Rufat, D.},
41+
title = {Triangle},
42+
year = {2023},
43+
publisher = {GitHub},
44+
journal = {GitHub repository},
45+
url = {https://github.com/drufat/triangle}
46+
}
47+
48+
@article{shewchuck,
49+
author = {Shewchuk, J. R.},
50+
doi = {10.1016/S0925-7721(01)00047-5},
51+
journal = {Computational Geometry},
52+
language = {eng},
53+
number = {1},
54+
pages = {21-74},
55+
publisher = {Elsevier B.V},
56+
title = {Delaunay refinement algorithms for triangular mesh generation},
57+
volume = {22},
58+
year = {2002},
59+
}

paper/paper.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
---
2+
title: "sectionproperties: A Python package for the analysis of arbitrary cross-sections using the finite element method"
3+
tags:
4+
- python
5+
- computational mechanics
6+
- finite element method
7+
- cross-section
8+
- stress analysis
9+
- engineering
10+
authors:
11+
- given-names: Robbie
12+
non-dropping-particle: van
13+
surname: Leeuwen
14+
orcid: 0009-0004-8056-3977
15+
affiliation: 1
16+
- name: Connor Ferster
17+
orcid: 0009-0005-0861-2428
18+
affiliation: 2
19+
affiliations:
20+
- name: Independent Researcher, Australia
21+
index: 1
22+
- name: Independent Researcher, Canada # update
23+
index: 2
24+
date: 13 October 2023
25+
bibliography: paper.bib
26+
---
27+
28+
# Summary
29+
30+
Properties of plane cross-sections are often required in engineering research, analysis,
31+
and design. For example, cross-sectional properties are used to determine the
32+
displacements, natural frequencies, and stresses within beams under complex loading.
33+
`sectionproperties` is a Python package for the analysis of _arbitrary_ cross-sections
34+
using the finite element method. `sectionproperties` can be used to determine
35+
geometric and warping properties, as well as visualising cross-sectional stresses
36+
resulting from combinations of applied loads. `sectionproperties` aims to provide a
37+
pre-processor, analysis engine, and post-processor, in a single open source and
38+
accessible package, that can be used by researchers, practising engineers, and students.
39+
40+
# Statement of Need
41+
42+
Obtaining the geometric properties of simple shapes is a classical engineering problem
43+
with well-defined analytical solutions. However, obtaining warping properties, e.g. for
44+
torsion and shear analyses, involves solving partial differential equations [@pilkey].
45+
While some analytical solutions exist for a small subset of geometries, the method for
46+
obtaining these results is not able to be generalised to shapes commonly used in
47+
engineering pratice. Further, the analysis of arbitrary composite geometries, in which a
48+
cross-section could consist of any shape with any number of internal holes, and be made
49+
from any number of materials, complicates both geometric and warping computations.
50+
51+
To the best of our knowledge, there is no open source software available for the
52+
computation of both geometric and warping propreties for composite, arbitary
53+
cross-sections. While there are several commercial solutions available, e.g.
54+
[`RSECTION 1`](https://www.dlubal.com/en/products/cross-section-properties-software/rsection),
55+
[`ShapeDesigner SaaS`](http://mechatools.com/en/shapedesigner.html), or
56+
[`CADRE Profiler`](https://www.cadreanalytic.com/profiler.htm), none of these are
57+
open source or provide an application programming interface (API) that would enable
58+
these programs to be used for research. As a result, `sectionproperties` supports both
59+
engineering practice and research, by implementing an open source solution to the
60+
complex modelling problem that is arbitrary composite geometric and warping analyses.
61+
62+
# Implementation
63+
64+
`sectionproperties` harnesses the power of Shapely [@shapely] to streamline geometry
65+
generation, and triangle [@triangle] (a python port of Triangle [@shewchuck]) to produce
66+
a triangular mesh of six-noded quadratic elements. The finite element method is used to
67+
solve for the geometric and warping properties, the latter involving the solution of
68+
partial differential equations and boundary value problems [@pilkey]. For example, the
69+
Saint-Venant torsion constant ($J$) is obtained by solving for the warping function,
70+
$\omega$ [@pilkey]:
71+
72+
$$
73+
\nabla^2 \omega = 0
74+
$$
75+
76+
subject to the boundary condition:
77+
78+
$$
79+
\frac{\partial \omega}{\partial x} n_x + \frac{\partial \omega}{\partial y} n_y = y n_x - x n_y
80+
$$
81+
82+
Using the finite element method, this problem is reduced to a set of linear equations of
83+
the form:
84+
85+
$$
86+
\textbf{K} \boldsymbol{\omega} = \textbf{F}
87+
$$
88+
89+
where the stiffness matrix and load vector at the element level are defined as:
90+
91+
$$
92+
\textbf{k}^e = \sum_{i=1}^6 w_i \textbf{B}_i^{\rm T} \textbf{B}_i J_i
93+
$$
94+
95+
$$
96+
\textbf{f}^e = \sum_{i=1}^6 w_i \textbf{B}_i^{\rm T}
97+
\begin{bmatrix}
98+
\textbf{N}_i \textbf{y}_e \\
99+
-\textbf{N}_i \textbf{x}_e \\
100+
\end{bmatrix} J_i
101+
$$
102+
103+
In the above, $\textbf{N}$ and $\textbf{B}$ are the shape functions and their
104+
derivatives, and $w_i$ and $J_i$ are the weights and Jacobians of the current
105+
integration point. The boundary conditions neccesitate the inversion of a nearly
106+
singular global stiffness matrix. As such, the Lagrangian multiplier method is used to
107+
solve the set of linear equations of the form $\textbf{K} \textbf{u} = \textbf{F}$ by
108+
introducing an extra constraint on the solution vector, whereby the mean value is equal
109+
to zero [@larson].
110+
111+
$$
112+
\begin{bmatrix}
113+
\textbf{K} & \textbf{C}^{\rm{T}} \\
114+
\textbf{C} & 0 \\
115+
\end{bmatrix}
116+
\begin{bmatrix}
117+
\textbf{u} \\
118+
\lambda \\
119+
\end{bmatrix} =
120+
\begin{bmatrix}
121+
\textbf{F} \\
122+
0 \\
123+
\end{bmatrix}
124+
$$
125+
126+
where $\textbf{C}$ is the assembly of $\sum_{i} w_i \textbf{N}_i J_i$, and $\lambda$
127+
may be though of as a relatively small force acting to enforce the constraints. Once the
128+
warping function has been evaluated, the Saint-Venant torsion constant can be calculated
129+
as follows:
130+
131+
$$
132+
J = I_{xx} + I_{yy} - \boldsymbol{\omega}^{\rm T} \textbf{K} \boldsymbol{\omega}
133+
$$
134+
135+
The calculation of plastic properties is meshless, and is conducted using an iterative
136+
method to enforce plastic equilibrium, yielding the plastic centroids. A full
137+
description of the theoretical background underpinning `sectionproperties` can
138+
be found in the
139+
[documentation](https://sectionproperties.readthedocs.io/en/stable/user_guide/theory.html).
140+
141+
An example of some of the visualisation generated by `sectionproperties` can be seen in
142+
\autoref{fig:example} below.
143+
144+
![Plot of the centroids and torsion stress distribution for a bulb-section modelled in `sectionproperties`.\label{fig:example}](figures/example.png)
145+
146+
# Software Development
147+
148+
The `sectionproperties` package is available on [GitHub](https://github.com/robbievanleeuwen/section-properties),
149+
where the source code, issue tracker, CI workflow, and discussion board can be found.
150+
Pre-commit hooks are used to ensure code quality and style is consistent across all
151+
contributions. There is an extensive testing and validation suite used to ensure that
152+
the output produced by `sectionproperties` is verified and repeatable, including a set
153+
of benchmarking tests. `sectionproperties` has an actively maintained and complete
154+
[documentation](https://sectionproperties.readthedocs.io), including
155+
[installation instructions](https://sectionproperties.readthedocs.io/en/stable/installation.html),
156+
a detailed [user guide](https://sectionproperties.readthedocs.io/en/stable/user_guide.html),
157+
a list of [examples](https://sectionproperties.readthedocs.io/en/stable/examples.html),
158+
and an [API reference](https://sectionproperties.readthedocs.io/en/stable/api.html).
159+
160+
# Conclusion
161+
162+
In this paper we have described `sectionproperties`, a Python package that calculates
163+
the section properties of arbitrary sections. It is our hope that this project is used
164+
by researchers and practising engineers to improve their experimental and analysis
165+
workflows.
166+
167+
# Acknowledgements
168+
169+
We acknowledge the contributions from all the
170+
[contributors](https://github.com/robbievanleeuwen/section-properties/graphs/contributors)
171+
to `sectionproperties`.
172+
173+
# References

0 commit comments

Comments
 (0)