Skip to content

short_fibre_composite: Mori-Tanaka over the fibre orientation distribution - #133

Draft
petlenz wants to merge 3 commits into
feature/orientation-averagingfrom
feature/short-fibre-composite
Draft

petlenz wants to merge 3 commits into
feature/orientation-averagingfrom
feature/short-fibre-composite

Conversation

@petlenz

@petlenz petlenz commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Closes #106. Part of the uvwmaterial port (#94); stacked on #132.

short_fibre_composite: Mori–Tanaka stiffness of fibres in an isotropic matrix averaged over the fibre orientation distribution, as a tangent producer over phase nodes (#130). The orientation enters as the second-order tensor orientation [a11, a22, a33, a12, a13, a23]; the ACG distribution with that second moment (#132) gives the quadrature directions, Lebedev precision (default 23) the weights. Two averagings as in uvwmaterial: concentration (the orientation average of the dilute concentration inside Mori–Tanaka) and stiffness (the average of the unidirectional Mori–Tanaka stiffness).

Matrix and fibre are phases (matrix, fibre: produced tangent and fraction; the fibre's eshelby is an eshelby_spheroid or eshelby_cylinder along x₁ consuming the matrix Poisson's ratio — #128, #130). The composite consumes their properties and nothing else. Everything is formed once in the fibre frame — the dilute concentration T₁ = (I + S₁ : Cₘ⁻¹ : (C_f − Cₘ))⁻¹, the unidirectional stiffness and (C_f − Cₘ) : T₁ — and rotated onto the directions with otimesu(R, R) fixed per direction at construction. One rank-4 inverse per update instead of one per direction, and a transversely isotropic fibre tangent given in the fibre frame is rotated with the rest. Outputs tangent, concentration_matrix, concentration_fibre; the stress is a linear_stress on the tangent. The two fractions must sum to one.

Tests (test_short_fibre_composite, 6): aligned fibres equal the unidirectional mean_field_tangent to 1e-12 for both averagings (tangent and concentrations); the isotropic orientation gives an isotropic tangent; Σ c A = I and the linear_stress gives C : ε; stiffness ordering aligned > mostly aligned > random along x₁; a wrong orientation trace, averaging and Lebedev degree are rejected; JSON.

Report docs/materials/short_fibre_composite/report.json: aligned, injection-moulded (0.7, 0.25, 0.05) and random orientation on one point, the aligned case checked against the unidirectional composite.

889/889 tests pass (GCC 14, reports on).

JSON input

New material type: short_fibre_composite. A json_model document that loads (the FromJson test of the PR):

{"materials": [
  {"type": "external_strain_source", "name": "strain"},
  {"type": "constant_scalar", "name": "Km", "value": 3.0},  {"type": "constant_scalar", "name": "Gm", "value": 1.0},
  {"type": "constant_scalar", "name": "Kf", "value": 60.0}, {"type": "constant_scalar", "name": "Gf", "value": 30.0},
  {"type": "isotropic_tangent", "name": "Cm", "K_source": "Km", "G_source": "Gm"},
  {"type": "isotropic_tangent", "name": "Cf", "K_source": "Kf", "G_source": "Gf"},
  {"type": "isotropic_moduli", "name": "moduli", "tangent_source": "Cm"},
  {"type": "eshelby_spheroid", "name": "shape", "nu_source": "moduli", "nu_property": "poisson_ratio", "aspect_ratio": 10.0},
  {"type": "constant_scalar", "name": "c", "value": 0.2},
  {"type": "constant_scalar", "name": "cm", "value": 0.8},
  {"type": "phase", "name": "fibres", "tangent_source": "Cf", "eshelby_source": "shape", "fraction_source": "c"},
  {"type": "phase", "name": "matrix", "tangent_source": "Cm", "fraction_source": "cm"},
  {"type": "short_fibre_composite", "name": "sf", "matrix": "matrix", "fibre": "fibres",
   "orientation": [0.8, 0.1, 0.1, 0, 0, 0], "averaging": "concentration", "precision": 23},
  {"type": "linear_stress", "name": "composite", "tangent_source": "sf", "strain_source": "strain"}
]}

The fibre's Eshelby node lies along x₁ (the fibre frame; a transversely isotropic fibre tangent is given in that frame); orientation = [a11, a22, a33, a12, a13, a23] of the second-order orientation tensor; averaging concentration | stiffness; precision a Lebedev degree (3 … 23). Outputs tangent, concentration_matrix, concentration_fibre.

@petlenz

petlenz commented Oct 17, 2026

Copy link
Copy Markdown
Member Author

Review findings (design, tmech expressions instead of component loops, modern C++, comments, tests, correctness). Severity: must = wrong result, hang, build break or unreachable feature; should = design, duplication, accuracy; nit = style.

short_fibre_composite — needs changes

  • [must] only the Eshelby tensor is rotated; a transversely isotropic Cf is used unrotated and nothing checks it. Compute T1 = inv(Is + S1:M) once in the fibre frame and rotate(T1, R_q) per node (also replaces 26–194 inverses per update by one and makes averaging: stiffness literally ⟨C_UD⟩). Add an anisotropic-fibre test.
  • [should] default precision 15 → 1–2 % tangent error (see Orientation averaging with the angular central Gaussian distribution #132).
  • [should] cache keyed on ν only, but m_aspect_ratio is a parameter reference → stale m_S after set_parameter.
  • [should] / cm with volume_fraction ≤ 1 accepted → inf at c = 1.
  • [nit] views::zip(m_nodes, m_S); redundant (void)lebedev::rule; negative precision cast in message.

@petlenz

petlenz commented Oct 17, 2026

Copy link
Copy Markdown
Member Author

Rebased on the Eshelby-node refactor (#128): the fibre shape is an eshelby_spheroid/_cylinder node along x₁ named by eshelby; aspect_ratio left the composite. Of the review findings this covers:

  • must, anisotropic fibre used unrotated: T₁, the unidirectional stiffness and (C_f − Cₘ) : T₁ are formed in the fibre frame and rotated per direction; a transversely isotropic C_f in that frame is rotated with them. One inverse per update (was one per direction).
  • should, default precision 15: now 23.
  • should, cache keyed on ν while aspect_ratio can change: the cache is gone — the Eshelby node owns the tensor and the rotations are fixed per direction.
  • should, c = 1 → division by zero: the fraction must lie in [0, 1).
  • should, poisson_of duplicate: gone, the node checks its matrix.

Not added: an anisotropic-fibre test — the repo has no transversely isotropic linear material to feed it yet.

@petlenz
petlenz force-pushed the feature/orientation-averaging branch from 98a1951 to af8c49a Compare October 17, 2026 15:41
@petlenz
petlenz force-pushed the feature/short-fibre-composite branch from 3805b49 to 7208e62 Compare October 17, 2026 15:48
@petlenz
petlenz force-pushed the feature/orientation-averaging branch from af8c49a to d228631 Compare October 17, 2026 16:41
@petlenz
petlenz force-pushed the feature/short-fibre-composite branch from 7208e62 to 90289e1 Compare October 17, 2026 16:48
@petlenz

petlenz commented Oct 17, 2026

Copy link
Copy Markdown
Member Author

Producer/consumer pass: the fibre is one inclusion node (inclusion parameter) — material, produced fraction and Eshelby node along x₁ — instead of fibre/volume_fraction/eshelby spelled out again on the composite; the fraction bound (< 1) is checked per update on the produced value.

@petlenz
petlenz force-pushed the feature/orientation-averaging branch from d228631 to 1c1894f Compare October 17, 2026 21:13
@petlenz
petlenz force-pushed the feature/short-fibre-composite branch from 90289e1 to f444ebe Compare October 17, 2026 21:19
@petlenz
petlenz force-pushed the feature/orientation-averaging branch from 1c1894f to d38f8e9 Compare October 17, 2026 22:38
@petlenz
petlenz force-pushed the feature/short-fibre-composite branch from f444ebe to ef6e567 Compare October 17, 2026 22:46
@petlenz
petlenz force-pushed the feature/orientation-averaging branch from d38f8e9 to a894d13 Compare October 18, 2026 12:02
@petlenz
petlenz force-pushed the feature/short-fibre-composite branch 2 times, most recently from 5b014b8 to 7058b57 Compare October 18, 2026 12:02
@petlenz
petlenz force-pushed the feature/orientation-averaging branch from a894d13 to 03b3598 Compare October 18, 2026 13:38
@petlenz
petlenz force-pushed the feature/short-fibre-composite branch from 7058b57 to 557b163 Compare October 18, 2026 13:38
@petlenz
petlenz force-pushed the feature/orientation-averaging branch from 03b3598 to a22be6e Compare October 18, 2026 20:03
@petlenz
petlenz force-pushed the feature/short-fibre-composite branch from 557b163 to 40204f6 Compare October 18, 2026 20:03
@petlenz
petlenz force-pushed the feature/orientation-averaging branch from a22be6e to ed2da02 Compare October 18, 2026 20:22
@petlenz
petlenz force-pushed the feature/short-fibre-composite branch from 40204f6 to d65215c Compare October 18, 2026 20:22
…ution

Spheroidal fibres in an isotropic matrix with the second-order orientation
tensor: Mori-Tanaka with the orientation-averaged dilute concentration, or
the averaged unidirectional stiffness. Eshelby tensors per direction are
cached for the matrix Poisson ratio. Report with aligned, injection-moulded
and random states against the unidirectional composite and isotropy.
… in the fibre frame

Both phases come in as produced properties (tangent, fraction, the fibre's
Eshelby tensor along x1); the composite consumes them, forms the dilute
concentration once in the fibre frame, rotates onto the quadrature directions
with otimesu(R, R) fixed per direction, and produces the tangent and the two
concentrations. The stress is a linear_stress on the tangent. No material_ref.
@petlenz
petlenz force-pushed the feature/orientation-averaging branch from ed2da02 to d855f53 Compare October 19, 2026 04:06
@petlenz
petlenz force-pushed the feature/short-fibre-composite branch from d65215c to 02524f8 Compare October 19, 2026 04:06
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