Skip to content

uvwmaterial mapping document and card converter - #139

Merged
petlenz merged 50 commits into
mainfrom
feature/uvwmaterial-mapping
Oct 27, 2026
Merged

petlenz merged 50 commits into
mainfrom
feature/uvwmaterial-mapping

Conversation

@petlenz

@petlenz petlenz commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Closes #125. Part of the uvwmaterial port (#94); stacked on #138.

  • docs/uvwmaterial-mapping.md: every class of uvwmaterial with its numsim-materials counterpart, the renamed parameters (E, ν → K, G; aspec_ratio → aspect_ratio; vrh → hill; scs → self_consistent; the 9-component orientation tensor → 6 components), the status of each port with its PR or issue, and the nested card next to the flat graph document it becomes.
  • tools/convert_uvwmaterial_card.py: converts a uvwmaterial card into a json_model document for the supported types — linear elasticity, incremental elasticity, rule of mixtures, mean-field composites with sphere / long-fibre / ellipsoid Eshelby tensors, short-fibre composites, and isotropic damage with its state function, yield function and propagation laws (damage_exponential2 becomes exponential_damage_law with β = 1/(ε_f − ε₀)). Composites come out in the producer/consumer form of rule_of_mixture: Voigt, Reuss and Hill effective stiffness #130–short_fibre_composite: Mori-Tanaka over the fibre orientation distribution #133: a linear phase material becomes constant K, G and an isotropic_tangent; every phase is a phase node (produced tangent, fraction, Eshelby tensor, the matrix phase with the fraction the inclusions leave); the composite is the tangent producer <name>_tangent and <name> its linear_stress; the point names the tangent producer. A self-consistent card wires the matrix shape and the effective-medium ν over a local edge and puts residual on the point. A rule of mixtures with a nonlinear phase (damage) is Voigt through mean_field_stress — Reuss and Hill with nonlinear phases need the local strains of Nonlinear rule of mixtures with per-phase history #117 and raise with that number, as a nonlinear matrix of a mean-field card raises with Nonlinear mean field by linear comparison: plasticity and damage in the phases #116. Types that are not ported yet raise with the issue number that covers them; the matrix Poisson ratio repeated in the old Eshelby blocks is dropped, since the graph reads it from the matrix tangent.
  • Tests: tools/tests (8, ctest convert_uvwmaterial_card): the Mori–Tanaka, self-consistent, short-fibre, linear and damage-in-Voigt rule-of-mixture cards taken from uvwmaterial's examples, the propagation laws and state functions, the unported types; test_uvwmaterial_cards loads the converted Mori–Tanaka card through json_model and gets the analytic Mori–Tanaka bulk modulus from mt_tangent.

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

@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.

mapping doc + converter — needs changes

  • [must] convert_uvwmaterial_card.py:171 emits top-level point; json_model rejects it ("unrecognised top-level key"). The gtest pastes a hand-edited literal, never the converter's output. Emit {"model": {...}, "point": {...}} (the report layout) and let the gtest load converter output.
  • [must] linear → linear_damage_law with K, but numsim's law takes kappa_0, kappa_f; uvw linear is D = K·κ → power_damage_law with m = 1 (mapping doc line 22 wrong too).
  • [must] vector_strain_state_function emits m, n vectors; numsim wants m_direction, n_direction axis indices.
  • [must] strain_energy_state_function needs tangent_source and youngs_modulus; converter emits only strain_source.
  • [should] 4 of ~12 card kinds tested; one gtest loading every fixture through json_model would have caught all four musts. No card path in errors; if/elif chains next to the tables; handlers untyped.
  • [nit] converter test under the numpy guard; literal 6000.000000000001; doc row 28 wrong name; Peerlings d_max 0.999 vs uvw 0.99.

@petlenz

petlenz commented Oct 17, 2026

Copy link
Copy Markdown
Member Author

Review findings addressed in the last commit, together with the Eshelby-node refactor:

  • must, output rejected by json_model: the converter writes the report layout {"model": {"materials": […]}, "point": {…}}; the C++ cards test now holds the converter's actual model output for the MORI_TANAKA card of the Python tests instead of a hand-edited literal.
  • must, linear → linear_damage_law with K: it is power_damage_law with m = 1 (uvwmaterial's D = K·κ); the mapping row says so.
  • must, vector_strain_state_function m/n vectors: converted to the axis indices m_direction/n_direction; a non-axis vector raises.
  • must, strain_energy_state_function: tangent_source (the elastic material) and youngs_modulus (the card's E, or 9KG/(3K+G)).
  • Eshelby nodes: one eshelby_sphere/_cylinder/_spheroid per uvwmaterial eshelby_tensor, named <prefix>_<key>_shape and wired to the composite's matrix; inclusion and short_fibre_composite name it. Mapping document rows and example regenerated.
  • Tests: the Python suite covers the node wiring for Mori–Tanaka and short fibre, the linear law and both state functions' parameters, the axis-vector rejection.

Still open: a gtest that loads every Python fixture through json_model, card paths in error messages, the if/elif tables, typed handlers.

@petlenz
petlenz force-pushed the feature/damage-laws branch from 747415f to 30ae6c6 Compare October 17, 2026 16:14
@petlenz
petlenz force-pushed the feature/uvwmaterial-mapping branch from 68a6d39 to d920fb3 Compare October 17, 2026 16:16
@petlenz
petlenz force-pushed the feature/damage-laws branch from 30ae6c6 to ac4fc2a Compare October 17, 2026 17:20
@petlenz
petlenz force-pushed the feature/uvwmaterial-mapping branch from d920fb3 to fdaa5f7 Compare October 17, 2026 17:22
@petlenz

petlenz commented Oct 17, 2026

Copy link
Copy Markdown
Member Author

Producer/consumer pass: the converter emits a constant_scalar per volume fraction and inclusion phases for the rule of mixtures, the Mori–Tanaka inclusions and the short-fibre phase; Eshelby nodes consume isotropic_moduli of the composite's matrix (<matrix>_moduli, made once). Mapping rows and the example are regenerated; the C++ cards test holds the converter's actual output.

@petlenz
petlenz force-pushed the feature/damage-laws branch from ac4fc2a to 90bf8c3 Compare October 17, 2026 21:44
@petlenz
petlenz force-pushed the feature/uvwmaterial-mapping branch from fdaa5f7 to 00adc74 Compare October 17, 2026 21:44
@petlenz
petlenz force-pushed the feature/damage-laws branch from 90bf8c3 to 80652e8 Compare October 17, 2026 22:46
@petlenz
petlenz force-pushed the feature/uvwmaterial-mapping branch from 00adc74 to 439b34d Compare October 17, 2026 22:46
@petlenz
petlenz force-pushed the feature/damage-laws branch from 80652e8 to 28d4b5e Compare October 18, 2026 13:01
@petlenz
petlenz force-pushed the feature/uvwmaterial-mapping branch from 439b34d to c81bf8f Compare October 18, 2026 13:13
@petlenz
petlenz force-pushed the feature/damage-laws branch from 28d4b5e to 13fd875 Compare October 18, 2026 13:38
@petlenz
petlenz force-pushed the feature/uvwmaterial-mapping branch from c81bf8f to d9a9773 Compare October 18, 2026 13:38
@petlenz
petlenz force-pushed the feature/damage-laws branch from 13fd875 to 485fd9b Compare October 18, 2026 18:55
@petlenz
petlenz force-pushed the feature/uvwmaterial-mapping branch from d9a9773 to 76c0d56 Compare October 18, 2026 18:55
@petlenz
petlenz force-pushed the feature/damage-laws branch from 485fd9b to 44f79fd Compare October 18, 2026 20:03
@petlenz
petlenz force-pushed the feature/uvwmaterial-mapping branch from 76c0d56 to 083302e Compare October 18, 2026 20:03
@petlenz
petlenz force-pushed the feature/damage-laws branch from 44f79fd to 056f7b1 Compare October 18, 2026 20:22
@petlenz
petlenz force-pushed the feature/uvwmaterial-mapping branch from 083302e to b6f2221 Compare October 18, 2026 20:22
load_driver runs one material point under mixed strain/stress control
(uniaxial stress solves the five lateral strains with the material tangent)
and records the Newton residuals; material_report runs the load cases of a
case.json and writes CSV; reports/make_report.py turns them into figures and
the results section of docs/materials/<material>/README.md.
The correction solves (P:C:P + Isym - P + Iskw) : d_eps = -P:(sigma - sigma*)
with tmech::invf instead of a hand-written 6x6 elimination; Iskw makes the
operator regular on the full 9x9 space. Strain, stress and tangent are
tensors, converted to and from the evaluator buffers with tensor_conversion.
A report document holds the model graph, the material point, recorded
columns wired to any graph property ("material::property[i,j]"), the load
cases, the figures and the checks. Includes merge shared cases and figures;
"$name" strings take parameters. material_report writes resolved.json,
graph.json (materials, parameters, produced and consumed properties) and
CSV per case; make_report.py evaluates the checks against closed forms,
draws the figures and writes the results with the wiring diagram. Every
report is a ctest (checks only).
C++: load_control (stress/strain projectors), load_path (steps as a view),
report_json (parsing into value types), case_runner (material_point and
run_case over a step_sink concept), csv_sink, graph_description; the tool
is now an entry point. load_driver keeps no per-step state: a step_result
carries its start state, so tangent_error works for any earlier step.
Produced properties are listed by name (the registry orders by address).

Python: dataclasses for runs, cases and check results; expressions, checks,
panel renderers (registry by kind) and Markdown sections as separate
functions; unit tests in reports/test_make_report.py (ctest report_script).
… 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.
…history

sigma_{n+1} = sigma_n + C : (eps_{n+1} - eps_n) with the tangent read from
another material, for path-dependent tangents. Report: equals the total
form on every path, a closed path returns to zero, exact for any step.
Drivers: the convergence test also scales with |C| |d eps| (|A| |dF|), so
a hypoelastic stress crossing zero under stress control converges.
eps_th = alpha (T - T_ref) I from a scalar temperature source; linear
elasticity subtracts an optional eigenstrain: sigma = C : (eps - eps_eig).
dz/dt = (k1 + k2 z^m) (1 - z)^n with Arrhenius rate constants, as a rate
law for rk_integrator next to curing_rate (the autocatalytic term alone;
nth order is curing_rate with m = 0).
inclusion takes a fraction_source ("material::property") so the volume
fraction can follow the degree of cure; the chemical shrinkage
beta xi I is thermal_eigenstrain with the cure state as its source.
Three propagation laws of uvwmaterial next to the linear and exponential
ones (damage_exponential2 is the existing exponential law). Report of
isotropic_damage with every law recorded; the report point takes
stress_property and tangent_property; named entries of an include can be
replaced, so the tangent check skips the steps on the damage surface.
…d the state-function parameters

The converter writes an eshelby_sphere / _cylinder / _spheroid node per
uvwmaterial eshelby_tensor, wired to the composite's matrix, and the inclusion
or short_fibre_composite names it. Its output is the report layout
{"model", "point"}: json_model rejects an unknown top-level key, so the
earlier {"materials", "point"} did not load. uvwmaterial's linear law
D = K kappa is the power law with m = 1 (linear_damage_law is the kappa_0 ..
kappa_f ramp); strain_energy_state_function gets tangent_source and
youngs_modulus, vector_strain_state_function the axis indices. The C++ cards
test holds the converter's actual output.
@petlenz
petlenz force-pushed the feature/damage-laws branch from 056f7b1 to fc0f56b Compare October 19, 2026 04:07
@petlenz
petlenz force-pushed the feature/uvwmaterial-mapping branch from b6f2221 to 98ec074 Compare October 19, 2026 04:07
Main has the reviewed split of this branch (#199-#203), so main's version is
taken everywhere; the branch no longer differs from main.
…ls-and-constants

# Conflicts:
#	tests/CMakeLists.txt
@petlenz
petlenz changed the base branch from feature/damage-laws to main October 24, 2026 21:17
…eshelby-tensors

# Conflicts:
#	tests/CMakeLists.txt
…v-depolarisation

# Conflicts:
#	tests/CMakeLists.txt
…/rule-of-mixture

# Conflicts:
#	tests/CMakeLists.txt
# Conflicts:
#	include/numsim-materials/report/report_json.h
#	tests/CMakeLists.txt
residual_source, residual_tolerance and max_passes are driver parameters
(material_point's defaults) and keys of the report's "point"; the mean-field
tangent report uses them for the self-consistent fixed point.
…averaging

# Conflicts:
#	tests/CMakeLists.txt
…-composite

# Conflicts:
#	tests/CMakeLists.txt
…-elasticity

# Conflicts:
#	include/numsim-materials/umat/deformation_gradient_driver.h
#	include/numsim-materials/umat/material_point_driver.h
#	tests/CMakeLists.txt
…genstrain

# Conflicts:
#	tests/CMakeLists.txt
# Conflicts:
#	include/numsim-materials/report/report_json.h
#	tests/CMakeLists.txt
#	tests/test_report_case.cpp
The report's "point" names them for materials that publish e.g.
damaged_stress / damaged_tangent (isotropic_damage report).
# Conflicts:
#	reports/CMakeLists.txt
#	tests/CMakeLists.txt
@petlenz
petlenz marked this pull request as ready for review October 27, 2026 17:50
@petlenz
petlenz merged commit 958fcdb into main Oct 27, 2026
2 checks passed
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.

uvwmaterial to numsim-materials type and parameter mapping, and a converter for old material cards

1 participant