Skip to content

mean_field_strain and mean_field_stress: strain localisation around the phase materials (linear) - #144

Open
petlenz wants to merge 1 commit into
feature/hencky-elasticityfrom
feature/mean-field-local-strain
Open

petlenz wants to merge 1 commit into
feature/hencky-elasticityfrom
feature/mean-field-local-strain

Conversation

@petlenz

@petlenz petlenz commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Part of #116 (the linear half). Part of the uvwmaterial port (#94); stacked on #141 (the whole stack: Eshelby and depolarisation nodes, phase nodes, producer/consumer wiring).

Strain localisation as two nodes around the phase materials. Nothing walks the graph, nothing re-binds relays; the engine orders everything and the materials are ordinary consumers of a produced strain.

  • mean_field_strain: from the composite strain increment (strain_source, history) and the phases' tangents, fractions and Eshelby tensors (matrix, phases: phase nodes) it produces one strain per phase, strain_<phase> = ε_r,ₙ + A_r : Δε (history properties: commit, revert and the UMAT state vector carry them), and the concentrations concentration_<phase>. kernel is any of the global schemes — voigt (A = I, no tangents read), reuss, hill (Aᵣ = ℂᵣ⁻¹ : ℂ_R and the mean with I, no Eshelby tensors), dilute, mori_tanaka — so the rule of mixtures localises through the same pair.
  • The phase materials consume those strains like any other: "strain_source": "mt_strain", "strain_property": "strain_matrix" (materials: strain consumers name the strain property they read #145). Here linear_stress / linear_elasticity on the producers' tangents — evaluated once per update, at their local strain.
  • mean_field_stress: stress = Σ c_r σ_r and tangent = Σ c_r C_r : A_r from the materials' current stresses and tangents (matrix_stress_source, stress_sources, optional tangent_sources, matrix_stress_property / matrix_tangent_property for a material that names them differently) and the concentrations of the strain node; residual = the largest relative difference between a phase node's tangent and its material's current one — identically zero here, the handle the nonlinear PR uses.

With linear phases every edge is global, one pass is the fixed point and the result equals mean_field_tangent + linear_stress to round-off, with the phase strains and stresses available as properties. The nonlinear case (a phase whose tangent depends on its own strain) is the next PR: a local tangent edge on the phase node and the passes closing the fixed point.

Tests (test_mean_field_local, 4): the linear wiring converges in one pass (residual = 0) and equals the tangent homogenisation (tangent, stress, matrix strain); Voigt, Reuss and Hill through the pair equal rule_of_mixture (tangent, concentrations, stress; Voigt: equal strain, Reuss: equal stress); non-parallel source lists are rejected; JSON.

Docs: docs/mean_field.md (the composite layer: phase nodes, tangent homogenisation, the self-consistent cycle, strain localisation, who runs the fixed point) and the README links.

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

JSON input

{"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": "Ki", "value": 60.0}, {"type": "constant_scalar", "name": "Gi", "value": 30.0},
  {"type": "isotropic_tangent", "name": "C_m", "K_source": "Km", "G_source": "Gm"},
  {"type": "isotropic_tangent", "name": "C_i", "K_source": "Ki", "G_source": "Gi"},
  {"type": "isotropic_moduli", "name": "moduli", "tangent_source": "C_m"},
  {"type": "eshelby_sphere", "name": "sphere", "nu_source": "moduli", "nu_property": "poisson_ratio"},
  {"type": "constant_scalar", "name": "c", "value": 0.3},
  {"type": "constant_scalar", "name": "cm", "value": 0.7},
  {"type": "phase", "name": "matrix", "tangent_source": "C_m", "fraction_source": "cm"},
  {"type": "phase", "name": "spheres", "tangent_source": "C_i", "fraction_source": "c", "eshelby_source": "sphere"},
  {"type": "mean_field_strain", "name": "mt_strain", "strain_source": "strain", "matrix": "matrix", "phases": ["spheres"]},
  {"type": "linear_stress", "name": "m", "tangent_source": "C_m", "strain_source": "mt_strain", "strain_property": "strain_matrix"},
  {"type": "linear_stress", "name": "s", "tangent_source": "C_i", "strain_source": "mt_strain", "strain_property": "strain_spheres"},
  {"type": "mean_field_stress", "name": "mt", "concentration_source": "mt_strain", "matrix": "matrix", "phases": ["spheres"],
   "matrix_stress_source": "m", "matrix_tangent_source": "C_m", "stress_sources": ["s"], "tangent_sources": ["C_i"]}
]}

@petlenz
petlenz force-pushed the feature/hencky-elasticity branch 2 times, most recently from ebfb2d6 to df4dddb Compare October 18, 2026 13:38
@petlenz
petlenz force-pushed the feature/mean-field-local-strain branch from fd0fcdc to 4506dbc Compare October 18, 2026 13:53
@petlenz petlenz changed the title mean_field_composite: local mode re-evaluating the phases at their local strains mean_field_strain and mean_field_stress: strain localisation around the phase materials (linear) Oct 18, 2026
@petlenz
petlenz force-pushed the feature/hencky-elasticity branch from df4dddb to a0b41e5 Compare October 18, 2026 18:55
@petlenz
petlenz force-pushed the feature/mean-field-local-strain branch from 4506dbc to f17f10d Compare October 18, 2026 18:55
@petlenz
petlenz force-pushed the feature/hencky-elasticity branch from a0b41e5 to 2e918d1 Compare October 18, 2026 20:03
@petlenz
petlenz force-pushed the feature/mean-field-local-strain branch from f17f10d to a0a7d3b Compare October 18, 2026 20:03
@petlenz
petlenz force-pushed the feature/hencky-elasticity branch from 2e918d1 to d2a423f Compare October 18, 2026 20:22
@petlenz
petlenz force-pushed the feature/mean-field-local-strain branch from a0a7d3b to 7f55103 Compare October 18, 2026 20:22
…he phase materials

The composite is split into two nodes. mean_field_strain consumes the composite
strain increment and the phases' tangents, fractions and Eshelby tensors and
produces one strain per phase (history) and the concentration tensors, for
the voigt, reuss, hill, dilute and mori_tanaka kernels. The phase materials
consume those strains through strain_source / strain_property like any other
strain. mean_field_stress averages the stresses and tangents they produce with
the concentrations and reports a residual, the difference between the tangent
a phase node carried and its material's current one.

With linear phases every edge is global, one pass is exact and the result
equals mean_field_tangent with a linear_stress to round-off, the phase strains
and stresses available as properties. docs/mean_field.md describes the
composite layer.
@petlenz
petlenz force-pushed the feature/hencky-elasticity branch from d2a423f to 72adaf0 Compare October 19, 2026 04:07
@petlenz
petlenz force-pushed the feature/mean-field-local-strain branch from 7f55103 to 427f671 Compare October 19, 2026 04:07
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