First-Ply-Failure of a Composite Laminate (structures/composites/laminate-first-ply-failure)
Use when the task is laminate-level first-ply-failure (FPF) strength:
finding the load at which the first ply of a symmetric balanced
composite laminate fails under in-plane load resultants. This leaf
implements the strength chain in pure Python, stdlib only: mid-plane
strain recovery from the A-matrix inverse compliance, per-ply strain
transformation to the material axes, per-ply stress recovery with the
material 2D stiffness, the Tsai-Wu failure index in every ply, and the
FPF load scale factor k* = 1 / max(FI) with the critical ply and the
reserve factor. It pairs with structures/composites/laminate-stiffness,
which assembles the stiffness this leaf inverts, and
structures/composites/failure-criteria, which owns the lamina-level
index formula for user-supplied stresses.
Domain quick reference
- Loads: in-plane resultants {Nx, Ny, Nxy} in N/mm act on the laminate;
the leaf works in units of N/mm, MPa and dimensionless strain.
- Mid-plane strains: {ex, ey, gxy} = [A]^-1 {N}. A balanced symmetric
laminate decouples shear, so ex = a11 Nx + a12 Ny, ey = a12 Nx +
a22 Ny and gxy = a66 Nxy, where a_ij are the A-inverse compliance
entries in mm/N.
- Ply k at angle theta: material-axis strains {e1, e2, g12} come from
the rotation e1 = ex c^2 + ey s^2 + gxy c s, e2 = ex s^2 + ey c^2 -
gxy c s, g12 = 2 (ey - ex) c s + gxy (c^2 - s^2), with c = cos(theta),
s = sin(theta).
- Material-axis stresses: {s1, s2, t12} = [Q] {e1, e2, g12} with the
plane-stress stiffness q11 = E1/(1 - nu12 nu21), q22 = E2/(1 - nu12
nu21), q12 = nu12 E2/(1 - nu12 nu21), q66 = G12 and nu21 = nu12 E2/E1.
- Tsai-Wu index: FI = F1 s1 + F2 s2 + F11 s1^2 + F22 s2^2 + F66 t12^2 +
2 F12 s1 s2 with F1 = 1/Xt - 1/Xc, F2 = 1/Yt - 1/Yc, F11 = 1/(Xt Xc),
F22 = 1/(Yt Yc), F66 = 1/S^2 and F12 = -0.5 sqrt(F11 F22). FI >= 1.0
marks ply failure.
- First ply failure: the ply with the largest index is critical; the
FPF scale factor is k* = 1 / max(FI) and the FPF load resultant for
the uniaxial case is k* Nx, with the reserve factor equal to k*. The
index is quadratic in stress, so k* = 1 / FI is a linearized reserve
factor; it is exact at the failure boundary itself and is the
convention of this leaf.
- CMH-17 frames the ply allowables and lamina data context; the
relations above are standard mechanics, summary-only.
Workflow
- Fix the material: engineering constants E1, E2, nu12, G12 and the
allowables Xt, Xc, Yt, Yc, S in MPa (q_matrix_from_constants builds
[Q] without importing the laminate-stiffness module).
- Get the laminate in-plane compliance: assemble the A block with
a_matrix_from_plies (angles in degrees, ply thickness in mm) and
invert it with a_inverse_compliance into (a11, a12, a22, a66); or
take the compliance directly from the laminate-stiffness leaf.
- Recover the mid-plane strains with midplane_strains from the applied
resultants (Nx, Ny, Nxy in N/mm).
- Per ply, transform the strains with ply_material_strains and recover
the material stresses with ply_material_stresses; ply_failure_indices
runs the whole per-ply loop and returns the index list in ply order.
- Evaluate the laminate: first_ply_failure returns the dict with
max_fi, critical_ply_index, critical_ply_deg, fpf_scale_k,
fpf_load_nx and reserve_factor (first_ply_failure_load is an alias).
- Confirm the deterministic checks with the contract test
scripts/test_laminate_first_ply_failure.py.
Worked example
T300/5208: E1 = 181 GPa, E2 = 10.3 GPa, G12 = 7.17 GPa, nu12 = 0.28;
Xt = Xc = 1500 MPa, Yt = 40 MPa, Yc = 246 MPa, S = 68 MPa. Laminate
[0/90/45/-45]s, ply thickness 0.125 mm (8 plies), Nx = 100 N/mm. Real
module outputs:
- Material stiffness: q11 = 181811.1 MPa, q12 = 2896.9 MPa,
q22 = 10346.2 MPa, q66 = 7170.0 MPa.
- Laminate A block: A11 = A22 = 76368.2 N/mm, A12 = 22607.4 N/mm,
A66 = 26880.4 N/mm; compliance a11 = a22 = 1.4352e-5 mm/N,
a12 = -4.2487e-6 mm/N, a66 = 3.7202e-5 mm/N.
- Mid-plane strains: ex = 1.4352e-3, ey = -4.2487e-4, gxy = 0
(uniaxial load on a balanced symmetric laminate).
- Per-ply failure indices: [0.0254, 0.3130, 0.1827, 0.1827, 0.1827,
0.1827, 0.3130, 0.0254]; the 90-degree plies are critical. The
90-degree transverse stress s2 = 13.62 MPa dominates its index through
the F2 linear term; the 0-degree fiber stress s1 = 259.7 MPa stays far
below Xt.
- FPF summary: max_fi = 0.313007, critical_ply_index = 1 (90 degrees),
fpf_scale_k = 3.1948, FPF load Nx = 319.5 N/mm, reserve factor 3.195.
Pitfalls
- Forgetting the failure index is quadratic: FI is a sum of linear
and quadratic stress terms, so the scale factor k* = 1 / max(FI) is
a linearized reserve factor - exact at the failure boundary, and an
approximation away from it.
- Reading the critical ply off the wrong stress: in the worked
[0/90/45/-45]s case the 90-degree ply is critical through its
transverse stress s2 (13.62 MPa against Yt = 40 MPa), not the
0-degree fiber stress (259.7 MPa against 1500 MPa); the largest
stress is not the failing one.
- Feeding unbalanced or unsymmetric resultants: the strain recovery
ex = a11 Nx + a12 Ny, ey = a12 Nx + a22 Ny, gxy = a66 Nxy assumes a
balanced symmetric laminate; coupling terms outside that model
need the full laminate-stiffness ABD treatment.
- Swapping units between resultants and stiffness: loads are in
N/mm and moduli in MPa, with ply thickness in mm; the A-matrix
entries come out in N/mm and the compliance in mm/N, so mixing SI
meters into the stack breaks the strain scale.
- Using a singular Poisson product: nu12 * nu21 >= 1 makes the
plane-stress denominator invalid and raises ValueError; the nu21 =
nu12 E2/E1 consistency must hold for the material input.
- Treating FPF as ultimate laminate failure: first-ply failure is
the first ply event under the Tsai-Wu convention; post-FPF load
redistribution and delamination growth are different leaves.
Verification
- Confirm first_ply_failure on the worked laminate returns max_fi about
0.3130 with the critical ply at 90 degrees and FPF Nx about 319.5 N/mm.
- Unidirectional identity: a [0]8 laminate under Nx fails in the fiber
direction; with sigma1 = Nx/t and Xt = Xc the index is (sigma1/Xt)^2,
so at sigma1 = Xt the index is 1.0 and k* = Xt/sigma1 = 1. The 0-ply
stress recovered from the strain equals E1 ex exactly.
- Mirror symmetry: reversing the ply list order leaves the A block and
the FPF result unchanged for the same set of ply angles.
- Determinism: identical inputs give bit-identical floats run to run.
- ValueError rejection of non-physical inputs: non-positive allowables,
non-positive engineering constants, a singular Poisson product, empty
ply lists, non-positive ply thickness, and non-positive diagonal
compliance terms all raise.
- Run the contract test offline: python3
scripts/test_laminate_first_ply_failure.py (34 tests, deterministic).
Related leaves
- structures/composites/laminate-stiffness: ABD assembly, the strain
recovery start point.
- structures/composites/failure-criteria: lamina-level index from given
stresses.
- structures/composites/laminate-hygrothermal-response: thermal and
moisture strain response before the mechanical load step.
- structures/composites/delamination-growth: energy-based growth, not
stress-based ply failure.
Behavior contract (gate 3)
Run the deterministic contract test (stdlib unittest, offline):
python3 scripts/test_laminate_first_ply_failure.py
The test covers the T300/5208 worked example (A block about
76368/22607/26880 N/mm, ex about 1.435e-3, ey about -4.25e-4, max
Tsai-Wu index about 0.3130 in the 90-degree ply, FPF load about
319.5 N/mm, reserve factor about 3.195), the [Q] builder from
engineering constants including its isotropic reduction, the [0]8
unidirectional closed forms (fiber-direction failure at sigma1 = Xt and
the quadratic index scaling), the stress-strain round trip, mirror
symmetry under reversed ply order, determinism, the exact result-dict
keys, and ValueError rejection of non-physical inputs.
Compliance
- Standards referenced, not reproduced: CMH-17 (Composite Materials
Handbook, SAE) and FAR-25 (14 CFR Part 25) frame the ply data and
airframe certification context; the lamination-theory relations are
common mechanics, summary-only per standards-map.yaml.
- compliance: STANDARDS-REF, gated: false.
1---2name: laminate-first-ply-failure3description: Use when you must compute the first-ply-failure load of a composite laminate: recover the mid-plane strains of a symmetric balanced laminate from its in-plane compliance under applied load resultants, transform the strains to each ply material axis, compute the per-ply Tsai-Wu failure index, and return the critical ply. Produces the mid-plane strains, the per-ply failure indices, the critical ply, the first-ply-failure load scale factor, the FPF load resultant, and the reserve factor. Trigger: first-ply-failure load, first ply failure, critical ply, tsai-wu failure index, reserve factor, mid-plane strain recovery, in-plane load resultant, symmetric balanced laminate, quasi-isotropic laminate, laminate failure envelope, FPF load, per-ply failure index, composite laminate strength.4license: Apache-2.05---67# First-Ply-Failure of a Composite Laminate (structures/composites/laminate-first-ply-failure)89Use when the task is laminate-level first-ply-failure (FPF) strength:10finding the load at which the first ply of a symmetric balanced11composite laminate fails under in-plane load resultants. This leaf12implements the strength chain in pure Python, stdlib only: mid-plane13strain recovery from the A-matrix inverse compliance, per-ply strain14transformation to the material axes, per-ply stress recovery with the15material 2D stiffness, the Tsai-Wu failure index in every ply, and the16FPF load scale factor k* = 1 / max(FI) with the critical ply and the17reserve factor. It pairs with structures/composites/laminate-stiffness,18which assembles the stiffness this leaf inverts, and19structures/composites/failure-criteria, which owns the lamina-level20index formula for user-supplied stresses.2122## Domain quick reference2324- Loads: in-plane resultants {Nx, Ny, Nxy} in N/mm act on the laminate;25 the leaf works in units of N/mm, MPa and dimensionless strain.26- Mid-plane strains: {ex, ey, gxy} = [A]^-1 {N}. A balanced symmetric27 laminate decouples shear, so ex = a11 Nx + a12 Ny, ey = a12 Nx +28 a22 Ny and gxy = a66 Nxy, where a_ij are the A-inverse compliance29 entries in mm/N.30- Ply k at angle theta: material-axis strains {e1, e2, g12} come from31 the rotation e1 = ex c^2 + ey s^2 + gxy c s, e2 = ex s^2 + ey c^2 -32 gxy c s, g12 = 2 (ey - ex) c s + gxy (c^2 - s^2), with c = cos(theta),33 s = sin(theta).34- Material-axis stresses: {s1, s2, t12} = [Q] {e1, e2, g12} with the35 plane-stress stiffness q11 = E1/(1 - nu12 nu21), q22 = E2/(1 - nu1236 nu21), q12 = nu12 E2/(1 - nu12 nu21), q66 = G12 and nu21 = nu12 E2/E1.37- Tsai-Wu index: FI = F1 s1 + F2 s2 + F11 s1^2 + F22 s2^2 + F66 t12^2 +38 2 F12 s1 s2 with F1 = 1/Xt - 1/Xc, F2 = 1/Yt - 1/Yc, F11 = 1/(Xt Xc),39 F22 = 1/(Yt Yc), F66 = 1/S^2 and F12 = -0.5 sqrt(F11 F22). FI >= 1.040 marks ply failure.41- First ply failure: the ply with the largest index is critical; the42 FPF scale factor is k* = 1 / max(FI) and the FPF load resultant for43 the uniaxial case is k* Nx, with the reserve factor equal to k*. The44 index is quadratic in stress, so k* = 1 / FI is a linearized reserve45 factor; it is exact at the failure boundary itself and is the46 convention of this leaf.47- CMH-17 frames the ply allowables and lamina data context; the48 relations above are standard mechanics, summary-only.4950## Workflow51521. Fix the material: engineering constants E1, E2, nu12, G12 and the53 allowables Xt, Xc, Yt, Yc, S in MPa (q_matrix_from_constants builds54 [Q] without importing the laminate-stiffness module).552. Get the laminate in-plane compliance: assemble the A block with56 a_matrix_from_plies (angles in degrees, ply thickness in mm) and57 invert it with a_inverse_compliance into (a11, a12, a22, a66); or58 take the compliance directly from the laminate-stiffness leaf.593. Recover the mid-plane strains with midplane_strains from the applied60 resultants (Nx, Ny, Nxy in N/mm).614. Per ply, transform the strains with ply_material_strains and recover62 the material stresses with ply_material_stresses; ply_failure_indices63 runs the whole per-ply loop and returns the index list in ply order.645. Evaluate the laminate: first_ply_failure returns the dict with65 max_fi, critical_ply_index, critical_ply_deg, fpf_scale_k,66 fpf_load_nx and reserve_factor (first_ply_failure_load is an alias).676. Confirm the deterministic checks with the contract test68 scripts/test_laminate_first_ply_failure.py.6970## Worked example7172T300/5208: E1 = 181 GPa, E2 = 10.3 GPa, G12 = 7.17 GPa, nu12 = 0.28;73Xt = Xc = 1500 MPa, Yt = 40 MPa, Yc = 246 MPa, S = 68 MPa. Laminate74[0/90/45/-45]s, ply thickness 0.125 mm (8 plies), Nx = 100 N/mm. Real75module outputs:7677- Material stiffness: q11 = 181811.1 MPa, q12 = 2896.9 MPa,78 q22 = 10346.2 MPa, q66 = 7170.0 MPa.79- Laminate A block: A11 = A22 = 76368.2 N/mm, A12 = 22607.4 N/mm,80 A66 = 26880.4 N/mm; compliance a11 = a22 = 1.4352e-5 mm/N,81 a12 = -4.2487e-6 mm/N, a66 = 3.7202e-5 mm/N.82- Mid-plane strains: ex = 1.4352e-3, ey = -4.2487e-4, gxy = 083 (uniaxial load on a balanced symmetric laminate).84- Per-ply failure indices: [0.0254, 0.3130, 0.1827, 0.1827, 0.1827,85 0.1827, 0.3130, 0.0254]; the 90-degree plies are critical. The86 90-degree transverse stress s2 = 13.62 MPa dominates its index through87 the F2 linear term; the 0-degree fiber stress s1 = 259.7 MPa stays far88 below Xt.89- FPF summary: max_fi = 0.313007, critical_ply_index = 1 (90 degrees),90 fpf_scale_k = 3.1948, FPF load Nx = 319.5 N/mm, reserve factor 3.195.919293## Pitfalls9495- Forgetting the failure index is quadratic: FI is a sum of linear96 and quadratic stress terms, so the scale factor k* = 1 / max(FI) is97 a linearized reserve factor - exact at the failure boundary, and an98 approximation away from it.99- Reading the critical ply off the wrong stress: in the worked100 [0/90/45/-45]s case the 90-degree ply is critical through its101 transverse stress s2 (13.62 MPa against Yt = 40 MPa), not the102 0-degree fiber stress (259.7 MPa against 1500 MPa); the largest103 stress is not the failing one.104- Feeding unbalanced or unsymmetric resultants: the strain recovery105 ex = a11 Nx + a12 Ny, ey = a12 Nx + a22 Ny, gxy = a66 Nxy assumes a106 balanced symmetric laminate; coupling terms outside that model107 need the full laminate-stiffness ABD treatment.108- Swapping units between resultants and stiffness: loads are in109 N/mm and moduli in MPa, with ply thickness in mm; the A-matrix110 entries come out in N/mm and the compliance in mm/N, so mixing SI111 meters into the stack breaks the strain scale.112- Using a singular Poisson product: nu12 * nu21 >= 1 makes the113 plane-stress denominator invalid and raises ValueError; the nu21 =114 nu12 E2/E1 consistency must hold for the material input.115- Treating FPF as ultimate laminate failure: first-ply failure is116 the first ply event under the Tsai-Wu convention; post-FPF load117 redistribution and delamination growth are different leaves.118## Verification119120- Confirm first_ply_failure on the worked laminate returns max_fi about121 0.3130 with the critical ply at 90 degrees and FPF Nx about 319.5 N/mm.122- Unidirectional identity: a [0]8 laminate under Nx fails in the fiber123 direction; with sigma1 = Nx/t and Xt = Xc the index is (sigma1/Xt)^2,124 so at sigma1 = Xt the index is 1.0 and k* = Xt/sigma1 = 1. The 0-ply125 stress recovered from the strain equals E1 ex exactly.126- Mirror symmetry: reversing the ply list order leaves the A block and127 the FPF result unchanged for the same set of ply angles.128- Determinism: identical inputs give bit-identical floats run to run.129- ValueError rejection of non-physical inputs: non-positive allowables,130 non-positive engineering constants, a singular Poisson product, empty131 ply lists, non-positive ply thickness, and non-positive diagonal132 compliance terms all raise.133- Run the contract test offline: python3134 scripts/test_laminate_first_ply_failure.py (34 tests, deterministic).135136## Related leaves137138- structures/composites/laminate-stiffness: ABD assembly, the strain139 recovery start point.140- structures/composites/failure-criteria: lamina-level index from given141 stresses.142- structures/composites/laminate-hygrothermal-response: thermal and143 moisture strain response before the mechanical load step.144- structures/composites/delamination-growth: energy-based growth, not145 stress-based ply failure.146147## Behavior contract (gate 3)148149Run the deterministic contract test (stdlib unittest, offline):150151 python3 scripts/test_laminate_first_ply_failure.py152153The test covers the T300/5208 worked example (A block about15476368/22607/26880 N/mm, ex about 1.435e-3, ey about -4.25e-4, max155Tsai-Wu index about 0.3130 in the 90-degree ply, FPF load about156319.5 N/mm, reserve factor about 3.195), the [Q] builder from157engineering constants including its isotropic reduction, the [0]8158unidirectional closed forms (fiber-direction failure at sigma1 = Xt and159the quadratic index scaling), the stress-strain round trip, mirror160symmetry under reversed ply order, determinism, the exact result-dict161keys, and ValueError rejection of non-physical inputs.162163## Compliance164165- Standards referenced, not reproduced: CMH-17 (Composite Materials166 Handbook, SAE) and FAR-25 (14 CFR Part 25) frame the ply data and167 airframe certification context; the lamination-theory relations are168 common mechanics, summary-only per standards-map.yaml.169- compliance: STANDARDS-REF, gated: false.