Skip to content

Commit 54b5821

Browse files
Merge branch 'master' into mypy
2 parents 14acad8 + 7ee9a82 commit 54b5821

File tree

2 files changed

+83
-13
lines changed

2 files changed

+83
-13
lines changed

src/sectionproperties/analysis/fea.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,33 @@
2626
def _assemble_torsion(
2727
k_el: npt.NDArray[np.float64],
2828
f_el: npt.NDArray[np.float64],
29+
c_el: npt.NDArray[np.float64],
30+
n: npt.NDArray[np.float64],
2931
b: npt.NDArray[np.float64],
3032
weight: float,
3133
nx: float,
3234
ny: float,
33-
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
35+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64], npt.NDArray[np.float64]]:
3436
"""Utility function for calculating the torsion stiffness matrix and load vector.
3537
3638
Args:
3739
k_el: Element stiffness matrix
3840
f_el: Element load vector
41+
c_el: Element constraint vector
42+
n: Shape function
3943
b: Strain matrix
4044
weight: Effective weight
4145
nx: Global x-coordinate
4246
ny: Global y-coordinate
4347
4448
Returns:
45-
Torsion stiffness matrix and load vector (``k_el``, ``f_el``)
49+
Torsion stiffness matrix and load vector (``k_el``, ``f_el``, ``c_el``)
4650
"""
4751
# calculated modulus weighted stiffness matrix and load vector
4852
k_el += weight * b.transpose() @ b
4953
f_el += weight * b.transpose() @ np.array([ny, -nx])
50-
return k_el, f_el
54+
c_el += weight * n
55+
return k_el, f_el, c_el
5156

5257

5358
@njit(cache=True, nogil=True) # type: ignore
@@ -275,30 +280,32 @@ def geometric_properties(
275280

276281
def torsion_properties(
277282
self,
278-
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]:
283+
) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64], npt.NDArray[np.float64]]:
279284
"""Calculates the element warping stiffness matrix and the torsion load vector.
280285
281286
Returns:
282-
Element stiffness matrix ``k_el`` and element torsion load vector ``f_el``
287+
Element stiffness matrix ``k_el``, element torsion load vector ``f_el``
288+
and element constraint vector ``c_el``
283289
"""
284290
# initialise stiffness matrix and load vector
285291
k_el = np.zeros(shape=(6, 6), dtype=float)
286292
f_el = np.zeros(shape=6, dtype=float)
293+
c_el = np.zeros(shape=6, dtype=float)
287294

288295
# Gauss points for 4 point Gaussian integration
289296
gps = gauss_points(n=4)
290297

291298
for gp in gps:
292299
# determine shape function, shape function derivative,
293300
# jacobian and global coordinates
294-
_, b, j, nx, ny = shape_function(coords=self.coords, gauss_point=gp)
301+
n, b, j, nx, ny = shape_function(coords=self.coords, gauss_point=gp)
295302

296303
weight = gp[0] * j * self.material.elastic_modulus
297304

298305
# calculated modulus weighted stiffness matrix and load vector
299-
k_el, f_el = _assemble_torsion(k_el, f_el, b, weight, nx, ny)
306+
k_el, f_el, c_el = _assemble_torsion(k_el, f_el, c_el, n, b, weight, nx, ny)
300307

301-
return k_el, f_el
308+
return k_el, f_el, c_el
302309

303310
def shear_load_vectors(
304311
self,

src/sectionproperties/analysis/section.py

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,17 +1416,19 @@ def assemble_torsion(
14161416
col: list[float] = [] # list holding column indices
14171417
data: list[float] = [] # list holding stiffness matrix entries
14181418
f_torsion = np.zeros(n_size) # force vector array
1419+
c_torsion = np.zeros(n_size) # constraint vector array
14191420

14201421
# loop through all elements in the mesh
14211422
for el in self.elements:
14221423
# determine number of nodes in the current element
14231424
n = len(el.node_ids)
14241425

14251426
# calculate the element stiffness matrix and torsion load vector
1426-
k_el, f_el = el.torsion_properties()
1427+
k_el, f_el, c_el = el.torsion_properties()
14271428

14281429
# assemble the torsion load vector
14291430
f_torsion[el.node_ids] += f_el
1431+
c_torsion[el.node_ids] += c_el
14301432

14311433
for node_id in el.node_ids:
14321434
row.extend([node_id] * n)
@@ -1437,15 +1439,15 @@ def assemble_torsion(
14371439
progress.update(task_id=task, advance=1)
14381440

14391441
# construct Lagrangian multiplier matrix:
1440-
# column vector of ones
1442+
# column vector
14411443
row.extend(range(n_size))
14421444
col.extend([n_size] * n_size)
1443-
data.extend([1] * n_size)
1445+
data.extend(c_torsion)
14441446

1445-
# row vector of ones
1447+
# row vector
14461448
row.extend([n_size] * n_size)
14471449
col.extend(range(n_size))
1448-
data.extend([1] * n_size)
1450+
data.extend(c_torsion)
14491451

14501452
k_lg = coo_matrix(
14511453
(data, (row, col)), shape=(n_size + 1, n_size + 1), dtype=float
@@ -1681,6 +1683,67 @@ def plot_centroids(
16811683

16821684
return ax
16831685

1686+
def plot_warping_function(
1687+
self,
1688+
title: str = "Warping Function",
1689+
level: int = 20,
1690+
cmap: str = "viridis",
1691+
alpha: float = 0.2,
1692+
with_lines: bool = True,
1693+
**kwargs,
1694+
):
1695+
r"""Plots the warping function over the mesh.
1696+
1697+
Args:
1698+
title: Plot title
1699+
level: Number of contour levels
1700+
cmap: Colormap
1701+
with_lines: If set to True, contour lines are displayed
1702+
alpha: Transparency of the mesh outlines: :math:`0 \leq \alpha \leq 1`
1703+
kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context`
1704+
1705+
Raises:
1706+
RuntimeError: If a warping analysis has not been performed
1707+
1708+
Returns:
1709+
Matplotlib axes object
1710+
"""
1711+
if self.section_props.omega is None:
1712+
raise RuntimeError(
1713+
"Perform a warping analysis before plotting the warping function."
1714+
)
1715+
1716+
# create plot and setup the plot
1717+
with post.plotting_context(title=title, **kwargs) as (fig, ax):
1718+
assert ax
1719+
1720+
# create triangulation
1721+
triang = tri.Triangulation(
1722+
self._mesh_nodes[:, 0],
1723+
self._mesh_nodes[:, 1],
1724+
self._mesh_elements[:, 0:3],
1725+
)
1726+
1727+
if with_lines:
1728+
ax.tricontour(
1729+
triang,
1730+
self.section_props.omega,
1731+
colors="k",
1732+
levels=level,
1733+
)
1734+
1735+
ax.tricontourf(
1736+
triang,
1737+
self.section_props.omega,
1738+
cmap=cmap,
1739+
levels=level,
1740+
)
1741+
1742+
# plot the finite element mesh
1743+
self.plot_mesh(alpha=alpha, materials=False, **dict(kwargs, ax=ax))
1744+
1745+
return ax
1746+
16841747
def display_mesh_info(self) -> None:
16851748
"""Prints mesh statistics to the command line."""
16861749
console = Console()

0 commit comments

Comments
 (0)