Skip to content

Add plane projection and minimum circumscribed circle (Shear Path Analysis 2D) - #70

Open
zairisabri123 wants to merge 5 commits into
faberorg:mainfrom
zairisabri123:feature/plane-projection-and-Shear-path-analysis-2D
Open

zairisabri123 wants to merge 5 commits into
faberorg:mainfrom
zairisabri123:feature/plane-projection-and-Shear-path-analysis-2D

Conversation

@zairisabri123

Copy link
Copy Markdown

This PR adds the projection of a stress or strain tensor onto a material plane, and the minimum circumscribed circle of the resulting shear path. The circle gives the shear stress amplitude τa (the radius) and the mean shear stress τm (the length of the centre vector), following Papadopoulos.

Changes

struct_mech/transformations.py
plane_basis(normal): in-plane basis (l, r), with l = normalise(ẑ × n) and r = n × l.
tensor_projection_on_plane(vector, normal): returns the normal stress σn and the shear (τl, τr). Leading dimensions are preserved.
core/decompositions/multiaxial/shear_path_analysis_2d.py
min_circumscribed_circle(points): exact smallest enclosing circle (Welzl), covering both 2-point and 3-point support. NumPy only.
longest_chord_circle(points): comparison baseline only. It underestimates τa by up to 13.4 %.

Tests

Unit tests for both modules, plus an end-to-end test from the projection to the circle.
ruff, mypy and pytest (443 passed) all pass.

Notes

Strain inputs must use tensor shear strain (ε₁₂ = γ₁₂/2).
The path must have shape (n_steps, 2). To handle several nodes or planes, call the function in a loop.

Implement tensor_projection_on_plane (WG6 register, priority 8) in
struct_mech/transformations.py. A Voigt tensor of shape (..., 6) and a
plane unit normal of shape (3,) give the normal component (...) and the
in-plane shear (..., 2); leading dimensions are preserved.

The in-plane basis is l = normalise(z_hat x n), r = n x l, as in Cizova
and the Pisa scripts, with the fallback l = x_hat when n is parallel to
z_hat (plane_basis). The docstring explains why the circumscribed circle
radius is invariant to this choice while the centre components are not.

Only fatpy.utils.voigt is used; nothing from struct_mech.stress.
…ord baseline

Implement min_circumscribed_circle (WG6 register, priority 10) in
core/decompositions/multiaxial/shear_path_analysis_2d.py: the exact
smallest circle enclosing a path of shape (n_steps, 2), returned as a
centre (2,) and a radius. It uses the incremental algorithm of Welzl,
without recursion and without an optimiser, so both two-point
(diameter) and three-point supports are found. Degenerate inputs (one
point, two points, collinear or repeated points) are handled.

The function is a reduction over the time axis, so any other shape,
including 3D input, raises ValueError; the module docstring documents
the (n_planes, n_steps, 2) convention for a future multi-plane wrapper.
The module imports numpy only, nothing from struct_mech.

longest_chord_circle is added as a non-conservative comparison
baseline (pairs only, as in the current Pisa approach), not for use in
a criterion. Tests cover the reference paths, an acute isosceles
triangle where the longest chord underestimates the radius, the Jung
bound, degenerate and wrong-shape inputs, and a cross-check against a
brute-force enumeration of all pairs and triads.
…cle end to end

Chain tensor_projection_on_plane and min_circumscribed_circle as a
caller would, looping explicitly over planes and nodes, one
(n_steps, 2) shear path at a time:

- fully reversed uniaxial tension, planes at 45 degrees: shear
  amplitude sigma_a / 2, normal stress sigma / 2;
- fully reversed torsion, plane normal to the axis: amplitude tau_a,
  no normal stress;
- proportional loading: no shear on principal planes, a straight
  segment through the origin on any other plane;
- rotated or reflected in-plane basis and flipped normal: same radius,
  centre rotated.

The normal stress on each plane is checked against its closed form.
Sample the reference shear paths (proportional, with offset, circle,
ellipse) at 8 to 1000 steps per cycle, with stratified random starting
phases refined around the worst one, and report the worst relative
error of the radius, its sign, the fitted order of convergence, the
minimum steps per cycle for 1 % and 0.1 % accuracy and the error at
72 steps per cycle, with a log-log convergence plot.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant